android 4.2 bluetooth OPP 蓝牙启动,扫描,使能

蓝牙启动:

SystemServer.java

bluetooth = new BluetoothManagerService(context);                     ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth);

  BluetoothManagerService的构造函数里,调用getNameAndAddress(),在这个BluetoothHandler里,绑定了 IBluetooth.class.getName,通过aidl启动了远程 AdapterService服务, AdapterService.java里的静态块实现蓝牙的启动(上电?)

static {

        classInitNative();

}

InitNativie

使能(Enable)

BluetoothEnabler.java  /   SettingsAppWidgetProvider.java  (setBluetoothEnabled)

LocalBluetoothAdapter (setBluetoothEnabled)

BluetoothAdapter.java (enable)

IBluetooth.aidl (enable)

AdapterService.java (enable)   

AdapterService.java (enableNative)

apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp(enableNative)

externel/bluedroid/btif/src/bluetooth.c (btif_enable_bluetooth)

扫描:

BluetoothSettings.java

  @Override

    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {

            case MENU_ID_SCAN:

                if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) {

                    startScanning();

                }

                return true;

            case MENU_ID_RENAME_DEVICE:

                new BluetoothNameDialogFragment().show(

                        getFragmentManager(), "rename device");

                return true;

            case MENU_ID_VISIBILITY_TIMEOUT:

                new BluetoothVisibilityTimeoutFragment().show(

                        getFragmentManager(), "visibility timeout");

                return true;

 

            case MENU_ID_SHOW_RECEIVED:

                Intent intent = new Intent(BTOPP_ACTION_OPEN_RECEIVED_FILES);

                getActivity().sendBroadcast(intent);

                return true;

        }

        return super.onOptionsItemSelected(item);

}

 

DeviceListPreferenceFragment.java (startScanning)

LocalBluetoothAdapter (startScanning)

BluetoothAdapter.java (startDiscovery)

IBluetooth.aidl (startDiscovery)

apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java (startDiscovery)   

AdapterService.java (startDiscoveryNative)

apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp(startDiscoveryNative)

externel/bluedroid/btif/src/bluetooth.c   (static const bt_interface_t bluetoothInterface)

externel/bluedroid/btif/src/btif_dm.c(btif_bm_start_discovery)

 

下往上调用:

Bluetooth.c

com_android_bluetooth_btservice_AdapterService.cpp

JniCallbacks.java

RemoteDevices.java / AdapterProperties.java / AdapterState.java / BondStateMachine.java

底层调用JniCallbacks.java,分别调用到RemoteDevices.java / AdapterProperties.java / AdapterState.java / BondStateMachine.java里。

 RemoteDevices.java通过 Intent,最终发一个广播,如发送BluetoothDevice.ACTION_FOUND这个广播被BluetoothEventManager.java里的广播收到,根据这个广播,然后分发给具体的 handler去处理。

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {

        @Override

        public void onReceive(Context context, Intent intent) {

            String action = intent.getAction();

            BluetoothDevice device = intent

                    .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                    

            Handler handler = mHandlerMap.get(action);

            if (handler != null) {

                handler.onReceive(context, intent, device);

            }

        }

    };

 

这里的 handler分发如下:

// Bluetooth on/off broadcasts

        addHandler(BluetoothAdapter.ACTION_STATE_CHANGED, new AdapterStateChangedHandler());

        // Discovery broadcasts

        addHandler(BluetoothAdapter.ACTION_DISCOVERY_STARTED, new ScanningStateChangedHandler(true));

        addHandler(BluetoothAdapter.ACTION_DISCOVERY_FINISHED, new ScanningStateChangedHandler(false));

        addHandler(BluetoothDevice.ACTION_FOUND, new DeviceFoundHandler());

        addHandler(BluetoothDevice.ACTION_DISAPPEARED, new DeviceDisappearedHandler());

        addHandler(BluetoothDevice.ACTION_NAME_CHANGED, new NameChangedHandler());

        // Pairing broadcasts

        addHandler(BluetoothDevice.ACTION_BOND_STATE_CHANGED, new BondStateChangedHandler());

        addHandler(BluetoothDevice.ACTION_PAIRING_CANCEL, new PairingCancelHandler());

 

        // Fine-grained state broadcasts

        addHandler(BluetoothDevice.ACTION_CLASS_CHANGED, new ClassChangedHandler());

        addHandler(BluetoothDevice.ACTION_UUID, new UuidChangedHandler());

        // Dock event broadcasts

        addHandler(Intent.ACTION_DOCK_EVENT, new DockEventHandler());

界面的更新:

通过回调 BluetoothSettings.java里的回调函数(BluetoothSettings extends DeviceListPreferenceFragment implements BluetoothCallback

onBluetoothStateChanged

onDeviceBondStateChanged

在这两个函数里,updateContent,来刷新界面上显示的设备。在updateContent里,调用addDeviceCategory对更新当前的界面节点。

private void addDeviceCategory(PreferenceGroup preferenceGroup, int titleId,

       BluetoothDeviceFilter.Filter filter) {

    preferenceGroup.setTitle(titleId);

    getPreferenceScreen().addPreference(preferenceGroup);

    setFilter(filter);

    setDeviceListGroup(preferenceGroup);

    addCachedDevices();

    preferenceGroup.setEnabled(true);

}

所有C/C++JAVA调用的文件:

packages/apps/Bluetooth/jni/com_android_bluetooth_hdp.cpp

packages/apps/Bluetooth/jni/com_android_bluetooth_a2dp.cpp

packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp

packages/apps/Bluetooth/jni/com_android_bluetooth_pan.cpp

packages/apps/Bluetooth/jni/com_android_bluetooth_hfp.cpp

packages/apps/Bluetooth/jni/com_android_bluetooth_hid.cpp

 

OPP:

1      BluetoothOppReceiver.java 这个类里描述的是蓝牙传输文件过程中接收到的广播事件。

2       BluetoothOppTransfer.java 管理文件传输的类

3       BluetoothOppService.java蓝牙传输文件后台的类

4       BluetoothOppObexClientSession.java 具体实现文件传输的类

5       BluetoothOppRfcommListener创建进程在OPUSH(OBEX Object Push) Chanel侦听socket消息,并回调BluetoothOppService中的回调函数进行处理。

6       BluetoothOppRfcommTransport利用socket实现传输过程,只是封装来一下,并无实质内容。

7       BluetoothOppObexServerSession为BluetoothOppService提供对象传输服务器端功能。

8       BluetoothOppObexClientSession为BluetoothOppService提供对象传输客户端功能

9       BluetoothOppSendFileInfo  发送的文件信息

10     BluetoothOppReceiveFileInfo 接受的文件信

                          opp发送文件详细过程

 

通过其他应用“分享”时,进入BluetoothOppLauncherActivity,这个Activity无界面,这个Activity会处理文件类型, URI,并将相关信息存起来:

             if (stream != null && type != null) {

                  Log.v(TAG, "Get ACTION_SEND intent: Uri = " + stream + "; mimetype = "                                         + type);

                  // Save type/stream, will be used when adding transfer

                 // session to DB.

                     BluetoothOppManager.getInstance(this).saveSendingFileInfo(type,

                            stream.toString(), false);

             }

    如果是飞行模式,则不允许进行文件传输,相关错误信息在                                BluetoothOppBtErrorActivity界面显示。

             if (!isBluetoothAllowed()) {

                Intent in = new Intent(this, BluetoothOppBtErrorActivity.class);

                in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                in.putExtra("title", this.getString(R.string.airplane_error_title));

                in.putExtra("content", this.getString(R.string.airplane_error_msg));

                this.startActivity(in);

                finish();

                return;

         }

Ø  设备如果蓝牙还未enable,则需要先BluetoothOppBtEnableActivity界面。执行BluetoothOppBtEnableActivityonClick方法,并在BluetoothOppBtEnablingActivity显示传输文件的进度;如果蓝牙已经enable了,则进入DeviceListPreferenceFragment(DevicePickerFragment),选择将要的设备;选完设备后,会发出一个BluetoothDevicePicker.ACTION_DEVICE_SELECTED的广播,广播会被BluetoothOppReceiver接收到,提示“正在向XXX发送XX文件”。同时执行startTransfer,会通过BluetoothOppManager里的InsertShareInfoThread线程,存储传送的文件的相关信息(URI,类型,时间,destination

Ø  BluetoothOppProvider里的insert 方法中,会启动BluetoothOppService,后面就开始了文件的传输。

              |>context.startService(new Intent(context, BluetoothOppService.class));

                     |>onStartCommand()

                            |> updateFromProvider()

                                   |>UpdateThread.start()

                                          |>insertShare()

                                                 |>BluetoothOppTransfer.start()

Ø  SD卡重新挂载时,MediaProvider会自动扫描SD卡上的媒体来更新媒体数据库的。谁更新了SD卡上的媒体,谁通知MediaProvider把更新了的媒体同步到MediaProvider的媒体数据库中。有两种方式,恰好蓝牙和下载器分别使用了这两种方式,这里就以它们两个程序来说明一下。

MediaScannerConnection,蓝牙传输文件时就是用的这种方式,每当接收到新的媒体文件,都会通过这种方式告诉MediaProvider同步媒体数据库。

建立连接

mConnection = new MediaScannerConnection(mContext, this);

因为建立连接是一个异步过程,所以,在建立连接时需要加入一个监听器。这样,连接建立后就可以得到通知,并进行下一步。

更新媒体数据库

mConnection.scanFile(mInfo.mFilename, mInfo.mMimetype);

这也是一个异步过程,更新完毕后,监听器中得到通知,并断开连接。

断开连接

mConnection.disconnect();

 

              文件发送调用关系:

                   |――BluetoothOppProvider

                                 |――BluetoothOppService

                                        |――BluetoothOppTransfer

                                       |――OBEX

 

                      BluetoothOppTransfer start()

                          |>start()

                                 |outbound>startConnectSession

                                        |handler发出RFCOMM_CONNECTED消息―>startObexSession

                                 |inbound>startObexSession

                                        |>mSession.start(mSessionHandler)  

                                               |>BluetoothOppObexClientSession.start()

                                                      |>doSend()

                                                             |―发MSG_SHARE_COMPLETEEventHandler>mSession.stop()

 

                         接收文件流程:

1.     蓝牙开启后,蓝牙状态即是 BluetoothAdapter.STATE_ON

2.     BluetoothOppService Receiver接收到BluetoothAdapter.STATE_ON后,启动startSocketListener()

3.     mSocketListener.start(mHandler) 里通过handler 发送一个MSG_INCOMING_BTOPP_CONNECTION消息

4.     这个消息在BluetoothOppServicehandler处理后创建一个  createServerSession(transport);

5.     createServerSession   mServerSession.preStart(),进而new obexSesstion,接收文件

OPP接收文件进度的更新:

BluetoothOppService.java里调用mNotifier.updateNotification(),通过Handlder来实现没100ms来更新一次UI,更新UI是另起的一个线程

NotificationUpdateThread,在该线程里更新进度updateActiveNotification

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 蓝牙 OPP (Object Push Profile) 是一种用于在两个设备之间传输文件的蓝牙协议。其代码结构主要包括以下几个部分: 1. 权限声明:在 AndroidManifest.xml 文件中,需要声明蓝牙相关的权限,包括BLUETOOTHBLUETOOTH_ADMIN和WRITE_EXTERNAL_STORAGE等权限。 2. Activity/Fragment:为了实现文件传输功能,需要创建相应的Activity或Fragment来处理蓝牙连接、文件搜索和文件发送等操作。通过BluetoothAdapter可以获取本地蓝牙适配器的实例,并通过BluetoothDevice获取设备的地址和名称。监听蓝牙连接状态的变化并处理相应的回调。 3. Service:为了实现后台文件接收,需要创建一个继承自Service的服务。该服务主要用于监听蓝牙连接状态和接收文件,在设备收到文件时触发相应的回调函数。 4. BroadcastReceiver:为了接收文件传输的通知,需要创建一个继承自BroadcastReceiver的接收器,并在AndroidManifest.xml中进行注册。当蓝牙操作状态发生变化时,该接收器会接收到相应的广播,并触发相应的回调函数进行处理。 5. 文件操作:在 OPP 中,文件传输是通过流的方式进行的,需要借助Java IO流和Android的文件操作类来实现文件的读取和写入。可以使用BluetoothSocket来获取输入输出流,并进行文件的发送和接收。 总结:Android 蓝牙 OPP 的代码结构主要包括权限声明、Activity/Fragment、Service、BroadcastReceiver和文件操作等部分。通过这些组件的协同工作,可以实现蓝牙设备间的文件传输功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值