2

我一直在开发一个应用程序来使用手机/平板电脑的相机闪光灯作为手电筒。一切似乎都运行良好,但是当我在运行 Android 4.1.2 的 Droid Bionic 上对其进行测试时,该应用程序无法打开闪光灯,即使它说可以。这是我使用的java代码:

    package com.example.flash;

    import android.app.Activity;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.hardware.Camera;
    import android.hardware.Camera.Parameters;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.Menu;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.Toast;

    public class MainActivity extends Activity {

    private boolean isFlashOn = false;
    private Camera camera;
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    button = (Button) findViewById(R.id.buttonFlashlight);
    Context context = this;
    PackageManager pm = context.getPackageManager();

    if(!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
        Log.e("err", "Device has no camera!");
        Toast.makeText(getApplicationContext(),
        "Your device doesn't have camera!",Toast.LENGTH_SHORT).show();
        return;
        }

    camera = Camera.open();

    final Parameters p = camera.getParameters();

    button.setOnClickListener(new OnClickListener() {
        public void onClick(View arg0) {
            if (isFlashOn) {
            Log.i("info", "torch is turned off!");                   
            p.setFlashMode(Parameters.FLASH_MODE_OFF);
            camera.setParameters(p);                   
            isFlashOn = false;
            button.setText("Tap to turn flashlight on.");
            } 
            else {
            Log.i("info", "torch is turned on!");
            p.setFlashMode(Parameters.FLASH_MODE_TORCH);
            camera.setParameters(p);
            isFlashOn = true;
            button.setText("Tap to turn flashlight off.");
            }
        }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (camera != null) {
        camera.release();
    }

}}

这段代码是正确的还是我错过了什么?

日志猫:

07-03 18:48:29.064: E/Trace(773): error opening trace file: No such file or directory (2)
07-03 18:48:30.535: D/Camera(773): app passed NULL surface
07-03 18:48:31.023: D/libEGL(773): loaded /system/lib/egl/libEGL_emulation.so
07-03 18:48:31.073: D/(773): HostConnection::get() New Host Connection established     0x2a13c3c0, tid 773
07-03 18:48:31.123: D/libEGL(773): loaded /system/lib/egl/libGLESv1_CM_emulation.so
07-03 18:48:31.173: D/libEGL(773): loaded /system/lib/egl/libGLESv2_emulation.so
07-03 18:48:31.406: W/EGL_emulation(773): eglSurfaceAttrib not implemented
07-03 18:48:31.433: D/OpenGLRenderer(773): Enabling debug mode 0
07-03 18:48:31.723: I/Choreographer(773): Skipped 58 frames!  The application may be doing too much work on its main thread.
07-03 18:49:05.923: D/dalvikvm(773): GC_CONCURRENT freed 202K, 12% free 2623K/2956K, paused 74ms+25ms, total 234ms
07-03 18:49:06.216: W/EGL_emulation(773): eglSurfaceAttrib not implemented
07-03 18:49:09.584: D/Camera(773): app passed NULL surface
07-03 18:49:09.853: W/EGL_emulation(773): eglSurfaceAttrib not implemented
07-03 18:49:11.813: I/info(773): torch is turned on!
07-03 18:49:13.467: I/info(773): torch is turned off!
07-03 18:49:16.263: W/EGL_emulation(773): eglSurfaceAttrib not implemented
07-03 18:49:16.713: D/AndroidRuntime(773): Shutting down VM
07-03 18:49:16.713: W/dalvikvm(773): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
07-03 18:49:16.936: E/AndroidRuntime(773): FATAL EXCEPTION: main
07-03 18:49:16.936: E/AndroidRuntime(773): java.lang.RuntimeException: Method called after release()
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.hardware.Camera._stopPreview(Native Method)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.hardware.Camera.stopPreview(Camera.java:543)
07-03 18:49:16.936: E/AndroidRuntime(773):  at com.example.flash.MainActivity.surfaceDestroyed(MainActivity.java:140)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.SurfaceView.updateWindow(SurfaceView.java:553)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:231)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.View.dispatchWindowVisibilityChanged(View.java:7544)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1039)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1039)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1039)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1039)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1211)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.Choreographer.doCallbacks(Choreographer.java:562)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.Choreographer.doFrame(Choreographer.java:532)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.os.Handler.handleCallback(Handler.java:725)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.os.Handler.dispatchMessage(Handler.java:92)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.os.Looper.loop(Looper.java:137)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.app.ActivityThread.main(ActivityThread.java:5041)
07-03 18:49:16.936: E/AndroidRuntime(773):  at java.lang.reflect.Method.invokeNative(Native Method)
07-03 18:49:16.936: E/AndroidRuntime(773):  at java.lang.reflect.Method.invoke(Method.java:511)
07-03 18:49:16.936: E/AndroidRuntime(773):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
07-03 18:49:16.936: E/AndroidRuntime(773):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
07-03 18:49:16.936: E/AndroidRuntime(773):  at dalvik.system.NativeStart.main(Native Method)
07-03 18:49:24.854: E/Trace(811): error opening trace file: No such file or directory (2)
07-03 18:49:25.413: D/libEGL(811): loaded /system/lib/egl/libEGL_emulation.so
07-03 18:49:25.567: D/(811): HostConnection::get() New Host Connection established 0x2a15f570, tid 811
07-03 18:49:25.643: D/libEGL(811): loaded /system/lib/egl/libGLESv1_CM_emulation.so
07-03 18:49:25.663: D/libEGL(811): loaded /system/lib/egl/libGLESv2_emulation.so
07-03 18:49:25.934: W/EGL_emulation(811): eglSurfaceAttrib not implemented
07-03 18:49:25.963: D/OpenGLRenderer(811): Enabling debug mode 0
07-03 18:53:12.298: D/Camera(811): app passed NULL surface
07-03 18:53:12.723: D/dalvikvm(811): GC_CONCURRENT freed 172K, 11% free 2600K/2904K, paused 9ms+165ms, total 421ms
07-03 18:53:12.934: E/EGL_emulation(811): rcCreateWindowSurface returned 0
07-03 18:53:12.934: E/EGL_emulation(811): tid 811: eglCreateWindowSurface(631): error 0x3003 (EGL_BAD_ALLOC)
07-03 18:53:12.943: D/AndroidRuntime(811): Shutting down VM
07-03 18:53:12.943: W/dalvikvm(811): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
07-03 18:53:13.033: E/AndroidRuntime(811): FATAL EXCEPTION: main
07-03 18:53:13.033: E/AndroidRuntime(811): java.lang.RuntimeException: createWindowSurface failed EGL_BAD_ALLOC
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.HardwareRenderer$GlRenderer.createSurface(HardwareRenderer.java:1064)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.HardwareRenderer$GlRenderer.createEglSurface(HardwareRenderer.java:961)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.HardwareRenderer$GlRenderer.initialize(HardwareRenderer.java:787)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1502)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.Choreographer.doCallbacks(Choreographer.java:562)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.Choreographer.doFrame(Choreographer.java:532)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.os.Handler.handleCallback(Handler.java:725)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.os.Handler.dispatchMessage(Handler.java:92)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.os.Looper.loop(Looper.java:137)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.app.ActivityThread.main(ActivityThread.java:5041)
07-03 18:53:13.033: E/AndroidRuntime(811):  at java.lang.reflect.Method.invokeNative(Native Method)
07-03 18:53:13.033: E/AndroidRuntime(811):  at java.lang.reflect.Method.invoke(Method.java:511)
07-03 18:53:13.033: E/AndroidRuntime(811):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
07-03 18:53:13.033: E/AndroidRuntime(811):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
07-03 18:53:13.033: E/AndroidRuntime(811):  at dalvik.system.NativeStart.main(Native Method)
4

2 回答 2

2

更新

我认为关键是您正在运行 Android 4.1.2。从Android 4.0开始,如果要使用Camera Device,即使只想使用flash,也不得不使用SurfaceView。

在上一个答案(如下)中,我为您提供了一个使用 SurfaceView 的 Torch 应用程序的链接。尝试一下或根据您的代码进行调整。

以前的答案:

正如在许多其他情况下(如本例)所述,您可能会遇到在 Android 世界中非常普遍的特定于设备的问题。

尽管getSupportedFlashModes()可能会FLASH_MODE_TORCH在几乎所有设备上返回,但其中许多设备实际上并不支持它。

无论如何,你可以试试这些:

  • camera.startPreview();之后使用camera = Camera.open();
  • 尝试FLASH_MODE_OFF初始设置(之前camera.startPreview();)。
  • 检查此 Torch 应用程序是否适用于您的设备。如果是这样,您可以将其与您的源代码进行比较。
  • 从 Play 商店下载 Torch 应用程序以测试它是否是设备问题。
  • Droid Bionic 支持论坛中发布问题。

更新:我会说final关键字是您的代码中的问题。尝试将其更改为:

//camera = Camera.open();
//final Parameters p = camera.getParameters();

button.setOnClickListener(new OnClickListener() {
    public void onClick(View arg0) {
        if (isFlashOn) {
           Log.i("info", "torch is turned off!");                   
           cam.stopPreview();
           cam.release();
           isFlashOn = false;
           button.setText("Tap to turn flashlight on.");
           } 
        else {
           Log.i("info", "torch is turned on!");
           camera = Camera.open();
           Parameters p = camera.getParameters();
           p.setFlashMode(Parameters.FLASH_MODE_OFF);
           camera.setParameters(p);
           camera.startPreview();
           p.setFlashMode(Parameters.FLASH_MODE_TORCH);
           camera.setParameters(p);
           isFlashOn = true;
           button.setText("Tap to turn flashlight off.");
        }
    }
});
于 2013-06-23T02:23:16.157 回答
0

"android.permission.FLASHLIGHT"使用清单中的权限

<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.CAMERA" />
于 2013-06-23T02:21:21.213 回答