您的位置:首页 > 移动开发

Android AppOpsService服务实践贴

2016-07-29 17:54 417 查看
版本信息:
Android 4.4.2


一、与AppOpsService因缘

自己整了个系统服务,然后在系统服务中通过Settings设置属性值、读写系统数据库:

private boolean setStaticIpInfo(int index, String value) {
boolean ret = false;
try {
ret = System.putString(mContext.getContentResolver(), mSettingNames[index], value);
return true;
} catch (Exception e) {
e.printStackTrace();
ret = false;
}

return ret;
}


结果,老给报错误:
Package android does not belong to 10023
对应错误出处:
AppOpsManager.java (frameworks\base\core\java\android\app)
public void checkPackage(int uid, String packageName) {
try {
if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
throw new SecurityException(
"Package " + packageName + " does not belong to " + uid);
}
}
}

Bad call: specified package android under uid 10023 but it is really 1000
对应错误出处:
AppOpsService.java (frameworks\base\services\java\com\android\server)
private Ops getOpsLocked(int uid, String packageName, boolean edit) {
if (pkgUid != uid) {
// Oops!  The package name is not valid for the uid they are calling
// under.  Abort.
Slog.w(TAG, "Bad call: specified package " + packageName
+ " under uid " + uid + " but it is really " + pkgUid);
return null;
}
}


二、为什么报这些错误

AppOpsService是一个系统服务,从版本4..4.2(Added in
API level 19)之后引进(据说),用来对系统权限进行检测,以运行/禁止某种操作。

“AppOpsManager是一个访问AppOpsService服务的类,同时有 Java 和 C 的实现,为了应对某些 native code 的服务,比如说 Camera。”

要想使用AppOpsService功能,就需要在权限检测的地方添加这部分代码,比如:

对于以上的错误,Settings在put数据之前,就添加了AppOpsService功能:

SettingsProvider.java (frameworks\base\packages\settingsprovider\src\com\android\providers\settings)
@Override
public Bundle call(String method, String request, Bundle args) {
// Framework can't do automatic permission checking for calls, so we need
// to do it here.
if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException(
String.format("Permission denial: writing to settings requires %1$s",
android.Manifest.permission.WRITE_SETTINGS));
}

// Also need to take care of app op.
if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SETTINGS, Binder.getCallingUid(),
getCallingPackage()) != AppOpsManager.MODE_ALLOWED) {
return null;
}

final ContentValues values = new ContentValues();
values.put(Settings.NameValueTable.NAME, request);
values.put(Settings.NameValueTable.VALUE, newValue);
}


可知,在更改数据前,先进行常规的WRITE_SETTINGS检查,然后利用AppOpsService进行进一步检查。

三、问题解决

由于特殊情况,直接把AppOpsService服务注释掉了。

但是,对于API版本6.0(API level 23)及以上,可以参考:
https://developer.android.com/reference/android/provider/Settings.System.html#canWrite%28android.content.Context%2

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: