Android中有时我们会有这样的需求:通过拨号调起我们的程序。这个需求如何实现呢?
思路当然是在我们的应用中实现一个广播接收器(BroadcastReceiver),对打电话时系统发出的广播进行拦截。
实现步骤:
1、在AndroidMainfest.xml中添加权限:
2、实现拨号广播接收器:
public class LaunchAppViaDialReceiver extendsBroadcastReceiver {
@Overridepublic voidonReceive(Context context, Intent intent) {if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
Bundle bundle=intent.getExtras();if (null ==bundle)return;
String phoneNumber=intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);if (phoneNumber.equals("1234")) {
setResultData(null);
abortBroadcast();
Intent appIntent= new Intent(context, MainActivity.class);
appIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(appIntent);
}
}
}
}
3、在AndroidMainfest.xml中注册广播接收器
本以为大功告成,但在测试过程中发现不同手机出现了不同效果:
小米4拨号后可以正常调起应用(电话没有拨打出去)
华为荣耀6、htc one拨号后会开始打电话(当然是空号),电话挂断后应用正常调起
魅族mx3拨号后开始打电话(是空号),电话挂断后应用不会调起(收不到打电话的广播)
显然这个方式不完美,那么还有没有其他办法呢?
经过一番摸索,最终实现了手头有的机型都可以正常调起应用(有的在挂掉电话后才能调起)。
实现方案就是读取用户最后一条通话记录,对号码进行判断,如果是我们期望的号码就调起我们的应用。
这种方式依然不够完美(需要增加读取通话记录权限),但功能基本达到可用状态。
实现方案:
1、在AndroidMainfest.xml中添加权限:
2、实现通话观察服务类:
public class CallAppService extendsService {private static final String TAG = "CallAppService";private final Handler mHandler = new MyHandler(this);static class MyHandler extendsHandler {private final WeakReferencemService;publicMyHandler(CallAppService service) {
mService= new WeakReference<>(service);
}
@Overridepublic voidhandleMessage(Message msg) {
CallAppService service=mService.get();if (service != null) {
service.handleMessage(msg);
}
}
}
@SuppressWarnings("UnusedParameters")private voidhandleMessage(Message msg) {
Intent appIntent= new Intent(this, MainActivity.class);
appIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(appIntent);
}
@Overridepublic int onStartCommand(Intent intent, int flags, intstartId) {
Log.i(TAG,"onStartCommand");
getAllCallLogs();returnSTART_STICKY;
}
@Nullable
@OverridepublicIBinder onBind(Intent intent) {return null;
}private voidgetAllCallLogs() {
Uri mediaUri=android.provider.CallLog.Calls.CONTENT_URI;
getContentResolver().registerContentObserver(mediaUri,false, newCustomContentObserver(mHandler));
}class CustomContentObserver extendsContentObserver {private finalHandler handler;publicCustomContentObserver(Handler handler) {super(handler);this.handler =handler;
}
@Overridepublic booleandeliverSelfNotifications() {return false;
}public voidlogCallLog() {
String columns[]= newString[]{
CallLog.Calls._ID,
CallLog.Calls.NUMBER,
CallLog.Calls.DATE,
CallLog.Calls.DURATION,
CallLog.Calls.TYPE};
Cursor c;
c= getContentResolver().query(Uri.parse("content://call_log/calls"),
columns,null, null, "Calls._ID DESC"); //last record first
while (c != null &&c.moveToNext()) {
String number=c.getString(c.getColumnIndex(CallLog.Calls.NUMBER));if (number.equals("1234")) {this.handler.obtainMessage().sendToTarget();
}else{return;
}
}if (c != null) {
c.close();
}
}
@Overridepublic void onChange(booleanselfChange){super.onChange(selfChange);
logCallLog();
}
}
}
3、在AndroidManifest.xml中注册服务:
4、在应用启动后启动服务:
startService(new Intent(MainActivity.this, CallAppService.class));
以上就是目前的方案,如果大家有更好的方案,欢迎交流。