AIDL 访问远程服务

 

最近在做电信翼支付钱包的插件开发,其中在下载卡应用时要求插件使用 AIDL 向钱包通知鉴权结果,然后钱包根据鉴权结果下载卡应用。在这里记录 AIDL 使用步骤。

开发工具:IntelliJ IDEA 14.1.3
开发环境:Win7、Android 4.2.2、Java 1.7.0

1、添加 .aidl 接口定义文件

在 src 目录新建 chinatelecom.mwallet.appservice 包目录(对应远程服务的 package),在目录里新建 ICTWalletService.aidl 文件,文件内容如下:

package chinatelecom.mwallet.appservice;

/**
 * Created by Administrator on 2015/7/13.
 */
interface ICTWalletService {
    //向主客户端通知鉴权结果函数,
    //如果鉴权成功,主客户端发起创建辅助安全域请求,界面停留在插件界面等待安全域创建结果通知
    //如果鉴权失败,界面应停留在插件,提示用户鉴权失败
    //输入:authenticateSuccess表示鉴权是否成功
    //    oprtype鉴权类型,01-应用下载,04-应用删除,05-应用升级
    //    oprAppletAID。所操作对应的Applet AID
    //输出:如果操作对应Applet存在于主服务队列中,返回true,否则返回false
    boolean sendAuthenticateResult(boolean authenticateSuccess, String operType, String oprAppletAID);
}

2、生成 .java 接口实现文件

执行 Make Project 将在 gen/chinatelecom/mwallet/appservice 目录下生存 ICTWalletService.java 文件:

/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: D:\javaspace\Idea\Android\wuhan-ct-nfc\src\chinatelecom\mwallet\appservice\ICTWalletService.aidl
 */
package chinatelecom.mwallet.appservice;
/**
 * Created by Administrator on 2015/7/13.
 */
public interface ICTWalletService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements chinatelecom.mwallet.appservice.ICTWalletService
{
private static final java.lang.String DESCRIPTOR = "chinatelecom.mwallet.appservice.ICTWalletService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
...

3、定义连接类

定义 ServiceConnect 的子类 AidlServiceConnection,用于处理连接成功的事件。将 AidlServiceConnection 类定义为 MainActivity 的内部类方便调用公共变量。

注意,服务连接成功后才能初始化服务接口和执行接口定义的方法。

public class MainActivity extends Activity implements SEService.CallBack {
    ...
    // 启动模式
    private int startMode = -1;
    // 应用ID
    private String AID = "";
    // 远程服务接口
    private ICTWalletService aidl;
    // 服务链接对象
    private AidlServiceConnection connection;

    // 服务链接类
    public class AidlServiceConnection implements ServiceConnection {
        public void onServiceConnected(ComponentName name, IBinder service) {
            try {
                // 初始化服务接口
                aidl = ICTWalletService.Stub.asInterface(service);
                switch (startMode) {
                    case 1:
                        //执行下载应用鉴权处理
                        if(aidl.sendAuthenticateResult(true, "01", AID)){
                            // 显示下载进度给用户看
                        }
                        break;
                    case 2:
                        //执行删除应用鉴权处理
                        if(aidl.sendAuthenticateResult(true, "04", AID)){
                            // 如果删除鉴权成功,直接推出插件,返回钱包
                            MainActivity.this.finish();
                        }
                        break;
                }
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        public void onServiceDisconnected(ComponentName name) {
        }
    }
    ...
}

4、绑定服务

在 MainActivity.onCreate 方法里绑定服务。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 获取从手机钱包传过来的参数
        Intent intent = getIntent();
        startMode = intent.getIntExtra("startMode", -1);
        AID = intent.getStringExtra("AID");

        if (startMode > 0) { // 安装或删除卡应用
            // 新建一个 connection 对象
            connection = new AidlServiceConnection();

            // 绑定服务
            Intent i = new Intent("chinatelecom.mwallet.appservice.CTWalletService");
            i.putExtra("TSM_RESULT_RECEIVER", new NFCReceiver(new Handler()));
            bindService(i, connection, Context.BIND_AUTO_CREATE);
        } else if(startMode == 0){ // 正常启动
            init();
        }
    }

    public void init(){
        // 正常启动的初始化
    }

5、解绑服务

在 MainActivity.onDestroy

    @Override
    protected void onDestroy() {
        if (seService != null && seService.isConnected()) {
            seService.shutdown();
        }
        super.onDestroy();
        unbindService(connection);
    }

附录

题外话

移动电子钱包在安装插件时就直接将卡应用安装好,电信的就显得多余的繁琐。

NFCReceiver 类

NFCReceiver 类用于处理下载事件,定义为 MainActivity 的内部类方便调用公共变量。

    // 服务通知类
    public class NFCReceiver extends ResultReceiver {

        public NFCReceiver(Handler handler) {
            super(handler);
        }

        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            super.onReceiveResult(resultCode, resultData);
            switch (resultCode)
            {
                case 0: //应用下载成功
                    //添加应用下载成功处理代码
                    break;
                case 1: //应用下载进行中
                    //获取下载比例参数
                    break;
                case 2: //应用下载失败
                    int errcode = resultData.getInt("errcode");
                    //添加应用下载失败处理代码
                    break;
                default:
                    //返回resultCode错误,添加错误处理代码
                    break;
            }
        }
    }

前一篇:
后一篇:

发表评论