使用相机闪光灯作为手电筒的应用程序使用 Eclipse 不工作

Posted

技术标签:

【中文标题】使用相机闪光灯作为手电筒的应用程序使用 Eclipse 不工作【英文标题】:App using camera flash as a torch using Eclipse not working 【发布时间】:2013-06-19 20:54:36 【问题描述】:

我一直在开发一款将手机/平板电脑的相机闪光灯用作手电筒的应用。一切似乎都运行良好,但是当我在运行 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();
    


这段代码是正确的还是我遗漏了什么?

Logcat:

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)

【问题讨论】:

您的 LogCat 说什么?你在其他设备上测试过吗? 它不显示任何错误。当我单击模拟器上的按钮时,它还会显示“手电筒已打开”或“手电筒已关闭”。我无法在其他设备上测试它,因为我没有其他运行 android 并有相机闪光灯的设备。 如果在声明“参数 p”时删除关键字 final 会发生什么? 当我删除关键字 final 时,当我稍后使用“p”时会收到多条错误消息。 【参考方案1】:

更新

我认为关键是您运行的是 Android 4.1.2。从Android 4.0开始,如果你想使用Camera Device,即使你只想使用闪光灯,也不得不使用SurfaceView。

在上一个答案(如下)中,我给了你一个指向Torch app which uses SurfaceView 的链接。尝试一下或根据您的代码调整它。

以前的答案:

正如在许多其他情况 (like this one) 中所述,您可能会遇到在 Android 世界中非常常见的特定于设备的问题。

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

不管怎样,你可以试试这些:

camera = Camera.open(); 之后使用camera.startPreview(); 最初尝试设置FLASH_MODE_OFF(在camera.startPreview();之前)。 检查this Torch app 是否在您的设备中工作。如果确实如此,您可以将其与您的源代码进行比较。 从 Play 商店下载 Torch 应用以测试是否是设备问题。 在Droid Bionic support forum 中发布问题。

更新:我想说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.");
        
    
);

【讨论】:

我按照您的建议进行了更改,但仍然无效。我还在 Play 商店中安装了该应用程序和另一个应用程序。您推荐的应用程序在我的手机上根本无法运行,但另一个运行良好...... This guy 是 TeslaLED 的开发者。在您的设备中尝试该应用程序。如果有效,请尝试this code(他告诉那里他正在使用它)。 我对此很陌生,所以请耐心等待...我用相应的代码替换了新代码,但它无法识别 cam 变量。它应该自然地认识到这一点还是我需要在某个地方声明它? 您必须声明它,就像您在原始代码中使用“私人相机相机”所做的那样;声明。 改代码声明私有Camera cam还是不行;【参考方案2】:

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

<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.CAMERA" />

【讨论】:

我已经将它们与 一起包含在我的清单文件中,对吗?

以上是关于使用相机闪光灯作为手电筒的应用程序使用 Eclipse 不工作的主要内容,如果未能解决你的问题,请参考以下文章

我需要啥权限才能在相机预览中使用相机闪光灯?

无法连接到手电筒小部件中的相机服务

在Android中打开相机闪光灯LED? [复制]

如何在不破坏相机应用程序的情况下在Android手机上打开手电筒[重复]

Android系统之路(初识MTK) ------Android11.0给系统相机添加闪光灯低电Toast提醒

Android系统之路(初识MTK) ------Android11.0给系统相机添加闪光灯低电Toast提醒