05-09 17:01:13.547: I/ActivityManager(3003): START u0 {act=android.intent.action.VIEW cat=[android.intent.category.BROWSABLE] dat=https://www.baidu.com cmp=android/com.android.internal.app.ResolverActivity} from pid 5222
05-09 17:01:13.587: I/ActivityManager(3003): Start proc system:ui for activity android/com.android.internal.app.ResolverActivity: pid=15544 uid=1000 gids={41000, 3002, 3001, 3003, 1028, 1015, 1023, 1021, 3004, 3005, 1000, 3009, 1010}
05-09 17:01:14.557: I/ActivityManager(3003): Displayed android/com.android.internal.app.ResolverActivity: +975ms

从ActivityManger输出Log可以知道是ResolverActivity处理app选择。

android\frameworks\base\core\java\com\android\internal\app\ResolverActivity.java

protected void onCreate(Bundle savedInstanceState) {
// Use a specialized prompt when we're handling the 'Home' app startActivity()
final int titleResource;
final Intent intent = makeMyIntent();
final Set<String> categories = intent.getCategories();
if (Intent.ACTION_MAIN.equals(intent.getAction())
&& categories != null
&& categories.size() == 1
&& categories.contains(Intent.CATEGORY_HOME)) {
titleResource = com.android.internal.R.string.whichHomeApplication;//选择主屏幕应用
} else {
titleResource = com.android.internal.R.string.whichApplication;//选择要使用的应用:
} onCreate(savedInstanceState, intent, getResources().getText(titleResource),
null, null, true);
}
 protected void onCreate(Bundle savedInstanceState, Intent intent,
CharSequence title, Intent[] initialIntents, List<ResolveInfo> rList,
boolean alwaysUseOption) {
setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert);
super.onCreate(savedInstanceState);
try {
mLaunchedFromUid = ActivityManagerNative.getDefault().getLaunchedFromUid(
getActivityToken());
} catch (RemoteException e) {
mLaunchedFromUid = -1;
}
mPm = getPackageManager();
mAlwaysUseOption = alwaysUseOption;
mMaxColumns = getResources().getInteger(R.integer.config_maxResolverActivityColumns); AlertController.AlertParams ap = mAlertParams; ap.mTitle = title; mPackageMonitor.register(this, getMainLooper(), false);
mRegistered = true; final ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
mIconDpi = am.getLauncherLargeIconDensity();
mIconSize = am.getLauncherLargeIconSize(); mAdapter = new ResolveListAdapter(this, intent, initialIntents, rList, mLaunchedFromUid);//获取APP列表
int count = mAdapter.getCount();
if (mLaunchedFromUid < 0 || UserHandle.isIsolated(mLaunchedFromUid)) {
// Gulp!
finish();
return;
} else if (count > 1) {
ap.mView = getLayoutInflater().inflate(R.layout.resolver_list, null);
mListView = (ListView) ap.mView.findViewById(R.id.resolver_list);
mListView.setAdapter(mAdapter);
mListView.setOnItemClickListener(this);
mListView.setOnItemLongClickListener(new ItemLongClickListener()); if (alwaysUseOption) {
mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
} else if (count == 1) {
startActivity(mAdapter.intentForPosition(0));
mPackageMonitor.unregister();
mRegistered = false;
finish();
return;
} else {
ap.mMessage = getResources().getText(R.string.noApplications);
} setupAlert(); if (alwaysUseOption) {
final ViewGroup buttonLayout = (ViewGroup) findViewById(R.id.button_bar);
if (buttonLayout != null) {
buttonLayout.setVisibility(View.VISIBLE);
mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always);
mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once);
} else {
mAlwaysUseOption = false;
}
// Set the initial highlight if there was a preferred or last used choice
final int initialHighlight = mAdapter.getInitialHighlight();
if (initialHighlight >= 0) {
mListView.setItemChecked(initialHighlight, true);
onItemClick(null, null, initialHighlight, 0); // Other entries are not used
}
}
}

点击“始终”按钮,设置默认程序

public void onButtonClick(View v) {
final int id = v.getId();
startSelected(mListView.getCheckedItemPosition(), id == R.id.button_always);
dismiss();
} void startSelected(int which, boolean always) {
if (isFinishing()) {
return;
}
ResolveInfo ri = mAdapter.resolveInfoForPosition(which);
Intent intent = mAdapter.intentForPosition(which);
onIntentSelected(ri, intent, always);
finish();
} protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) {
if (mAlwaysUseOption && mAdapter.mOrigResolveList != null) {
// Build a reasonable intent filter, based on what matched.
IntentFilter filter = new IntentFilter(); if (intent.getAction() != null) {
filter.addAction(intent.getAction());
}
Set<String> categories = intent.getCategories();
if (categories != null) {
for (String cat : categories) {
filter.addCategory(cat);
}
}
filter.addCategory(Intent.CATEGORY_DEFAULT); int cat = ri.match&IntentFilter.MATCH_CATEGORY_MASK;
Uri data = intent.getData();
if (cat == IntentFilter.MATCH_CATEGORY_TYPE) {
String mimeType = intent.resolveType(this);
if (mimeType != null) {
try {
filter.addDataType(mimeType);
} catch (IntentFilter.MalformedMimeTypeException e) {
Log.w("ResolverActivity", e);
filter = null;
}
}
}
if (data != null && data.getScheme() != null) {
// We need the data specification if there was no type,
// OR if the scheme is not one of our magical "file:"
// or "content:" schemes (see IntentFilter for the reason).
if (cat != IntentFilter.MATCH_CATEGORY_TYPE
|| (!"file".equals(data.getScheme())
&& !"content".equals(data.getScheme()))) {//注意这里排除了"file://", "content://"
filter.addDataScheme(data.getScheme()); // Look through the resolved filter to determine which part
// of it matched the original Intent.
Iterator<PatternMatcher> pIt = ri.filter.schemeSpecificPartsIterator();
if (pIt != null) {
String ssp = data.getSchemeSpecificPart();
while (ssp != null && pIt.hasNext()) {
PatternMatcher p = pIt.next();
if (p.match(ssp)) {
filter.addDataSchemeSpecificPart(p.getPath(), p.getType());
break;
}
}
}
Iterator<IntentFilter.AuthorityEntry> aIt = ri.filter.authoritiesIterator();
if (aIt != null) {
while (aIt.hasNext()) {
IntentFilter.AuthorityEntry a = aIt.next();
if (a.match(data) >= 0) {
int port = a.getPort();
filter.addDataAuthority(a.getHost(), port >= 0 ? Integer.toString(port) : null);
break;
}
}
}
pIt = ri.filter.pathsIterator();
if (pIt != null) {
String path = data.getPath();
while (path != null && pIt.hasNext()) {
PatternMatcher p = pIt.next();
if (p.match(path)) {
filter.addDataPath(p.getPath(), p.getType());
break;
}
}
}
}
} if (filter != null) {
final int N = mAdapter.mOrigResolveList.size();
ComponentName[] set = new ComponentName[N];
int bestMatch = 0;
for (int i=0; i<N; i++) {
ResolveInfo r = mAdapter.mOrigResolveList.get(i);
set[i] = new ComponentName(r.activityInfo.packageName, r.activityInfo.name);
if (r.match > bestMatch) bestMatch = r.match;
}
if (alwaysCheck) {
getPackageManager().addPreferredActivity(filter, bestMatch, set, intent.getComponent());//设置默认
} else {
try {
AppGlobals.getPackageManager().setLastChosenActivity(intent,
intent.resolveTypeIfNeeded(getContentResolver()),
PackageManager.MATCH_DEFAULT_ONLY,
filter, bestMatch, intent.getComponent());
} catch (RemoteException re) {
Log.d(TAG, "Error calling setLastChosenActivity\n" + re);
}
}
}
} if (intent != null) {
startActivity(intent);
}
}

android设置多个类似APP其中的一个为默认的更多相关文章

  1. 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 ...

  2. Android 4.3实现类似iOS在音乐播放过程中如果有来电则音乐声音渐小铃声渐大的效果

    目前Android的实现是:有来电时,音乐声音直接停止,铃声直接直接使用设置的铃声音量进行铃声播放. Android 4.3实现类似iOS在音乐播放过程中如果有来电则音乐声音渐小铃声渐大的效果. 如果 ...

  3. Android 一个app启动另一个app

    最近,一个app启动另一个app,这个玩法挺火的嘛,有没有试过更新QQ到5.1版本,QQ的健康里面就可以添加其他app,实现从QQ跳转到其他app应用.这个挺好玩的,一下子带来了多少流量啊. 一.先来 ...

  4. Android M 特性 Doze and App Standby模式详解

    版权声明:本文由郑桂涛原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/185 来源:腾云阁 https://www.qclo ...

  5. Android - 分享内容 - 接收其他APP的内容

    就象程序可以发送数据给其他程序,所以也可以接收其他程序的数据.想一下用户如何和程序交互,以及想从其他程序接收什么样类型的数据.例如,一个社交程序可能对接收其他程序的文字(比如有趣的网址)感兴趣.Goo ...

  6. Android - 分享内容 - 给其他APP发送内容

    创建一个intent时,必须要指定intent将要触发的操作.Android定义了很多操作,包括ACTION_SEND,就象可以猜到的一样,表示intent是把数据从一个activity发送给另一个, ...

  7. Android TV开发总结(三)构建一个TV app的焦点控制及遇到的坑

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52835829 前言:上篇中,&l ...

  8. Android TV开发总结(一)构建一个TV app前要知道的事儿

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52792562 前言:近年来,智能 ...

  9. android一个app打开另一个app的指定页面

    一个app打开另一个app的指定页面方法 有以下几种 1.通过包名.类名 2.通过intent的 action 3.通过Url 方案1. ComponentName componentName = n ...

随机推荐

  1. java gui 下拉框中项删除按钮

    http://www.cnblogs.com/kangls/archive/2013/03/21/2972943.html http://m.blog.csdn.net/blog/ycb1689/74 ...

  2. SpringBoot之springfox(Swagger) (ApiDoc接口文档)

    Springfox的前身是swagger-springmvc,是一个开源的API doc框架,可以将我们的Controller的方法以文档的形式展现,基于Swagger. 官网地址:http://sp ...

  3. java 进程启用远程查看

    用jconsole 1.启动脚本增加: JAVA_OPTS="-Djava.net.preferIPv4Stack=true -Djava.rmi.server.hostname=192.1 ...

  4. [IIS]IIS扫盲(七)

    (4)汉化补丁 许多软件都是英文版本的,国人的英语水平普遍不高,包括笔者.因为这个,影响了不少人学习电脑的兴趣. 为了占领市场,软件开发商提供了中文版本:为了大家学习方便,爱好汉化工作的国人制作了汉化 ...

  5. ThinkPHP 3.2.3 Pager分页

    不是很喜欢TP的分页类,因为生成的分页url感觉有点不好理解,例如访问路径xxxx/home/show.html,在模板输出分页后,例如产生了页码,页码链接的路径会变成xxxx/home/show/p ...

  6. Array,ArrayList、List<T>、HashSet<T>、LinkedList<T>与Dictionary<K,V>

    Array: 数组在C#中最早出现的.在内存中是连续存储的,所以它的索引速度非常快,而且赋值与修改元素也很简单. 但是数组存在一些不足的地方.在数组的两个数据间插入数据是很麻烦的,而且在声明数组的时候 ...

  7. 继承自NSObject的不常用又很有用的函数(2)

    函数调用 Objective-C是一门动态语言,一个函数是由一个selector(SEL),和一个implement(IML)组成的.Selector相当于门牌号,而Implement才是真正的住户( ...

  8. 2016年11月26号随笔(关于oracle数据库)

    今天写了几个小时的sql语句,一开始我并没有思路,有思路便开始写. 首先我查询了入库表中的3级单位下的各个网点的入库信息,找到这些信息后,我又去入库明细表中查询入库的详细信息 找到了我要的把捆包箱的各 ...

  9. 洛谷P3366 【模板】最小生成树

    P3366 [模板]最小生成树 319通过 791提交 题目提供者HansBug 标签 难度普及- 提交  讨论  题解 最新讨论 里面没有要输出orz的测试点 如果你用Prim写了半天都是W- 题目 ...

  10. win7出现无法连接到代理服务器的错误,不能上网的问题的解决

    今天晚上突然停电,等我打开电脑发现不然上网,用google浏览器出现这个错误: 用IE诊断错误如下: 说是不能连到代理服务器,但是我没有连接到代理服务器啊,但是我的QQ能登,就是不能用浏览器上网,经过 ...