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
`-- tools

8 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.mfbz.cn/a/569923.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PVE虚拟机隐藏状态栏虚拟设备

虚拟机启动后&#xff0c;状态栏会出现一些虚拟设备&#xff0c;点击弹出会导致虚拟机无法使用。 解决方案&#xff1a; 1、在桌面新建disable_virtio_removale.bat文件&#xff0c;内容如下&#xff1a; ECHO OFF FOR /f %%A IN (reg query "HKLM\SYSTEM\CurrentContro…

【机器学习与实现】机器学习概述

目录 一、机器学习的基本概念和方法&#xff08;一&#xff09;基本概念&#xff08;二&#xff09;机器学习的一般过程举例&#xff08;三&#xff09;样本和参数估计 二、机器学习的步骤总结&#xff08;一&#xff09;机器学习的主要步骤&#xff08;二&#xff09;样本及样…

MyBatis基础操作

黑马程序员JavaWeb开发教程 文章目录 根据资料中提供的《tlias智能学习辅助系统》页面原型及需求&#xff0c;完成员工管理的需求开发一、环境准备1、准备数据库表emp2、创建一个新的springboot工程&#xff0c;选择引入对应的起步依赖&#xff08;mybatis、mysql驱动、lombok&…

SpringBoot项目启动,传参有哪些方式?

SpringBoot项目启动&#xff0c;传参有哪些方式&#xff1f; 1.Spring级别的参数 直接在启动 Spring Boot 应用的命令行中使用 -- 后跟参数名和值的方式来传递参数。 记住&#xff1a;一般是对于Spring Boot应用特有的配置参数&#xff0c;确保它们遵循Spring Boot的配置属性命…

PC端微信软件如何多开【详细教程】

现在工作中&#xff0c;很多小伙伴会用到两个微信。如何在PC端同时登录多个微信呢&#xff1f;赶快跟着下面的教程学起来吧 1、创建一个txt文本文件 2、输入以下代码并保存 echo offstart "" "复制粘贴微信的目标地址" 需要开几个微信就复制几行exit示例…

顺序表leetcode刷题(C语言版)

一.移除元素 对于本题&#xff0c;共有两种解法&#xff1a; 思路一&#xff1a;创建新的数组&#xff0c;遍历原数组&#xff0c;将不为value的值放到新数组中&#xff0c;但本题不允许使用新的数组&#xff0c;因此该方法不行 思路二&#xff1a;使用快慢指针&#xff0c;原数…

2.5G交换机 TL-SE2109简单开箱评测,8个2.5G电口+1个10G光口(SFP+)

TPLINK&#xff08;普联&#xff09;的万兆上联的2.5G网管交换机TL-SE2109简单开箱测评。8个2.5电口&#xff0c;1个万兆SFP口。 TL-SH5428 万兆交换机开箱和简单的评测&#xff1a;https://blog.zeruns.tech/archives/707.html WiFi7无线路由器TL-7DR6560简单开箱测评&#x…

震惊!小红书矩阵账号管理-批量发布笔记

“小红书引流软件矩阵工具-笔记批量发” 昨天&#xff0c;有个粉丝急匆匆地来找我&#xff0c;一脸焦急地说&#xff1a;“大佬&#xff0c;我现在运营着好几个小红书账号&#xff0c;每天都要发布内容&#xff0c;可把我忙坏了&#xff0c;有没有什么高效的管理方法啊&#xf…

开源协议的对比和商业上的安全使用

开源协议的对比和商业上的安全使用 开源组件是&#xff1a;“任何人都可以自由使用、更改和共享&#xff08;以修改或未修改的形式&#xff09;的软件”。当今企业依靠开源来加速开发、降低成本和推动创新。对开放源码的糟糕管理可能会使组织面临安全、法律和操作风险。 使用…

Python基础进阶语法

目录&#xff1a; 一、基础语法二、进阶语法 一、基础语法 二、进阶语法 1、列表推导式运用 解析&#xff1a;先循环1到10内的数字&#xff0c;然后过滤大于5的数&#xff0c;赋值到new_list数组中进行打印结果。

重学java 22.面向对象 继承、抽象综合案例

我们纵横交错&#xff0c;最后回到原点 —— 24.4.23 综合案例 流程思维图 代码实现 方式1 利用set方法为属性赋值 父类&#xff1a; public abstract class Development extends Employee{}子类1&#xff1a; public class JavaEE extends Development{Overridepublic void w…

Redis可视化工具RedisInsight

下载地址&#xff1a;RedisInsight - The Best Redis GUIRedisInsight provides an intuitive and efficient graphical interface for Redis, allowing you to interact with your databases and manage your data.https://redis.com/redis-enterprise/redis-insight/#insight…

APP自定义身份证相机(Android +iOS)

基本上同时兼容安卓和苹果的插件都需要付费&#xff0c;这里我找了2个好用的免费插件 1.仅支持安卓&#xff1a;自定义身份证相机&#xff08;支持蒙版自定义&#xff09;&#xff0c;内置蒙版&#xff0c;照片预览&#xff0c;身份证裁剪 - DCloud 插件市场、 2.支持iOS(已测…

前端CSS基础8(盒子模型(margin、border、padding、content))

前端CSS基础8&#xff08;盒子模型&#xff08;margin、border、padding、content&#xff09;&#xff09; CSS盒子模型CSS中常用的长度单位元素的分类&#xff0c;各个元素的显示模式修改元素的显示模式&#xff08;类型&#xff09;盒子模型的组成部分盒子内容区-contentCSS…

激活虚拟环境.ps1“因为在此系统上禁止运行脚本”解决办法

激活虚拟环境.ps1“因为在此系统上禁止运行脚本”解决办法 1.问题收录 Django激活虚拟环境时遇到的&#xff0c;已解决&#xff0c;作以收录&#xff0c;希望能帮到大家 2.分析问题 核心是Powershell的安全策略&#xff0c;将XX命令视为不安全脚本&#xff0c;不允许执行&…

树莓集团有效链接政、企、校,搭建三方合作平台

树莓集团——数字生态产业链建设者&#xff0c;有效链接政、企、校&#xff0c;搭建三方合作平台。集团旗下树莓教育拥有发展数字影像培训十余年的成都王老师摄影培训学校&#xff0c;一家在数字影像教育领域中独树一帜的专业机构。树莓集团凭借其深厚的教育积淀和丰富的实践经…

单片机通讯协议

参考&#xff1a;江科大单片机教程 STM32入门教程-2023版 细致讲解 中文字幕_哔哩哔哩_bilibili IIC通讯协议SPI通信协议UARTCANUSB速度100k-400khz4Mhz-线数2 CLK,DATA4CLK,ENB,IO,OI额外设备一主多从一主多从 一般不用自己写&#xff0c;都有相应的库或官方提供相应的&#…

Mysql用语句创建表/插入列【示例】

一、 创建表 COMMENT表示字段或列的注释 -- 新建student表 CREATE TABLE student (id BIGINT NOT NULL COMMENT 学生id, enroll_date DATE NOT NULL COMMENT 注册时间, NAME VARCHAR(18) DEFAULT NOT NULL COMMENT 学生姓名, deal_flag TINYINT(1) DEFAULT 0 NOT NULL COMM…

linux开发板开机启动向日葵

硬件&#xff1a;orangepi 5 pro 操作系统&#xff1a;ubuntu 20.4 lts 安装向日葵 根据我的实测&#xff0c;arm架构的ubuntu系统只能安装向日葵提供的麒麟系统的那个版本&#xff0c;具体安装方式官网下载页面有 允许任意用户连接到 X11 使用root用户登录后打开终端输入一下…

数据分析学习资源(未完)

1、PDF 数据分析自学攻略 增长黑客&#xff08;AARRR&#xff09; 量化思维