一个很简陋的小例子
个人理解上其实是同名类跨进程欺骗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>