一个很简陋的小例子
参考自:通过AIDL及反射机制,使用隐藏API挂断电话
个人理解上其实是同名类跨进程欺骗Dalvik VM,大伙儿可进一步联想扩展下功能,定会有惊喜!!!
以下为源码,仅做个人备份及参考。
package lab.sodino.phonecall; import android.app.Activity; import android.os.Bundle; public class PhoneCall extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
package lab.sodino.phonecall; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.telephony.TelephonyManager; import android.widget.Toast; /** *@author Sodino Email:sodinoopen@hotmail<br/> *@version 2011-2-6 下午10:38:55 */ public class PhoneListener extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); LogOut.out(this, "ord:" + isOrderedBroadcast() + " act:" + action); Toast toast = Toast.makeText(context, "", Toast.LENGTH_SHORT); if (action.equals("android.intent.action.NEW_OUTGOING_CALL")) { toast.setText("Outgoing"); } else { toast.setText("InComing"); TelephonyManager tm = (TelephonyManager) context .getSystemService(Service.TELEPHONY_SERVICE); boolean incomingFlag = false; String incoming_number = ""; switch (tm.getCallState()) { case TelephonyManager.CALL_STATE_RINGING: incomingFlag = true;// 标识当前是来电 incoming_number = intent.getStringExtra("incoming_number"); LogOut.out(this, "RINGING :" + incoming_number); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } Intent tmpI = new Intent(context, ShowAct.class); tmpI.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(tmpI); break; case TelephonyManager.CALL_STATE_OFFHOOK: if (incomingFlag) { LogOut.out(this, "incoming ACCEPT :" + incoming_number); } break; case TelephonyManager.CALL_STATE_IDLE: if (incomingFlag) { LogOut.out(this, "incoming IDLE"); } break; } } toast.show(); } }
package lab.sodino.phonecall; import java.lang.reflect.Method; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.telephony.TelephonyManager; import android.view.View; import android.widget.Button; import com.android.internal.telephony.ITelephony; /** *@author Sodino Email:sodinoopen@hotmail<br/> *@version 2011-2-6 下午08:33:25 */ public class ShowAct extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setWindowAnimations(0); setContentView(R.layout.show); Button btnRefuse = (Button) findViewById(R.id.btnRefuse); btnRefuse.setOnClickListener(new Button.OnClickListener() { public void onClick(View view) { endCall(); } }); Button btnReceiver = (Button) findViewById(R.id.btnRefuse); btnReceiver.setOnClickListener(new Button.OnClickListener() { public void onClick(View view) { answerCall(); } }); } private void answerCall() { TelephonyManager telMag = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); Class<TelephonyManager> c = TelephonyManager.class; Method mthEndCall = null; try { mthEndCall = c.getDeclaredMethod("getITelephony", (Class[]) null); mthEndCall.setAccessible(true); ITelephony iTel = (ITelephony) mthEndCall.invoke(telMag, (Object[]) null); iTel.answerRingingCall(); LogOut.out(this, iTel.toString()); } catch (Exception e) { e.printStackTrace(); } LogOut.out(this, "answer call"); } private void endCall() { TelephonyManager telMag = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); Class<TelephonyManager> c = TelephonyManager.class; Method mthEndCall = null; try { mthEndCall = c.getDeclaredMethod("getITelephony", (Class[]) null); mthEndCall.setAccessible(true); ITelephony iTel = (ITelephony) mthEndCall.invoke(telMag, (Object[]) null); iTel.endCall(); LogOut.out(this, iTel.toString()); } catch (Exception e) { e.printStackTrace(); } LogOut.out(this, "endCall test"); } public void onStart() { super.onStart(); // 1.经测试,貌似无法杀掉phone程序 // ActivityManager actMag = (ActivityManager) // getSystemService(Context.ACTIVITY_SERVICE); // actMag.killBackgroundProcesses("com.android.phone"); // 2.来个恶搞:直接回桌面去,heihei... // Intent tmpI = new Intent(Intent.ACTION_MAIN); // tmpI.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // tmpI.addCategory(Intent.CATEGORY_HOME); // startActivity(tmpI); // LogOut.out(this, "killBgPro&&startHome"); } public void onPause() { super.onPause(); finish(); } }
关键文件:ITelephony.aidl
package com.android.internal.telephony; interface ITelephony{ boolean endCall(); void answerRingingCall(); }
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="lab.sodino.phonecall" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".PhoneCall" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".ShowAct" android:launchMode="singleInstance"> </activity> <receiver android:name=".PhoneListener"> <intent-filter android:priority="-1000"> <action android:name="android.intent.action.PHONE_STATE"></action> <category android:name="android.intent.category.DEFAULT"></category> </intent-filter> <intent-filter> <action android:name="android.intent.action.NEW_OUTGOING_CALL"></action> <category android:name="android.intent.category.DEFAULT"></category> </intent-filter> </receiver> </application> <uses-sdk android:minSdkVersion="3" /> <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"></uses-permission> <uses-permission android:name="android.permission.CALL_PHONE"></uses-permission> <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission> </manifest>
本文内容归CSDN博客博主Sodino 所有
转载请注明出处: http://blog.csdn.net/sodino/archive/2011/02/12/6181610.aspx