我开发了一个可以打开LED闪光灯的Android应用程序。这似乎适用于大多数手机,但由于该应用程序可从Google Play下载,我在手电筒中收到一些崩溃报告。 我甚至得到了Nexus 5的报告,我有同样的手机,但我没有任何问题。这是我的代码:
private ImageButton mFlashButton;
private Parameters mParams;
private Camera mCamera;
private Thread t;
private ImageView ivRing;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.flashlight_fragment,
container, false);
ivRing = (ImageView) view.findViewById(R.id.ivRing);
// flash switch button
mFlashButton = (ImageButton) view.findViewById(R.id.flashlight_button);
// Switch button click event to toggle flash on/off
mFlashButton.setOnClickListener(mClickListener);
return view;
}
View.OnClickListener mClickListener = new View.OnClickListener() {
public void onClick(View v) {
if (mLightOn) {
turnOffFlash();
} else {
turnOnFlash();
}
}
};
@Override
public void onStart() {
super.onStart();
SurfaceView preview = (SurfaceView) getView().findViewById(R.id.PREVIEW);
SurfaceHolder mHolder = preview.getHolder();
mHolder.addCallback(this);
}
@Override
public void onPause() {
super.onPause();
turnOffFlash(true);
}
// Turning On flash
private void turnOnFlash() {
if (!mLightOn) {
//if camera not found, break
if (mCamera == null || mParams == null) {
Toast.makeText(getActivity(), "Error", Toast.LENGTH_SHORT).show();
} else {
mParams = mCamera.getParameters();
mParams.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(mParams);
mCamera.startPreview();
mLightOn = true;
}
}
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
// Turning Off flash
private void turnOffFlash() {
if (mLightOn) {
//if camera is null, break;
if (mCamera == null || mParams == null) {
Toast.makeText(getActivity(), "Error", Toast.LENGTH_SHORT).show();
} else {
//strobo not running, just turn flash off
mParams = mCamera.getParameters();
mParams.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(mParams);
mCamera.stopPreview();
mLightOn = false;
}
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (mCamera == null) {
//next line forced closed once, should look into this
try {
mCamera = Camera.open();
mParams = mCamera.getParameters();
} catch (Exception e) {
Toast.makeText(getActivity(), "Something went wrong, please restart flashlight", Toast.LENGTH_SHORT).show();
}
try {
mCamera.setPreviewDisplay(holder);
} catch (Exception e) {
mCamera.release();
mCamera = null;
Toast.makeText(getActivity(), "Something went wrong, please restart flashlight", Toast.LENGTH_SHORT).show();
}
}
}
}
这些是我得到的崩溃报告:
java.lang.RuntimeException: setParameters failed
at android.hardware.Camera.native_setParameters(Native Method)
at android.hardware.Camera.setParameters(Camera.java:1650)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
此崩溃报告:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.Camera.setPreviewDisplay(android.view.SurfaceHolder)' on a null object reference
at android.view.SurfaceView.updateWindow(SurfaceView.java:572)
at android.view.SurfaceView.access$000(SurfaceView.java:86)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:175)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:847)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1867)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:996)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5600)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
at android.view.Choreographer.doCallbacks(Choreographer.java:574)
at android.view.Choreographer.doFrame(Choreographer.java:544)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
有没有人有丝毫的线索在这里发生什么?事实上,它不会在我的Nexus 5上崩溃而在另一个上崩溃会让我感到困惑。
提前致谢
答案 0 :(得分:1)
可能有些设备不支持闪存(可能是他们没有闪存)所以为此你首先要检查设备是否支持手电筒。
boolean hasFlash = getApplicationContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
if (!hasFlash) {
// device doesn't support flash
// Show alert message and close the application
AlertDialog alert = new AlertDialog.Builder(context)
.create();
alert.setTitle("Error");
alert.setMessage("Sorry, your device doesn't support flash light!");
alert.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// closing the application or what ever you want if device does not support
finish();
}
});
alert.show();
return;
}
else {
//turn on flash light code here....
}
答案 1 :(得分:1)
mCamera.setPreviewDisplay(holder);
失败了。您正在将NPE调用到另一个方法而不是在方法中处理NPE。