我把這個默認(rèn)啟動器起名為NewLauncher漓拾,它的功能是能夠以列表的形式展現(xiàn)你設(shè)備上的可啟動應(yīng)用(可啟動應(yīng)用是指用戶點擊主屏幕或啟動器界面上的圖標(biāo)就能打開的應(yīng)用),比如微信,微博晦闰,QQ等等痢站。
使用PackageManager可獲取所有可啟動主Activity,可啟動主Activity都帶有包含MAIN操作(action)和LAUNCHER類別(category)的intent過濾器(intent-filter)冤吨。打開任何一個應(yīng)用項目AndroidManifest.xml文件蒿柳,可以看到
獲取方法如下
private void setupAdapter(){
Intent startupIntent = newIntent(Intent.ACTION_MAIN);
startupIntent.addCategory(Intent.CATEGORY_LAUNCHER);
/**使用了Fragment,所以調(diào)用getActivity()獲取當(dāng)前上下文Context**/
final PackageManager packageManager = getActivity().getPackageManager();
/**獲取匹配的activity列表**/
List<ResolverInfo> activities = packageManager.queryIntentActivities(startupIntent,0);
}
在PackageManager返回的ResolveInfo對象中漩蟆,可以獲取activity標(biāo)簽和其他一些元數(shù)據(jù)垒探。首先,對ResolveInfo對象中的activity標(biāo)簽按首字母排序怠李。
Collections.sort(activities, new Comparator() {
@Override
public intcompare(ResolveInfo o1,ResolveInfo o2) {
PackageManager packageManager1 = getActivity().getPackageManager();
return String.CASE_INSENSITIVE_ORDER.compare(
o1.loadLabel(packageManager1).toString(),
o2.loadLabel(packageManager1).toString());
}
});
要創(chuàng)建啟動activity的顯示intent圾叼,需要從ResolveInfo對象中獲取activity的包名與類名,這些信息可以從ResolveInfo對象的ActivityInfo中獲取捺癞。下面創(chuàng)建一個顯示intent并啟動目標(biāo)activity
@Override
public void onClick(View v) {
/**mResolveInfo就是之前獲取的activities**/
ActivityInfo activityInfo = mResolveInfo.activityInfo;
Intent i = newIntent(Intent.ACTION_MAIN)
.setClassName(activityInfo.applicationInfo.packageName, activityInfo.name)
/**為了在啟動新activity時啟動新任務(wù)夷蚊,需要為intent添加一個標(biāo)志
FLAG_ACTIVITY_NEW_TASK標(biāo)志控制每個activity僅創(chuàng)建一個任務(wù)**/
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
作為顯示intent的一部分,我們還發(fā)送了ACTION_MAIN操作翘簇。發(fā)送的intent是否包含操作(action)撬码,對于大多數(shù)應(yīng)用來說沒有什么差別,不過版保,有些應(yīng)用的啟動行為可能會有所不同呜笑。取決與不同的啟動要求夫否,同樣的activity可能會顯示不同的用戶界面。開發(fā)人員最好能明確啟動意圖叫胁,以便讓activity完成它應(yīng)該完成的任務(wù)凰慈。
通常的顯示intent創(chuàng)建一般使用接受Context和Class對象的Intent構(gòu)造方法
public Intent(Context packageContext, Class<?> cls)
該構(gòu)造方法使用傳入的參數(shù)來獲取Intent需要的ComponentName,ComponentName由包名和類名共同組成驼鹅。該構(gòu)造方法會通過Activity類自行確定全路徑包名微谓。也可以自己通過包名和類名創(chuàng)建ComponentName,然后使用下面的Intent方法創(chuàng)建顯示intent
public Intent setComponent(Component component)
不過输钩,setClassName(...)方法能夠自動創(chuàng)建ComponentName豺型,需要實現(xiàn)的代碼相對較少。
public Intent setClassName(String packageName, String className)
通過添加HOME和DEFAULT類別定義买乃,NewLauncher應(yīng)用的activity會成為可選的主界面姻氨,進入設(shè)置-->應(yīng)用管理-->選擇默認(rèn)應(yīng)用設(shè)置-->桌面-->選擇NewLauncher即可。不用擔(dān)心剪验,之后再通過相同的操作便可修改回來肴焊,別忘了,我們可以通過NewLauncher啟動設(shè)置功戚。
有關(guān)Fragment和RecyclerView的使用并沒有本文闡述娶眷,因為目前為止,這個應(yīng)用都比較簡單啸臀,有興趣的朋友可以在這個鏈接查看源代碼届宠。
該應(yīng)用還有很多可以擴展的地方,希望有一天可以自己做出一個覺得可以替代系統(tǒng)桌面的應(yīng)用啟動器壳咕。