因为公司主要做蓝牙手环这块。这阵子负责来电提醒和短信提醒。其实原理比较简单。就是开启一个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判断。在蓝牙发送数据之后回调改变了这个标记。
好了。就这些 了。第一次发博客。代码没整理有点乱。请见谅。