安卓开发中,要提高开发效率,掌握一些快捷方式是必不可少的,特别是对于android入门阶段的童鞋而言,非常重要。今天小编在安卓开发教程网站上,搜罗了一些常用的Android 适配多种 ROM 的快捷方式,分享给大家,一起来看看他们是怎么实现的吧。

首先,需要获取权限:

<!-- 添加快捷方式 -->

<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />

<!-- 移除快捷方式 -->

<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />

<!-- 查询快捷方式 -->

<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />

然后,定义一下我们要发起的action:

//删除快捷方式的action

public static final String ACTION_REMOVE_SHORTCUT = "com.android.launcher.action.UNINSTALL_SHORTCUT";

//添加快捷方式的action

public static final String ACTION_ADD_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT";

然后写2个方法即可:

//删除快捷方式

public static void removeShortcut(Context context, Intent actionIntent, String name) {

Intent intent = new Intent(ACTION_REMOVE_SHORTCUT);

intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);

intent.putExtra("duplicate", false);

intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, actionIntent);

context.sendBroadcast(intent);

}

//增加快捷方式

public static void addShortcut(Context context, Intent actionIntent, String name,

boolean allowRepeat, Bitmap iconBitmap) {

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

}

这种方法,在大部分的手机都能正常使用。但是在某些国产手机上会有各种各样的问题。比如hw的手机这样做就完全无效、小米的手机 无法重复创建快捷方式等。那现在看看有没有什么方法 能解决这些问题。

首先我们来看一张图:

这张图很清晰的告诉我们launcher这个应用下面 是有一个数据库的。

我们可以打开这个数据库 看看到底是什么?

你看这个就一目了然了,快捷方式都是存在于这个表里面的!所以 ,我们除了发送广播可以创建快捷方式以外,我们直接操作数据库也应该是可以创建快捷方式的。

但是我们要注意啊,各家的lanucher 都有很大不同的,上面的截图 是用的模拟器,所以是官方的rom,那路径肯定就是常规的,但是深度定制的android系统,大家都知道各家lanucher都是自己在做,所以favorites 这张表的位置到底在哪里,这就是个问题了。我们需要先查找出来这张表到底在哪个位置才能好操作这个表,要想知道这个表在哪个位置,我们首先要知道对于这个rom来说,是哪个lanucher在启作用?包名是什么?

//此函数返回当前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;

}

有些人可能对于4-5行还是理解不了,为什么这个相当于是启动lanucher的intent 其实很简单,我们在android studio里 run一个app的时候,我们通常都能看到下面这个界面:

你看android studio 实际上安装完我们的应用以后 也是通过 这个intent来启动手机里的lanucher 然后让lanucher来运行我们的app,因为studio也不知道你手机里的lanucher到底是哪个,所以只能用intent来完成,这也就是上述代码能必定成功运行的原因!否则的话 android studio 就无法把你的app run进去了~~

当然了你也可以进入shell ,打ps 命令看看到底是不是有这个 包名的 进程在 运行中~~

拿到了我们的lanucher的包名,下面一步就是去我们的包名下操作那个数据库即可了。那显然这个步骤 最合适的就是contentprovider来操作了。

//此函数返回 要查找的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 "";

}

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

}

好,到这里 我们就能拿到所有rom 任意一款手机的 快捷方式 那张数据库表对应的uri了。

到这里应该来说问题就基本解决了,你所有对快捷方式的操作都可以直接通过这个uri来进行,无非就是一些crud的拼装。

再也不需要经过广播 那一道程序了,但是这里要注意的是这种方法通常耗时都比较久,根据手机的性能的不同 200ms-600ms 才能完成uri的查找。所以记得做一下异步处理。

并且所有你对lanucher的 需求 都可以这么来做,比方说有些功能 在使用原生lanucher的手机上使用正常,在小米 华为 oppo使用不正常了,你就去找出来那个不正常的rom的lanucher的 包名,然后找出他provider需要的权限,然后在你的manifest里 直接加权限 应该就可以正常使用了。第三方lanucher 引起的bug 基本上都可以通过这个方案来解决。

以上就是Android 适配多种 ROM 的快捷方式的实现方法,大家不妨在自己的android环境下试一下伤面子这些操作,看看有没有什么问题。

Android开发中适配多种 ROM 的快捷方式是如何实现的?的更多相关文章

  1. Android 适配多种ROM的快捷方式

    快捷方式 应该来说 很多人都做过,我们就来看一下基本的快捷方式 是怎么实现的,会有什么问题? 首先 肯定要获取权限: <!-- 添加快捷方式 --> <uses-permission ...

  2. Android 开发中的屏幕适配技术详解

    本文主要介绍Android开发中比较头疼繁琐的一个问题-屏幕适配问题.主要从适配原因.基本核心概念.适配方法等方面介详细 介绍从而是的深入或者进一步对Android屏幕适配技术的掌握和理解. 真题园网 ...

  3. Android开发中怎样调用系统Email发送邮件(多种调用方式)

    在Android中调用其他程序进行相关处理,几乎都是使用的Intent,所以,Email也不例外,所谓的调用Email,只是说Email可以接收Intent并做这些事情 我们都知道,在Android中 ...

  4. Android 开发中,as或者idea对gradle的使用

    原文:Android 开发中,as或者idea对gradle的使用 本文属于转载收藏,侵删,出处:私人博客 ---------------------------------------------- ...

  5. Android开发中Eclispe相关问题及相应解决(持续更新)

    1.Eclipse项目中的Android Private Libraries没有自动生成. 一般而言,在Android开发中,项目中引用到的jar包会放到项目目录中的libs中,引入库会放到Andro ...

  6. Android开发中,那些让您觉得相见恨晚的方法、类或接口

    Android开发中,那些让你觉得相见恨晚的方法.类或接口本篇文章内容提取自知乎Android开发中,有哪些让你觉得相见恨晚的方法.类或接口?,其实有一部是JAVA的,但是在android开发中也算常 ...

  7. Android开发中常见的设计模式

    对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是非常有必要的.对于想系统的学习设计模式的 ...

  8. 转:Android开发中的MVP架构(最后链接资源不错)

    Android开发中的MVP架构 最近越来越多的人开始谈论架构.我周围的同事和工程师也是如此.尽管我还不是特别深入理解MVP和DDD,但是我们的新项目还是决定通过MVP来构建. 这篇文章是我通过研究和 ...

  9. 转: Android开发中的MVP架构详解(附加链接比较不错)

    转: http://www.codeceo.com/article/android-mvp-artch.html 最近越来越多的人开始谈论架构.我周围的同事和工程师也是如此.尽管我还不是特别深入理解M ...

随机推荐

  1. MySQL之正则表达式

    一.介绍 正则表达式用来描述或者匹配符合规则的字符串.它的用法和like比较相似,但是它又比like更强大,能够实现一些很特殊的规则匹配:正则表达式需要使用REGEXP命令,匹配上返回"1& ...

  2. Weex 版扫雷游戏开发

    扫雷是一个喜闻乐见的小游戏,今天在看 Weex 文档的过程中,无意中发现用 Weex 完全可以开发一个扫雷出来.当然这个扫雷和 Windows 那个有一点差距,不过麻雀虽小五脏俱全,随机布雷.自动挖雷 ...

  3. 使用CLion

    CLion是JetBrains公司的一款C++的IDE.默认使用Cmake构建. ubuntu和fedora下的安装 在ubuntu下安装了CLion,和QtCreator相比: ibus输入法能输入 ...

  4. 洛谷 P1296奶牛的耳语 题解

    题目传送门 这道题很显然可以用O(n2)的方法来做(记得排序),由于数据较水...但还是在for循环中加一些优化:++i,据说这样会快一些... #include<bits/stdc++.h&g ...

  5. 【PAT】1002. 写出这个数 (20)

    1002. 写出这个数 (20) 读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字. 输入格式:每个测试输入包含1个测试用例,即给出自然数n的值.这里保证n小于10100. 输出格式 ...

  6. Django+Nginx+uwsgi搭建自己的博客(六)

    这篇应该是2017年的最后一篇博客了,在这里首先祝大家元旦快乐! 从这篇博客开始,将会介绍Blogs App的功能实现,包括数据模型的建立.相关功能的视图函数的实现.前端页面的设计等,这意味着我们即将 ...

  7. Redux学习之我对于其工作流程的理解和实践

      目录 1 工作流程图 2 各部位职责 3 Demo   1 工作流程图   2 各部位职责 我在理解这个流程图的时候,采用的是一种容易记住的办法,并且贴切实际工作职责. 我们可以把整个Redux工 ...

  8. 八步详解Hibernate的搭建及使用

    本文通过了八个步骤以及一些实例添加用户来介绍Hibernate的搭建和使用,真切的介绍了hibernate的基本用法,其中好多优点等待我们自己去发现,比如hibernate中的缓存机制,映射方案. 1 ...

  9. windows下srand48()和drand48()的问题

    前几天在windows下用MINGW编译一段代码时,出现了错误提示说srand48()和drand48()的未定义,去网上搜了下,发现好多人也遇到了同样的问题,大约有两种解决方案: 第一个就是说gcc ...

  10. FastReport.Net使用:[32]对话框使用2

    方法/步骤 1.先浏览下数据,成绩表中有部分科目成绩没有,如果是这种情况,报表是不能打印的. 2.添加一个对话框,将其Visible属性设置为False,默认情况下改对话框是不显示的. 将确定按钮的D ...