项目场景:
提示:Android R camera逻辑 从photos->portrait->panorama:
问题camera切换模式时,会先关闭当前模式的摄像头;在新的模式准备好后,重新打开摄像头。
问题描述
提示:从人像到全景切换模式后预览黑屏:
M03D750 05-16 20:30:07.605 565 10480 E android.hardware.camera.provider@2.4-service: 25, vl53l0_open_dev: Error open stmvl53l0_ranging device,error num:No such file or directory
M03D751 05-16 20:30:07.605 565 10480 E android.hardware.camera.provider@2.4-service: 347, tof_ctrl_init: fail to open tof dev
M03D752 05-16 20:30:07.605 565 10480 I android.hardware.camera.provider@2.4-service: 375, tof_ctrl_init: done 6
M03D753 05-16 20:30:07.605 565 10480 E isp_alg_fw: 6553, ispalg_tof_init: fail to do tof init
原因分析:
提示:进入全景模式后,打开摄像头初始化失败(人像模式camera没有完全关闭导致):
此问题是偶现,猜测是因为opencamera和close是异步原因导致
现在根据猜测找到相应位置的代码,输出日志,验证
下面要一步步找到相应的代码
PANORAMA(8,
R.string.mode_panorama,
R.drawable.icon_more_panorama,
R.string.mode_panorama_desc), // 8
看到全景为modeID为8
//然后在CameraActivity.java中打印(这个应该是触发关闭当前和打开下一个模式camera的事件)
@Override
public void switchToMode(int index) {
Log.d("index:="+index);
switchToMode(index, true);
}
//然后调用
@Override
public void switchToMode(int index, boolean disableAnimation) {
if (mCurrentModeIndex != index && mModeStripView != null) {
Log.e("Switch to mode " + index);
onModeSelecting(disableAnimation);
mCameraAppUI.setModeStripViewVisibility(true);
// mCameraAppUI.setModeScrollBarVisibility(true);
mModeStripView.setCurrentModeWithModeIndex(index);
// when restore default from settings need check module changed from PIP to photo.
if (restoreDefaultPreferences &&
mCurrentModeIndex == CapturingMode.PIP_PHOTO.getModuleId() &&
index == CapturingMode.PHOTO.getModuleId()) {
restoreDefaultPreferences = false;
onModeSelected(index);
}
}
}
@Override
public void onModeSelected(final int modeIndex) {
// Record last used camera mode for quick switching
,,,
mModeChangeRunnable.setTargetIndex(modeIndex);
if(CustomUtil.getInstance().getBoolean(CustomFields.DEF_CAMERA_SUPPORT_HELP_TIP_TUTORIAL,false)
&& (mHelpTipsManager != null)){
mHelpTipsManager.notifyModeChanged(modeIndex,mModeChangeRunnable);
}else{
mModeChangeRunnable.run();
}
}
private final ModeChangeRunnable mModeChangeRunnable =new ModeChangeRunnable() {
int updateModeIndex;
@Override
public void run() {
Log.w("close module " + mCurrentModule);
/**
* Pauses the module. Always call this method whenever it's being put in the
* background.
*/
closeModule(mCurrentModule);
updateModeIndex = getPreferredChildModeIndex(mTargetIndex);
setModuleFromModeIndex(updateModeIndex);
Log.w("openModule");
/**
* Resumes the module. Always call this method whenever it's being put in
* the foreground.
*/
openModule(mCurrentModule);
mCurrentModule.onOrientationChanged(mLastRawOrientation);
Log.w("open module " + mCurrentModule);
}
};
解决方案:
提示:如果上述猜测正确,把异步改为同步:
例如:新建一个 Message
对象,并将读取到的数据存入 Message
,然后 mHandler.obtainMessage(READ_DATA, bytes, -1, buffer).sendToTarget();
换成 mHandler.sendMessage()
。