您的位置:首页 > 移动开发 > Android开发

说说Android桌面(Launcher应用)背后的故事(二)——应用程序的添加

2012-12-25 20:15 603 查看



一、调用系统快捷方式列表

[java] view plaincopy

 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);    

 

这个获取到的就是所有可以创建的快捷方式,但是我们需要在这个列表中加入其他项怎么办呢?因为我们知道,我需要在这个列表中加入“应用程序”,这一项,这样当我们点击应用程序的时候,就可以显示应用程序列表。这个时候,我们只需要传入额外的信息就可以了,如下:

 

[java] view plaincopy

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中处理该请求对应的逻辑:如果用户选择的是“应用程序”,则调用系统应用程序列表,否则,直接请求创建快捷方式

[java] view plaincopy

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中。这里就顺带实现一下。布局 和效果略过,只记录如果获取应用程序信息。

[java] view plaincopy

/** 
 * 同样,以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);这个方法源码是:

[java] view plaincopy

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_TASK  
    app.setActivity(component, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);  
      
    return app;  
}  

 

这样就得到了所有的应用程序信息。系统Launcher在其GridView中列出的所有应用就是这么获取的。

 

三、获取应用程序信息的其他方式:

下面这个获取到的应用信息,你会发现比上面的方法多了很多,因为其获得的是系统中所有的安装包信息

[java] view plaincopy

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,其源码是:

[java] view plaincopy

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中的应用程序信息是如何获取到的了。

转载处:http://zhhx.blog.sohu.com/210960706.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐