一、前言
android 系统签名应用进行蓝牙分享会失败,近段开发蓝牙的时候发现了这个问题;
普通应用进行蓝牙文件分享是ok的,但是系统签名应用分享蓝牙文件就会失败。
这个问题目前在aml方案是有的,在安卓原生流程应该也是有这个问题的,但是在rk方案没遇到。
有可能是rk方案在某个流程做了处理。
这里简单分析一下处理的内容。
二、分析解决
1、主要日志
查看报错信息:
07-02 22:57:31.376 937 2839 w urigrantsmanagerservice: for security reasons, the system cannot issue a uri permission grant to content://com.mobisystems.office.remotefiles/yxnzzxrzoi8vc2ftcgxlcy9hzxr0aw5nx1n0yxj0zwqucgrm/0 [user 0]; use startactivityascaller() instead
07-02 22:57:31.379 937 2839 w bundle : key android.intent.extra.stream expected arraylist<android.net.uri> but value was of a different type. the default value <null> was returned.
07-02 22:57:31.380 937 2839 w bundle : attempt to cast generated internal exception:
07-02 22:57:31.380 937 2839 w bundle : java.lang.classcastexception: cannot cast android.net.uri$stringuri to java.util.arraylist
07-02 22:57:31.380 937 2839 w urigrantsmanagerservice: for security reasons, the system cannot issue a uri permission grant to content://com.mobisystems.office.remotefiles/yxnzzxrzoi8vc2ftcgxlcy9hzxr0aw5nx1n0yxj0zwqucgrm/0 [user 0]; use startactivityascaller() instead
07-02 22:57:31.382 756 875 d devicehalaidl: [default] setaudioportconfig
07-02 22:57:31.384 937 2839 v grammaticalinflectionutils: attributionsource: attributionsource { uid = 1002, packagename = null, attributiontag = null, token = android.os.binder@8d82233, deviceid = 0, next = null } does not have read_system_grammatical_gender permission.
07-02 22:57:31.385 937 2839 w optprop : cannot read opt property android.window.property_compat_allow_resizeable_activity_overrides
07-02 22:57:31.385 937 2839 w optprop : cannot read opt property android.window.property_compat_allow_min_aspect_ratio_override
上面的日志信息很重要。
日志看起来是权限报错:
... does not have read_system_grammatical_gender permission.
但是实际并不是权限报错;尝试添加了权限也是不行的。
并且应用是系统签名,权限应该是比较大的。
2、具体分析日志
其实关键是下面这段日志:
urigrantsmanagerservice: for security reasons, the system cannot issue a uri permission grant to content://com.mobisystems.office.remotefiles/yxnzzxrzoi8vc2ftcgxlcy9hzxr0aw5nx1n0yxj0zwqucgrm/0 [user 0]; use startactivityascaller() instead
frameworks\base\services\core\java\com\android\server\uri\urigrantsmanagerservice.java
/**
* check if the targetpkg can be granted permission to access uri by
* the callinguid using the given modeflags. throws a security exception
* if callinguid is not allowed to do this. returns the uid of the target
* if the uri permission grant should be performed; returns -1 if it is not
* needed (for example targetpkg already has permission to access the uri).
* if you already know the uid of the target, you can supply it in
* lasttargetuid else set that to -1.
*/
private int checkgranturipermissionunlocked(int callinguid, string targetpkg, granturi granturi,
int modeflags, int lasttargetuid) {
if (!iscontenturiwithaccessmodeflags(granturi, modeflags,
/* logaction */ "grant uri permission")) {
return -1;
}
if (targetpkg != null) {
if (debug) slog.v(tag, "checking grant " + targetpkg + " permission to " + granturi);
}
// bail early if system is trying to hand out permissions directly; it
// must always grant permissions on behalf of someone explicit.
final int callingappid = userhandle.getappid(callinguid);
if ((callingappid == system_uid) || (callingappid == root_uid)) {
if ("com.android.settings.files".equals(granturi.uri.getauthority())
|| "com.android.settings.module_licenses".equals(granturi.uri.getauthority())
|| "com.mobisystems.office.remotefiles".equals(granturi.uri.getauthority())
|| "com.skg.filemanager.provider".equals(granturi.uri.getauthority())
|| "com.debug.fastpass.fileprovider".equals(granturi.uri.getauthority())) {
// exempted authority for
// 1. cropping user photos and sharing a generated license html
// file in settings app
// 2. sharing a generated license html file in tvsettings app
// 3. sharing module license files from settings app
} else {
//这里就是报错的地方:::
slog.w(tag, "for security reasons, the system cannot issue a uri permission"
+ " grant to " + granturi + "; use startactivityascaller() instead");
return -1;
}
}
...
首先上面注释的地方就写了:if callinguid is not allowed to do this. 不允许系统签名应用使用临时uri地址。
代码中有判断 callingappid == system_uid 如果没有添加白名单就会报错,打印:for security reasons …
这个是处于系统安全原因考虑,不允许系统签名使用临时的uri访问系统。
蓝牙分享和某些投屏情况是需要临时uri进行控制系统的,但是系统签名应用权限比较大,所以被禁止了。
如果需要不被禁止可以在上面添加白名单,比如:
com.debug.fastpass.fileprovider 或者 com.mobisystems.office.remotefiles
fileprovider 的名称可以在应用的androidmanifest中查看,也可以在报错信息中查看
比如上面报错就有:
cannot issue a uri permission grant to content://com.mobisystems.office.remotefiles/...
只要提取content://xxx/ 中的xxx内容就可以了。
上面的代码如果整个去掉 (callingappid == system_uid) || 也是可以的,就会去除校验所有系统签名应用;
但是有可能造成edla认证失败。
另外在rk方案的代码查看,是没有修改到 urigrantsmanagerservice.java 的,
不清楚是在这个流程前面还是后面进行了处理。。。
三、其他
1、小结
系统应用无法进行蓝牙文件分享是因为framework中做了安全校验;
限制了系统签名应用进行临时uri的访问。
如果要去除这个现实可以在 urigrantsmanagerservice.java 进行适配修改。
2、普通应用蓝牙文件分享知识
android蓝牙文件分享代码实战指南:
通过蓝牙技术,用户可以在设备之间快速传输图片、音频、文档等各类文件。
本文基于实际项目经验,详细讲解 android 蓝牙文件分享的完整实现方案,
包括单文件分享、多文件批量分享、权限配置、关键 api 使用及常见问题解决方案。
以上就是android系统应用蓝牙分享失败分析解决方法的详细内容,更多关于android系统应用蓝牙分享失败的资料请关注代码网其它相关文章!
发表评论