Android中通过拨号调起应用的实现方式及特殊情况处理

Android中有时我们会有这样的需求:通过拨号调起我们的程序。这个需求如何实现呢?

思路当然是在我们的应用中实现一个广播接收器(BroadcastReceiver),对打电话时系统发出的广播进行拦截。

实现步骤:

1、在AndroidMainfest.xml中添加权限:

<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />

 

2、实现拨号广播接收器:

public class LaunchAppViaDialReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(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中注册广播接收器

<receiver
    android:name=".LaunchAppViaDialReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter android:priority="1000">
        <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
    </intent-filter>
</receiver>

 

本以为大功告成,但在测试过程中发现不同手机出现了不同效果: 
小米4拨号后可以正常调起应用(电话没有拨打出去) 
华为荣耀6、htc one拨号后会开始打电话(当然是空号),电话挂断后应用正常调起 
魅族mx3拨号后开始打电话(是空号),电话挂断后应用不会调起(收不到打电话的广播)

显然这个方式不完美,那么还有没有其他办法呢?

经过一番摸索,最终实现了手头有的机型都可以正常调起应用(有的在挂掉电话后才能调起)。

实现方案就是读取用户最后一条通话记录,对号码进行判断,如果是我们期望的号码就调起我们的应用。

这种方式依然不够完美(需要增加读取通话记录权限),但功能基本达到可用状态。

实现方案:

1、在AndroidMainfest.xml中添加权限:

<uses-permission android:name="android.permission.READ_CALL_LOG" />

 

2、实现通话观察服务类:

public class CallAppService extends Service {

    private static final String TAG = "CallAppService";

    private final Handler mHandler = new MyHandler(this);

    static class MyHandler extends Handler {

        private final WeakReference<CallAppService> mService;

        public MyHandler(CallAppService service) {
            mService = new WeakReference<>(service);
        }

        @Override
        public void handleMessage(Message msg) {
            CallAppService service = mService.get();
            if (service != null) {
                service.handleMessage(msg);
            }
        }
    }

    @SuppressWarnings("UnusedParameters")
    private void handleMessage(Message msg) {
        Intent appIntent = new Intent(this, MainActivity.class);
        appIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(appIntent);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand");
        getAllCallLogs();
        return START_STICKY;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void getAllCallLogs() {
        Uri mediaUri = android.provider.CallLog.Calls.CONTENT_URI;
        getContentResolver().registerContentObserver(mediaUri, false, new CustomContentObserver(mHandler));
    }

    class CustomContentObserver extends ContentObserver {

        private final Handler handler;

        public CustomContentObserver(Handler handler) {
            super(handler);
            this.handler = handler;
        }

        @Override
        public boolean deliverSelfNotifications() {
            return false;
        }

        public void logCallLog() {
            String columns[] = new String[]{
                    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();
            }
        }

        @Override
        public void onChange(boolean selfChange){
            super.onChange(selfChange);
            logCallLog();
        }
    }
}

 

3、在AndroidManifest.xml中注册服务:

<service android:name=".service.CallAppService" />

 

4、在应用启动后启动服务:

startService(new Intent(MainActivity.this, CallAppService.class));

 

以上就是目前的方案,如果大家有更好的方案,欢迎交流。

posted @ 2016-01-18 15:03  观海云不远  阅读(786)  评论(0编辑  收藏  举报