You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android蓝牙文件接收完成是否对外发广播?对应Intent是什么?

监听蓝牙文件接收完成的可行方案

我完全懂你现在的困扰——那些你尝试的BT_OPP_TRANSFER_DONE之类的Intent,确实是系统默认蓝牙应用的私有广播,只给自身组件用,对外根本不触发,也就导致你实际传文件时接收器毫无反应,只有手动用ADB发Intent才会生效。下面给你几个经过验证的可行思路:

1. 监听媒体扫描完成广播

蓝牙接收的文件基本都会被系统媒体扫描器识别,你可以监听公开的android.intent.action.MEDIA_SCANNER_FINISHED广播。不过要注意,这个广播会在所有媒体文件扫描完成时触发,不止是蓝牙文件,所以需要额外判断文件的来源路径。

在AndroidManifest里的过滤配置示例:

<receiver android:name=".BluetoothFileReceiver">
    <intent-filter>
        <action android:name="android.intent.action.MEDIA_SCANNER_FINISHED" />
        <data android:scheme="file" />
    </intent-filter>
</receiver>

然后在接收器里获取文件路径,判断是否来自蓝牙默认接收目录(通常是/sdcard/Bluetooth/或者/storage/emulated/0/Bluetooth/),再执行你的逻辑。

2. 用ContentObserver监听BluetoothShare数据库

系统蓝牙应用会把所有传输记录存在content://com.android.bluetooth.opp/btopp这个ContentProvider里,你可以注册一个ContentObserver来监听这个数据库的变化,一旦有新的传输完成记录,就触发你的代码。

步骤参考:

  • 先申请对应权限:Android 6.0+需要动态申请READ_EXTERNAL_STORAGE;Android 10+如果要直接访问文件,可能需要MANAGE_EXTERNAL_STORAGE权限(需用户手动在设置授权),或者用MediaStore操作。
  • 代码里注册ContentObserver:
getContentResolver().registerContentObserver(
        Uri.parse("content://com.android.bluetooth.opp/btopp"),
        true,
        new ContentObserver(new Handler(Looper.getMainLooper())) {
            @Override
            public void onChange(boolean selfChange) {
                super.onChange(selfChange);
                // 查询最新的传输记录,判断状态是否为完成
                Cursor cursor = getContentResolver().query(
                        Uri.parse("content://com.android.bluetooth.opp/btopp"),
                        new String[]{"_id", "status", "uri"},
                        null,
                        null,
                        "_id DESC" // 取最新的一条记录
                );
                if (cursor != null && cursor.moveToFirst()) {
                    int status = cursor.getInt(cursor.getColumnIndex("status"));
                    // 状态值2通常代表传输完成(不同系统版本可能有差异,建议自行测试确认)
                    if (status == 2) {
                        String fileUri = cursor.getString(cursor.getColumnIndex("uri"));
                        // 这里执行你的业务逻辑
                    }
                    cursor.close();
                }
            }
        }
);

注意:不同厂商的定制系统可能会修改这个ContentProvider的结构或包名,需要做适配测试。

3. 借助AccessibilityService捕获通知

如果上面的方法都不满足需求,你可以用AccessibilityService监听系统蓝牙应用的通知——当文件接收完成时,系统会弹出对应通知,AccessibilityService可以捕获到这个通知的内容,进而触发你的逻辑。

实现步骤:

  • 创建继承自AccessibilityService的类:
public class BluetoothAccessibilityService extends AccessibilityService {
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        if (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
            List<CharSequence> texts = event.getText();
            if (!texts.isEmpty()) {
                for (CharSequence text : texts) {
                    // 根据系统语言判断通知关键词,比如中文的"已接收"、英文的"Received"
                    if (text.toString().contains("已接收")) {
                        // 执行你的逻辑
                        break;
                    }
                }
            }
        }
    }

    @Override
    public void onInterrupt() {}
}
  • 在AndroidManifest中注册Service:
<service
    android:name=".BluetoothAccessibilityService"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>
    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibility_service_config" />
</service>
  • 创建res/xml/accessibility_service_config.xml配置文件:
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeNotificationStateChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true" />

这种方法需要用户手动在系统设置里开启辅助功能,体验上有一点门槛,但兼容性相对较好。

4. 权限适配提醒

  • Android 6.0及以上,必须动态申请READ_EXTERNAL_STORAGE权限;
  • Android 10(API 29)及以上,访问外部存储优先用MediaStore,或者申请MANAGE_EXTERNAL_STORAGE权限(需用户手动授权);
  • 部分定制系统的蓝牙应用包名可能不是com.android.bluetooth,监听ContentObserver时需要注意适配。

内容的提问来源于stack exchange,提问作者Prince Rambade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:40:23