說說Android案頭(Launcher應用)背後的故事(二)——應用程式的添加

來源:互聯網
上載者:User

 部落格搬家啦——為了更好地經營部落格,本人已經將部落格遷移至www.ijavaboy.com。這裡已經不再更新,給您帶來的不便,深感抱歉!這篇文章的新地址:點擊我

上篇中,講到了第一個功能中需要擷取應用程式的資訊,然後添加到案頭。這裡,先記錄下如何擷取Android中的應用程式資訊。

一、調用系統捷徑列表

         Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);        pickIntent.putExtra(Intent.EXTRA_INTENT,                new Intent(Intent.ACTION_CREATE_SHORTCUT));        pickIntent.putExtra(Intent.EXTRA_TITLE,                res.getString(R.string.title_select_app));                pickIntent.putExtras(bundle);                startActivityForResult(pickIntent, REQUEST_PICK_SHORTCUT);

 

這個擷取到的就是所有可以建立的捷徑,但是我們需要在這個列表中加入其他項怎麼辦呢?因為我們知道,我需要在這個列表中加入“應用程式”,這一項,這樣當我們點擊應用程式的時候,就可以顯示應用程式列表。這個時候,我們只需要傳入額外的資訊就可以了,如下:

 

Resources res = getResources();/** * 用一個Bundle對象,傳遞兩個list資訊 * 一個list中存放需要附加到快捷列表中的項的文字 * 一個list中存放每一個對應的表徵圖資訊 */        Bundle bundle = new Bundle();                ArrayList<String> shortcutNames = new ArrayList<String>();        shortcutNames.add(res.getString(R.string.group_application));        shortcutNames.add("其他");        //顯示在List第一個的應用捷徑的名字        bundle.putStringArrayList(Intent.EXTRA_SHORTCUT_NAME, shortcutNames);                //顯示表徵圖        ArrayList<ShortcutIconResource> shortcutIcons =                new ArrayList<ShortcutIconResource>();        shortcutIcons.add(ShortcutIconResource.fromContext(UorderLauncher.this,                R.drawable.icon));        shortcutIcons.add(ShortcutIconResource.fromContext(UorderLauncher.this,                R.drawable.icon));        bundle.putParcelableArrayList(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, shortcutIcons);                Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);        pickIntent.putExtra(Intent.EXTRA_INTENT,                new Intent(Intent.ACTION_CREATE_SHORTCUT));        pickIntent.putExtra(Intent.EXTRA_TITLE,                res.getString(R.string.title_select_app));        //將附加資訊加入到pickIntent        pickIntent.putExtras(bundle);                startActivityForResult(pickIntent, REQUEST_PICK_SHORTCUT);

二、調用應用程式列表

當我們點擊我們附加的項“應用程式”時,我們希望彈出應用程式列表,這個也可以條用系統內建列表,也可以使用自己定義的列表。

1、調用系統應用資訊列表

在上面我們加上了一個附加項“應用程式”,那麼我們怎麼知道,當前點擊的是“應用程式”這一項呢?注意上面我們啟動的時候是startActivityForResult(pickIntent, REQUEST_PICK_SHORTCUT);

在onActivityResult中處理該請求對應的邏輯:如果使用者選擇的是“應用程式”,則調用系統應用程式列表,否則,直接請求建立捷徑

private void addShortcut(Intent data){Resources res = getResources();final String appName = res.getString(R.string.group_application);final String shortcutName = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);if(appName.equals(shortcutName)){//說明使用者選擇的是應用程式,進入應用程式列表Intent mainIntent = new Intent(Intent.ACTION_MAIN,null);mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);startActivityForResult(pickIntent, REQUEST_PICK_APPLICATION);}else{//否則,直接建立捷徑startActivityForResult(data, REQUEST_CREATE_SHORTCUT);}}

這樣,就實現點擊“應用程式”則顯示應用程式列表,否則,建立捷徑

2、擷取所有應用程式資訊,實現自訂的應用程式列表

其實,對於系統中所有應用程式的資訊,程式中都是可以擷取到的。在案頭點擊的時候用的是系統內建的應用程式列表。但是,當點擊案頭下方的應用程式圖示的時候,就需要顯示一個GridView顯示所有的應用程式資訊,這裡,就需要擷取應用程式資訊,然後放入每一個item中。這裡就順帶實現一下。布局和效果略過,只記錄如果擷取應用程式資訊。

/** * 同樣,以ACTION_MAIN和CATEGORY_LAUNCHER作為過濾條件 * 查詢所有符合的應用資訊(ResolveInfo) * ResolveInfo中就包含了我們需要的主要資訊。 * 當然還有其他的方式擷取應用資訊,如PackageInfo,關於這些資訊,可以參看 * http://android.tgbus.com/Android/tutorial/201108/364210.shtml */final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);final PackageManager pManager = this.getPackageManager();/** * queryIntentActivities通過解析所有應用程式中含有如下Intent-filter的App * <intent-filter> * <action android:name="android.intent.action.MAIN" /> * <category android:name="android.intent.category.LAUNCHER" /> * </intent-filter> */final List<ResolveInfo> infoList = pManager.queryIntentActivities(mainIntent, 0);if(infoList != null){ArrayList<AppInfo> appList = new ArrayList<AppInfo>();for(ResolveInfo info : infoList){AppInfo app = makeAppInfo(pManager, info);appList.add(app);}return appList;}return null;

程式還包含了一個makeAppInfo(pManager, info);這個方法源碼是:

private AppInfo makeAppInfo(PackageManager pManager, ResolveInfo info) {//有了ComponentName,就可以儲存每個應用程式的啟動資訊//下次我們可以直接啟動它ComponentName component = new ComponentName(info.activityInfo.applicationInfo.packageName,info.activityInfo.name);//這個是自己定義的一個用來封裝我們需要的應用程式的資訊AppInfo app = new AppInfo();//擷取應用的名稱CharSequence appName = info.loadLabel(pManager);if(appName == null){//如果沒有成功擷取到,則用其主Activity的名字作為應用程式名稱appName = info.activityInfo.name;}app.name = appName.toString();//擷取應用程式的表徵圖Drawable draw = info.activityInfo.loadIcon(pManager);//應用程式圖片可以大小不一,這裡需要將他們的size限定在一定的大小app.icon = BitmapUtils.createIconThumbnail(draw, getApplicationContext());//將啟動資訊儲存在AppInfo中,在我們的應用中啟動另一個應用程式,使用FLAG_ACTIVITY_NEW_TASKapp.setActivity(component, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);return app;}

 

這樣就得到了所有的應用程式資訊。系統Launcher在其GridView中列出的所有應用就是這麼擷取的。

 

三、擷取應用程式資訊的其他方式:

下面這個擷取到的應用資訊,你會發現比上面的方法多了很多,因為其獲得的是系統中所有的安裝包資訊

List<PackageInfo> packageList = this.getPackageManager().getInstalledPackages(0);appList = new ArrayList<AppInfo>();for(PackageInfo info : packageList){CharSequence appName = info.applicationInfo.loadLabel(getPackageManager());if(TextUtils.isEmpty(appName)){appName = info.packageName;}//加上下面這個if條件就把系統內建的應用給過濾掉了,擷取到的僅僅是我們自己安裝的if((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)<=0){ComponentName comp = getComponentName(info.packageName);AppInfo appInfo = new AppInfo();appInfo.icon = info.applicationInfo.loadIcon(getPackageManager());appInfo.name = appName.toString();appInfo.setActivity(comp, Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);appList.add(appInfo);}}

程式中調用了getComponentName,其源碼是:

private ComponentName getComponentName(String packageName) {Intent intent = new Intent(Intent.ACTION_MAIN, null);intent.addCategory(Intent.CATEGORY_LAUNCHER);intent.setPackage(packageName);List<ResolveInfo> infoList = getPackageManager().queryIntentActivities(intent, 0);if(infoList != null && infoList.size()>0){ResolveInfo info = infoList.get(0);if(info != null){String pkgName = info.activityInfo.packageName;String clsName = info.activityInfo.name;return new ComponentName(pkgName, clsName);}}return null;}

 

到處,也就很清楚Launcher中長按案頭,應用程式是如何選擇和在GridView中的應用程式資訊是如何擷取到的了。

下一篇,將繼續介紹CellLayout自訂控制項的實現原理!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.