【问题标题】:Android bluetooth print stopped working on 4.1Android 蓝牙打印在 4.1 上停止工作
【发布时间】:2012-09-12 12:46:42
【问题描述】:

我们有一个将图像打印到蓝牙打印机的应用程序。此应用程序在 Android 4.0 ICS 上运行良好,但当我们将其中一个升级到 Android 4.1 jelly bean 时,logcat 中的打印停止工作:

W/System.err(19319):java.lang.SecurityException:权限被拒绝: 编写 com.android.bluetooth.opp.BluetoothOppProvider uri content://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);

现在我们已经死在水里了。任何建议都值得赞赏。

【问题讨论】:

  • 我在果冻豆上使用蓝牙也有同样的问题。
  • 此代码在 2.3.8 以下不起作用,您能帮帮我吗?当我使用此代码并尝试发送文件时,它什么也没显示。我使用断点进行检查,它只是从所有行传递,然后什么都没有发生。在 2.3.8 中它正在工作。 @grennis
  • 发布的代码并非在所有地方都有效。使用下面答案中发布的方法。
  • 你错了@Drawable 这段代码在 HTC AMAZE 中运行良好,在 2.3.4 中运行,但在三星 Galaxy Tab P1000 中运行 Os 2.2。有什么解决办法吗?

标签: android bluetooth


【解决方案1】:

发现这将不再适用于 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);

这可行,但它会弹出“选择设备”用户界面。如果您不希望这样,您必须处理意图android.bluetooth.devicepicker.action.LAUNCH 并使用广播消息android.bluetooth.devicepicker.action.DEVICE_SELECTED 进行响应。但是用户仍然可以获得选择器弹出窗口。

更新:我写了一封blog post,详细说明了如何执行此操作。

【讨论】:

  • 很好的答案+1。但是你能告诉我如何使用这种方法分享其他媒体吗? @grennis
  • 有效,但您对选择设备 UI 的不可预测性是正确的。非常令人沮丧的是,他们无缘无故地添加了这个。
  • 您能否提供一个代码示例来处理 LAUNCH 意图并使用广播 DEVICE_SELECTED 进行响应?
  • 很抱歉。我修复了链接。
  • @GregEnnis 广播 DEVICE_SELECTED 不再适用于 Android 6(不确定 5),因为它是受保护的广播。您是否找到任何解决方法?
猜你喜欢
  • 1970-01-01
  • 2012-04-07
  • 1970-01-01
  • 2011-07-05
  • 1970-01-01
  • 1970-01-01
  • 2014-12-16
  • 1970-01-01
  • 2013-01-09
相关资源
最近更新 更多