在BluetoothGattCallback中使用Content Provider时出现安全问题

时间:2014-03-10 19:49:15

标签: android bluetooth

当调用onCharacteristicChanged()回调时,我正在观察一个奇怪的权限相关问题。

我正在编写Android服务,使用蓝牙LE API与外围角色的LE(低能耗)传感器进行通信。我在传感器通知任何变化的特征上启用通知。

当调用onCharacteristicChanged()回调时,我的服务检索特征的值并将其存储在内容提供者中。对此内容提供商的访问受签名级别权​​限的限制。托管我服务的应用程序具有这些权限

以下是onCharacteristicChanged的简化代码:

@Override
public void onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
    super.onCharacteristicChanged(gatt, characteristic);

    Log.v(TAG, "pid=" + android.os.Process.myPid() + " uid=" + android.os.Process.myUid());

    Uri uri = mContext.getContentResolver().insert(URI_VALUES, characteristic.getValue());
}

在上面的回调中调用insert()api时,我获得了安全权限。

02-27 15:15:32.752: V/ProxyGattClient(10511): pid=10511 uid=10177
02-27 15:15:32.792: E/PersistenceUtil(10511): Error saving a reading into the database
02-27 15:15:32.792: E/PersistenceUtil(10511): java.lang.SecurityException: Permission Denial: writing com.example.content.MyContentProvider uri content://com.example/values from pid=1336, uid=1002 requires com.example.permission.ACCESS_CONTENT, or grantUriPermission()
02-27 15:15:32.792: E/PersistenceUtil(10511):   at android.content.ContentProvider$Transport.enforceWritePermissionInner(ContentProvider.java:445)
02-27 15:15:32.792: E/PersistenceUtil(10511):   at android.content.ContentProvider$Transport.enforceWritePermission(ContentProvider.java:382)
02-27 15:15:32.792: E/PersistenceUtil(10511):   at android.content.ContentProvider$Transport.insert(ContentProvider.java:210)
02-27 15:15:32.792: E/PersistenceUtil(10511):   at android.content.ContentResolver.insert(ContentResolver.java:917)
02-27 15:15:32.792: E/PersistenceUtil(10511):   at com.qcl.vh.ble.ProxyGattClient.onCharacteristicChanged(ProxyGattClient.java:101)
02-27 15:15:32.792: E/PersistenceUtil(10511):   at android.bluetooth.BluetoothGatt$1.onNotify(BluetoothGatt.java:425)
02-27 15:15:32.792: E/PersistenceUtil(10511):   at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:397)
02-27 15:15:32.792: E/PersistenceUtil(10511):   at android.os.Binder.execTransact(Binder.java:388)
02-27 15:15:32.792: E/PersistenceUtil(10511):   at dalvik.system.NativeStart.run(Native Method)

运行'adb shell ps'显示pid = 1336,uid = 1002是“com.android.bluetooth”进程的进程ID。上面的堆栈跟踪显示,内容提供商的插入是在蓝牙进程的上下文中调用的。当然,这个过程没有在内容提供者中写入的权限,因而也没有这个例外。

当我在onCharacteristicChanged()中记录进程的id时,它显示了pid = 10511 uid = 10177,这是托管我的应用程序的进程的进程ID。

有人可以解释上述行为吗?为什么在蓝牙进程的上下文中调用insert(),而回调本身在我的应用程序进程中运行。

我在Samsung Galaxy S3,Android 4.3上运行。

感谢

1 个答案:

答案 0 :(得分:0)

我相信你的错误答案是正确的。

requires com.example.permission.ACCESS_CONTENT

您必须允许其他人从您的contentProvider中读取内容。详细了解here

您能否告诉您如何知道主机应用程序具有这些权限?我过去曾问过一个非常类似的问题:

What's the difference between android:permission="packagename.permissions.BROWSER_PROVIDER" and android:grantUriPermissions?