AIDL是Android接口描述语言。
最早的Android中提供了自动挂断电话的功能,但是随着版本的升高这些功能已经被
隐藏起来了,所以要想完成挂断电话的功能,则要依靠AIDL技术完成。
在main.xml中:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:background="#00ff33">
<EditText
android:id="@+id/phonenumber"
android:layout_margin="8dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/setnumber"
android:layout_width="100dp"
android:layout_height="40dp"
android:textColor="#ffffff"
android:background="#3399ff"
android:text="设置黑名单"/>
<Button
android:id="@+id/cancelnumber"
android:layout_marginLeft="20dp"
android:layout_width="100dp"
android:layout_height="40dp"
android:textColor="#ffffff"
android:background="#3399ff"
android:text="取消黑名单"/>
</LinearLayout>
</LinearLayout>
在src下新建包:com.android.internal.telephony,(包名不能改)
并新建文件ITelephony.aidl
在ITelephony.aidl中:
package com.android.internal.telephony ;
interface ITelephony {
boolean endCall() ; // 挂断电话
void answerRingingCall() ; // 拨打电话
}
在IService.java中:
package com.li.phone;
public interface IService {
}
在PhoneBroadcastReceiver.java中:
package com.li.phone;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class PhoneBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())) { // 去电
String outgoingNumber = intent
.getStringExtra(Intent.EXTRA_PHONE_NUMBER); // 去电号码
Intent pit = new Intent(context, PhoneService.class);
pit.putExtra("outgoingNumber", outgoingNumber);
context.startService(pit);
} else { // 来电
context.startService(new Intent(context, PhoneService.class));
}
}
}
在PhoneService.java中:
package com.li.phone;
import java.lang.reflect.Method;
import android.app.Service;
import android.content.Context;
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;
import com.android.internal.telephony.ITelephony;
public class PhoneService extends Service {
private TelephonyManager telephony = null;
private AudioManager audio = null; // 声音服务
private String phoneNumber = null; // 要过滤的电话
private IBinder myBinder = new BinderImpl();
class BinderImpl extends Binder implements IService {
@Override
public String getInterfaceDescriptor() {
return "黑名单号码" + PhoneService.this.phoneNumber + "设置成功!";
}
}
@Override
public IBinder onBind(Intent intent) {
this.phoneNumber = intent.getStringExtra("phonenumber"); // 取得电话号码
this.audio = (AudioManager) super
.getSystemService(Context.AUDIO_SERVICE); // 声音服务
this.telephony = (TelephonyManager) super
.getSystemService(Context.TELEPHONY_SERVICE);
this.telephony.listen(new PhoneStateListenerImpl(),
PhoneStateListener.LISTEN_CALL_STATE); // 设置监听操作
return this.myBinder;
}
private class PhoneStateListenerImpl extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: // 挂断电话
PhoneService.this.audio
.setRingerMode(AudioManager.RINGER_MODE_NORMAL); // 正常音
break;
case TelephonyManager.CALL_STATE_RINGING: // 领音响起
if (incomingNumber.equals(PhoneService.this.phoneNumber)) { // 电话号码匹配
ITelephony iTelephony = getITelephony() ;
if (iTelephony != null) {
try {
iTelephony.endCall() ; // 挂断电话
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK: // 接听电话
break;
}
}
}
private ITelephony getITelephony() {
ITelephony iTelephony = null ;
Class<TelephonyManager> cls = TelephonyManager.class ;
Method getITelephonyMethod = null ;
try {
getITelephonyMethod = cls.getDeclaredMethod("getITelephony") ;
getITelephonyMethod.setAccessible(true) ; // 取消封装
} catch (Exception e) {
}
try {
iTelephony = (ITelephony) getITelephonyMethod
.invoke(this.telephony);
return iTelephony ;
} catch (Exception e) {
}
return iTelephony ;
}
}
在MyPhoneDemo.java中:
package com.li.phone;
import com.li.phone.PhoneService.BinderImpl;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MyPhoneDemo extends Activity {
private EditText phoneNumber = null ;
private Button setNumber = null ;
private Button cancelNumber = null ;
private IService service = null ;
private ServiceConnectionImpl serviceConnection = new ServiceConnectionImpl() ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main);
this.phoneNumber = (EditText) super.findViewById(R.id.phonenumber) ;
this.setNumber = (Button) super.findViewById(R.id.setnumber) ;
this.cancelNumber = (Button) super.findViewById(R.id.cancelnumber) ;
this.setNumber.setOnClickListener(new SetOnClickListenerImpl()) ;
this.cancelNumber.setOnClickListener(new CancelOnClickListenerImpl()) ;
}
private class SetOnClickListenerImpl implements OnClickListener {
public void onClick(View v) {
Intent intent = new Intent(MyPhoneDemo.this,PhoneService.class) ;
intent.putExtra("phonenumber", MyPhoneDemo.this.phoneNumber
.getText().toString());
MyPhoneDemo.this.bindService(intent,
MyPhoneDemo.this.serviceConnection,
Context.BIND_AUTO_CREATE);
}
}
private class CancelOnClickListenerImpl implements OnClickListener {
public void onClick(View v) {
if(MyPhoneDemo.this.service != null) {
MyPhoneDemo.this.unbindService(MyPhoneDemo.this.serviceConnection) ;
MyPhoneDemo.this.stopService(new Intent(MyPhoneDemo.this,PhoneService.class)) ;
Toast.makeText(MyPhoneDemo.this, "黑名单已取消", Toast.LENGTH_LONG)
.show();
MyPhoneDemo.this.service = null ;
}
}
}
private class ServiceConnectionImpl implements ServiceConnection {
public void onServiceConnected(ComponentName name, IBinder service) {
MyPhoneDemo.this.service = (BinderImpl) service ;
try {
Toast.makeText(MyPhoneDemo.this, service.getInterfaceDescriptor(), Toast.LENGTH_LONG).show() ;
} catch (RemoteException e) {
}
}
public void onServiceDisconnected(ComponentName name) {
}
}
}
修改AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.li.phone"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MyPhoneDemo"
android:label="@string/title_activity_my_phone_demo" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".PhoneService" />
<receiver android:name=".PhoneBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
</manifest>