Android 蓝牙无法发送或接收某些类型文件

Android 蓝牙应用使得用户能够在蓝牙设备之间进行文件传输。用户可以通过蓝牙连接两台设备,并在它们之间传输文件,如照片、音乐、视频等。这对于用户来说是非常便利的,无需使用数据线或互联网连接,可以直接在附近的设备之间进行文件共享。

文章目录

  • 1. 蓝牙无法发送某些类型文件
  • 2. 蓝牙无法接收某些类型文件
  • 3. 蓝牙权限问题

从 Andorid 13 后蓝牙模块位置从 packages/apps/Bluetooth/变成了 packages/modules/Bluetooth

server@dev-fj-srv:/work/AndrodU/packages/modules/Bluetooth/android/app$ tree -L 1
.
|-- Android.bp
|-- AndroidManifest.xml
|-- OWNERS
|-- app.iml
|-- certs
|-- jni
|-- lib
|-- proguard.flags
|-- res
|-- services
|-- src
|-- tests
`-- tools8 directories, 5 files

1. 蓝牙无法发送某些类型文件

原生蓝牙的ACTION_SEND_MULTIPLEACTION_SEND二种action分享类型做了限制,所以会导致部分类型的文件无法通过蓝牙分享,为了解除这种限制,可以将数据类型设置成*/*,即<data android:mimeType="*/*" />

packages/modules/Bluetooth/android/app/AndroidManifest.xml

<activity android:name="com.android.bluetooth.opp.BluetoothOppLauncherActivity"android:process="@string/process"android:theme="@style/opp_launcher_activity"android:label="@string/bt_share_picker_label"android:enabled="false"android:exported="true"><intent-filter><action android:name="android.intent.action.SEND"/><category android:name="android.intent.category.DEFAULT"/><!-- @{ support sending all types of files.<data android:mimeType="image/*"/><data android:mimeType="video/*"/><data android:mimeType="audio/*"/><data android:mimeType="text/x-vcard"/><data android:mimeType="text/x-vcalendar"/><data android:mimeType="text/calendar"/><data android:mimeType="text/plain"/><data android:mimeType="text/html"/><data android:mimeType="text/xml"/><data android:mimeType="application/zip"/><data android:mimeType="application/vnd.ms-excel"/><data android:mimeType="application/msword"/><data android:mimeType="application/vnd.ms-powerpoint"/><data android:mimeType="application/pdf"/><data android:mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"/><data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document"/><data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation"/><data android:mimeType="application/x-hwp"/>--><data android:mimeType="*/*" /><!-- @} --></intent-filter><intent-filter><action android:name="android.intent.action.SEND_MULTIPLE"/><category android:name="android.intent.category.DEFAULT"/><!-- @{ support sending all types of files.<data android:mimeType="image/*"/><data android:mimeType="video/*"/><data android:mimeType="x-mixmedia/*"/><data android:mimeType="text/x-vcard"/>--><data android:mimeType="*/*" /><!-- @} --></intent-filter><intent-filter><action android:name="android.btopp.intent.action.OPEN"/><category android:name="android.intent.category.DEFAULT"/><data android:mimeType="vnd.android.cursor.item/vnd.android.btopp"/></intent-filter>
</activity>

2. 蓝牙无法接收某些类型文件

log 报错分析

04-20 19:27:10.928 23480 12218 D BtOppObexClient: Start!
04-20 19:27:11.031 23480 12224 D BtOppObexClient: Create ClientSession with transport com.android.bluetooth.BluetoothObexTransport@c894e88
04-20 19:27:11.227 23480 12224 D BtOppObexClient: OBEX session created
04-20 19:27:11.808 23480 12224 I BtOppObexClient: Remote reject, Response code is 207
04-20 19:27:11.810 23480 12224 I BtOppObexClient: Remote reject file type application/vnd.android.package-archive
04-20 19:27:11.810 23480 12224 I BtOppObexClient: Response error code is 207
04-20 19:27:11.824 23480 12224 D BtOppObexClient: Client thread waiting for next share, sleep for 500
04-20 19:27:11.825 23480 12218 D BtOppObexClient: Stop!
04-20 19:27:11.917 23480 12224 D BtOppObexClient: OBEX session disconnected
04-20 19:27:12.932 23480 12231 D BtOppObexClient: Stop!

BtOppObexClient: Remote reject file type application/vnd.android.package-archive 根据log信息找到代码位置:src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java

@VisibleForTesting
int sendFile(BluetoothOppSendFileInfo fileInfo) {
...} else if (responseCode == ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE) {Log.i(TAG, "Remote reject file type " + fileInfo.mMimetype);status = BluetoothShare.STATUS_NOT_ACCEPTABLE;} 
...
}

src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java 中的 public int onPut(Operation op)

// Reject anything outside the "acceptlist" plus unspecified MIME Types.
if (mimeType == null || (!isAcceptlisted && !Constants.mimeTypeMatches(mimeType,Constants.ACCEPTABLE_SHARE_INBOUND_TYPES))) {if (D) {Log.w(TAG, "mimeType is null or in unacceptable list, reject the transfer");}return ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE;
}

此处定义了常量Constants.ACCEPTABLE_SHARE_INBOUND_TYPES,来过滤可接收的文件类型的mimeType

/*** The MIME type(s) of we could accept from other device.* This is in essence a "acceptlist" of acceptable types.* Today, restricted to images, audio, video and certain text types.*/
static final String[] ACCEPTABLE_SHARE_INBOUND_TYPES = new String[]{"image/*","video/*","audio/*","text/x-vcard","text/x-vcalendar","text/calendar","text/plain","text/html","text/xml","application/epub+zip","application/zip","application/vnd.ms-excel","application/msword","application/vnd.ms-powerpoint","application/pdf","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.openxmlformats-officedocument.presentationml.presentation","application/x-hwp",
};

因此,如果需要接收所有文件类型,可以修改此ACCEPTABLE_SHARE_INBOUND_TYPES

static final String[] ACCEPTABLE_SHARE_INBOUND_TYPES = new String[]{"*/*"
};

3. 蓝牙权限问题

部分应用的图片无法通过蓝牙分享,蓝牙通知显示文件传输失败:未知文件,无法正确处理请求。log输出报错如下:

12-02 02:12:22.290  5046  6302 E DatabaseUtils: Writing exception to parcel
12-02 02:12:22.290  5046  6302 E DatabaseUtils: java.lang.SecurityException: com.android.bluetooth has no access to content://media/external/images/media/1000000037
12-02 02:12:22.290  5046  6302 E DatabaseUtils: 	at com.android.providers.media.MediaProvider.enforceCallingPermissionInternal(MediaProvider.java:10014)
12-02 02:12:22.290  5046  6302 E DatabaseUtils: 	at com.android.providers.media.MediaProvider.enforceCallingPermission(MediaProvider.java:9911)
12-02 02:12:22.290  5046  6302 E DatabaseUtils: 	at com.android.providers.media.MediaProvider.checkAccess(MediaProvider.java:10035)
12-02 02:12:22.290  5046  6302 E DatabaseUtils: 	at com.android.providers.media.MediaProvider.openFileAndEnforcePathPermissionsHelper(MediaProvider.java:8294)
12-02 02:12:22.290  5046  6302 E DatabaseUtils: 	at com.android.providers.media.MediaProvider.openFileCommon(MediaProvider.java:7901)
12-02 02:12:22.290  5046  6302 E DatabaseUtils: 	at com.android.providers.media.MediaProvider.openTypedAssetFileCommon(MediaProvider.java:7969)
12-02 02:12:22.290  5046  6302 E DatabaseUtils: 	at com.android.providers.media.MediaProvider.openTypedAssetFile(MediaProvider.java:7913)
12-02 02:12:22.290  5046  6302 E DatabaseUtils: 	at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:562)
12-02 02:12:22.290  5046  6302 E DatabaseUtils: 	at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:327)
12-02 02:12:22.290  5046  6302 E DatabaseUtils: 	at android.os.Binder.execTransactInternal(Binder.java:1285)
12-02 02:12:22.290  5046  6302 E DatabaseUtils: 	at android.os.Binder.execTransact(Binder.java:1244)

log表明蓝牙无法获取此媒体文件,缺少权限,由于Android 13后新增了媒体文件的细分权限,蓝牙的AndroidManifest.xml中没有添加这些细分权限,遇到的images文件出现的此问题,添加READ_MEDIA_IMAGES权限后测试成功。

<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />

STATUS_OBEX_DATA_ERROR:由于在 OBEX 级别接收或处理数据时出现错误,因此无法完成此传输。

/*** Get status description according to status code.*/
public static String getStatusDescription(Context context, int statusCode, String deviceName) {String ret;if (statusCode == BluetoothShare.STATUS_PENDING) {ret = context.getString(R.string.status_pending);} else if (statusCode == BluetoothShare.STATUS_RUNNING) {ret = context.getString(R.string.status_running);} else if (statusCode == BluetoothShare.STATUS_SUCCESS) {ret = context.getString(R.string.status_success);} else if (statusCode == BluetoothShare.STATUS_NOT_ACCEPTABLE) {ret = context.getString(R.string.status_not_accept);} else if (statusCode == BluetoothShare.STATUS_FORBIDDEN) {ret = context.getString(R.string.status_forbidden);} else if (statusCode == BluetoothShare.STATUS_CANCELED) {ret = context.getString(R.string.status_canceled);} else if (statusCode == BluetoothShare.STATUS_FILE_ERROR) {ret = context.getString(R.string.status_file_error);} else if (statusCode == BluetoothShare.STATUS_ERROR_NO_SDCARD) {int id = deviceHasNoSdCard()? R.string.status_no_sd_card_nosdcard: R.string.status_no_sd_card_default;ret = context.getString(id);} else if (statusCode == BluetoothShare.STATUS_CONNECTION_ERROR) {ret = context.getString(R.string.status_connection_error);} else if (statusCode == BluetoothShare.STATUS_ERROR_SDCARD_FULL) {int id = deviceHasNoSdCard() ? R.string.bt_sm_2_1_nosdcard : R.string.bt_sm_2_1_default;ret = context.getString(id);} else if ((statusCode == BluetoothShare.STATUS_BAD_REQUEST) || (statusCode== BluetoothShare.STATUS_LENGTH_REQUIRED) || (statusCode== BluetoothShare.STATUS_PRECONDITION_FAILED) || (statusCode== BluetoothShare.STATUS_UNHANDLED_OBEX_CODE) || (statusCode== BluetoothShare.STATUS_OBEX_DATA_ERROR)) {ret = context.getString(R.string.status_protocol_error);} else {ret = context.getString(R.string.status_unknown_error);}return ret;
}

无法查询到传输的文件信息,所以显示为未知文件。

if (info.mFileName == null) {info.mFileName = context.getString(R.string.unknown_file);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/4131.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot的“大学生社团活动平台”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“大学生社团活动平台”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统结构图 管理员登录界面图 管理员功能界…

C#基础|数组的使用、字符串的分隔与连接

哈喽,你好,我是雷工! 01 数组概念 数组是一个变量,用来存储“相同数据类型”的“一组数据”。 02 数组与普通变量的区别 声明一个变量,就是在内存空间分配一块儿合适的空间; 声明一个数组,就是在内存空间分配一串儿连续的空间。 03 数组基本要素 标识符:数组的名…

SpringCloud中网关-详解、案例(代码)

简介&#xff1a;在Spring Cloud中&#xff0c;网关的角色是非常重要的&#xff0c;它负责整个系统的入口流量&#xff0c;并且可以处理路由、过滤、协议转换等操作 目录 1、网关的技术实现 1.1 网关功能 1.2 网关的形式 2、网关实现步骤 2.1 添加相关依赖 2.2 创建此mod…

【算法刷题 | 贪心算法05】4.27(K次取反后最大化的数组和、加油站)

文章目录 8.K次取反后最大化的数组和8.1题目8.2解法&#xff1a;贪心8.2.1贪心思路8.2.2代码实现 9.加油站9.1题目9.2解法&#xff1a;贪心9.2.1贪心思路9.2.2代码实现 8.K次取反后最大化的数组和 8.1题目 给你一个整数数组 nums 和一个整数 k &#xff0c;按以下方法修改该数…

【深度学习-番外1】Win10系统搭建VSCode+Anaconda+Pytorch+CUDA深度学习环境和框架全过程

专栏的老读者们都知道&#xff0c;以前的文章以使用MATLAB的为多。 不过后续陆续开始展开深度学习算法的应用&#xff0c;就会逐渐引入Python语言了&#xff08;当然MATLAB的代码也会同步更新&#xff09;&#xff0c;这是由于在深度学习领域&#xff0c;Python应用更为广泛。…

6.比较含退格的字符串(力扣字符串)(两种解法:字符串操作,栈)

目录 题目链接 法一&#xff1a;普通字符串操作 法二&#xff1a;栈操作 题目链接 . - 力扣&#xff08;LeetCode&#xff09; 法一&#xff1a;普通字符串操作 用len1记录目前s的字符个数&#xff0c;len2记录目前t的字符个数 如果不是#&#xff0c;则s[len1] s[i] 如果是…

解决Android Studio安卓开发写入文件问题

有很多小伙伴想把文件写进安卓系统储存失败&#xff0c;类似下面的代码 val file File("account.txt")val writer BufferedWriter(FileWriter(file))writer.use {it.write(username "," password)} 用java方式写入读出文件但是显示成功但是找不到文件…

Linux--自主编写shell

目录 准备知识 shell原理 shell与用户互动的过程 实现shell 0.用到的头文件和宏定义 1.首先我们需要自己输出一个命令行 2.获取用户命令行字符 3.命令行字符串分割 4.执行命令 5.设置循环 6.检测内建命令 7.完善细节--获取工作目录而非路径 准备知识 Linux--环境…

Linux系统安全与应用【二】

目录 1.开关机安全控制 1.2 实例&#xff1a;GRUB 菜单设置密码 2.终端登录安全控制 2.1 限制root只在安全终端登录 ​3.弱口令检测 3.1 Joth the Ripper,JR​编辑 4.网络端口扫描 4.1 nmap命令 1.开关机安全控制 1.1 GRUB限制 限制更改GRUB引导参数 通常情况下在系统…

类和对象【三】析构函数和拷贝构造函数

文章目录 析构函数析构函数的定义析构函数的作用主要作用次要作用 析构函数的特点 拷贝构造函数拷贝构造函数的定义拷贝构造函数的作用主要作用次要作用 拷贝构造函数的特点浅拷贝和深拷贝浅拷贝深拷贝 拷贝构造函数的调用场景 析构函数 析构函数的定义 析构函数(destructor) …

mybatis基本使用

文章目录 1. mybatis2. 基本使用(1) maven坐标(2) 配置文件编写(3) 数据库操作(4) 注解查询 2. 基本配置(1) 读取外部配置文件(2) mapper映射 3. 映射文件查询删除/修改/新增 动态sql 1. mybatis MyBatis 是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高…

使用 Gradio 的“热重载”模式快速开发 AI 应用

在这篇文章中&#xff0c;我将展示如何利用 Gradio 的热重载模式快速构建一个功能齐全的 AI 应用。但在进入正题之前&#xff0c;让我们先了解一下什么是重载模式以及 Gradio 为什么要采用自定义的自动重载逻辑。如果你已熟悉 Gradio 并急于开始构建&#xff0c;请直接跳转到第…

记录些RAG中Chunk切分方法

非结构化数据 在处理非结构化数据时&#xff0c;文本切分策略的选择至关重要&#xff0c;以保持信息完整性和提高检索效率。以下是一些有效的切分方法&#xff1a; 固定长度切分&#xff1a;将文本按照固定的字数或词数进行切分&#xff0c;例如每个文档切分成300个字或300个…

【Camera KMD ISP SubSystem笔记】Request 流转与Bubble机制

ISP中断类型 SOF: 一帧图像数据开始传输 EOF: 一帧图像数据传输完成 REG_UPDATE: ISP寄存器更新完成(每个reg group都有独立的这个中断) EPOCH: ISP某一行结尾(默认20)就会产生此中断 BUFFER DONE: 一帧图像数据ISP完全写到DDR了 管理Isp request的几个List st…

代码随想录:二叉树22-24

目录 700.二叉搜索树的搜索 题目 代码&#xff08;二叉搜索树迭代&#xff09; 代码&#xff08;二叉搜索树递归&#xff09; 代码&#xff08;普通二叉树递归&#xff09; 代码&#xff08;普通二叉树迭代&#xff09; 98.验证二叉搜索树 题目 代码&#xff08;中序递…

oracle rman restore database的时候报错RMAN-06023: 没有找到数据文件1的副本来还原

一 问题描述 在oracle异地备份恢复测试数据库上执行restore database的时候报错&#xff1a; RMAN-06023: 没有找到数据文件1的副本来还原 可是我看备份明明都是存在的&#xff0c;而且已经执行了catalog start with命令。 有点奇怪的是catalog start with的时候&#xff0c…

4.10 海思SS928开发 - uboot开发 - 环境变量使用注意

4.10 uboot开发 - 环境变量使用注意 更新 uboot 镜像文件时&#xff0c;环境变量相关工具也需要更新。uboot 镜像文件与环境变量工具如果不对应的话&#xff0c;可能会导致莫名其妙的问题。更新 uboot 镜像文件时&#xff0c;最好将储存在磁盘上的环境变量擦除。因为当磁盘上存…

牛客NC143 矩阵乘法【中等 矩阵 C++/Java/Go/PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/bf358c3ac73e491585943bac94e309b0 思路 矩阵算法在图像处理、神经网络、模式识别等领域有着广泛的用途。在矩阵乘法中&#xff0c;A矩阵和B矩阵可以做乘法运算必须满足A矩阵的列的数量等于B矩阵的行的数量。运算…

d13(126-129)-勇敢开始Java,咖啡拯救人生

目录 Arrays类 数组中存储对象时 排序 在要比较的类中public class 类名 implements Comparable <类名> Comparator JDK8新特性&#xff1a;Lambda表达式 Lambda表达式的省略写法 方法引用 静态方法引用 实例方法引用 特定类型的方法引用 构造器引用 医院挂号系…

FANUC机器人SOCKET连接指令编写

一、创建一个.KL文件编写连接指令 创建一个KL文本来编写FANUC机器人socket连接指令 二、KAREL指令代码 fanuc机器人karel编辑器编辑的karel代码如下&#xff1a; PROGRAM SM_CON %COMMENT SOCKET连接 %STACKSIZE 4000 --堆栈大小 %INCLUDE klevccdfVAR status,data_type,in…