赞
踩
1、背景
项目中遇到一个需求,要对Mdmservice进行管控。简化下来大概就是需要监听一个系统属性值,当这个属性值变为false的时候,禁止调用扬声器、听筒。跟踪代码发现这个需求里面的场景,只需要处理MediaRecorder就能达到目标。
2、实现
根据需求,调用扬声器、听筒之前读取一下系统属性值判断一下即可,有个场景是正在调用扬声器、听筒的过程中属性值发生变化,着重要处理的就是这个场景。
2.1 定义AIDL接口
接口名称定为INotifyPolicyChange.aidl,直接给出代码:
/*
* server use this interface of client
*/
interface INotifyPolicyChange {
void notifyPolicyChange();
}
2.2 在IMdmService.aidl中定义注册、去注册接口
interface IMdmService {
//Interactive interface
void registerCallBack(IBinder token, INotifyPolicyChange callback);
void unregisterCallBack(INotifyPolicyChange callback);
……
}
2.3 在MdmService中实现注册、去注册
给出代码片段:
private RemoteCallbackList<INotifyPolicyChange> mCallBacks = new RemoteCallbackList<>(); final class ClientDeathCallback implements DeathRecipient { public final IBinder mToken; public final INotifyPolicyChange mCallback; public ClientDeathCallback(IBinder token, INotifyPolicyChange mCallback) { this.mToken = token; this.mCallback = mCallback; } @Override public void binderDied() { Log.d(TAG,"client died! mToken=" + mToken + ";callback=" + mCallback); try { unregisterCallBack(mCallback); } catch (RemoteException e) { e.printStackTrace(); } } } public void registerCallBack(IBinder token, INotifyPolicyChange callback) throws RemoteException { ClientDeathCallback clientDeathCallback = new ClientDeathCallback(token, callback); //register callback mCallBacks.register(callback); //register recipient token.linkToDeath(clientDeathCallback, 0); } public void unregisterCallBack(INotifyPolicyChange callback) throws RemoteException { mCallBacks.unregister(callback); } /** * notify client that policy change */ private void notifyChange() { final int len = mCallBacks.beginBroadcast(); for(int i = 0; i < len; i++) { try { mCallBacks.getBroadcastItem(i).notifyPolicyChange(); } catch (RemoteException e) { e.printStackTrace(); } } mCallBacks.finishBroadcast(); } public boolean setMicrophonePolicy(int policy) throws RemoteException { if(isActive) { boolean success = MdmDevicePolicyManager.getInstance(mContext) .getPeripheralPolicy().setMicrophonePolicy(policy); //notify client policy changed if(success) { notifyChange(); } return success; } return false; }
2.4 在MediaRecorder中实现业务逻辑
给出代码片段:
private IBinder mBinder; private IMdmService mMdmService; public MediaRecorder() { //get mdmservice mBinder and register a callback mBinder = ServiceManager.getService("mdm3"); mMdmService = mBinder == null ? null : IMdmService.Stub.asInterface(mBinder); if(mMdmService != null) { try { mMdmService.registerCallBack(new Binder(), mNotifyCallBack); } catch (RemoteException e) { e.printStackTrace(); } } else { Log.e(TAG, "MediaRecorder cannot get mdmservice mBinder!"); } } private INotifyPolicyChange mNotifyCallBack = new INotifyPolicyChange.Stub() { @Override public void notifyPolicyChange() throws RemoteException { //add logic here } };
mBinder = ServiceManager.getService("mdm3");
这句代码能获取到MdmService实例是因为在SystemService已经以“mdm3”对MdmService注册过了。
2.5 在mk及其他文件里注册新增AIDL文件
新增了AIDL之后,需手动注册,否则编译时找不到相应文件。
core/java/android/service/mdm3/INotifyPolicyChange.aidl
编译过后,“api/current.txt”、“api/system-current.txt”、“api/test-current”也新增了相应接口。
这样,就完成了在framework中新增一个AIDL接口。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。