首先向像我一样的Mono for Android程序员致敬,因为我晓得Mono开发Android的无限的蛋疼!致敬!
最近在为Android项目app添加快捷方式,情景是这样的,为了争取同行业的竞争力,我们打算让app在第一次运行时添加快捷方式到桌面上,之后每隔n天后就检查桌面上是否存在快捷方式,否则就添加。
这一过程听起来很好实现,但是说与做之间还是有一段距离的,添加还没什么问题,在AndroidMainFest文件里添加“com.android.launcher.permission.INSTALL_SHORTCUT”权限后,使用系统广播可以轻松来实现添加快捷方式。但是在我判断桌面上是否已经存在的时候就出现麻烦了,输出窗口里打印了这么一句话“Failed to find provider info for com.android.launcher.settings”。之后我在网上查找了原因后,发现可能和sdk版本之间有一定关系,简单的说就是创建和删除快捷方式的receiver没什么变化但是查询的provider有了变化,网上有这么一个方法:
public bool hasShortCut(Context context)
{
string url = "";
if (getSystemVersion() < 8)
{
url = "content://com.android.launcher.settings/favorites?notify=true";
}
else
{
url = "content://com.android.launcher2.settings/favorites?notify=true";
}
ContentResolver resolver = context.ContentResolver;
ICursor cursor = resolver.Query(Android.Net.Uri.Parse(url), null, "title=?", new string[] { appName }, null);
if (cursor != null && cursor.MoveToFirst())
{
cursor.Close();
return true;
}
return false;
}
private int getSystemVersion()
{
return Convert.ToInt32(Android.OS.Build.VERSION.SdkInt.ToString());
}
但是还是没有实现效果,现在又输出了“Failed to find provider info for com.android.launcher.settings” 的错误,这次我直接跑去stackoverflow 查找 http://stackoverflow.com/questions/8501306/android-shortcut-access-launcher-db(这是stackoverflow网站上的解释),我就直接拿来用:
string getAuthorityFromPermission(string permission)
{
if (permission == null) return null;
IList<PackageInfo> packs = context.PackageManager.GetInstalledPackages(PackageInfoFlags.Providers);
if (packs != null)
{
foreach (PackageInfo pack in packs)
{
IList<ProviderInfo> providers = pack.Providers;
if (providers != null)
{
foreach (ProviderInfo provider in providers)
{
if (permission.Equals(provider.ReadPermission))
return provider.Authority;
if (permission.Equals(provider.WritePermission))
return provider.Authority;
}
}
}
}
return null;
}
但是这次我执行getAuthorityFromPermission(“com.android.launcher2.permission.READ_SETTINGS”)方法返回的值却是null,很是不解,最后我在它遍历的时候打印出所有的值,查看结果后,我发现了点东西:(看图)
因为我的手机是Htc的,由原来的com.android.launcher.permission.READ_SETTINGS,变成了现在看到的com.htc.launcher.permission.READ_SETTINGS,于是我就把参数修改下,变成了getAuthorityFromPermission(“com.htc.launcher2.permission.READ_SETTINGS”),几经周折下图是最后的代码:
这时候我满心欢喜的开始调试,结果,又报错。。。报错的原因说是权限安全问题,我这时突然想起来,那个AndroidMainfest文件也应该要修改了,对要修改成这样:
到此为止总算是大功告成了,对于android设备的厂商定制我是感到很是无奈啊,这是htc的,如果是联想的,金立的等等其他厂商,难道我要写不同版本的AndroidMainfest吗?这个很明显是不明智的。但是在Android上层应用开发的技术层面上来讲,应该是不可能在代码里动态添加权限的。但是网上有人提供了权限列表,我们可以拿来用下,把下面那些不同的厂商的权限都写进去,然后再代码里匹配包含“permission.READ_SETTINGS”的,然后得到的值就是Authority变量,目前我也只能这样做,你们有什么好的方法,请多多指教!
执行:getAuthorityFromPermission(“permission.READ_SETTINGS”)
string getAuthorityFromPermission(string permission)
{
if (permission == null) return null;
IList<PackageInfo> packs = context.PackageManager.GetInstalledPackages(PackageInfoFlags.Providers);
if (packs != null)
{
foreach (PackageInfo pack in packs)
{
IList<ProviderInfo> providers = pack.Providers;
if (providers != null)
{
foreach (ProviderInfo provider in providers)
{
Console.WriteLine("\r\n【" + provider.ReadPermission + "】\r\n");
if (provider.ReadPermission.Contains(permission))
return provider.Authority;
}
}
}
}
return null;
}
android.permission.WRITE_EXTERNAL_STORAGE | 写入外部存储 |
android.permission.CALL_PHONE | 拨打电话 |
android.permission.CALL_PRIVILEGED | 通话权限 |
android.permission.EXPAND_STATUS_BAR | 状态栏控制 |
android.permission.GET_TASKS | 获取任务信息 |
android.permission.READ_CONTACTS | 读取联系人 |
android.permission.SET_WALLPAPER | 设置桌面壁纸 |
android.permission.SET_WALLPAPER_HINTS | 设置壁纸建议 |
android.permission.VIBRATE | 使用振动 |
android.permission.WRITE_SETTINGS | 读写系统设置 |
android.permission.BIND_APPWIDGET | 绑定小插件 |
android.permission.INTERNET | 访问网络 |
android.permission.ACCESS_NETWORK_STATE | 获取网络状态 |
android.permission.WRITE_EXTERNAL_STORAGE | 写入外部存储 |
android.permission.WRITE_SECURE_SETTINGS | 读写系统敏感设置 |
android.permission.ACCESS_WIFI_STATE | 获取WiFi状态 |
android.permission.CHANGE_WIFI_STATE | 改变WiFi状态 |
android.permission.MODIFY_PHONE_STATE | 修改电话状态 |
android.permission.CHANGE_NETWORK_STATE | 改变网络状态 |
android.permission.READ_SYNC_SETTINGS | 读取同步设置 |
android.permission.WRITE_SYNC_SETTINGS | 写入同步设置 |
android.permission.BLUETOOTH | 使用蓝牙 |
android.permission.BLUETOOTH_ADMIN | 蓝牙管理 |
android.permission.WAKE_LOCK | 唤醒锁定 |
android.permission.DEVICE_POWER | 电源管理 |
android.permission.RESTART_PACKAGES | 结束系统任务 |
android.permission.KILL_BACKGROUND_PROCESSES | 结束后台进程 |
android.permission.READ_PHONE_STATE | 读取电话状态 |
android.permission.SYSTEM_ALERT_WINDOW | 显示系统窗口 |
android.permission.ACCESS_FINE_LOCATION | 获取精确位置 |
android.permission.ACCESS_COARSE_LOCATION | 获取粗略位置 |
android.permission.READ_EXTERNAL_STORAGE |
|
com.anddoes.launcher.permission.READ_SETTINGS |
|
com.anddoes.launcher.permission.WRITE_SETTINGS |
|
com.android.launcher.permission.READ_SETTINGS |
|
com.android.launcher.permission.WRITE_SETTINGS |
|
com.teslacoilsw.launcher.permission.READ_SETTINGS |
|
com.teslacoilsw.launcher.permission.WRITE_SETTINGS |
|
org.adw.launcher.permission.READ_SETTINGS |
|
org.adw.launcher.permission.WRITE_SETTINGS |
|
com.fede.launcher.permission.READ_SETTINGS |
|
com.fede.launcher.permission.WRITE_SETTINGS |
|
com.google.android.gm.permission.READ_CONTENT_PROVIDER |
|
com.doodleapp.launcher.permission.READ_SETTINGS |
|
com.doodleapp.launcher.permission.WRITE_SETTINGS |
|
com.htc.launcher.permission.READ_SETTINGS |
|
com.htc.launcher.permission.WRITE_SETTINGS |
|
com.gtp.nextlauncher.permission.READ_SETTINGS |
|
com.gtp.nextlauncher.permission.WRITE_SETTINGS |
|
com.neomtel.mxhome.permission.READ_SETTINGS |
|
com.neomtel.mxhome.permission.WRITE_SETTINGS |
|
com.miui.mihome2.permission.READ_SETTINGS |
|
com.miui.mihome2.permission.WRITE_SETTINGS |
|
com.lge.launcher.permission.READ_SETTINGS |
|
com.lge.launcher.permission.WRITE_SETTINGS |
|
com.sec.android.app.launcher.permission.READ_SETTINGS |
|
com.sec.android.app.launcher.permission.WRITE_SETTINGS |