注意:2.3上实现方式接听使用answerRingingCallWithBroadcast方法

注意:android2.3版本及以上不支持下面的自动接听方法。
(会抛异常:java.lang.SecurityException: Neither user xxxxx nor current process has android.permission.MODIFY_PHONE_STATE.)
原因:android2.3版本及以上android.permission.MODIFY_PHONE_STATE权限限制已经改为系统权限。

普通应用程序已经无法调用,所以网上找到的那些如何使用android.permission.MODIFY_PHONE_STATE的文章均已失效,但仍有引用的办法就是让你的程序程序系统程序。一种就是预制到ROM中,另一种就是使用系统签名。第一种我已经试验通过,第二种还有待验证。


言归正传,先说下如何使用映射机制实现自动接听和挂断。 

第一步:准备应用环境需要的系统包和aidl文件。 




(1)在应用中创建包:android.telephony 


将android系统框架下的\framework\telephony\java\android\telephony目录中的NeighboringCellInfo.aidl文件复制到上面创建的包(android.telephony )中; 


(2)在应用中创建包:com.android.internal.telephony 


将android系统框架下的\framework\telephony\java\com\android\internal\telephony目录中的ITelephony.aidl文件复制到上面创建的包(com.android.internal.telephony )中; 






第二步:创建一个获取ITelephony的方法 


PhoneUtils.java 

Java代码 

package com.zhouzijing.android.demo; 


import java.lang.reflect.Method; 

import com.android.internal.telephony.ITelephony; 

import android.telephony.TelephonyManager; 


public class PhoneUtils { 


public static ITelephony getITelephony(TelephonyManager telephony) throws Exception { 

Method getITelephonyMethod = telephony.getClass().getDeclaredMethod("getITelephony"); 

getITelephonyMethod.setAccessible(true);//私有化函数也能使用 

return (ITelephony)getITelephonyMethod.invoke(telephony); 

} 

} 



第三步:创建电话广播拦截器 


MyPhoneBroadcastReceiver.java 

Java代码 

package com.zhouzijing.android.demo; 


import com.android.internal.telephony.ITelephony; 

import android.content.BroadcastReceiver; 

import android.content.Context; 

import android.content.Intent; 

import android.telephony.TelephonyManager; 

import android.util.Log; 


public class MyPhoneBroadcastReceiver extends BroadcastReceiver { 


private final static String TAG = MyPhone.TAG; 


@Override 

public void onReceive(Context context, Intent intent) { 

String action = intent.getAction(); 

Log.i(TAG, "[Broadcast]"+action); 


//呼入电话 

if(action.equals(MyPhone.B_PHONE_STATE)){ 

Log.i(TAG, "[Broadcast]PHONE_STATE"); 

doReceivePhone(context,intent); 

} 

} 



public void doReceivePhone(Context context, Intent intent) { 

String phoneNumber = intent.getStringExtra( 

TelephonyManager.EXTRA_INCOMING_NUMBER); 

TelephonyManager telephony = (TelephonyManager)context.getSystemService( 

Context.TELEPHONY_SERVICE); 

int state = telephony.getCallState(); 


switch(state){ 

case TelephonyManager.CALL_STATE_RINGING: 

Log.i(TAG, "[Broadcast]等待接电话="+phoneNumber); 

try { 

ITelephony iTelephony = PhoneUtils.getITelephony(telephony); 

iTelephony.answerRingingCall();//自动接通电话 

//iTelephony.endCall();//自动挂断电话 

} catch (Exception e) { 

Log.e(TAG, "[Broadcast]Exception="+e.getMessage(), e); 

} 

break; 

case TelephonyManager.CALL_STATE_IDLE: 

Log.i(TAG, "[Broadcast]电话挂断="+phoneNumber); 

break; 

case TelephonyManager.CALL_STATE_OFFHOOK: 

Log.i(TAG, "[Broadcast]通话中="+phoneNumber); 

break; 

} 

} 


} 





第四部:注册电话广播拦截器 


MyPhone.java 

Java代码 

package com.zhouzijing.android.demo; 


import android.app.Activity; 

import android.content.IntentFilter; 

import android.os.Bundle; 

import android.telephony.TelephonyManager; 

import android.util.Log; 

import android.view.View; 


public class MyPhone extends Activity { 

public final static String TAG = "MyPhone"; 


public final static String B_PHONE_STATE = TelephonyManager.ACTION_PHONE_STATE_CHANGED; 


private MyPhoneBroadcastReceiver mBroadcastReceiver; 


@Override 

public void onCreate(Bundle savedInstanceState) { 

super.onCreate(savedInstanceState); 

setContentView(R.layout.my_phone); 

} 


//按钮1-注册广播 

public void registerThis(View v) { 

Log.i(TAG, "registerThis"); 

mBroadcastReceiver = new MyPhoneBroadcastReceiver(); 

IntentFilter intentFilter = new IntentFilter(); 

intentFilter.addAction(B_PHONE_STATE); 

intentFilter.setPriority(Integer.MAX_VALUE); 

registerReceiver(mBroadcastReceiver, intentFilter); 

} 


//按钮2-撤销广播 

public void unregisterThis(View v) { 

Log.i(TAG, "unregisterThis"); 

unregisterReceiver(mBroadcastReceiver); 

} 

} 


第5步:在AndroidManifest.xml配置权限 

Xml代码 

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

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

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

其中: 

Java代码 

iTelephony.answerRingingCall();//自动接通电话




必须有权限 android.permission.MODIFY_PHONE_STATE




Java代码


iTelephony.endCall();//自动挂断电话


必须有权限 android.permission.CALL_PHONE



因为Android2.3以上增加了对permission android.permission.MODIFY_PHONE_STATE 的限制,2.3之前的通过反射机制调用ITelephone的能力的做法已经不适用。


2.3上实现方式:

public synchronized void answerRingingCall() {


查询系统PhoneAPP应用(PhoneGlobals.java)实现了对耳机插入、多媒体按键等通知的接受和处理。其中未发现有特殊的地方,个人认为,如果系统接收到此广播应该可以进行接听或挂断操作。

private void answerRingingCallWithBroadcast(Context context,TelephonyManager telmanager){   

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

        //判断是否插上了耳机   

        if (! audioManager.isWiredHeadsetOn()) {  

       //4.1以上系统限制了部分权限, 使用三星4.1版本测试提示警告:Permission Denial: not allowed to send broadcast android.intent.action.HEADSET_PLUG from pid=1324, uid=10017 

//这里需要注意一点,发送广播时加了权限“android.permission.CALL_PRIVLEGED”,则接受该广播时也需要增加该权限。但是4.1以上版本貌似这个权限只能系统应用才可以得到。测试的时候,自定义的接收器无法接受到此广播,后来去掉了这个权限,设为NULL便可以监听到了。 


        if(android.os.Build.VERSION.SDK_INT >=15 ){ 

                Intent meidaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);   

                KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK);   

                meidaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT,keyEvent);   

                context.sendOrderedBroadcast(meidaButtonIntent, null);   

        }else{ 

// 以下适用于Android2.3及2.3以上的版本上 ,但测试发现4.1系统上不管用。 

        Intent localIntent1 = new Intent(Intent.ACTION_HEADSET_PLUG);   

                localIntent1.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);   

                localIntent1.putExtra("state", 1);   

                localIntent1.putExtra("microphone", 1);   

                localIntent1.putExtra("name", "Headset");   

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

                 

                Intent localIntent2 = new Intent(Intent.ACTION_MEDIA_BUTTON);   

                KeyEvent localKeyEvent1 = new KeyEvent(KeyEvent.ACTION_DOWN,   KeyEvent.KEYCODE_HEADSETHOOK);   

                localIntent2.putExtra(Intent.EXTRA_KEY_EVENT,   localKeyEvent1);   

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

                 

                Intent localIntent3 = new Intent(Intent.ACTION_MEDIA_BUTTON);   

                KeyEvent localKeyEvent2 = new KeyEvent(KeyEvent.ACTION_UP,  KeyEvent.KEYCODE_HEADSETHOOK);   

                localIntent3.putExtra(Intent.EXTRA_KEY_EVENT,  localKeyEvent2);   

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

                 

                Intent localIntent4 = new Intent(Intent.ACTION_HEADSET_PLUG);   

                localIntent4.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);   

                localIntent4.putExtra("state", 0);   

                localIntent4.putExtra("microphone", 1);   

                localIntent4.putExtra("name", "Headset");   

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

        } 

               

        } else {   

            Intent meidaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);   

            KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK);   

            meidaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT,keyEvent);   

            context.sendOrderedBroadcast(meidaButtonIntent, null);   

        }   

    }



效果图:


Android 自动接听电话并回复 安卓自动接听电话app_Android 自动接听电话并回复

Android 自动接听电话并回复 安卓自动接听电话app_Android 自动接听电话并回复_02