Android AIDL远程调用
2014-06-20 11:11
218 查看
首先介绍一下AIDL
AIDL简介
AIDL(AndRoid接口描述语言)是一种借口描述语言; 编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的. 如果需要在一个Activity中, 访问另一个Service中的某个对象, 需要先将对象转化成 AIDL可识别的参数(可能是多个参数), 然后使用AIDL来传递这些参数, 在消息的接收端, 使用这些参数组装成自己需要的对象.
我的理解它和java中的RMI的概念差不多,在这里我就不相信讲解什么事AIDL 了。既然AIDL是既然是可以在不同进程间(IPC)进行操作。
下面我来通过一个简单的两个项目实例来讲解,一个是Server,一个是Client.
在Server客户端。
1.创建一个文件ITestService.aidl,如下所示:
package com.lifeblood;
interface ITestService {
int getAccountBalance();
void setOwnerNames(in List<String> names);
int getCustomerList(in String branch, out String[] customerList);
void showTest();
}
复制代码
2.创建TestService.java类,该类继承Service类,实现public IBinder onBind(Intent intent)方法,
如下所示:
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
mContext = this;
return binder; //返回AIDL接口实例化对象
}
复制代码
同时在该类中,实例化ITestService.stub字柄
//实现AIDL接口中各个方法
private ITestService.Stub binder = new Stub(){
private String name = null;
public int getAccountBalance() throws RemoteException {
// TODO Auto-generated method stub
return 100000;
}
public int getCustomerList(String branch, String[] customerList)
throws RemoteException {
// TODO Auto-generated method stub
customerList[0] = name;
System.out.println("Name:"+branch);
return 0;
}
public void setOwnerNames(List<String> names) throws RemoteException {
// TODO Auto-generated method stub
name = names.get(0);
System.out.println("Size:"+names.size()+"=="+names.get(0));
}
public void showTest() throws RemoteException {
// TODO Auto-generated method stub
Intent intent = new Intent(mContext, AidlTtest.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
};
复制代码
3.然后在Activity子类中进行测试,主要的工作就是开启上面实例化的Service子类
Intent service = new Intent(this, TestService.class);
startService(service);
复制代码
4.在AndroidManifest.xml注册该Service
<service android:name="TestService" android:process=":remote">
<intent-filter>
<!-- AIDL完整路径名。必须指明,客户端能够通过AIDL类名查找到它的实现类 -->
<action android:name="com.lifeblood.ITestService" />
</intent-filter>
</service>
复制代码
(这样Server端的编码就结束了。然后就在Client类书写代码了。)
5.其实Aidl远程就相当于JAVA RMI 远程调用,也就是说也要在客户端书写一样的AIDL源文件。而且package包没有限制。可以写在任何你认为
合适的地方。此步略。
6.最后在Client端的Acitivty中写入,如下代码:
//创建远程调用对象
private ServiceConnection connection = new ServiceConnection(){
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
//从远程service中获得AIDL实例化对象
tService = ITestService.Stub.asInterface(service);
System.out.println("Bind Success:"+tService);
}
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
tService = null;
}
};
................................
public void onClick(View v) {
// TODO Auto-generated method stub
int viewId = v.getId();
try{
if (viewId == btn.getId()){
Intent service = new Intent(ITestService.class.getName());
//ITestService.class.getName()
//绑定AIDL
bindService(service, connection, BIND_AUTO_CREATE);
}else if (viewId == btn1.getId()){
text.setText("远程结果:"+tService.getAccountBalance());
}else if (viewId == btn2.getId()){
List<String> names = new ArrayList<String>();
names.add("李彬彬");
tService.setOwnerNames(names);
}else if (viewId == btn3.getId()){
String[] customerList = new String[1];
tService.getCustomerList("向华", customerList);
text.setText("远程结果:"+customerList[0]);
}else if (viewId == btn4.getId()){
tService.showTest();
}
}catch(RemoteException e){
e.printStackTrace();
}
...............................
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unbindService(connection);
}
复制代码
其中,
//创建远程调用对象
private ServiceConnection connection = new ServiceConnection(){
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
//从远程service中获得AIDL实例化对象
tService = ITestService.Stub.asInterface(service);
System.out.println("Bind Success:"+tService);
}
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
tService = null;
}
};
用于实例化该 private ITestService tService = null变量。 这样就可以通过点击事件来启动该服务中的方法.
try{
if (viewId == btn.getId()){
Intent service = new Intent(ITestService.class.getName());
//ITestService.class.getName()
//绑定AIDL
bindService(service, connection, BIND_AUTO_CREATE);
}else if (viewId == btn1.getId()){
text.setText("远程结果:"+tService.getAccountBalance());
}else if (viewId == btn2.getId()){
List<String> names = new ArrayList<String>();
names.add("mingg");
tService.setOwnerNames(names);
}else if (viewId == btn3.getId()){
String[] customerList = new String[1];
tService.getCustomerList("向华", customerList);
text.setText("远程结果:"+customerList[0]);
}else if (viewId == btn4.getId()){
tService.showTest();
}
如果要退出程序,不要忘了在onDestroy方法中加入
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unbindService(connection);
}
要注意以下几点:
使用getApplicationContext()所获取的上下文来绑定和解绑定服务,这个时候即使不用unbindService也是不会出错的。具体原因还未深究。
如果不想用getApplicationContext(),那么就必须在结束Activity时运行解绑定操作。
如果unbindService(conn)中的conn没有被绑定到服务端,将报java.lang.IllegalArgumentException: Service not registered这样的错误。证明了这个方法不宜调用第二次。
当以startService的方式打开服务,即使当前服务没有绑定的对象也不会停止服务,除非stopService才能停止。反之如果先运行的是bindService,那么,只要当前的绑定对象都失去连接,就会停止服务 。
[align=left]这里回过头来说明一些android中的service[/align]
[align=left]Service概念及用途:[/align]
Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行,那 我们什么时候会用到Service呢?比如我们播放音乐的时候,有可能想边听音乐边干些其他事情,当我们退出播放音乐的应用,如果不用Service,我 们就听不到歌了,所以这时候就得用到Service了,又比如当我们一个应用的数据是通过网络获取的,不同时间(一段时间)的数据是不同的这时候我们可以
用Service在后台定时更新,而不用每打开应用的时候在去获取。
[align=left]Service生命周期 :[/align]
Android Service的生命周期并不像Activity那么复杂,它只继承了onCreate(),onStart(),onDestroy()三个方法,当我 们第一次启动Service时,先后调用了onCreate(),onStart()这两个方法,当停止Service时,则执行onDestroy() 方法,这里需要注意的是,如果Service已经启动了,当我们再次启动Service时,不会在执行onCreate()方法,而是直接执行
onStart()方法,具体的可以看下面的实例。
[align=left] (我是参考一个实例,如一个博客日志写的)[/align]
[align=left]下面我再举一个例子,这个例子是实现来电防火墙的功能,就是说,如果有指定的号码打入,电话会自动静音,并且会自动断开。[/align]
[align=left]由于Android1.1以上版本已经屏蔽了一些断开电话接入的API,而采取了AIDL方式。[/align]
[align=left]接下来讲解,我实现的过程和一些关键代码,如下所示:[/align]
package com.android.internal.telephony;
interface ITelephony {
boolean endCall();
void answerRingingCall();
}
复制代码
为了显示所有细节,我将我写得所示关键代码写入:
package com.test.telephone;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.RemoteException;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.TextView;
import com.android.internal.telephony.ITelephony;
/***
*
* 参考:
* http://blog.csdn.net/chenzheng_java/archive/2011/03/20/6262578.aspx
* @author mingg
*
*/
public class ActivityMain extends Activity {
private static final String TAG = "Telephony";
TextView view = null;
TelephonyManager mTelephonyMgr;
private ITelephony iTelephony;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTelephonyMgr = (TelephonyManager) this
.getSystemService(Context.TELEPHONY_SERVICE);
mTelephonyMgr.listen(new TeleListener(),
PhoneStateListener.LISTEN_CALL_STATE);
view = new TextView(this);
view.setText("listen the state of phone\n");
setContentView(view);
}
class TeleListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: { //待机状态
Log.e(TAG, "CALL_STATE_IDLE");
view.append("CALL_STATE_IDLE " + "\n");
//待机状态响铃正常
AudioManager audioManager=(AudioManager)getSystemService(Context.AUDIO_SERVICE);
if(audioManager!=null){
/**设置响铃正常**、
*
*/
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
audioManager.getStreamVolume(AudioManager.STREAM_RING);//设置音量
}
break;
}
case TelephonyManager.CALL_STATE_OFFHOOK: {//电话被挂起了
Log.e(TAG, "CALL_STATE_OFFHOOK");
view.append("CALL_STATE_OFFHOOK" + "\n");
break;
}
case TelephonyManager.CALL_STATE_RINGING: { //来电
/**有电话接入**、
*
*/
if(incomingNumber.equals("15915780893")){//黑名单电话号码
AudioManager audioManager=(AudioManager)getSystemService(Context.AUDIO_SERVICE);
if(audioManager!=null){
/**设置为静音模式**/
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
//也可以改为震动模式
// audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);//
audioManager.setRingerMode(AudioManager.STREAM_RING);
}
getTelephony();
//初始化iTelephony
try {
iTelephony.endCall();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Log.e(TAG, "CALL_STATE_RINGING");
view.append("CALL_STATE_RINGING" +incomingNumber+ "\n");
break;
}
default:
break;
}
}
}
public void getTelephony()
{
TelephonyManager telMgr =
(TelephonyManager)getSystemService(Service.TELEPHONY_SERVICE);
Class <TelephonyManager> c = TelephonyManager.class;
Method getITelephonyMethod = null;
try {
getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[])null);
getITelephonyMethod.setAccessible(true);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
iTelephony = (ITelephony) getITelephonyMethod.invoke(telMgr, (Object[])null);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
复制代码
代码分析:TelephonyManager mTelephonyMgr;mTelephonyMgr = (TelephonyManager) this
.getSystemService(Context.TELEPHONY_SERVICE);
mTelephonyMgr.listen(new TeleListener(),
PhoneStateListener.LISTEN_CALL_STATE);这个就是电话管理器,电话有三种状态,可以对其进行监听。class TeleListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: { //待机状态
break;
}
case TelephonyManager.CALL_STATE_OFFHOOK: {//电话被挂起了
}
case TelephonyManager.CALL_STATE_RINGING: { //来电
/**有电话接入**、
*
*/
break;
}
default:
break;
}
}
}
这里我们来看来电时候的状态:TelephonyManager.CALL_STATE_RINGING if(audioManager!=null){
/**设置为静音模式**/
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
//也可以改为震动模式
// audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);//
audioManager.setRingerMode(AudioManager.STREAM_RING);
}
getTelephony();
//初始化iTelephony
iTelephony.endCall(); //挂断电话。这里我们没有使用Service子类实现,由于实现的功能简单,如果实现的逻辑比较复杂的话,我们一般希望加入Service,如第一个实例那样封装Aidl。注意:在getTelephony()方法中,我们使用JAVA反射机制。TelephonyManager telMgr = (TelephonyManager)getSystemService(Service.TELEPHONY_SERVICE);
Class <TelephonyManager> c = TelephonyManager.class;
Method getITelephonyMethod = null;
getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[])null);
getITelephonyMethod.setAccessible(true);
iTelephony = (ITelephony) getITelephonyMethod.invoke(telMgr, (Object[])null);关于JAVA的反射机制,我将会在后续再次提到。最后当然不要忘了在AndroidManifest.xml进行权限申请:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
复制代码
http://www.apkbus.com/forum.php?mod=viewthread&tid=142
AIDL简介
AIDL(AndRoid接口描述语言)是一种借口描述语言; 编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的. 如果需要在一个Activity中, 访问另一个Service中的某个对象, 需要先将对象转化成 AIDL可识别的参数(可能是多个参数), 然后使用AIDL来传递这些参数, 在消息的接收端, 使用这些参数组装成自己需要的对象.
我的理解它和java中的RMI的概念差不多,在这里我就不相信讲解什么事AIDL 了。既然AIDL是既然是可以在不同进程间(IPC)进行操作。
下面我来通过一个简单的两个项目实例来讲解,一个是Server,一个是Client.
在Server客户端。
1.创建一个文件ITestService.aidl,如下所示:
package com.lifeblood;
interface ITestService {
int getAccountBalance();
void setOwnerNames(in List<String> names);
int getCustomerList(in String branch, out String[] customerList);
void showTest();
}
复制代码
2.创建TestService.java类,该类继承Service类,实现public IBinder onBind(Intent intent)方法,
如下所示:
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
mContext = this;
return binder; //返回AIDL接口实例化对象
}
复制代码
同时在该类中,实例化ITestService.stub字柄
//实现AIDL接口中各个方法
private ITestService.Stub binder = new Stub(){
private String name = null;
public int getAccountBalance() throws RemoteException {
// TODO Auto-generated method stub
return 100000;
}
public int getCustomerList(String branch, String[] customerList)
throws RemoteException {
// TODO Auto-generated method stub
customerList[0] = name;
System.out.println("Name:"+branch);
return 0;
}
public void setOwnerNames(List<String> names) throws RemoteException {
// TODO Auto-generated method stub
name = names.get(0);
System.out.println("Size:"+names.size()+"=="+names.get(0));
}
public void showTest() throws RemoteException {
// TODO Auto-generated method stub
Intent intent = new Intent(mContext, AidlTtest.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
};
复制代码
3.然后在Activity子类中进行测试,主要的工作就是开启上面实例化的Service子类
Intent service = new Intent(this, TestService.class);
startService(service);
复制代码
4.在AndroidManifest.xml注册该Service
<service android:name="TestService" android:process=":remote">
<intent-filter>
<!-- AIDL完整路径名。必须指明,客户端能够通过AIDL类名查找到它的实现类 -->
<action android:name="com.lifeblood.ITestService" />
</intent-filter>
</service>
复制代码
(这样Server端的编码就结束了。然后就在Client类书写代码了。)
5.其实Aidl远程就相当于JAVA RMI 远程调用,也就是说也要在客户端书写一样的AIDL源文件。而且package包没有限制。可以写在任何你认为
合适的地方。此步略。
6.最后在Client端的Acitivty中写入,如下代码:
//创建远程调用对象
private ServiceConnection connection = new ServiceConnection(){
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
//从远程service中获得AIDL实例化对象
tService = ITestService.Stub.asInterface(service);
System.out.println("Bind Success:"+tService);
}
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
tService = null;
}
};
................................
public void onClick(View v) {
// TODO Auto-generated method stub
int viewId = v.getId();
try{
if (viewId == btn.getId()){
Intent service = new Intent(ITestService.class.getName());
//ITestService.class.getName()
//绑定AIDL
bindService(service, connection, BIND_AUTO_CREATE);
}else if (viewId == btn1.getId()){
text.setText("远程结果:"+tService.getAccountBalance());
}else if (viewId == btn2.getId()){
List<String> names = new ArrayList<String>();
names.add("李彬彬");
tService.setOwnerNames(names);
}else if (viewId == btn3.getId()){
String[] customerList = new String[1];
tService.getCustomerList("向华", customerList);
text.setText("远程结果:"+customerList[0]);
}else if (viewId == btn4.getId()){
tService.showTest();
}
}catch(RemoteException e){
e.printStackTrace();
}
...............................
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unbindService(connection);
}
复制代码
其中,
//创建远程调用对象
private ServiceConnection connection = new ServiceConnection(){
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
//从远程service中获得AIDL实例化对象
tService = ITestService.Stub.asInterface(service);
System.out.println("Bind Success:"+tService);
}
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
tService = null;
}
};
用于实例化该 private ITestService tService = null变量。 这样就可以通过点击事件来启动该服务中的方法.
try{
if (viewId == btn.getId()){
Intent service = new Intent(ITestService.class.getName());
//ITestService.class.getName()
//绑定AIDL
bindService(service, connection, BIND_AUTO_CREATE);
}else if (viewId == btn1.getId()){
text.setText("远程结果:"+tService.getAccountBalance());
}else if (viewId == btn2.getId()){
List<String> names = new ArrayList<String>();
names.add("mingg");
tService.setOwnerNames(names);
}else if (viewId == btn3.getId()){
String[] customerList = new String[1];
tService.getCustomerList("向华", customerList);
text.setText("远程结果:"+customerList[0]);
}else if (viewId == btn4.getId()){
tService.showTest();
}
如果要退出程序,不要忘了在onDestroy方法中加入
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unbindService(connection);
}
要注意以下几点:
使用getApplicationContext()所获取的上下文来绑定和解绑定服务,这个时候即使不用unbindService也是不会出错的。具体原因还未深究。
如果不想用getApplicationContext(),那么就必须在结束Activity时运行解绑定操作。
如果unbindService(conn)中的conn没有被绑定到服务端,将报java.lang.IllegalArgumentException: Service not registered这样的错误。证明了这个方法不宜调用第二次。
当以startService的方式打开服务,即使当前服务没有绑定的对象也不会停止服务,除非stopService才能停止。反之如果先运行的是bindService,那么,只要当前的绑定对象都失去连接,就会停止服务 。
[align=left]这里回过头来说明一些android中的service[/align]
[align=left]Service概念及用途:[/align]
Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行,那 我们什么时候会用到Service呢?比如我们播放音乐的时候,有可能想边听音乐边干些其他事情,当我们退出播放音乐的应用,如果不用Service,我 们就听不到歌了,所以这时候就得用到Service了,又比如当我们一个应用的数据是通过网络获取的,不同时间(一段时间)的数据是不同的这时候我们可以
用Service在后台定时更新,而不用每打开应用的时候在去获取。
[align=left]Service生命周期 :[/align]
Android Service的生命周期并不像Activity那么复杂,它只继承了onCreate(),onStart(),onDestroy()三个方法,当我 们第一次启动Service时,先后调用了onCreate(),onStart()这两个方法,当停止Service时,则执行onDestroy() 方法,这里需要注意的是,如果Service已经启动了,当我们再次启动Service时,不会在执行onCreate()方法,而是直接执行
onStart()方法,具体的可以看下面的实例。
[align=left] (我是参考一个实例,如一个博客日志写的)[/align]
[align=left]下面我再举一个例子,这个例子是实现来电防火墙的功能,就是说,如果有指定的号码打入,电话会自动静音,并且会自动断开。[/align]
[align=left]由于Android1.1以上版本已经屏蔽了一些断开电话接入的API,而采取了AIDL方式。[/align]
[align=left]接下来讲解,我实现的过程和一些关键代码,如下所示:[/align]
package com.android.internal.telephony;
interface ITelephony {
boolean endCall();
void answerRingingCall();
}
复制代码
为了显示所有细节,我将我写得所示关键代码写入:
package com.test.telephone;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.RemoteException;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.TextView;
import com.android.internal.telephony.ITelephony;
/***
*
* 参考:
* http://blog.csdn.net/chenzheng_java/archive/2011/03/20/6262578.aspx
* @author mingg
*
*/
public class ActivityMain extends Activity {
private static final String TAG = "Telephony";
TextView view = null;
TelephonyManager mTelephonyMgr;
private ITelephony iTelephony;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTelephonyMgr = (TelephonyManager) this
.getSystemService(Context.TELEPHONY_SERVICE);
mTelephonyMgr.listen(new TeleListener(),
PhoneStateListener.LISTEN_CALL_STATE);
view = new TextView(this);
view.setText("listen the state of phone\n");
setContentView(view);
}
class TeleListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: { //待机状态
Log.e(TAG, "CALL_STATE_IDLE");
view.append("CALL_STATE_IDLE " + "\n");
//待机状态响铃正常
AudioManager audioManager=(AudioManager)getSystemService(Context.AUDIO_SERVICE);
if(audioManager!=null){
/**设置响铃正常**、
*
*/
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
audioManager.getStreamVolume(AudioManager.STREAM_RING);//设置音量
}
break;
}
case TelephonyManager.CALL_STATE_OFFHOOK: {//电话被挂起了
Log.e(TAG, "CALL_STATE_OFFHOOK");
view.append("CALL_STATE_OFFHOOK" + "\n");
break;
}
case TelephonyManager.CALL_STATE_RINGING: { //来电
/**有电话接入**、
*
*/
if(incomingNumber.equals("15915780893")){//黑名单电话号码
AudioManager audioManager=(AudioManager)getSystemService(Context.AUDIO_SERVICE);
if(audioManager!=null){
/**设置为静音模式**/
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
//也可以改为震动模式
// audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);//
audioManager.setRingerMode(AudioManager.STREAM_RING);
}
getTelephony();
//初始化iTelephony
try {
iTelephony.endCall();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Log.e(TAG, "CALL_STATE_RINGING");
view.append("CALL_STATE_RINGING" +incomingNumber+ "\n");
break;
}
default:
break;
}
}
}
public void getTelephony()
{
TelephonyManager telMgr =
(TelephonyManager)getSystemService(Service.TELEPHONY_SERVICE);
Class <TelephonyManager> c = TelephonyManager.class;
Method getITelephonyMethod = null;
try {
getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[])null);
getITelephonyMethod.setAccessible(true);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
iTelephony = (ITelephony) getITelephonyMethod.invoke(telMgr, (Object[])null);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
复制代码
代码分析:TelephonyManager mTelephonyMgr;mTelephonyMgr = (TelephonyManager) this
.getSystemService(Context.TELEPHONY_SERVICE);
mTelephonyMgr.listen(new TeleListener(),
PhoneStateListener.LISTEN_CALL_STATE);这个就是电话管理器,电话有三种状态,可以对其进行监听。class TeleListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: { //待机状态
break;
}
case TelephonyManager.CALL_STATE_OFFHOOK: {//电话被挂起了
}
case TelephonyManager.CALL_STATE_RINGING: { //来电
/**有电话接入**、
*
*/
break;
}
default:
break;
}
}
}
这里我们来看来电时候的状态:TelephonyManager.CALL_STATE_RINGING if(audioManager!=null){
/**设置为静音模式**/
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
//也可以改为震动模式
// audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);//
audioManager.setRingerMode(AudioManager.STREAM_RING);
}
getTelephony();
//初始化iTelephony
iTelephony.endCall(); //挂断电话。这里我们没有使用Service子类实现,由于实现的功能简单,如果实现的逻辑比较复杂的话,我们一般希望加入Service,如第一个实例那样封装Aidl。注意:在getTelephony()方法中,我们使用JAVA反射机制。TelephonyManager telMgr = (TelephonyManager)getSystemService(Service.TELEPHONY_SERVICE);
Class <TelephonyManager> c = TelephonyManager.class;
Method getITelephonyMethod = null;
getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[])null);
getITelephonyMethod.setAccessible(true);
iTelephony = (ITelephony) getITelephonyMethod.invoke(telMgr, (Object[])null);关于JAVA的反射机制,我将会在后续再次提到。最后当然不要忘了在AndroidManifest.xml进行权限申请:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
复制代码
http://www.apkbus.com/forum.php?mod=viewthread&tid=142
相关文章推荐
- Android AIDL远程调用
- Android AIDL和远程Service调用(一)
- Android aidl 工具及远程调用 (一)
- Android 之 AIDL 和远程 Service 调用
- Android工作实践总结:Aidl 远程调用(aidl实例总结)
- Android通过Service调用远程接口—AIDL-进程间通信
- Android中的跨进程通信的实现——远程调用过程和aidl
- Android AIDL远程调用
- Android中使用AIDL调用远程服务
- android中的跨进程通信的实现(一)——远程调用过程和aidl
- Android -- service的开启方式, start开启和绑定开启服务,调用服务的的方法, aidl调用远程服务
- Android Service AIDL 远程调用服务之简单音乐播放实例【转载】
- android 中activity调用远程service中的方法之 aidl的使用
- Android AIDL和远程Service调用(二)
- android中的跨进程通信的实现(一)——远程调用过程和aidl
- android,aidl,绑定远程服务,调用远程服务的方法
- Android -- service的开启方式, start开启和绑定开启服务,调用服务的的方法, aidl调用远程服务
- 18_Android中Service的生命周期,远程服务,绑定远程服务,aidl服务调用,综合服务案例,编写一个应用程序调用远程支付宝远程服务场景
- Android AIDL远程调用
- Android学习指南之二十二:实例讲解AIDL和远程Service调用