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));

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

Android中通过拨号调起应用的实现方式及特殊情况处理的更多相关文章

  1. Android中H5和Native交互的两种方式

    Android中H5和Native交互的两种方式:http://www.jianshu.com/p/bcb5d8582d92 注意事项: 1.android给h5页面注入一个对象(WZApp),这个对 ...

  2. Android中多线程编程(三)Handler更新UI的方式

    Handler更新UI的方式和原因以及遇到的问题 1.方式: 仅仅能通过Handler来更新UI. 代码例如以下: package com.chengdong.su.handlerdemo; impo ...

  3. android中实现拨号功能

    1.要实现拨号功能,首先需要开启拨号权限 修改AndroidManifest.xml文件,添加如下内容: <uses-permission android:name="android. ...

  4. Android中设置控件的背景颜色的方式整理

    版权声明:本文为博主原创文章,未经博主允许不得转载. 前言 在Android开发中,经常需要设置控件的背景颜色或者图片的src颜色. 效果图 代码分析 根据使用的方法不同,划分为 setBackgro ...

  5. Android中Button四种点击事件实现方式

    1.Xml添加监听属性,这里添加的doClick. <Button android:id="@+id/bt1" android:layout_width="wrap ...

  6. Android中对应用程序的行为拦截实现方式概要

    这次是真的好长时间都没有写博客了,主要不是因为工作上的事,主要还是这个问题真的有点复杂,实现起来有点麻烦,所以研究了很长时间(大约有一个月的时间).但是幸好最后问题搞定了~~ 一.问题场景 想实现36 ...

  7. Android中实现短信发送的一种方式

    SendSmsActivity.java: package com.test.smsmangerdemo.sendsmsactivity; import android.support.v7.app. ...

  8. Android中服务的生命周期与两种方式的区别

    服务的生命周期跟Activity的生命周期类似.但是生命周期甚至比你关注服务如何创建和销毁更重要,因为服务能够在用户不知情的情况下在后台运行. 服务的生命周期---从创建到销毁---可以被分为以下两个 ...

  9. 在web项目中获取ApplicationContext上下文的3种主要方式及适用情况

    最近在做web项目,需要写一些工具方法,涉及到通过Java代码来获取spring中配置的bean,并对该bean进行操作的情形.而最关键的一步就是获取ApplicationContext,过程中纠结和 ...

随机推荐

  1. RabbitMQ .NET Client 实战实验

    由于公司业务需求,最近想上RabbitMQ,之前我研究了一段时间微软的MSMQ.开源队列有很多,各有优劣.就先拿RabbitMQ练练手吧.本篇着重代码部分,至于怎么安装,怎么配置不在赘述.而且代码是在 ...

  2. C# String与StringBuilder (转载)

    1.什么时候用String?什么时候用StringBuilder? 字符串一旦创建就不可修改大小,所以对字符串添加或删除操作比较频繁的话.那就不要用String而用StringBuilder. 例如: ...

  3. 在cengos中安装zabbix server/agent, 并创建一个简单demo

    添加zabbix更新源 rpm -ivh http://repo.zabbix.com/zabbix/2.4/rhel/6/x86_64/zabbix-release-2.4-1.el6.noarch ...

  4. Python学习之路——基础2(含深浅拷贝)

    逻辑运算符:not  and  or 等同于c/c++中的 !.&&.||,除了写法上的不同,实际原理是一样的. 运算也遵循短路原则.由于Python本身不支持++/--操作符,所以避 ...

  5. Vue nodejs商城项目- 前后端数据传递

    .利用Mongoose查询MongoDB 通过mongoose插件可以简捷地从mondodb中获取数据,首先安装mongoose: cnpm install mongoose --save   使用m ...

  6. Question20171231 聊聊为什么32bit只能支持4GB内存

    1. 32位系统最大只能支持4GB内存之由来 也许大家对这个问题都不陌生,实际装过系统用过电脑的朋友可能都有这样的经历:自己电脑配的是4G的内存条,可是装完系统之后发现电脑上显示的只有3.2G左右可用 ...

  7. 为什么需要Vlan ? Vlan实现原理 ? 不同Vlan的通信 ?

    好文章!!良心推荐!!! 原文链接 https://blog.csdn.net/cwm_meng_home/article/details/49762807

  8. leetcode笔记(六)740. Delete and Earn

    题目描述 Given an array nums of integers, you can perform operations on the array. In each operation, yo ...

  9. canvas 制作表情包

    canvas 制作表情包 代码如下. <!DOCTYPE html> <html> <head> <title>表情制作</title> & ...

  10. Asp.NET Core 在IIS部署 An assembly specified in the application dependencies manifest was not found

    今天在发布应用的时候,出来了一个报错:An assembly specified in the application dependencies manifest was not found 情况如下 ...