zoukankan      html  css  js  c++  java
  • Android sdk 3.2蓝牙主动发起配对实例(通过类反射)

    在蓝牙开发是吃透了苦头,蓝牙老是需要重新配对才能使用,最好是通过类反射解决了问题。

    在framework里,有很多@hide掉的方法,猜想是因为,android为了安全,SDK里提供的那个连接方法,在调用底层的时候,做了限制.有时候 解决不了的问题,可以去看看framework里的或者 用JNI直接去调底层的.

     android   Java代码 
    package cn.madfinger.core; 
     
    import java.io.IOException; 
    import java.lang.reflect.Method
    import java.util.ArrayList; 
    import java.util.List; 
    import java.util.UUID; 
     
    import android.app.Activity; 
    import android.bluetooth.BluetoothAdapter; 
    import android.bluetooth.BluetoothDevice; 
    import android.bluetooth.BluetoothSocket; 
    import android.content.BroadcastReceiver; 
    import android.content.Context; 
    import android.content.Intent; 
    import android.content.IntentFilter; 
    import android.os.Bundle; 
    import android.util.Log; 
    import android.view.View; 
    import android.widget.AdapterView; 
    import android.widget.ArrayAdapter; 
    import android.widget.Button; 
    import android.widget.ListView; 
    import android.widget.Toast; 
    import android.widget.ToggleButton; 
     
    public class BlueToothTestActivity extends Activity { 
        //该UUID表示串口服务 
         static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB"; 
        Button btnSearch, btnDis, btnExit; 
        ToggleButton tbtnSwitch; 
        ListView lvBTDevices; 
        ArrayAdapter<String> adtDevices; 
        List<String> lstDevices = new ArrayList<String>(); 
        BluetoothAdapter btAdapt; 
        public static BluetoothSocket btSocket; 
     
        @Override 
        public void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.main); 
            // Button 设置 
            btnSearch = (Button) this.findViewById(R.id.btnSearch); 
            btnSearch.setOnClickListener(new ClickEvent()); 
            btnExit = (Button) this.findViewById(R.id.btnExit); 
            btnExit.setOnClickListener(new ClickEvent()); 
            btnDis = (Button) this.findViewById(R.id.btnDis); 
            btnDis.setOnClickListener(new ClickEvent()); 
     
            // ToogleButton设置 
            tbtnSwitch = (ToggleButton) this.findViewById(R.id.tbtnSwitch); 
            tbtnSwitch.setOnClickListener(new ClickEvent()); 
     
            // ListView及其数据源 适配器 
            lvBTDevices = (ListView) this.findViewById(R.id.lvDevices); 
            adtDevices = new ArrayAdapter<String>(this, 
                    android.R.layout.simple_list_item_1, lstDevices); 
            lvBTDevices.setAdapter(adtDevices); 
            lvBTDevices.setOnItemClickListener(new ItemClickEvent()); 
     
            btAdapt = BluetoothAdapter.getDefaultAdapter();// 初始化本机蓝牙功能 
     
            // ======================================================== 
            // modified by wiley 
            /*
             * if (btAdapt.getState() == BluetoothAdapter.STATE_OFF)// 读取蓝牙状态并显示
             * tbtnSwitch.setChecked(false); else if (btAdapt.getState() ==
             * BluetoothAdapter.STATE_ON) tbtnSwitch.setChecked(true);
             */ 
            if (btAdapt.isEnabled()) { 
                tbtnSwitch.setChecked(false); 
            } else { 
                tbtnSwitch.setChecked(true); 
            } 
            // ============================================================ 
            // 注册Receiver来获取蓝牙设备相关的结果 
            IntentFilter intent = new IntentFilter(); 
            intent.addAction(BluetoothDevice.ACTION_FOUND);// 用BroadcastReceiver来取得搜索结果 
            intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); 
            intent.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED); 
            intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 
            registerReceiver(searchDevices, intent); 
        } 
     
        private BroadcastReceiver searchDevices = new BroadcastReceiver() { 
     
            public void onReceive(Context context, Intent intent) { 
                String action = intent.getAction(); 
                Bundle b = intent.getExtras(); 
                Object[] lstName = b.keySet().toArray(); 
     
                // 显示所有收到的消息及其细节 
                for (int i = 0; i < lstName.length; i++) { 
                    String keyName = lstName[i].toString(); 
                    Log.e(keyName, String.valueOf(b.get(keyName))); 
                } 
                BluetoothDevice device = null; 
                // 搜索设备时,取得设备的MAC地址 
                if (BluetoothDevice.ACTION_FOUND.equals(action)) { 
                    device = intent 
                            .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
                    if (device.getBondState() == BluetoothDevice.BOND_NONE) { 
                        String str = "未配对|" + device.getName() + "|" 
                                + device.getAddress(); 
                        if (lstDevices.indexOf(str) == -1)// 防止重复添加 
                            lstDevices.add(str); // 获取设备名称和mac地址 
                        adtDevices.notifyDataSetChanged(); 
                    } 
                }else if(BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)){ 
                    device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
                    switch (device.getBondState()) { 
                    case BluetoothDevice.BOND_BONDING: 
                        Log.d("BlueToothTestActivity", "正在配对......"); 
                        break; 
                    case BluetoothDevice.BOND_BONDED: 
                        Log.d("BlueToothTestActivity", "完成配对"); 
                        connect(device);//连接设备 
                        break; 
                    case BluetoothDevice.BOND_NONE: 
                        Log.d("BlueToothTestActivity", "取消配对"); 
                    default: 
                        break; 
                    } 
                } 
                 
            } 
        }; 
     
        @Override 
        protected void onDestroy() { 
            this.unregisterReceiver(searchDevices); 
            super.onDestroy(); 
            android.os.Process.killProcess(android.os.Process.myPid()); 
        } 
     
        class ItemClickEvent implements AdapterView.OnItemClickListener { 
     
            @Override 
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, 
                    long arg3) { 
                if(btAdapt.isDiscovering())btAdapt.cancelDiscovery(); 
                String str = lstDevices.get(arg2); 
                String[] values = str.split("\\|"); 
                String address = values[2]; 
                Log.e("address", values[2]); 
                BluetoothDevice btDev = btAdapt.getRemoteDevice(address); 
                try { 
                    Boolean returnValue = false; 
                    if (btDev.getBondState() == BluetoothDevice.BOND_NONE) { 
                        //利用反射方法调用BluetoothDevice.createBond(BluetoothDevice remoteDevice); 
                        Method createBondMethod = BluetoothDevice.class 
                                .getMethod("createBond"); 
                        Log.d("BlueToothTestActivity", "开始配对"); 
                        returnValue = (Boolean) createBondMethod.invoke(btDev); 
                         
                    }else if(btDev.getBondState() == BluetoothDevice.BOND_BONDED){ 
                        connect(btDev); 
                    } 
                } catch (Exception e) { 
                    e.printStackTrace(); 
                } 
     
            } 
     
        } 
         
        private void connect(BluetoothDevice btDev) { 
            UUID uuid = UUID.fromString(SPP_UUID); 
            try { 
                btSocket = btDev.createRfcommSocketToServiceRecord(uuid); 
                Log.d("BlueToothTestActivity", "开始连接..."); 
                btSocket.connect(); 
            } catch (IOException e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } 
        } 
     
        class ClickEvent implements View.OnClickListener { 
            @Override 
            public void onClick(View v) { 
                if (v == btnSearch)// 搜索蓝牙设备,在BroadcastReceiver显示结果 
                { 
                    if (btAdapt.getState() == BluetoothAdapter.STATE_OFF) {// 如果蓝牙还没开启 
                        Toast.makeText(BlueToothTestActivity.this, "请先打开蓝牙", 1000) 
                                .show(); 
                        return; 
                    } 
                    if (btAdapt.isDiscovering()) 
                        btAdapt.cancelDiscovery(); 
                    lstDevices.clear(); 
                    Object[] lstDevice = btAdapt.getBondedDevices().toArray(); 
                    for (int i = 0; i < lstDevice.length; i++) { 
                        BluetoothDevice device = (BluetoothDevice) lstDevice[i]; 
                        String str = "已配对|" + device.getName() + "|" 
                                + device.getAddress(); 
                        lstDevices.add(str); // 获取设备名称和mac地址 
                        adtDevices.notifyDataSetChanged(); 
                    } 
                    setTitle("本机蓝牙地址:" + btAdapt.getAddress()); 
                    btAdapt.startDiscovery(); 
                } else if (v == tbtnSwitch) {// 本机蓝牙启动/关闭 
                    if (tbtnSwitch.isChecked() == false) 
                        btAdapt.enable(); 
     
                    else if (tbtnSwitch.isChecked() == true) 
                        btAdapt.disable(); 
                } else if (v == btnDis)// 本机可以被搜索 
                { 
                    Intent discoverableIntent = new Intent( 
                            BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); 
                    discoverableIntent.putExtra( 
                            BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); 
                    startActivity(discoverableIntent); 
                } else if (v == btnExit) { 
                    try { 
                        if (btSocket != null) 
                            btSocket.close(); 
                    } catch (IOException e) { 
                        e.printStackTrace(); 
                    } 
                    BlueToothTestActivity.this.finish(); 
                } 
            } 
     
        } 

  • 相关阅读:
    【转】Eclipse中查看jar包中的源码
    maven No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
    Android问题-DelphiXE8新建AVD出现“no system images installed for this target”
    Android教程-DelphiXE Android自适应屏幕办法
    教程-在F9后提示内存错误,点击了乎略,之后怎么取消乎略?
    PC问题-该虚拟机似乎正在使用中
    PC问题-(仅供备用)取消磁盘的自动扫描
    Delphi实例-IdTCPServer和IdTCPClient的使用(支持文件发送)
    Android教程-DelphiXE Android的所有权限按照分类总结说明
    C++问题-UniqueAppObject.cpp(147): error C3861: “GUXClientInit”: 找不到标识符
  • 原文地址:https://www.cnblogs.com/wellsoho/p/2252809.html
Copyright © 2011-2022 走看看