久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

android開(kāi)發(fā)之手機(jī)與單片機(jī)藍(lán)牙模塊通信

 迎著風(fēng)兒看星星 2015-03-18

之前兩篇都是在說(shuō)與手機(jī)的連接,,連接方法,和主動(dòng)配對(duì)連接,,都是手機(jī)與手機(jī)的操作,,做起來(lái)還是沒(méi)問(wèn)題的,但是最終的目的是與單片機(jī)的藍(lán)牙模塊的通信,。

 

下面是到目前為止嘗試的與單片機(jī)的通信方法,,沒(méi)有成功,但是從思路上來(lái)說(shuō)沒(méi)有問(wèn)題,,最大的問(wèn)題是與單片機(jī)配對(duì)的時(shí)候,,單片機(jī)的藍(lán)牙模塊的PIN配對(duì)碼是寫(xiě)死的,固定為1234,,

而手機(jī)這邊連接配對(duì)都是自動(dòng)生成的PIN配對(duì)碼,,這種方式在手機(jī)與手機(jī)配對(duì)的時(shí)候是極為方便的,但是在這里與單片機(jī)連接卻成了最大的問(wèn)題,,因?yàn)槭謾C(jī)自動(dòng)生成而且每次都不一樣,,所以沒(méi)法與單片機(jī)藍(lán)牙模塊的1234相同也就沒(méi)法陪對(duì)了。下面只是介紹的到目前為止我們的大題思路,,具體代碼很多,,而且涉及到項(xiàng)目也就沒(méi)有貼。

如果關(guān)于上面的問(wèn)題哪位同學(xué)有思路或者做過(guò)類似的項(xiàng)目還請(qǐng)指點(diǎn),。

 

首先,,如何開(kāi)啟藍(lán)牙設(shè)備和設(shè)置可見(jiàn)時(shí)間:

private void search() {        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();        if (!adapter.isEnabled()) {            adapter.enable();        }        Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);        enable.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 3600); //3600為藍(lán)牙設(shè)備可見(jiàn)時(shí)間         startActivity(enable);        Intent searchIntent = new Intent(this, ComminuteActivity.class);        startActivity(searchIntent);    }


正式開(kāi)始與藍(lán)牙模塊進(jìn)行通信

public class ComminuteActivity extends Activity {    private BluetoothReceiver receiver;    private BluetoothAdapter bluetoothAdapter;    private List<String> devices;    private List<BluetoothDevice> deviceList;    private Bluetooth client;    private final String lockName = 'YESYOU';    private String message = '000001';    private ListView listView;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.search_layout);        listView = (ListView) this.findViewById(R.id.list);        deviceList = new ArrayList<BluetoothDevice>();        devices = new ArrayList<String>();        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();        bluetoothAdapter.startDiscovery();        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);        receiver = new BluetoothReceiver();        registerReceiver(receiver, filter);        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                setContentView(R.layout.connect_layout);                BluetoothDevice device = deviceList.get(position);                client = new Bluetooth(device, handler);                try {                    client.connect(message);                } catch (Exception e) {                    Log.e('TAG', e.toString());                }            }        });    }    @Override    protected void onDestroy() {        unregisterReceiver(receiver);        super.onDestroy();    }    private final Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case Bluetooth.CONNECT_FAILED:                    Toast.makeText(ComminuteActivity.this, '連接失敗', Toast.LENGTH_LONG).show();                    try {                        client.connect(message);                    } catch (Exception e) {                        Log.e('TAG', e.toString());                    }                    break;                case Bluetooth.CONNECT_SUCCESS:                    Toast.makeText(ComminuteActivity.this, '連接成功', Toast.LENGTH_LONG).show();                    break;                case Bluetooth.READ_FAILED:                    Toast.makeText(ComminuteActivity.this, '讀取失敗', Toast.LENGTH_LONG).show();                    break;                case Bluetooth.WRITE_FAILED:                    Toast.makeText(ComminuteActivity.this, '寫(xiě)入失敗', Toast.LENGTH_LONG).show();                    break;                case Bluetooth.DATA:                    Toast.makeText(ComminuteActivity.this, msg.arg1 + '', Toast.LENGTH_LONG).show();                    break;            }        }    };    private class BluetoothReceiver extends BroadcastReceiver {        @Override        public void onReceive(Context context, Intent intent) {            String action = intent.getAction();            if (BluetoothDevice.ACTION_FOUND.equals(action)) {                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);                if (isLock(device)) {                    devices.add(device.getName());                }                deviceList.add(device);            }            showDevices();        }    }    private boolean isLock(BluetoothDevice device) {        boolean isLockName = (device.getName()).equals(lockName);        boolean isSingleDevice = devices.indexOf(device.getName()) == -1;        return isLockName && isSingleDevice;    }    private void showDevices() {        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,                devices);        listView.setAdapter(adapter);    }}

這里需要提一下的是,,startDiscovery()這個(gè)方法和它的返回值,它是一個(gè)異步方法,,會(huì)對(duì)其他藍(lán)牙設(shè)備進(jìn)行搜索,,持續(xù)時(shí)間為12秒。

搜索過(guò)程其實(shí)是在System Service中進(jìn)行,,我們可以通過(guò)cancelDiscovery()方法來(lái)停止這個(gè)搜索,。在系統(tǒng)搜索藍(lán)牙設(shè)備的過(guò)程中,系統(tǒng)可能會(huì)發(fā)送以下三個(gè)廣播:ACTION_DISCOVERY_START(開(kāi)始搜索),,

ACTION_DISCOVERY_FINISHED(搜索結(jié)束)

和ACTION_FOUND(找到設(shè)備),。

ACTION_FOUND這個(gè)才是我們想要的,這個(gè)Intent中包含兩個(gè)extra fields:    EXTRA_DEVICE和EXTRA_CLASS,,

包含的分別是BluetoothDevice和BluetoothClass,,

EXTRA_DEVICE中的BluetoothDevice就是我們搜索到的設(shè)備對(duì)象,從中獲得設(shè)備的名稱和地址,。

EXTRA_CLASS中的BluetoothClass是搜索到的設(shè)備的類型,,比如搜索到的是手機(jī)還是耳機(jī)或者其他,之后我會(huì)寫(xiě)一篇關(guān)于它的介紹,。

在這個(gè)上面我現(xiàn)在在想,,是否通過(guò)判斷搜索到的設(shè)備類型來(lái)識(shí)別單片機(jī)藍(lán)牙模塊與手機(jī)藍(lán)牙的不同,采取不一樣的配對(duì)方式,,從而不自動(dòng)生成配對(duì)碼,。不知是否可行,一會(huì)嘗試,。

 

 搜索到該設(shè)備后,,我們就要對(duì)該設(shè)備進(jìn)行連接和通信。

public void connect(final String message) {        Thread thread = new Thread(new Runnable() {            public void run() {                BluetoothSocket tmp = null;                Method method;                try {                    method = device.getClass().getMethod('createRfcommSocket', new Class[]{int.class});                    tmp = (BluetoothSocket) method.invoke(device, 1);                } catch (Exception e) {                    setState(CONNECT_FAILED);                    Log.e('TAG', e.toString());                }                socket = tmp;                try {                    socket.connect();                    isConnect = true;                } catch (Exception e) {                    setState(CONNECT_FAILED);                    Log.e('TAG', e.toString());                }	       if (isConnect) {                    try {                        OutputStream outStream = socket.getOutputStream();                        outStream.write(getHexBytes(message));                    } catch (IOException e) {                        setState(WRITE_FAILED);                        Log.e('TAG', e.toString());                    }                    try {                        InputStream inputStream = socket.getInputStream();                        int data;                        while (true) {                            try {                                data = inputStream.read();                                Message msg = handler.obtainMessage();                                msg.what = DATA;                                msg.arg1 = data;                                handler.sendMessage(msg);                            } catch (IOException e) {                                setState(READ_FAILED);                                Log.e('TAG', e.toString());                                break;                            }                        }                    } catch (IOException e) {                        setState(WRITE_FAILED);                        Log.e('TAG', e.toString());                    }                }                if (socket != null) {                    try {                        socket.close();                    } catch (IOException e) {                        Log.e('TAG', e.toString());                    }               }       }}

 這里包括寫(xiě)入和讀取,,用法和基本的Socket是一樣的,,但是寫(xiě)入的時(shí)候,需要將字符串轉(zhuǎn)化為16進(jìn)制:

private byte[] getHexBytes(String message) {        int len = message.length() / 2;        char[] chars = message.toCharArray();        String[] hexStr = new String[len];        byte[] bytes = new byte[len];        for (int i = 0, j = 0; j < len; i += 2, j++) {            hexStr[j] = '' + chars[i] + chars[i + 1];            bytes[j] = (byte) Integer.parseInt(hexStr[j], 16);        }        return bytes;    }


 

連接設(shè)備之前需要UUID,,所謂的UUID,,就是用來(lái)進(jìn)行配對(duì)的,全稱是Universally Unique Identifier,,是一個(gè)128位的字符串ID,,用于進(jìn)行唯一標(biāo)識(shí)。網(wǎng)上的例子,,包括谷歌的例子提供的uuid,,通用的'00001101-0000-1000-8000-00805F9B34FB'也試過(guò)了,在配對(duì)的時(shí)候都是自動(dòng)生成了配對(duì)碼,,也無(wú)法正常與單片機(jī)的藍(lán)牙模塊連接,,所以,,我就利用反射的原理,讓設(shè)備自己提供UUID嘗試,。到這里其實(shí)我有點(diǎn)懷疑自己對(duì)于UUID的理解是否正確了,。

            在谷歌提供的例子中,我們可以看到谷歌的程序員的程序水平很高,,一些好的編碼習(xí)慣我們可以學(xué)習(xí)一下,,像是在try..catch中才定義的變量,我們應(yīng)該在try...catch之前聲明一個(gè)臨時(shí)變量,,然后再在try...catch后賦值給我們真正要使用的變量,。這種做法的好處就是:如果我們直接就是使用真正的變量,,當(dāng)出現(xiàn)異常的時(shí)候,,該變量的使用就會(huì)出現(xiàn)問(wèn)題,而且很難進(jìn)行排查,,如果是臨時(shí)變量,,我么可以通過(guò)檢查變量的值來(lái)確定是否是賦值時(shí)出錯(cuò)。

   

作者:jason0539

微博:http://weibo.com/2553717707

博客:http://blog.csdn.net/jason0539(轉(zhuǎn)載請(qǐng)說(shuō)明出處)

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多