監聽手機來電與手機短信往藍牙發送協議實現通訊

因爲公司主要做藍牙手環這塊。這陣子負責來電提醒和短信提醒。其實原理比較簡單。就是開啓一個Service監聽手機的來電和短信。然後判斷手機跟藍牙的連接服務是是否連接,已連接的話則根據協議完手環發送來電、短信所需要的協議。不多說了。上代碼。首先是Service類中的onCreate方法中註冊手機來電和短信監聽。監聽我是用了TelephonyManager。短信我是用了SmsObserver。
tm  = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
        //創建一個監聽器,監聽電話呼叫狀態的變化。
        myPhoneListener = new MyPhoneListener();
        //開始監聽用戶的通話狀態
        tm.listen(myPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
        smsObserver = new SmsObserver(this, smsHandler);
        //註冊一個內容觀察者監聽短信的變化
       getContentResolver().registerContentObserver(SMS_INBOX, true,
                smsObserver);

然後短信監聽的話需要系統的一個Uri

 private Uri SMS_INBOX = Uri.parse("content://sms");

下面是一個電話監聽類
private class MyPhoneListener extends PhoneStateListener{

        //當手機呼叫狀態變化的時候 執行下面代碼。
        //state 電話的狀態
        //incomingnumber 來電號碼
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            try {
                //判斷我們當前手機的通話狀態
                switch (state) {
                    //手機處於空閒狀態,沒有人打電話 沒有零響
                    case TelephonyManager.CALL_STATE_IDLE:

                        if (!"".equals(incomingNumber)) {
                           
                            if (BLEServiceHelper.getInstance().getService() == null) {

                                BLEServiceHelper.getInstance().getService().connect(EBLEService.BLEType.CLOSE_PHONE_NOTIFT, BaseApplication.getInstance().getUserInfo().getMacAddress());

                                new Handler().postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        BLEServiceHelper.getInstance().getService().writeData(true, GattAttributes.TO_GET_PHONE_NOTIFT, EBLEService.BLEType.CLOSE_PHONE_NOTIFT, BlueToothInstruction.setNotifyData(false, null));
                                    }
                                },2000);
                            } else {

                                if (BLEServiceHelper.getInstance().getService() != null) {

                                    BLEServiceHelper.getInstance().getService().disconnectAndClose();
                                    BLEServiceHelper.getInstance().getService().connect(EBLEService.BLEType.CLOSE_PHONE_NOTIFT, BaseApplication.getInstance().getUserInfo().getMacAddress());

                                    new Handler().postDelayed(new Runnable() {
                                        @Override
                                        public void run() {
                                            BLEServiceHelper.getInstance().getService().writeData(true, GattAttributes.TO_GET_PHONE_NOTIFT, EBLEService.BLEType.CLOSE_PHONE_NOTIFT, BlueToothInstruction.setNotifyData(false, null));
                                        }
                                    }, 2000);

                                    // BLEServiceHelper.getInstance().getService().writeData(true, GattAttributes.TO_GET_PHONE_NOTIFT, EBLEService.BLEType.PHONE_NOTIFT, BlueToothInstruction.setNotifyData(false, null));
                                }else{
                                    Log.e(TAG,"2222");
                                }
                            }

                        }


                        break;
                    //手機零響狀態
                    case TelephonyManager.CALL_STATE_RINGING:
                        Log.e(TAG,"服務服務監聽到響鈴。。。");
                        BoundDeviceActivity.phoneNumber = incomingNumber;
                        //獲得來電號碼的名字

                        BoundDeviceActivity.contactName = getName(incomingNumber);
                        //判斷改號碼有沒有保存到手機聯繫人
                        parseContactName(BoundDeviceActivity.contactName);
                        if(BLEServiceHelper.getInstance().getService()!=null) {
                            BLEServiceHelper.getInstance().getService().disconnectAndClose();
                            String macAddress = BaseApplication.getInstance().getUserInfo().getMacAddress();
                        
                            if (macAddress == null || "".equals(macAddress)) {

                            } else {

                                BLEServiceHelper.getInstance().getService().connect(EBLEService.BLEType.PHONE_NOTIFT, macAddress);

                                new Handler().postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        // BLEServiceHelper.getInstance().getService().writeData(true, GattAttributes.TO_GET_PHONE_NOTIFT, EBLEService.BLEType.PHONE_NOTIFT, BlueToothInstruction.setNotifyData(true, null));
                                    }
                                }, 3000);

                                BLEServiceHelper.getInstance().getService().writeData(true, GattAttributes.TO_GET_PHONE_NOTIFT, EBLEService.BLEType.PHONE_NOTIFT, BlueToothInstruction.setNotifyData(true, null));

                            }


                        }else{
                            Log.e(TAG,"藍牙服務爲空時");
                            String macAddress = BaseApplication.getInstance().getUserInfo().getMacAddress();
                            if (macAddress == null || "".equals(macAddress)) {

                            } else {
                                BLEServiceHelper.getInstance().getService().connect(EBLEService.BLEType.PHONE_NOTIFT, macAddress);

                                new Handler().postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                         BLEServiceHelper.getInstance().getService().writeData(true, GattAttributes.TO_GET_PHONE_NOTIFT,
                                                                         EBLEService.BLEType.PHONE_NOTIFT, BlueToothInstruction.setNotifyData(true, null));
                                    }
                                }, 3000);
                                
                            }

                        }
                        break;
                    //電話接通狀態,用戶正在打電話
                    case TelephonyManager.CALL_STATE_OFFHOOK:

                        if(BLEServiceHelper.getInstance().getService()==null){

                            BLEServiceHelper.getInstance().getService().connect(EBLEService.BLEType.CLOSE_PHONE_NOTIFT, BaseApplication.getInstance().getUserInfo().getMacAddress());
                        }else{
                            if (BLEServiceHelper.getInstance().getService() != null) {

                                BLEServiceHelper.getInstance().getService().writeData(true, GattAttributes.TO_GET_PHONE_NOTIFT, EBLEService.BLEType.PHONE_NOTIFT, BlueToothInstruction.setNotifyData(false,null));
                            }
                        }

                        break;
                }
                super.onCallStateChanged(state, incomingNumber);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
其實我這邊是項目中的需求。大家需用的話只要在case中根據需求自己改即可。下面是上面getName(String address)的方法。也就是根據電話號碼得到存在手機聯繫人中的名字。覺得有些人應該會用到
<pre name="code" class="java">public String getName(String number){
        String phonename = null;
        Cursor c = getApplicationContext().getContentResolver().query(Uri.withAppendedPath(
                ContactsContract.PhoneLookup.CONTENT_FILTER_URI, number), new String[]{
                ContactsContract.PhoneLookup._ID,
                ContactsContract.PhoneLookup.NUMBER,
                ContactsContract.PhoneLookup.DISPLAY_NAME,
                ContactsContract.PhoneLookup.TYPE, ContactsContract.PhoneLookup.LABEL}, null, null,   null );

        if(c.getCount() == 0)
        {
            //沒找到電話號碼
            return null;
        } else if (c.getCount() > 0) {

            c.moveToFirst();
            phonename = c.getString(2); //獲取姓名
            return phonename;
        }
        return null;
    }


好了。電話監聽Service就到這裏。下面是短信的
public static boolean flag = true;
    class SmsObserver extends ContentObserver {
        private Context mContext;
        String[] projection = new String[] { "address", "body", "date", "type", "read" };
        public SmsObserver(Context context, Handler handler) {
            super(handler);
            mContext = context;

        }


        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            //每當有新短信到來時,使用我們獲取短消息的方法



           if (flag){
                Uri uri = Uri.parse("content://sms/inbox");
                Cursor c = mContext.getContentResolver().query(uri, projection, null, null, "date desc");//"date desc"



                if (c != null) {

                    if (c.moveToNext()) {
						//得到接收到短信的電話號碼
                        String address = c.getString(c.getColumnIndex("address"));
						//得到接收到短信的內容
                        String body = c.getString(c.getColumnIndex("body"));
						
                        

                    }
                    c.close();
                    flag = false;
 }


            }


        }

    }
需用注意的是。不知道是爲什麼。每收到一條短信時,onChange()方法會調用兩次。而我項目中是需要監聽到短信變化後往手環發數據。這樣的話他就會發兩次,這樣是不符合需求的,所以我是用了flag判斷。在藍牙發送數據之後回調改變了這個標記。

好了。就這些 了。第一次發博客。代碼沒整理有點亂。請見諒。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章