Android桌面小图标终极解决方案

`本来安卓创建桌面小图标大家都知道是有系统Api的,也很简单,但是有些定制神机改了后就比较蛋疼了,像OPPO的ColorOS3.0。但是都出自与安卓原理基本都是一样的,一般桌面的东西都会保存在一个叫launcher数据库里面,路径的话不同手机可能不太一样,一般是以xxx.xxx.xxx.launcher目录下,通过代码也是可以获取的,launcher数据库里面的几张表就是放这些东西的,有一张叫favorites(OPPOColor3.0叫singledesktopitems)的表就是放桌面图标信息的。所以不管你怎么做最后还是把图标信息插入这里。


要操作这种系统的数据库一般是通过Content Provider,所以第一步是拿到uri,之后无非就

是增删改查的一些炒作。这种直接操作数据库的方式除了麻烦点很实用,如果开发中遇到不能添

加的可以这样尝试。

系统Api创建的方法:

 Intent addShortcutIntent = new Intent(ACTION_ADD_SHORTCUT);
        // 是否允许重复创建
        addShortcutIntent.putExtra("duplicate", allowRepeat);
        // 快捷方式的标题
        addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
        // 快捷方式的图标
        addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, iconBitmap);
        // 快捷方式的动作
        addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, actionIntent);
        context.sendBroadcast(addShortcutIntent);
直接插入数据库的方式:

private void addShortCut2DB() {
        Uri uriFromLauncher = getUriFromLauncher(this);
        ContentValues contentValues = new ContentValues();
        contentValues.put("title","剑西");
//        id尽量大点,严谨点可以先查询数据库现在最大id是多少然后往后+1
        contentValues.put("_id",4855);
//        这里自己定义intent
        contentValues.put("intent","#Intent;action=android.intent.action.CREATE_SHORTCUT;category=android.intent.category.DEFAULT;component=com.henanjianye.soon.communityo2o/.activity.OpenDoor2Shortcut;end");
//       改成自己的包名
        contentValues.put("packageName","com.henanjianye.soon.communityo2o");
        contentValues.put("container",-100);
        contentValues.put("screenId",1005);
        contentValues.put("cellX",2);
        contentValues.put("cellY",2);
        contentValues.put("spanX",1);
        contentValues.put("spanY",1);
        contentValues.put("itemType",1);
        contentValues.put("appWidgetId",-1);
        contentValues.put("iconType",1);
        contentValues.put("modelState",0);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        contentValues.put("icon",  baos.toByteArray());
        getContentResolver().insert(uriFromLauncher,contentValues);
    }

    private String getAuthorityFromPermissionDefault(Context context) {
        return getAuthorityFromPermission(context, "com.android.launcher.permission.READ_SETTINGS");
    }

    private Uri getUriFromLauncher(Context context) {
        StringBuilder uriStrBuilder = new StringBuilder();
        //为了速度考虑,这里我们先查找默认的 看是否能查找到 因为多数手机的rom还是用的默认的lanucher
        String authority = getAuthorityFromPermissionDefault(context);
        //如果找不到的话 就说明这个rom一定是用的其他的自定义的lanucher。那就拼一下 这个自定义的lanucher的permission再去查找一次
        if (authority == null || authority.trim().equals("")) {
            authority = getAuthorityFromPermission(context, getCurrentLanucherPackageName(context) + ".permission.READ_SETTINGS");
        }
        uriStrBuilder.append("content://");
        //如果连上面的方法都查找不到这个authority的话 那下面的方法 就肯定查找到了 但是很少有情况会是如下这种
        //多数都是else里面的逻辑
        if (TextUtils.isEmpty(authority)) {
            int sdkInt = android.os.Build.VERSION.SDK_INT;
            if (sdkInt < 8) { // Android 2.1.x(API 7)以及以下的
                uriStrBuilder.append("com.android.launcher.settings");
            } else if (sdkInt < 19) {// Android 4.4以下
                uriStrBuilder.append("com.android.launcher2.settings");
            } else {// 4.4以及以上
                uriStrBuilder.append("com.android.launcher3.settings");
            }
        } else {
            uriStrBuilder.append(authority);
        }
        uriStrBuilder.append("/favorites?notify=true");
        return Uri.parse(uriStrBuilder.toString());
    }

    //此函数返回 要查找的permission的 provider的 authority
    private String getAuthorityFromPermission(Context context, String permission) {
        //返回安装的app的 provider的信息
        List<PackageInfo> packs = context.getPackageManager().getInstalledPackages(PackageManager.GET_PROVIDERS);
        //遍历获取到的安装包的信息
        for (PackageInfo pack : packs) {
            //每个安装包提供的provider 都在这个数组里面
            ProviderInfo[] providers = pack.providers;
            if (providers != null) {
                //遍历每个provider 看需要的权限是否与我们传进来的权限参数相等
                for (ProviderInfo providerInfo : providers) {
                    if (permission.equals(providerInfo.readPermission) || permission.equals(providerInfo.writePermission)) {
                        return providerInfo.authority;
                    }
                }
            }
        }
        return "";
    }

    //此函数返回当前rom下的lanucher的包名
    private String getCurrentLanucherPackageName(Context context) {
        //这个intent很好理解 就是启动lanucher的intent
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        //getPackageManager().resolveActivity 这个函数就是查询是否有符合条件的activity的
        ResolveInfo res = context.getPackageManager().resolveActivity(intent, 0);
        //为避免空指针 我们要判定下空,虽然你我都知道这种情况不会发生
        if (res == null || res.activityInfo == null) {
            return "";
        }
        return res.activityInfo.packageName;
    }

当然有写定制机的uri也许不太一样,比如oppo的,它launcher数据库里面的表名称变了,而且变态的加了一张白名单

的表,只要把自己的应用包名加入这个白名单你调用系统Api就能生成桌面小图标。添加方法如下:

 public static void add2OppoWhiteList(Context context) {
        if (Build.BRAND.contains("OPPO")) {
            try {
                ContentValues contentValues = new ContentValues();
                contentValues.put("itemName", context.getPackageName());
                contentValues.put("itemType", 0);
                contentValues.put("_id", 5201314);
                context.getContentResolver().insert(ShortcutHelper.getOppoWhiteUriFromLauncher(context), contentValues);
            } catch (Exception e) {
            }
        }
    }

终极解决方案:

上面自然可以适配一些机型,但是百家争鸣的Android的并不那么好完全适配,经过我们团队的摸索得出一个通用方案,其实很简单,既然没法创建小图标那么我就不创建呗,安装一个应用后你总得给我创建一个桌面图标吧!当用户点击“创建桌面快捷方式”的时候判断当前用户的机型时候需要采用这种特殊方式创建,如果需要那么跳转的APK安装界面,完成后生产小图标,接下里就是自己的业务了!!!!有没有很屌









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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值