Android Camera和CameraServie默认都没有api支持查询Camera是否在使用或者哪个应用在使用Camera。
使用Camera.open来判断会有些bug,可能会导致摄像头不能马上打开。
如果是自己的应用在使用Camera,自己释放重新打开即可,如果是别人的应用在使用,就不能再打开Camera了。
下面分析一个从Android类库层代码获取Camera当前使用的应用包名的分析过程。
前面6步都是和自己平台代码相关的,是一条基本的AIDL绑定过程。
第6步以后是Android原生代码,基本架构是一样的,主要实现是在C++底层。
1、系统内暴露的Manager
LwzCameraManager.java
public final class LwzCameraManager{
public String getUsingCameraAppPackage() {
try {
return mLwzSettingService.getUsingCameraAppPackage();
} catch (RemoteException e) {
e.printStackTrace();
}
return "";
}
}
2、aidl文件
ILwzCamera.aidl
interface ILwzCamera {
String getCameraHolderPakcage();
}
3、自己的CameraService
vendor\mstar\common\libraries\LwzService\LwzService\src\com\Lwz\main\service\service\LwzCameraService
public class LwzCameraService extends ILwzCamera.Stub {
@Override
public String getCameraHolderPakcage() {
"xxx"; //详细过程看下面。
}
}
添加LwzService的地方
4、CameraService相关的aidl
ILwzService
interface ILwzService {
xxx
ILwzCamera getLwzCamera();
}
5、自己的Service
管理不同的模块Service。
LwzService
public class LwzService extends Service{
private final ILwzService.Stub mBinder = new ILwzService.Stub() {
。。。
@Override
public ILwzCamera getLwzCamera() throws RemoteException {
if (mLwzCameraService == null) {
mLwzCameraService = new LwzCameraService(getApplicationContext());
}
return mLwzPictureService;
}
}
6、自己的CameraService部分讲解
vendor\mediatek\proprietary_tv\open\frameworks\broadcast\LwzService\src\com\Lwz\main\service\service\LwzCameraService
public class LwzCameraService extends ILwzCamera.Stub {
private static ICameraServiceProxy csp;
private Context mContext;
public LwzCameraService(Context context) {
mContext = context;
IBinder service = ServiceManager.getService(CAMERA_PROXY);
csp = ICameraServiceProxy.Stub.asInterface(service);
}
@Override
public String getCameraHolderPackage() {
try {
String state = csp.getCameraHolder();
String[] doesHasPackage = state.split("Package Name:");
if (doesHasPackage.length > 1) {
String[] trimToEnd = doesHasPackage[1].split(",");
if (trimToEnd.length > 0) {
return trimToEnd[0].trim();
}
}
} catch (RemoteException e) {
e.printStackTrace();
}
return "";
}
}
//Android原生代码
7、ICameraServiceProxy.aidl
release/frameworks/av/camera/aidl/android/hardware/ICameraServiceProxy.aidl
interface ICameraServiceProxy{
String getCameraHolder();
}
8、CameraServiceProxy.java
release/frameworks/base/services/core/java/com/android/server/camera/CameraServiceProxy.java
/**
* @hide
*/
public class CameraServiceProxy extends SystemService {
private ICameraService mCameraServiceRaw;
public String getCameraHolderInfo() {
try {
return mCameraServiceRaw.getCameraHolder();
} catch (Exception err) {
return "";
}
}
private final ICameraServiceProxy.Stub mCameraServiceProxy = new ICameraServiceProxy.Stub() {
@Override
public String getCameraHolder() {
try {
return mCameraServiceRaw.getCameraHolder();
} catch (Exception err) {
}
return "err";
}
@Override
public List<String> getUseableCameras() {
return iCameraNames;
}
。。。
}
9、ICameraService.aidl
frameworks/av/camera/aidl/android/hardware/ICameraService.aidl
/**
* @hide
*/
interface ICameraService {
String getCameraHolder();
。。。
}
实现ICameraService的具体代码,过程???
CPP代码
10、CameraService.cpp
/release/frameworks/av/services/camera/libcameraservice/CameraService.cpp
// 关键地方应用是mActiveClientManager.toString()这个字符串吧
// 我也不知道这个holder指针对象是如何返回数据给CameraServiceProxy.java的,可能是代码机制吧。
Status CameraService::getCameraHolder(
String16* holder) {
*holder = String16(mActiveClientManager.toString());
return Status::ok();
}
11、CameraService.h
/release/frameworks/av/services/camera/libcameraservice/CameraService.h
。。。
virtual binder::Status supportsCameraApi(
const String16& cameraId, int32_t apiVersion,
/*out*/
bool *isSupported);
virtual binder::Status getCameraHolder(String16* holder);
写到这里,就可以在上层获取到正在使用者的Camera包名了。
这里写的示例供大家参考,可能对应不同的系统框架会有区别。
共勉:生活要越来越好。
|