最近修改 Launcher 源代码,满足权限管理、拖动、像AWD Ex版本一样长按显示操作工具等,需要在 Launcher 安装完成后添加本机应用程序 ShortCut(快捷方式或图标),在Launcher源代码路径中 xml/default_workspace.xml 中:
<favorite launcher:packageName="com.android.contacts" launcher:className="com.android.contacts.DialtactsActivity" launcher:screen="2" launcher:x="0" launcher:y="3" />
以上是添加一个联系人的快捷方式,launcher:packageName 顾名思义是程序包名,而 launcher:className 确不同于程序的 className,不信可以测试,其实这个是程序入口 Activity,既启动软件第一个展现在你眼前的 Activity!
好,问题来了,要添加一个快捷方式,我需要获取这2个属性,第一想到的是当然是 PackageManager 中 applicationInfo 的一系列操作,发现并有我们想要的 packageName,但确没有我们想的 className(入口Activity)
第二想到的是反编译看源代码 AndroidManifest.xml 入口函数,不过试想如果很多应用程序呢,那不是搞死人 .. -.- ,直接 pass 掉,接下来看看网络炒的最热的代码:(话说很多人顶,莫非成功了?)
PackageManager pmPack = getPackageManager(); PackageInfo packinfo = pmPack.getInstalledPackages(PackageManager.GET_ACTIVITIES);//得到所有应用的包信息 packinfo.get(i).packageName//得到指定包的名字 packinfo.get(i).activities[0]//得到入口activity在我测试中,答案是 false 的,无论怎么弄,都是 null ..
回到宿舍,一直在想这个问题,为什么 Launcher 源代码可以获取到,是用什么方法呢,至于代码在那里,相信花点时间可以找到的,我始终还是相信 Android api 的强大,再看看文档,结果绕了一个念头,获取 Intent 来获取 ComponentName 或许可以!
PackageManager pManager = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); pManager = getPackageManager(); List<PackageInfo> packageInfos = pManager.getInstalledPackages(0); for(int i=0; i<packageInfos.size(); i++) { System.out.println(pManager.getLaunchIntentForPackage(packageInfos.get(i).packageName)); // simple,名字都可以看出来 } }
看到这个 act=android.intent.action.Main ,cmp=com.android.email/.activity.Welcome,
这里: act=android.intent.action.Main ,有没有是曾相识的感觉,对了,当然是 Application 的主启动 Activity 的 <intent-filter>
后面:.activity.Welcome,就是我们要的 className了,也就是主启动 Activity,也就是程序主要入口,如果遇到是点在前边,记得加上之前的 packageName 就搞定 ~
接下来就是处理了 ..
搞定,配置一下 Launcher xml/default_workspace.xml 是不是可以了? enjoy it