标签:
需要用Aidl,来与系统进程进行交互
(关于aidl的介绍:
http://chenfeng0104.iteye.com/blog/1255302
http://www.cnblogs.com/mydomainlistentome/p/4687173.html)
首先在src下建立这样的包:
com.android.internal.telephony
然后在这个包下建立这样的aidl文件:
ITelephony.aidl
package com.android.internal.telephony ;
interface ITelephony {
boolean endCall() ; // 挂断电话
void answerRingingCall() ; // 拨打电话
}
利用反射,在后台打印出隐藏的可以挂断电话的private类型的方法
private ITelephony getITelephony() {
ITelephony iTelephony=null;
Class<TelephonyManager> cls=TelephonyManager.class;
Method [] method= cls.getDeclaredMethods();
for(int i=0;i<method.length;i++){
System.out.println("方法:"+method[i]);
}
找到这个方法:
I/System.out(1406): 方法:private com.android.internal.telephony.ITelephony android.telephony.TelephonyManager.getITelephony()
07-31 21:59:27.522: I/System.out(1406): 方法:public static int android.telephony.TelephonyManager.getLteOnCdmaModeStatic()
07-31 21:59:27.522: I/System.out(1406): 方法:public static int android.telephony.TelephonyManager.getNetworkClass(int)
07-31 21:59:27.522: I/System.out(1406): 方法:public static java.lang.String android.telephony.TelephonyManager.getNetworkTypeName(int)
07-31 21:59:27.522: I/System.out(1406): 方法:public static int android.telephony.TelephonyManager.getPhoneType(int)
07-31 21:59:27.522: I/System.out(1406): 方法:private int android.telephony.TelephonyManager.getPhoneTypeFromNetworkType()
然后将这个方法解封,调用
private ITelephony getITelephony() {
ITelephony iTelephony = null;
Class<TelephonyManager> cls = TelephonyManager.class;
Method method = null;
// Method [] method= cls.getDeclaredMethods();
// for(int i=0;i<method.length;i++){
// System.out.println("方法:"+method[i]);
// }
try {
method = cls.getDeclaredMethod("getITelephony");
// 取消封装
method.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
// 使用invoke来执行这个私有方法
iTelephony = (ITelephony) method.invoke(telephone);
return iTelephony;
} catch (Exception e) {
e.printStackTrace();
}
return iTelephony;
}
解决以上的问题就可以实现电话拦截了,下面是全部代码:
service实现挂断:
package com.example.phonelistendemo;
import java.lang.reflect.Method;
import com.android.internal.telephony.ITelephony;
import android.app.Service;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
public class ServicePhone extends Service {
private TelephonyManager telephone = null;
private AudioManager audio = null;
private IBinder mbinder = new BinderImpl();
private String num = null;
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
mbinder = null;
num = null;
super.onDestroy();
}
public class BinderImpl extends Binder implements IService {
@Override
public String getInterfaceDescriptor() {
return "过滤电话:“" + ServicePhone.this.num + "”设置成功!";
}
}
public IBinder onBind(Intent arg0) {
audio = (AudioManager) getSystemService(AUDIO_SERVICE);
num = arg0.getStringExtra("Nums");
telephone = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
backGroundExecution();
return mbinder;
}
// 启动子线程
public void backGroundExecution() {
Thread thread = new Thread(null, backGroundProgress, "phoneListener");
thread.start();
}
// 实例化子线程
private Runnable backGroundProgress = new Runnable() {
public void run() {
telephone.listen(new PhoneStateListenerImpl(),
PhoneStateListener.LISTEN_CALL_STATE);
}
};
private class PhoneStateListenerImpl extends PhoneStateListener {
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
if (incomingNumber.equals(num)) {
ITelephony iTelephony=getITelephony();
if(iTelephony!=null){
try {
//挂断电话
iTelephony.endCall();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
break;
case TelephonyManager.CALL_STATE_IDLE:
//挂断提示音开启
//audio.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
break;
}
}
}
private ITelephony getITelephony() {
ITelephony iTelephony = null;
Class<TelephonyManager> cls = TelephonyManager.class;
Method method = null;
// Method [] method= cls.getDeclaredMethods();
// for(int i=0;i<method.length;i++){
// System.out.println("方法:"+method[i]);
// }
try {
method = cls.getDeclaredMethod("getITelephony");
// 取消封装
method.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
// 使用invoke来执行这个私有方法
iTelephony = (ITelephony) method.invoke(telephone);
return iTelephony;
} catch (Exception e) {
e.printStackTrace();
}
return iTelephony;
}
}
broadcastReceive 接收电话状态
package com.example.phonelistendemo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class ReceivePhone extends BroadcastReceiver {
public void onReceive(Context content, Intent intent) {
// 拨打电话
if (Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())) {
Intent in=new Intent(content,ServicePhone.class);
content.startService(in);
} else{
Intent in=new Intent(content, ServicePhone.class);
content.startService(in);
}
}
}
定义IService接口 标记绑定状态
package com.example.phonelistendemo;
public interface IService {
}
MainActivity
package com.example.phonelistendemo;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.phonelisten_Limite.R;
import com.example.phonelisten_Limite.R.id;
import com.example.phonelistendemo.ServicePhone.BinderImpl;
public class MainActivity extends Activity {
private Button bind, unBind;
private EditText num;
private ServiceConnection connect;
private IService service;
private String getNum;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connect=new ServiceConnection() {
public void onServiceDisconnected(ComponentName arg0) {
}
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
MainActivity.this.service=(BinderImpl)arg1;
try {
Toast.makeText(MainActivity.this, arg1.getInterfaceDescriptor(), Toast.LENGTH_LONG).show();
} catch (RemoteException e) {
e.printStackTrace();
}
}
};
init();
}
private void init() {
bind = (Button) findViewById(R.id.bind);
unBind = (Button) findViewById(id.unBind);
num = (EditText) findViewById(id.num);
bind.setOnClickListener(new BindListenImpl());
unBind.setOnClickListener(new UnBindListenImpl());
}
public class BindListenImpl implements OnClickListener {
public void onClick(View arg0) {
getNum=num.getText().toString();
Intent intent=new Intent(MainActivity.this,ServicePhone.class);
intent.putExtra("Nums", getNum);
bindService(intent, connect, BIND_AUTO_CREATE);
}
}
public class UnBindListenImpl implements OnClickListener {
public void onClick(View arg0) {
if(MainActivity.this.service != null) {
unbindService(connect) ;
stopService(new Intent(MainActivity.this,ServicePhone.class)) ;
getNum=null;
Toast.makeText(MainActivity.this, "黑名单已取消", Toast.LENGTH_LONG)
.show();
MainActivity.this.service = null ;
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
权限配置
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
广播配置:
<receiver android:name="com.example.phonelistendemo.ReceivePhone">
<intent-filter android:priority="999" >
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
布局自行解决
(ps:我是菜鸟,勿喷,谢谢)
标签:
原文地址:http://www.cnblogs.com/mydomainlistentome/p/4693850.html