android系统提供了电话相关的接口供调用,比如获取电话状态,获取手机服务等,也包括获取电话状态。因此可以根据电话状态的不同做不同操作。

本例主要分析一个来电自动接电话的代码,代码是由别人写的,拿来一起学习:

要想监听电话状态,一般的做法是写一个广播接收器监听电话状态的改变,配置文件如下:

[java] view plaincopyprint?

1. <receiver android:name=".AutoAnswerReceiver" android:enabled="true">

2.     <intent-filter>

3.         <action android:name="android.intent.action.PHONE_STATE" />

4.     </intent-filter>

5. </receiver>

<receiverandroid:name=".AutoAnswerReceiver"android:enabled="true">

<intent-filter>

<actionandroid:name="android.intent.action.PHONE_STATE" />

</intent-filter>

</receiver>

这个时候如果电话状态改变,比如来电等,就可以进入代码,代码如下:

[java] view plaincopyprint?

1. import android.content.BroadcastReceiver;

2. import android.content.Context;

3. import android.content.Intent;

4. import android.content.SharedPreferences;

5. import android.database.Cursor;

6. import android.media.AudioManager;

7. import android.net.Uri;

8. import android.preference.PreferenceManager;

9. import android.provider.ContactsContract.PhoneLookup;

10.import android.telephony.TelephonyManager;

11.

12.public class AutoAnswerReceiver extends BroadcastReceiver {

13.    @Override

14.    public void onReceive(Context context, Intent intent) {

15.

16.        // Load preferences

17.        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

18.

19.        // Check phone state

20.        String phone_state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);

21.        String number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);

22.

23.        if (phone_state.equals(TelephonyManager.EXTRA_STATE_RINGING) && prefs.getBoolean("enabled", false)) {

24.            // Check for "second call" restriction

25.            if (prefs.getBoolean("no_second_call", false)) {

26.                AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

27.                if (am.getMode() == AudioManager.MODE_IN_CALL) {

28.                    return;

29.                }

30.            }

31.

32.            // Check for contact restrictions

33.            String which_contacts = prefs.getString("which_contacts", "all");

34.            if (!which_contacts.equals("all")) {

35.                int is_starred = isStarred(context, number);

36.                if (which_contacts.equals("contacts") && is_starred < 0) {

37.                    return;

38.                }

39.                else if (which_contacts.equals("starred") && is_starred < 1) {

40.                    return;

41.                }

42.            }

43.

44.            // Call a service, since this could take a few seconds

45.            context.startService(new Intent(context, AutoAnswerIntentService.class));

46.        }

47.    }

48.

49.    // returns -1 if not in contact list, 0 if not starred, 1 if starred

50.    private int isStarred(Context context, String number) {

51.        int starred = -1;

52.        Cursor c = context.getContentResolver().query(

53.                Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, number),

54.                new String[] {PhoneLookup.STARRED},

55.                null, null, null);

56.        if (c != null) {

57.            if (c.moveToFirst()) {

58.                starred = c.getInt(0);

59.            }

60.            c.close();

61.        }

62.        return starred;

63.    }

64.}

importandroid.content.BroadcastReceiver;

importandroid.content.Context;

importandroid.content.Intent;

importandroid.content.SharedPreferences;

importandroid.database.Cursor;

importandroid.media.AudioManager;

importandroid.net.Uri;

importandroid.preference.PreferenceManager;

importandroid.provider.ContactsContract.PhoneLookup;

importandroid.telephony.TelephonyManager;

publicclass AutoAnswerReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intentintent) {

// Load preferences

SharedPreferences prefs =PreferenceManager.getDefaultSharedPreferences(context);

// Check phone state

String phone_state =intent.getStringExtra(TelephonyManager.EXTRA_STATE);

String number =intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);

if(phone_state.equals(TelephonyManager.EXTRA_STATE_RINGING) &&prefs.getBoolean("enabled", false)) {

// Check for "second call"restriction

if (prefs.getBoolean("no_second_call",false)) {

AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);

if (am.getMode() ==AudioManager.MODE_IN_CALL) {

return;

}

}

// Check for contact restrictions

String which_contacts = prefs.getString("which_contacts","all");

if(!which_contacts.equals("all")) {

int is_starred = isStarred(context,number);

if(which_contacts.equals("contacts") && is_starred < 0) {

return;

}

else if(which_contacts.equals("starred") && is_starred < 1) {

return;

}

}

// Call a service, since this could take afew seconds

context.startService(new Intent(context,AutoAnswerIntentService.class));

}

}

// returns -1 if not in contact list, 0 if notstarred, 1 if starred

private int isStarred(Context context, Stringnumber) {

int starred = -1;

Cursor c =context.getContentResolver().query(

Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,number),

new String[] {PhoneLookup.STARRED},

null, null, null);

if (c != null) {

if (c.moveToFirst()) {

starred = c.getInt(0);

}

c.close();

}

return starred;

}

}

暂且不管其他代码,因为其他的代码主要是对设置选项分别作判断,如果电话状态改变,则启动自动接听服务,即:context.startService(newIntent(context, AutoAnswerIntentService.class));

这样就启动了自动接听服务,在这个代码中,使用到了蓝牙接听电话的逻辑,也大概做一介绍:

先看代码如下:

[java] view plaincopyprint?

1. protected void onHandleIntent(Intent intent) {

2.     Context context = getBaseContext();

3.

4.     // Load preferences

5.     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

6.     BluetoothHeadset bh = null;

7.     if (prefs.getBoolean("headset_only", false)) {

8.         bh = new BluetoothHeadset(this, null);

9.     }

10.

11.    // Let the phone ring for a set delay

12.    try {

13.        Thread.sleep(Integer.parseInt(prefs.getString("delay", "2")) * 1000);

14.    } catch (InterruptedException e) {

15.        // We don't really care

16.    }

17.

18.    // Check headset status right before picking up the call

19.    if (prefs.getBoolean("headset_only", false) && bh != null) {

20.        if (bh.getState() != BluetoothHeadset.STATE_CONNECTED) {

21.            bh.close();

22.            return;

23.        }

24.        bh.close();

25.    }

26.

27.    // Make sure the phone is still ringing

28.    TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

29.    if (tm.getCallState() != TelephonyManager.CALL_STATE_RINGING) {

30.        return;

31.    }

32.

33.    // Answer the phone

34.    try {

35.        answerPhoneAidl(context);

36.    }

37.    catch (Exception e) {

38.        e.printStackTrace();

39.        Log.d("AutoAnswer","Error trying to answer using telephony service.  Falling back to headset.");

40.        answerPhoneHeadsethook(context);

41.    }

42.

43.    // Enable the speakerphone

44.    if (prefs.getBoolean("use_speakerphone", false)) {

45.        enableSpeakerPhone(context);

46.    }

47.    return;

48.}

protected void onHandleIntent(Intent intent) {

Context context = getBaseContext();

// Load preferences

SharedPreferences prefs =PreferenceManager.getDefaultSharedPreferences(context);

BluetoothHeadset bh = null;

if(prefs.getBoolean("headset_only", false)) {

bh = new BluetoothHeadset(this, null);

}

// Let the phone ring for a set delay

try {

Thread.sleep(Integer.parseInt(prefs.getString("delay","2")) * 1000);

} catch (InterruptedException e) {

// We don't really care

}

// Check headset status right before pickingup the call

if(prefs.getBoolean("headset_only", false) && bh != null) {

if (bh.getState() !=BluetoothHeadset.STATE_CONNECTED) {

bh.close();

return;

}

bh.close();

}

// Make sure the phone is still ringing

TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);

if (tm.getCallState() !=TelephonyManager.CALL_STATE_RINGING) {

return;

}

// Answer the phone

try {

answerPhoneAidl(context);

}

catch (Exception e) {

e.printStackTrace();

Log.d("AutoAnswer","Errortrying to answer using telephony service. Falling back to headset.");

answerPhoneHeadsethook(context);

}

// Enable the speakerphone

if(prefs.getBoolean("use_speakerphone", false)) {

enableSpeakerPhone(context);

}

return;

}

先判断是否设置为蓝牙耳机接电话,如果不是则使用普通方式接听,当然先确保此时电话还在响铃,因为有时候电话也可能只响一声。然后就自动接电话,见answerPhoneAidl(context); ,其中接电话的这段代码如下:

[java] view plaincopyprint?

1. // Answer the phone

2. try {

3.     answerPhoneAidl(context);

4. }

5. catch (Exception e) {

6.     e.printStackTrace();

7.     Log.d("AutoAnswer","Error trying to answer using telephony service.  Falling back to headset.");

8.     answerPhoneHeadsethook(context);

9. }

// Answer the phone

try {

answerPhoneAidl(context);

}

catch (Exception e) {

e.printStackTrace();

Log.d("AutoAnswer","Errortrying to answer using telephony service. Falling back to headset.");

answerPhoneHeadsethook(context);

}

先使用一般的aidl方式接听电话,如果出现异常,则模拟一个按键来接听电话,两段代码见下:

[java] view plaincopyprint?

1. private void answerPhoneHeadsethook(Context context) {

2.     // Simulate a press of the headset button to pick up the call

3.     Intent buttonDown = new Intent(Intent.ACTION_MEDIA_BUTTON);

4.     buttonDown.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK));

5.     context.sendOrderedBroadcast(buttonDown, "android.permission.CALL_PRIVILEGED");

6.

7.     // froyo and beyond trigger on buttonUp instead of buttonDown

8.     Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON);

9.     buttonUp.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));

10.    context.sendOrderedBroadcast(buttonUp, "android.permission.CALL_PRIVILEGED");

11.}

12.

13.@SuppressWarnings("unchecked")

14.private void answerPhoneAidl(Context context) throws Exception {

15.    // Set up communication with the telephony service (thanks to Tedd's Droid Tools!)

16.    TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);

17.    Class c = Class.forName(tm.getClass().getName());

18.    Method m = c.getDeclaredMethod("getITelephony");

19.    m.setAccessible(true);

20.    ITelephony telephonyService;

21.    telephonyService = (ITelephony)m.invoke(tm);

22.

23.    // Silence the ringer and answer the call!

24.    telephonyService.silenceRinger();

25.    telephonyService.answerRingingCall();

26.}

private void answerPhoneHeadsethook(Contextcontext) {

// Simulate a press of the headset button topick up the call

Intent buttonDown = newIntent(Intent.ACTION_MEDIA_BUTTON);

buttonDown.putExtra(Intent.EXTRA_KEY_EVENT,new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK));

context.sendOrderedBroadcast(buttonDown,"android.permission.CALL_PRIVILEGED");

// froyo and beyond trigger on buttonUpinstead of buttonDown

Intent buttonUp = newIntent(Intent.ACTION_MEDIA_BUTTON);

buttonUp.putExtra(Intent.EXTRA_KEY_EVENT,new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));

context.sendOrderedBroadcast(buttonUp,"android.permission.CALL_PRIVILEGED");

}

@SuppressWarnings("unchecked")

private void answerPhoneAidl(Context context)throws Exception {

// Set up communication with the telephonyservice (thanks to Tedd's Droid Tools!)

TelephonyManager tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);

Class c =Class.forName(tm.getClass().getName());

Method m =c.getDeclaredMethod("getITelephony");

m.setAccessible(true);

ITelephony telephonyService;

telephonyService = (ITelephony)m.invoke(tm);

// Silence the ringer and answer the call!

telephonyService.silenceRinger();

telephonyService.answerRingingCall();

}

一般由上述代码就可以接电话了,或许在某些手机上,如果本身更改了framework代码实现,可能会接不起来,需要另作修改。

本文开始提到的设置选项就是该应用启动界面,是用PreferenceActivity写的,见下:

public class AutoAnswerPreferenceActivity extendsPreferenceActivity implements OnSharedPreferenceChangeListener

然后加载xml,用户可以设置很多选项参数。

运行界面见下:

另外,本例中还有一个开机启动类,配置文件见下:

[java] view plaincopyprint?

1. <receiver android:name=".AutoAnswerBootReceiver" android:enabled="true">

2.     <intent-filter>

3.         <action android:name="android.intent.action.BOOT_COMPLETED" />

4.     </intent-filter>

5. </receiver>

<receiverandroid:name=".AutoAnswerBootReceiver"android:enabled="true">

<intent-filter>

<actionandroid:name="android.intent.action.BOOT_COMPLETED" />

</intent-filter>

</receiver>

可以设置notification提示用户

[java] view plaincopyprint?

1. public void onReceive(Context context, Intent intent) {

2.     AutoAnswerNotifier notifier = new AutoAnswerNotifier(context);

3.     notifier.updateNotification();

4. }

public void onReceive(Context context, Intentintent) {

AutoAnswerNotifier notifier = newAutoAnswerNotifier(context);

notifier.updateNotification();

}

AutoAnswerNotifier主要方法就是可以设置提示或者取消提示:

[java] view plaincopyprint?

1. private void enableNotification() {

2.     // Intent to call to turn off AutoAnswer

3.     Intent notificationIntent = new Intent(mContext, AutoAnswerPreferenceActivity.class);

4.     PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, notificationIntent, 0);

5.

6.     // Create the notification

7.     Notification n = new Notification(R.drawable.stat_sys_autoanswer, null, 0);

8.     n.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;

9.     n.setLatestEventInfo(mContext, mContext.getString(R.string.notification_title), mContext.getString(R.string.notification_text), pendingIntent);

10.    mNotificationManager.notify(NOTIFICATION_ID, n);

11.}

12.

13.private void disableNotification() {

14.    mNotificationManager.cancel(NOTIFICATION_ID);

15.}

private void enableNotification() {

// Intent to call to turn off AutoAnswer

Intent notificationIntent = newIntent(mContext, AutoAnswerPreferenceActivity.class);

PendingIntent pendingIntent =PendingIntent.getActivity(mContext, 0, notificationIntent, 0);

// Create the notification

Notification n = newNotification(R.drawable.stat_sys_autoanswer, null, 0);

n.flags |= Notification.FLAG_ONGOING_EVENT |Notification.FLAG_NO_CLEAR;

n.setLatestEventInfo(mContext,mContext.getString(R.string.notification_title),mContext.getString(R.string.notification_text), pendingIntent);

mNotificationManager.notify(NOTIFICATION_ID,n);

}

private void disableNotification() {

mNotificationManager.cancel(NOTIFICATION_ID);

}

最后,别忘记添加权限,因为操作电话等相关服务需要相关权限:

[java] view plaincopyprint?

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

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

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

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

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

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

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

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

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

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

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

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

本例代码会一并上传供下载学习,链接如下:
http://download.csdn.net/detail/bawang_cn/5031509

come from:http://blog.csdn.net/bawang_cn/article/details/8545043

android 自动接电话相关推荐

  1. android 自动拨打电话和挂断电话(反射和intent方式)

    欢迎来到博主的技术分享博客 今天分享的技术主要内容是自动拨打电话和挂断电话.自动拨打电话分为两种,一种是通过反射ITelephony这个类直接调用call方法,一种是通过intent方法.而挂断电话则 ...

  2. Android 自动接听电话和挂断

    注意:android2.3版本及以上不支持下面的自动接听方法.(会抛异常:java.lang.SecurityException: Neither user xxxxx nor current pro ...

  3. Android 自动接听电话

    1. android 2.3以下版本(不包括2.3) http://bbs.51cto.com/viewthread.php?tid=1078059&extra=&page=1 中的& ...

  4. android自动接听电话并回复,android自动接听电话各种异常处理

    public void autoAnswerPhone() { try { Log.i(TAG,"autoAnswerPhone"); ITelephony itelephony ...

  5. Android 自动、拨打电话、拨号

    个人中心 DownLoad Android 自动拨打电话功能可以通过以下步骤实现: 1. 在 AndroidManifest.xml 文件中添加拨打电话的权限: ``` <uses-permis ...

  6. Android 自动判断是电话,网址,EMAIL方法之Linkify

    ,当我们在一个EditText输入电话或者网址还是Email的时候,让Android自动判断,当我们输入的是电话,我们点击输入内容将调用打电话程序,当我们输入是网址点击将打开浏览器程序.而Linkif ...

  7. android自动接听和挂断电话

    实现android自动接听和挂断电话功能.代码如下: 添加权限 <uses-permission android:name="android.permission.CALL_PHONE ...

  8. Android入门篇(四):自动拨打电话、手动拨打电话

    Android入门篇(四):自动拨打电话.手动拨打电话 一.前言 最近在做的项目需要用到自动拨号的这一功能,17年写了一个,最近拿出来用发现不能使用了,后面查资料据说是因为Android 6(api2 ...

  9. Android手机拨打电话、手动发送短信与自动拨打电话、自动发送短信(代码很简单哦)

    Android实现手动拨打电话,即点击后跳转到手机默认电话号码输入页面,可以将相应号码传送过去: <span style="font-size:18px;"> Inte ...

最新文章

  1. ext form验证tip_FormValidator表单验证
  2. 计算机制图 教学大纲,《计算机制图》课程教学大纲.doc
  3. 利用CSS让元素垂直居中的两种实现方法
  4. Linux环境进程间通信---信号(下)
  5. 2440启动代码分析
  6. Linux编程(11)_信号
  7. 剑指offer面试题18. 删除链表的节点(双指针)(链表)
  8. BZOJ.4500.矩阵(差分约束 SPFA判负环 / 带权并查集)
  9. 变位齿轮重合度计算公式_求变位齿轮的变位系数计算公式。
  10. 二进制与十六进制的转换
  11. M1芯片安装CleanMyMac X4.7.4的方法(附下载)M1芯片安装那个CleanMyMac X版本?CleanMyMac X已完美支持M1芯片安装 支持big sur系统
  12. 微信小程序 收藏功能实现
  13. mac版源码编译安装mysql
  14. Unable to publish SessionDestroyedEvent for session (未解决)
  15. 4.17记录 LIS其二
  16. python三种注释方法
  17. python使用matplotlib绘制鼠标路径
  18. 全球及中国持续内存行业容量预测及需求规模调研报告2021年版
  19. 题-Knapsack
  20. 关闭电脑浏览器快捷键

热门文章

  1. jQuery实现品优购放大镜案例
  2. 单片机控制电机正反转
  3. 2019年第九届中国教育机器人大赛回顾与总结
  4. 算法设计--众数和重数问题(分治法)
  5. Tekla钢结构二次开发课程
  6. 有关有符号(signed)和无符号(unsigned)的典型例题
  7. 何为非侵入式负荷识别-负荷辨识(传统机器学习)
  8. 如何ping通带端口的网址
  9. SEH X64(1)
  10. jQuery实现模拟淘宝精品