我们有一个将图像打印到蓝牙打印机的应用程序。这个应用程序在Android 4.0 ICS上运行良好,但是当我们将其中一个升级到Android 4.1果冻bean时,打印在logcat中停止使用:
W / System.err(19319):java.lang.SecurityException:Permission Denial: 写com.android.bluetooth.opp.BluetoothOppProvider uri 内容://com.android.bluetooth.opp/btopp来自pid = 19319,uid = 10106 需要android.permission.ACCESS_BLUETOOTH_SHARE,或 grantUriPermission()
问题在于我们正在宣布该许可,因此这个错误对我们毫无意义。这是我们清单中的一行
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.turner.itstrategy.LumenboxClient"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="11" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_BLUETOOTH_SHARE"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.VIBRATE" />
(stuff removed)
</manifest>
以下是我们用来打印的代码。此代码取自stackoverflow和其他地方的示例。
ContentValues values = new ContentValues();
String path = Environment.getExternalStorageDirectory().toString();
File imageFile = new File(path, "CurrentLumenboxPrint.jpg");
//build the message to send on BT
values.put(BluetoothShare.URI, Uri.fromFile(imageFile).toString());
values.put(BluetoothShare.MIMETYPE, "image/jpeg");
values.put(BluetoothShare.DESTINATION, device.getAddress());
values.put(BluetoothShare.DIRECTION, BluetoothShare.DIRECTION_OUTBOUND);
Long ts = System.currentTimeMillis();
values.put(BluetoothShare.TIMESTAMP, ts);
// Here is where the exception happens
final Uri contentUri = getApplicationContext().getContentResolver().insert(BluetoothShare.CONTENT_URI, values);
现在我们已经死在水里......任何建议都值得赞赏。
答案 0 :(得分:6)
想出这将不再适用于4.1。直接写入内容提供商的权限现在受“签名”保护,这意味着您必须使用用于签署蓝牙应用程序的相同密钥对您的应用进行签名。
所以这就是我们最终如何做到这一点。首先使用共享意图将其直接发送到应用程序:
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("image/jpeg");
sharingIntent.setComponent(new ComponentName("com.android.bluetooth", "com.android.bluetooth.opp.BluetoothOppLauncherActivity"));
sharingIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(imageFile));
startActivity(sharingIntent);
这样可行,但它会弹出“选择设备”UI。如果您不希望必须处理意图android.bluetooth.devicepicker.action.LAUNCH
并使用广播消息android.bluetooth.devicepicker.action.DEVICE_SELECTED
进行响应。但是用户仍然可以获得选择器弹出窗口。
更新:我写了一篇blog post,其中详细说明了如何执行此操作。