一个app,多个入口图标,activity-alias实现多程序入口并显示指定view完成

http://blog.csdn.net/black0591/article/details/8264168

需求总是一个接一个。
missed call需要一个单独的图标,点击进入,而missed call 本身在linhone activity中。

思路,使用activity alias。
当然,需要intent启动activity,也就需要filter

在android的应用程序可以有多个Activity,每个Activity是同级别的,那么在启动程序时,最先启动哪个Activity呢?有些程序可能需要显示在程序列表里,有些不需要。怎么定义呢?

android.intent.action.MAIN 决定应用程序最先启动的Activity 。
android.intent.category.LAUNCHER决定应用程序是否显示在程序列表里。

因为你的程序可能有很多个activity,
只要xml配置文件中有这么一个intent-filter,而且里面有这个launcher,那么这个activity就是点击程序时最先运行的那个activity。

如果只有一个Activity,没有这两句也可以。

隐藏icon实际上就是注释掉intent-filter中的一句

[html] view
plain
copy

  1. <intent-filter>  
  2.     <action android:name="android.intent.action.MAIN" />  
  3.     <category android:name="android.intent.category.DEFAULT" />  
  4.     <!--    
  5.     <category android:name="android.intent.category.LAUNCHER" /> 
  6.     -->  
  7.     <category android:name="android.intent.category.BROWSABLE" />  
  8. </intent-filter>  

intent一定要有的3个匹配值, action, category, data.
在某个Activity里用startActivity()方法发送一个intent,这个intent设定了一些条件,比如用方法setAction(),addCategory()设定了两个属性,

  发送了这个intent之后,android会去系统里保存的MainManifest.xml清单(假设这个系统存放全部apk清单的文件为MainManifest.xml)里查找符合这两个属性的activity,然后启动它。

当某个Activity用startActivity(intentOther)方法向系统发送了一个intent(假如为 intentOther),那么android系统会去查找这个MainManifest.xml里注册的<intent-filter >属性,

  查找到符合这个 intentOther 的就启动这个Activity,如果有多个这样的Activity符合条件的话,就跳出一个对话框让用户选择究竟要启动哪一个

以上是理论, 实际代码如下:

[java] view
plain
copy

  1. <!-- display missed call -->  
  2. <activity-alias  
  3.     android:name="@string/missedcallactivity"  
  4.     android:icon="@drawable/missing_icon"  
  5.     android:label="@string/missedcallactivity"  
  6.     android:targetActivity=".CustomLinphoneDialer" >  
  7.     <intent-filter>  
  8.         <action android:name="android.intent.action.MAIN" />  
  9.    
  10.         <category android:name="android.intent.category.LAUNCHER" />  
  11.     </intent-filter>  
  12. </activity-alias>  

这个代码 能显示两个图标 ,我们的目的是 能显示通话记录, 还得调用target activity, and show call history activity.
是不是 需要 多个intent filter?  下面reference a  link to explan intent filter.

Intent filter

为了能支持隐式intent,activity、service和broadcast receiver会包含1到多个intent filter。每个intent filter描述组件的可接收一组intent的能力。在intent filter中,说明了可接受的类型,以及不想要的intent。隐式的intent要想投递到一个组件,只需通过组件的一个filter即可。

组件把filter分成多个,是为了针对具体不同的任务。在sample中的Note pad示例中,NoteEditor activity有两个filter,一个用于启动并打开指定的note,另一个是为了打开新的空的note。

一个intent filter是一个IntentFilter类的实例。但是,android系统必须在组件未启动的情况下就知道它的能力,因此intent filter一般不会在java代码中设置,而是在应用的manifest文件中作为<intent-filter>元素的方式声明。一个例 外是,为broadcast receiver注册动态的filter,可以调用Context.registerReceiver()方法,通过直接实例化IntentFilter 对象创建。

filter有三个平等的部分:action、data和category。隐式intent将测试这三个部分。一个intent要想投递到一个组 件,那么这三个测试都要通过才行。当然如果组件有多个intent filter,可能一个intent没有通过,但是通过了另外的一个,这样也可以把intent投递到组件。

action测试

在intent filter中可以包含多个action,比如:

[html] view
plain
copy

  1. <intent-filter . . . >  
  2.     <action android:name="com.example.project.SHOW_CURRENT" />  
  3.     <action android:name="com.example.project.SHOW_RECENT" />  
  4.     <action android:name="com.example.project.SHOW_PENDING" />  
  5.     . . .  
  6. </intent-filter>  

要想通过测试,intent中的action名称要匹配其中之一。

如果intent filter中不包含action列表,而intent指定action,那么intent没有匹配的action,不通过;intent未指定action,而intent filter指定,会自动通过测试。

category测试

在intent filter中可包含category列表:

[html] view
plain
copy

  1. <intent-filter . . . >  
  2.     <category android:name="android.intent.category.DEFAULT" />  
  3.     <category android:name="android.intent.category.BROWSABLE" />  
  4.     . . .  
  5. </intent-filter>  

intent想通过测试,必须匹配一个intent filter中的category。

原理上讲,intent如果没有category设置,那么总是可以通过测试。这基本上是正确的,但是有一个例外。Android在为所有隐式 intent执行startActivity()方法的时候,会认为它们至少包含了一个 android.intent.category.DEFAULT。因此,如果activity想收到隐式intent,必须加入这个category。

date测试

data元素在intent filter元素中,可以重复多次(action和category不允许重复的),也可以根本没有。比如:

[html] view
plain
copy

  1. <intent-filter . . . >  
  2.     <data android:mimeType="video/mpeg" android:scheme="http" . . . />  
  3.     <data android:mimeType="audio/mpeg" android:scheme="http" . . . />  
  4.     . . .  
  5. </intent-filter>  

在data元素中指定uri和数据类型(MIME类型)。uri是被分开表示的:

[html] view
plain
copy

  1. scheme://host:port/path  

其中host和port是关联的,如果host没有设置,port也会忽略。

所有这些属性都是可选的,但是不是独立的。比如,如果要设置path,那么也必须设置schema、host和port。

在比较intent中的uri和intent filter中指定的uri时,只会比较intent filter中提及的URL部分。比如,intent filter中只提及了schema,那么所有url包含这个schema的都匹配。在filter的path部分可以使用通配符做到灵活的匹配。

mimeType属性,比uri方式更常用。intent和intent filter都可以使用mime通配符的方式,比如,text/*。

如果既有mimeType,又有uri的情况,比较规则如下:

  • 如果intent和intent filter都没有设置任何uri和mimetype,通过;
  • intent包含uri但是没有data type的情况,intent filter的uri部分与之匹配,而且也没有data type部分,可以通过,比如mailto:和tel:
  • intent对象包含数据类型但是没有uri部分,那么仅当intent filter也只有数据类型,而没有uri部分的时候能通过;
  • intent对象包括uri和数据类型(或者数据类型在uri中),分两部分测试,intent对象的数据类型要匹配intent filter,intent对象的uri,或者匹配intent filter中的uri,或者intent filter中没有uri部分(仅当intent对象的uri是content:或者file:的时候)。

新思路,可以启动CustomLinphoneDialer界面,然后在跳转到呼叫记录view, 
如何跳转呢?
设置全局flag,然后判断跳转,这样的话就需要在manifest中定义feature 的meta data, 保存要跳转的view, 并在CustomLinphoneDialer.java中判断。

因此新的manifest 修改为。

[html] view
plain
copy

  1. <activity-alias  
  2.     android:description="@string/history"  
  3.     android:icon="@drawable/ic_launcher_history"  
  4.     android:label="@string/history"  
  5.     android:name="CustomHistoryActivity"  
  6.     android:targetActivity=".CustomLinphoneDialer" >  
  7.     <intent-filter >  
  8.         <action android:name="android.intent.action.MAIN" />  
  9.   
  10.         <category android:name="android.intent.category.LAUNCHER" />  
  11.     </intent-filter>  
  12.   
  13.     <meta-data  
  14.         android:name="dltype"  
  15.         android:value="@string/dialer_history" >  
  16.     </meta-data>  
  17. </activity-alias>  

程序中 判断处理
在onCreate中判断出flag值,

[java] view
plain
copy

  1. private void getlauncherFlag()   
  2. {  
  3.     // get launcher flag  
  4.     try   
  5.     {  
  6.         ActivityInfo info = this.getPackageManager().getActivityInfo( getComponentName(), PackageManager.GET_META_DATA);  
  7.         launcherType = info.metaData.getString("dltype");  
  8.     }   
  9.     catch (Exception e)   
  10.     {  
  11.         e.printStackTrace();  
  12.     }      
  13. }  

根据flag做跳转

[java] view
plain
copy

  1. private void applistLoginTransferView()   
  2. {  
  3.     try {  
  4.         Log.d(TAG, "launcherType=" + launcherType);  
  5.         if (null != launcherType)  
  6.         {  
  7.             if (launcherType.equals(STRING_DIALER_CONTACT))   
  8.             {  
  9.                 transfer2ContactList();  
  10.             }   
  11.             else   
  12.             {  
  13.                 if (launcherType.equals(STRING_DIALER_HISTORY))   
  14.                 {  
  15.                     transfer2HistoryList();  
  16.                 }   
  17.                 else   
  18.                 {  
  19.                     // do nothing.  
  20.                 }  
  21.             }  
  22.         }  
  23.     }  
  24.     catch (Exception e)  
  25.     {  
  26.         e.printStackTrace();  
  27.     }  
  28. }   

[java] view
plain
copy

  1. transfer2HistoryList();  

这个transfer2HistoryList是原来的跳转机制,略过。
到此activity-alias实现app另外程序入口并显示指定view完成。

http://blog.csdn.net/sam_zhang1984/article/details/7278470

一个工程对应一个AndroidManifest.xml文件,这个文件中包含有该项目的一些设置,如权限、SDk版Activity、Service信息等。一般而言,这个文件中会有且仅有一个application节点,这个节点表示这是一个应用程序,不管它下面还有多少子节点如Activity、Service等等。形象的说,就是这个项目生成的apk安装到Android设备后,应用程序列表中会出现一个ICON,这个ICON就是这个程序的执行入口了。

 

但是,某些情况下,我们需要为我们的apk设置多个执行入口,也就是安装后在应用程序列表中出现多个ICON图标,各个ICON是APP不同模块的入口点,并且各个模块运行在不同的进程中。

可能这种需求很少见,但还是有一个现实的例子:系统中的联系人和电话这两个程序。表面看来这是两个独立的应用程序,但实际上它们只是一个应用程序的两个执行入口而已,点击联系人图标就会进入联系人界面,点击电话图标就会进入拨号界面,这都是通过设置该项目下Activity的属性来实现的。

Activity有一个重要的属性process,这个属性是指定Activity运行时所在的进程。没有指定此属性的话,所有程序组件运行在应用程序默认的进程中,这个进程名跟应用程序的包名一致。中所有组建元素的process属性能够为该组件设定一个新的默认值。但是任何组件都可以覆盖这个默认值,允许你将你的程序放在多进程中运行。如果这个属性被分配的名字以:开头, 当这个activity运行时, 一个新的专属于这个程序的进程将会被创建。

以下面的代码为例,项目中有两个Activity,其中一个采用默认属性,另一个为其指定process属性以及新的ICON,这样该项目安装到设备上之后可以发现多了两个应用程序图标,一个是应用程序默认的图标,点击后进入HelloWorldActivity;另一个是手动指定的ICON,点击后进入NextPageActivity。这时使用adb shell查看进程可以发现,两个Activity是运行在不同的进程中的。

AndroidManifest.xml的主要内容如下:

[html] view
plain
copy

  1. <activity android:name=".HelloWorldActivity"    
  2.           android:label="@string/app_name"    
  3.           android:process=":process.main">    
  4.          <intent-filter>    
  5.                 <action android:name="android.intent.action.MAIN" />    
  6.                 <category android:name="android.intent.category.LAUNCHER" />    
  7.          </intent-filter>    
  8. </activity>    
  9.      
  10. <activity android:name="cn.ian.NextPageActivity"    
  11.       android:label="@string/nextpage"    
  12.       android:process=":process.sub"    
  13.       android:icon="@drawable/icon1"    
  14.       android:launchMode ="singleInstance">    
  15.      <intent-filter>    
  16.                 <action android:name="android.intent.action.MAIN" />    
  17.                 <category android:name="android.intent.category.LAUNCHER" />    
  18.          </intent-filter>    
  19. </activity>    

通过上面的方式,为App的各个组件指定process和icon属性,便能够达到类似于一个apk中打包多个程序(模块)的目的。

ps:要特别注意,为Activity指定process属性后,还必须为其指定launchMode为singleInstance,这样才有效。

时间: 2024-11-08 22:21:24

一个app,多个入口图标,activity-alias实现多程序入口并显示指定view完成的相关文章

Android在应用中依据包名启动另外一个APP

以下为TestIntentData工程 MainActivity如下: package cn.testintentdata; import java.util.List; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.a

Android 启动另一个App/apk中的Activity实现代码

Android 启动另一个App/apk中的Activity实现代码 前言: Android提供了在一个App中启动另一个App中的Activity的能力,这使我们的程序很容易就可以调用其他程序的功能,从而就丰富了我们App的功能.比如在微信中发送一个位置信息,对方可以点击这个位置信息启动腾讯地图并导航.这个场景在现实中作用很大,尤其是朋友在陌生的环境找不到对方时,这个功能简直就是救星. 本来想把本文的名字叫启动另一个进程中的Activity,觉得这样才有逼格.因为每个App都会运行在自己的虚拟

Android App更改应用的图标的实现方法

Android App更改应用的图标的实现方法 一般情况下,我们App图标在Androidmanifest.xml中设置,通过Application android:icon属性指定,写法如下: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package=&q

界面跳转-从一个app跳转到另一个app的某个界面

问题描述 从一个app跳转到另一个app的某个界面 以微信为例跳转到微信的附近的人的界面该如何实现,用intent意图会报permission 权限错误,有大神知道还有什么办法吗? 解决方案 通过openURL启动第三方app并传参数← iOS 5.1.1怎样去掉锁屏界面的相机快捷图标?iOS越狱原理 →通过openURL启动第三方app并传参数Posted on 2012 年 6 月 4 日 by rainbird ?Download this page in PDF format转自:htt

一个APP从启动到主页面显示经历了哪些过程?

本文以图文并茂的形式简单介绍一个APP从启动到主页面显示经历了哪些流程,以及实现的原理.不介绍具体源码,仅仅构建一个大体框架. 一.流程概述 启动流程: ①点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求; ②system_server进程接收到请求后,向zygote进程发送创建进程的请求; ③Zygote进程fork出新的子进程,即App进程; ④App进程,通过Binder IPC向sytem_server进程

Android Studio 1.0.2项目实战——从一个APP的开发过程认识Android Studio

Android Studio 1.0.1刚刚发布不久,谷歌紧接着发布了Android Studio 1.0.2版本,和1.0.0一样,是一个Bug修复版本.在上一篇Android Studio 1.0.1 + Genymotion安卓模拟器打造高效安卓开发环境,我们介绍了Android开发环境的搭建,今天先来说一下上一篇中大家问道比较多的问题,然后说一些Android Studio的使用技巧.    一.搭建开发环境中遇到的问题及解决办法  1.Genymotion模拟器网络错误 我们顺利的安装

Android studio创建第一个app

本文实例为大家介绍了Android studio创建第一个app的详细步骤,供大家参考,具体内容如下 1.创建HelloWorld项目 任何编程语言写出的第一个程序毫无疑问都会是Hello World,这已经是自20世纪70年代一直流传下来的传统,在编程界已成为永恒的经典,那么今天就来使用Android studio创建第一个app(Hello World). 首先运行Android studio,在弹出的快捷窗口中新建一个项目. 点击上面截图中的"Star a new Android Stud

安卓 平板-安卓平板怎么设置使其只能访问固定的某一个app

问题描述 安卓平板怎么设置使其只能访问固定的某一个app 如题 为了要使某一款平板只能使用我们的一个app 其他软件都不能使用 我们需要做什么?急!!! 解决方案 两种方法 一:将别的APP的图标隐藏 二:将别的APP使用加密 解决方案二: 不让平板安装其它app? 解决方案三: 1.设置app全屏模式, 2.屏蔽退出本app功能(或本app不加退出功能), 3.屏蔽该平板所有的物理按钮 这点有点难度,4.0以上android系统,屏蔽home键有难度. 4.屏蔽屏幕顶端下滑下拉设置菜单 上面几

ios开发中能不能用一个app去下载另一个app的安装包并自动安装

问题描述 ios开发中能不能用一个app去下载另一个app的安装包并自动安装 需求:有一个主APP,用来下载其他APP,比如下载完成后自行安装到主APP中(就像插件),然后会产生一个图标,点击这个图标就会启动新安装的APP,当安装这个APP后又返回到主APP中.---------有点像Iphone的桌面. 有没有大神知道类似的实现方法. 解决方案 你看看腾讯的qq农场,其中需要跳转到qq牧场的时候就和你的情况一样,ps:QQ农场和qq牧场是俩app 解决方案二: 一般来说都是跳到APP stor