最近在做电信翼支付钱包的插件开发,其中在下载卡应用时要求插件使用 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;
}
}
}