launcher修改--获取应用列表launcher源码解析

          在home节面上,当我们点击中间按键的时候,会跳转到一个下图,

在代码中是如何实现的呢?我们来找一下:

[java]  view plain copy
  1. mHandleView = (HandleView) findViewById(R.id.all_apps_button);  
  2.         mHandleView.setLauncher(this);  
  3.         mHandleView.setOnClickListener(this);  
  4.         mHandleView.setOnLongClickListener(this);  
再看onclick()方法:在onclick方法中,有一下代码

[java]  view plain copy
  1. else if (v == mHandleView) {  
  2.             if (isAllAppsVisible()) {  
  3.                 closeAllApps(true);  
  4.             } else {  
  5.                 showAllApps(true);  
  6.             }  
我们再找一下 showAllApps()方法

[java]  view plain copy
  1. void showAllApps(boolean animated) {  
  2.         mAllAppsGrid.zoom(1.0f, animated);  
  3.   
  4.         ((View) mAllAppsGrid).setFocusable(true);  
  5.         ((View) mAllAppsGrid).requestFocus();  
  6.           
  7.         // TODO: fade these two too  
  8.         mDeleteZone.setVisibility(View.GONE);  
  9.         mHandleView.setVisibility(View.GONE);  
  10.         mPreviousView.setVisibility(View.GONE);  
  11.         mNextView.setVisibility(View.GONE);  
  12.     hotseatLeft.setVisibility(View.GONE);  
  13.     hotseatRight.setVisibility(View.GONE);  
  14.     }  
在上面用到了mAllAppsGrid,我们找一下这个控件:

[java]  view plain copy
  1.     private AllAppsView mAllAppsGrid;  
  2.   
  3.         mAllAppsGrid = (AllAppsView)dragLayer.findViewById(R.id.all_apps_view);  
  4.         mAllAppsGrid.setLauncher(this);  
  5.         mAllAppsGrid.setDragController(dragController);  
  6.         ((View) mAllAppsGrid).setWillNotDraw(false); // We don't want a hole punched in our window.  
  7.         // Manage focusability manually since this thing is always visible  
  8.         ((View) mAllAppsGrid).setFocusable(false);  
上面代码是在Launcher.java中的setupview()方法中定义
all_apps_view是在all_app_2d.xml中定义。

你想找到AllApp2D.java中,可以找到mAllAppsGrid使用的方法,如addApps,removeApps,zoom这几个方法:

[java]  view plain copy
  1. public void addApps(ArrayList<ApplicationInfo> list) {  
  2. //        Log.d(TAG, "addApps: " + list.size() + " apps: " + list.toString());  
  3.   
  4.         final int N = list.size();  
  5.   
  6.         for (int i=0; i<N; i++) {  
  7.             final ApplicationInfo item = list.get(i);  
  8.             int index = Collections.binarySearch(mAllAppsList, item,  
  9.                     LauncherModel.APP_NAME_COMPARATOR);  
  10.             if (index < 0) {  
  11.                 index = -(index+1);  
  12.             }  
  13.             mAllAppsList.add(index, item);  
  14.         }  
  15.         mAppsAdapter.notifyDataSetChanged();  
  16.     }  
  17.   
  18.     public void removeApps(ArrayList<ApplicationInfo> list) {  
  19.         final int N = list.size();  
  20.         for (int i=0; i<N; i++) {  
  21.             final ApplicationInfo item = list.get(i);  
  22.             int index = findAppByComponent(mAllAppsList, item);  
  23.             if (index >= 0) {  
  24.                 mAllAppsList.remove(index);  
  25.             } else {  
  26.                 Log.w(TAG, "couldn't find a match for item \"" + item + "\"");  
  27.                 // Try to recover.  This should keep us from crashing for now.  
  28.             }  
  29.         }  
  30.         mAppsAdapter.notifyDataSetChanged();  
  31.     }  
  32.   
  33.      public void zoom(float zoom, boolean animate) {  
  34. //        Log.d(TAG, "zooming " + ((zoom == 1.0) ? "open" : "closed"));  
  35.         cancelLongPress();  
  36.   
  37.         mZoom = zoom;  
  38.   
  39.         if (isVisible()) {  
  40.             getParent().bringChildToFront(this);  
  41.             setVisibility(View.VISIBLE);  
  42.             mGrid.setAdapter(mAppsAdapter);  
  43.             if (animate) {  
  44.                 startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.all_apps_2d_fade_in));  
  45.             } else {  
  46.                 onAnimationEnd();  
  47.             }  
  48.         } else {  
  49.             if (animate) {  
  50.                 startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.all_apps_2d_fade_out));  
  51.             } else {  
  52.                 onAnimationEnd();  
  53.             }  
  54.         }  
  55.     }  
在zoom()方法里面有mGrid.setAdapter(mAppsAdapter),在构造方法中,给adapter已经赋值。

[java]  view plain copy
  1. public AllApps2D(Context context, AttributeSet attrs) {  
  2.         super(context, attrs);  
  3.         setVisibility(View.GONE);  
  4.         setSoundEffectsEnabled(false);  
  5.   
  6.         mAppsAdapter = new AppsAdapter(getContext(), mAllAppsList);  
  7.         mAppsAdapter.setNotifyOnChange(false);  
  8.     }  
那是如何获取应用列表的呢?我们再回到Launcher.java中,在loadHotseats()中:

[java]  view plain copy
  1. private void loadHotseats() {  
  2.        if (mHotseatConfig == null) {  
  3.            mHotseatConfig = getResources().getStringArray(R.array.hotseats);  
  4.            if (mHotseatConfig.length > 0) {  
  5.                mHotseats = new Intent[mHotseatConfig.length];  
  6.                mHotseatLabels = new CharSequence[mHotseatConfig.length];  
  7.                mHotseatIcons = new Drawable[mHotseatConfig.length];  
  8.            } else {  
  9.                mHotseats = null;  
  10.                mHotseatIcons = null;  
  11.                mHotseatLabels = null;  
  12.            }  
  13.   
  14.            TypedArray hotseatIconDrawables = getResources().obtainTypedArray(R.array.hotseat_icons);  
  15.            for (int i=0; i<mHotseatConfig.length; i++) {  
  16.                // load icon for this slot; currently unrelated to the actual activity  
  17.                try {  
  18.                    mHotseatIcons[i] = hotseatIconDrawables.getDrawable(i);  
  19.                } catch (ArrayIndexOutOfBoundsException ex) {  
  20.                    Log.w(TAG, "Missing hotseat_icons array item #" + i);  
  21.                    mHotseatIcons[i] = null;  
  22.                }  
  23.            }  
  24.            hotseatIconDrawables.recycle();  
  25.        }  
  26.   
  27.        PackageManager pm = getPackageManager();  
  28.        for (int i=0; i<mHotseatConfig.length; i++) {  
  29.            Intent intent = null;  
  30.            if (mHotseatConfig[i].equals("*BROWSER*")) {  
  31.                // magic value meaning "launch user's default web browser"  
  32.                // replace it with a generic web request so we can see if there is indeed a default  
  33.                String defaultUri = getString(R.string.default_browser_url);  
  34.                intent = new Intent(  
  35.                        Intent.ACTION_VIEW,  
  36.                        ((defaultUri != null)  
  37.                            ? Uri.parse(defaultUri)  
  38.                            : getDefaultBrowserUri())  
  39.                    ).addCategory(Intent.CATEGORY_BROWSABLE);  
  40.                // note: if the user launches this without a default set, she  
  41.                // will always be taken to the default URL above; this is  
  42.                // unavoidable as we must specify a valid URL in order for the  
  43.                // chooser to appear, and once the user selects something, that   
  44.                // URL is unavoidably sent to the chosen app.  
  45.            } else {  
  46.                try {  
  47.                    intent = Intent.parseUri(mHotseatConfig[i], 0);  
  48.                } catch (java.net.URISyntaxException ex) {  
  49.                    Log.w(TAG, "Invalid hotseat intent: " + mHotseatConfig[i]);  
  50.                    // bogus; leave intent=null  
  51.                }  
  52.            }  
  53.              
  54.            if (intent == null) {  
  55.                mHotseats[i] = null;  
  56.                mHotseatLabels[i] = getText(R.string.activity_not_found);  
  57.                continue;  
  58.            }  
  59.   
  60.            if (LOGD) {  
  61.                Log.d(TAG, "loadHotseats: hotseat " + i   
  62.                    + " initial intent=["   
  63.                    + intent.toUri(Intent.URI_INTENT_SCHEME)  
  64.                    + "]");  
  65.            }  
  66.   
  67.            ResolveInfo bestMatch = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);  
  68.            List<ResolveInfo> allMatches = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);  
  69.            if (LOGD) {   
  70.                Log.d(TAG, "Best match for intent: " + bestMatch);  
  71.                Log.d(TAG, "All matches: ");  
  72.                for (ResolveInfo ri : allMatches) {  
  73.                    Log.d(TAG, "  --> " + ri);  
  74.                }  
  75.            }  
  76.            // did this resolve to a single app, or the resolver?  
  77.            if (allMatches.size() == 0 || bestMatch == null) {  
  78.                // can't find any activity to handle this. let's leave the   
  79.                // intent as-is and let Launcher show a toast when it fails   
  80.                // to launch.  
  81.                mHotseats[i] = intent;  
  82.   
  83.                // set accessibility text to "Not installed"  
  84.                mHotseatLabels[i] = getText(R.string.activity_not_found);  
  85.            } else {  
  86.                boolean found = false;  
  87.                for (ResolveInfo ri : allMatches) {  
  88.                    if (bestMatch.activityInfo.name.equals(ri.activityInfo.name)  
  89.                        && bestMatch.activityInfo.applicationInfo.packageName  
  90.                            .equals(ri.activityInfo.applicationInfo.packageName)) {  
  91.                        found = true;  
  92.                        break;  
  93.                    }  
  94.                }  
  95.                  
  96.                if (!found) {  
  97.                    if (LOGD) Log.d(TAG, "Multiple options, no default yet");  
  98.                    // the bestMatch is probably the ResolveActivity, meaning the  
  99.                    // user has not yet selected a default  
  100.                    // so: we'll keep the original intent for now  
  101.                    mHotseats[i] = intent;  
  102.   
  103.                    // set the accessibility text to "Select shortcut"  
  104.                    mHotseatLabels[i] = getText(R.string.title_select_shortcut);  
  105.                } else {  
  106.                    // we have an app!  
  107.                    // now reconstruct the intent to launch it through the front  
  108.                    // door  
  109.                    ComponentName com = new ComponentName(  
  110.                        bestMatch.activityInfo.applicationInfo.packageName,  
  111.                        bestMatch.activityInfo.name);  
  112.                    mHotseats[i] = new Intent(Intent.ACTION_MAIN).setComponent(com);  
  113.   
  114.                    // load the app label for accessibility  
  115.                    mHotseatLabels[i] = bestMatch.activityInfo.loadLabel(pm);  
  116.                }  
  117.            }  
  118.   
  119.            if (LOGD) {  
  120.                Log.d(TAG, "loadHotseats: hotseat " + i   
  121.                    + " final intent=["   
  122.                    + ((mHotseats[i] == null)  
  123.                        ? "null"  
  124.                        : mHotseats[i].toUri(Intent.URI_INTENT_SCHEME))  
  125.                    + "] label=[" + mHotseatLabels[i]  
  126.                    + "]"  
  127.                    );  
  128.            }  
  129.        }  
  130.    }  

有点复杂,主要代码其实如下:

[java]  view plain copy
  1.  PackageManager pm = getPackageManager();  
  2. ResolveInfo bestMatch = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);  
  3. List<ResolveInfo> allMatches = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);  
这样就获取了。下面以一个简单的例子结束, 获取在sd卡中安装的程序列表:

[java]  view plain copy
  1. private void getSdcardApps(){  
  2.         mSdcardAppsList.clear();  
  3.         ActivityManager am = (ActivityManager)mLauncher.getSystemService(Activity.ACTIVITY_SERVICE);  
  4.         PackageManager pm =mLauncher.getPackageManager();    
  5.         List<android.content.pm.ApplicationInfo> list = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);  
  6.         for (android.content.pm.ApplicationInfo appInfo : list) {  
  7.                 if((appInfo.flags & android.content.pm.ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0){  
  8.                     for (ApplicationInfo applicationInfo : mAllAppsList) {  
  9.                         if(appInfo.packageName.equals(applicationInfo.componentName.getPackageName())){  
  10.                             mSdcardAppsList.add(applicationInfo);  
  11.                             break;  
  12.                         }  
  13.                     }  
  14.                 }  
  15.         }  
  16.         mAppsAdapter = new AppsAdapter(getContext(), mSdcardAppsList);  
  17.         mAppsAdapter.notifyDataSetChanged();  
  18.         mGrid.setAdapter(mAppsAdapter);  
  19.         text.setVisibility(View.VISIBLE);  
  20.         text.setBackgroundResource(R.drawable.tab_mmenu_b3_normal);  
  21.     }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值