挂断电话——黑名单拦截
需要用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:我是菜鳥,勿噴,謝謝)
總結
以上是生活随笔為你收集整理的挂断电话——黑名单拦截的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 永远的流水灯(Verilog)
- 下一篇: linux添加静态路由表,重启继续生效(