Android的AIDL以及挂断电话

Android的AIDL是什么呢,AIDL就是Android Interface Defination Language,其实说白了,它就是Android定义好的,进程间通信的一种机制而已,

有点像那个调用Service里面的方法。

好,我们下面就通过代码来说明

首先,我们先写一个接口

com.xiaobin.service.IService

 

[java][/java] view plaincopy

  1. package com.xiaobin.service;
  2. public interface IService
  3. {
  4.     public void sayService();
  5. }

很简单,就一个方法而已,和我们之前讲的调用Service里面的方法一样,

 

现在就说一下不同的地方啦,我们现在就要把上面那个接口里的方法的修饰符public去掉,然后再把后缀名改为.aidl

然后呢,我们就会发现Eclipse会帮我们生成一个类的了

接下来,我们再写一个Service类

com.xiaobin.service.remote.RemoteSrevice

 

[java][/java] view plaincopy

  1. package com.xiaobin.service.remote;
  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.os.IBinder;
  5. import android.os.RemoteException;
  6. import com.xiaobin.service.remote.IService;
  7. public class RemoteService extends Service
  8. {
  9.     @Override
  10.     public IBinder onBind(Intent intent)
  11.     {
  12.         //返回我们自己的Binder
  13.         return new MyBinder();
  14.     }
  15.     @Override
  16.     public void onCreate()
  17.     {
  18.         System.out.println(“service onCreate”);
  19.         super.onCreate();
  20.     }
  21.     //服务里面的方法
  22.     public void sayService()
  23.     {
  24.         System.out.println(“我是另一个进程里面的方法喔”);
  25.     }
  26.     //继承由AIDL生成的抽象类
  27.     class MyBinder extends IService.Stub
  28.     {
  29.         @Override
  30.         public void invokeServiceMethod() throws RemoteException
  31.         {
  32.             //调用服务里面的方法
  33.             sayService();
  34.         }
  35.     }
  36. }

 

 

写完这个之后,我们就要在AndroidMainfest里面注册它了

 

 

[html][/html] view plaincopy

  1. <service android:name=”com.xiaobin.service.remote.RemoteSrevice”>
  2.     <intent-filter>
  3.         <action android:name=”com.xiaobin.remoteservice”/>
  4.     </intent-filter>
  5. </service>

大家可以看到,我们指定了一个action,这个是为了呆会调用时所指定的。

 

好啦,到现在为止,我们的远程服务就已经写好的了

 

接下来,我们新建一个项目,注意,是新建一个项目,然后写一个调用刚刚我们写的这个服务的类

但在写之前,我们要把我们刚刚写好的aidl文件也拷贝到这个项目里面

 

那么,接下来,我们就写一下我们的调用逻辑了

com.xiaobin.aidlservice.MainActivity

 

[java][/java] view plaincopy

  1. package com.xiaobin.aidlservice;
  2. import android.app.Activity;
  3. import android.content.ComponentName;
  4. import android.content.Intent;
  5. import android.content.ServiceConnection;
  6. import android.os.Bundle;
  7. import android.os.IBinder;
  8. import android.os.RemoteException;
  9. import android.view.View;
  10. import android.widget.Toast;
  11. import com.xiaobin.service.remote.IService;
  12. public class MainActivity extends Activity
  13. {
  14.     private IService iService = null;
  15.     private MyServiceConnection conn;
  16.     @Override
  17.     public void onCreate(Bundle savedInstanceState)
  18.     {
  19.         super.onCreate(savedInstanceState);
  20.         this.setContentView(R.layout.main);
  21.         conn = new MyServiceConnection();
  22.         Intent intent = new Intent();
  23.         // 刚刚在注册那个服务时指定的
  24.         intent.setAction(“com.xiaobin.remoteservice”);
  25.         this.bindService(intent, conn, BIND_AUTO_CREATE);
  26.     }
  27.     public void click(View v)
  28.     {
  29.         try
  30.         {
  31.             if(iService != null)
  32.             {
  33.                 //调用接口里面的方法
  34.                 iService.invokeServiceMethod();
  35.             }
  36.             else
  37.             {
  38.                 Toast.makeText(this, “调用远程服务出错”, Toast.LENGTH_SHORT).show();
  39.             }
  40.         }
  41.         catch (RemoteException e)
  42.         {
  43.             e.printStackTrace();
  44.         }
  45.     }
  46.     @Override
  47.     protected void onDestroy()
  48.     {
  49.         if(conn != null)
  50.         {
  51.             this.unbindService(conn);
  52.         }
  53.         super.onDestroy();
  54.     }
  55.     class MyServiceConnection implements ServiceConnection
  56.     {
  57.         @Override
  58.         public void onServiceConnected(ComponentName name, IBinder service)
  59.         {
  60.             //拿到我们当时自己写的Binder对象
  61.             iService = IService.Stub.asInterface(service);
  62.         }
  63.         @Override
  64.         public void onServiceDisconnected(ComponentName name)
  65.         {
  66.         }
  67.     }
  68. }

 

好啦,到现在为止,我们的代码就写好的啦,现在我们就可以测试一下的啦,年一下System.out这个标签的输出就可以啦

 

讲到这里,我们就要讲一下AIDL有什么应用啦

下面我们就讲一个挂断电话的例子,我们知道,Android的api里面是没有挂断电话的操作的

那如果我们的应用就有这样一个需求呢,那怎么办

其实也很容易,就是通过aidl来挂断电话,那么我们现在来写一下

首先,我们先把两个aidl文件复制到src目录下面

你肯定会问,这些aidl文件是在那里找到的,那么我可以告诉你,这些是Android的源码里面找到的,就是在base这个下面的

大家可以下载下来看看,如果有不会的,请看点击这里

 

既然把aidl文件拷贝过去之后,我们就可以写代码啦

com.xiaobin.endcall.MainActivity

 

[java][/java] view plaincopy

  1. package com.xiaobin.endcall;
  2. import java.lang.reflect.Method;
  3. import com.android.internal.telephony.ITelephony;
  4. import android.app.Activity;
  5. import android.os.Bundle;
  6. import android.os.IBinder;
  7. import android.view.View;
  8. public class MainActivity extends Activity
  9. {
  10.     @Override
  11.     public void onCreate(Bundle savedInstanceState)
  12.     {
  13.         super.onCreate(savedInstanceState);
  14.         this.setContentView(R.layout.main);
  15.     }
  16.     public void click(View v)
  17.     {
  18.         endCall();
  19.     }
  20.     //挂断电话
  21.     private void endCall()
  22.     {
  23.         try
  24.         {
  25.             //通过反射拿到android.os.ServiceManager里面的getService这个方法的对象
  26.             Method method = Class.forName(“android.os.ServiceManager”).getMethod(“getService”, String.class);
  27.             //通过反射调用这个getService方法,然后拿到IBinder对象,然后就可以进行aidl啦
  28.             IBinder iBinder = (IBinder) method.invoke(null, new Object[] {TELEPHONY_SERVICE});
  29.             ITelephony telephony = ITelephony.Stub.asInterface(iBinder);
  30.             telephony.endCall();
  31.         }
  32.         catch (Exception e)
  33.         {
  34.             e.printStackTrace();
  35.         }
  36.     }
  37. }

 

 

因为那个服务没有公开的,所以我们就要用到反射来调用这个服务,来拿到Binder对象
还有重要的一点喔,要加上相应的权限,不然挂不断的喔

 

[html][/html] view plaincopy

  1. <uses-permission android:name=”android.permission.CALL_PHONE”/>

好啦,到这里,挂断电话的操作就完成的啦,可以测试一下啦,然后我们手机卫士的这个项目的黑名单那里也有挂断电话的操作的喔

 
今天源码下载

标签