最近搞一个将自己应用的Launcher引导用户设置为默认Launcher,本以为是一个小功能应该很快就可以搞定了,但是我真是低估了国内手机厂商定制Android修改的东西了。
难以解决的问题有以下三点:
0、监听home键
1、弹出设置默认桌面的框
2、设置完成后,按home键不退回到系统桌面
在这里难以解决的主要为小米、华为之流。
上代码:
就一个监听home键废了我老大劲才解决,尝试过的主要是只能监听到当前类的home事件,在切换到其他activity时就无法完成监听了。
最终通过以下方式解决:
http://my.oschina.net/u/223340/blog/386795?fromerr=4lufhjL1
- private final BroadcastReceiver homeReceiver = new BroadcastReceiver() {
- final String SYS_KEY = "reason"; // 标注下这里必须是这么一个字符串值
- final String SYS_HOME_KEY = "homekey";// 标注下这里必须是这么一个字符串值
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
- String reason = intent.getStringExtra(SYS_KEY);
- if (reason != null && reason.equals(SYS_HOME_KEY)) {
- Log.i("TT", "##################home键监听");
- Toast.makeText(MainActivity.this, "aaaa",
- Toast.LENGTH_SHORT).show();
- //弹出选择窗
- Intent intentw = new Intent(Intent.ACTION_MAIN);
- intentw.addCategory(Intent.CATEGORY_HOME);
- intentw.setClassName("android",
- "com.android.internal.app.ResolverActivity");
- startActivity(intentw);
- }
- }
- }
- };
然后在onCreate添加监听
- IntentFilter homeFilter = new IntentFilter(
- Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
- registerReceiver(homeReceiver, homeFilter);
好了下面来说一下第二个问题:
以前低版本的android设备或者现在的魅族、三星之类的设备中如果手机中装有两个以上的桌面APP时,按home键返回桌面时会弹出一个桌面选择框
用户勾选默认后就可以进入选择的桌面了。
但是。。。
这个在小米和华为设备中就无法弹出此框了。。。。悲催啊
通过各种查找资料和打印各种log最终找到这俩厂家弹出此框的东西了。。。。。
小米(同时也适用于大部分手机---华为除外):
- {act=android.intent.action.MAIN cat=[android.intent.category.HOME,android.intent.category.DEFAULT] cmp=android/com.android.internal.app.ResolverActivity} from pid 25308
看到了吧关键就是:
- android/com.android.internal.app.ResolverActivity
然后我们通过:
- Intent paramIntent = new Intent("android.intent.action.MAIN");
- paramIntent.setComponent(new ComponentName("android", "com.android.internal.app.ResolverActivity"));
- paramIntent.addCategory("android.intent.category.DEFAULT");
- paramIntent.addCategory("android.intent.category.HOME");
- mContext.startActivity(paramIntent);
这样就可以在小米之类的设备上弹出默认桌面选框了(前提是你设备中有两个或以上桌面应用)
然后来说说华为:奇葩啊
- {act=android.intent.action.MAIN cat=[android.intent.category.HOME,android.intent.category.DEFAULT] cmp=com.huawei.android.internal.app/.HwResolverActivity}
× 又不一样了:
- cmp=com.huawei.android.internal.app/.HwResolverActivity
通过:
- Intent paramIntent = new Intent("android.intent.action.MAIN");
- paramIntent.setComponent(new ComponentName("com.huawei.android.internal.app", "com.huawei.android.internal.app.HwResolverActivity"));
- paramIntent.addCategory("android.intent.category.DEFAULT");
- paramIntent.addCategory("android.intent.category.HOME");
- mContext.startActivity(paramIntent);
这样子就可以在奇葩的华为上弹出了。
虽然我个人比较喜欢华为的手机,但是还是要吐槽一下,真吭人啊!!!
弹框的问题解决了,现在说下第三个问题
上面也说了国内手机厂商定制的Android会更改很多底成的东西,
这里就是在弹出的框中勾选上默认,然后也选择了自己的Launcher了,结果你一按Home键又返回到了系统桌面。其实在这里你的桌面已经设为默认了,不信关机重启下试试看看是不是自己的应用Launcher,(小米的设备只要在设置——回复默认设置-回复一下就会看到系统桌面改为你自己的了)
下面直接上最终解决办法:
在弹框之前清除一下默认设置:我在网上奋战几天搜索到的解决办法
1、修改源码(我没有。。。)
2、通过反射删除默认设置(尝试过没用。。。)
3、删除默认桌面的数据(需要root。。。并且Root后也没用)
- Process su = Runtime.getRuntime().exec("su");
- String cmd = "cd /data/data/" + packageName + ";" + "rm -r `ls|grep -v lib`";
- cmd = cmd + "\n exit\n";
- su.getOutputStream().write(cmd.getBytes());
- if ((su.waitFor() != 0)) {
- throw new SecurityException();
- }
解决如下:
- /**
- * 清除默认桌面(采用先设置一个空的桌面为默认然后在将该空桌面禁用的方式来实现)
- * @param cont
- */
- public void clearDefaultLauncher() {
- PackageManager pm = mContext.getPackageManager();
- String pn = mContext.getPackageName();
- String hn = MockHome.class.getName();
- ComponentName mhCN = new ComponentName(pn, hn);
- Intent homeIntent = new Intent("android.intent.action.MAIN");
- homeIntent.addCategory("android.intent.category.HOME");
- homeIntent.addCategory("android.intent.category.DEFAULT");
- homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- pm.setComponentEnabledSetting(mhCN, 1, 1);
- mContext.startActivity(homeIntent);
- pm.setComponentEnabledSetting(mhCN, 0, 1);
- }
- <activity
- android:name="cn.neiwang.emm.ui.MockHome"
- android:enabled="false"
- android:label="MockHome" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.HOME" />
- </intent-filter>
- </activity>