android - 我需要帮助来使用 android cam 和理解 logcat

标签 android camera logcat

我在理解我的应用程序崩溃的 logcat 时遇到了问题。 (我是初学者,我的应用程序只是拍照,然后将其保存在特定文件夹中,但是当我按下应该允许我拍照的按钮时,它崩溃了,我收到了著名的消息( MY_APP_Name 没有响应)

这是MySurfaceView.java中的代码

package android.cam_bouton_save;



private SurfaceHolder holder;
private Camera camera;

public MySurfaceView(Context context, Camera camera)
{
    super(context);
    this.camera = camera;
    holder = getHolder();
    holder.addCallback(this);
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void surfaceChanged(SurfaceHolder holder, 
        int format, int weight, int height)
{
    if (holder.getSurface() == null)
        return;
    try
    {
        camera.stopPreview();
        camera.setPreviewDisplay(holder);
        camera.startPreview();
    }
    catch (Exception e){}
}

public void surfaceCreated(SurfaceHolder holder)
{
    try
    {
        camera.setPreviewDisplay(holder);
        camera.startPreview();
    }
    catch (IOException e){}
}

public void surfaceDestroyed(SurfaceHolder holder){}

这是日志猫:

05-14 17:15:04.216: E/AndroidRuntime(1123): FATAL EXCEPTION: main
05-14 17:15:04.216: E/AndroidRuntime(1123): java.lang.NullPointerException
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.cam_bouton_save.MySurfaceView.surfaceCreated(MySurfaceView.java:42)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.SurfaceView.updateWindow(SurfaceView.java:532)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.SurfaceView.dispatchDraw(SurfaceView.java:339)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.View.draw(View.java:6743)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.widget.FrameLayout.draw(FrameLayout.java:352)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.View.draw(View.java:6743)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.widget.FrameLayout.draw(FrameLayout.java:352)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1842)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewRoot.draw(ViewRoot.java:1407)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1163)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.os.Looper.loop(Looper.java:123)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.app.ActivityThread.main(ActivityThread.java:4627)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at java.lang.reflect.Method.invokeNative(Native Method)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at java.lang.reflect.Method.invoke(Method.java:521)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at dalvik.system.NativeStart.main(Native Method)

你能帮帮我吗?

    package android.cam_bouton_save;
      public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);

        Button bouton = (Button) findViewById(R.id.btn_photo);
    //  camera = Camera.open();
        mySurfaceView = new MySurfaceView(this, camera);
        final FrameLayout myPreview = (FrameLayout) findViewById(R.id.preview);
        myPreview.addView(mySurfaceView);

        bouton.setOnClickListener(new View.OnClickListener()  {
      //  @Override
         public void onClick(View actuelView)   {
            /* //camera.open();
            // camera.getParameters();*/

            camera = Camera.open();

        /*   camera = Camera.open();
             Parameters parameters = camera.getParameters();
             parameters.setPictureFormat(PixelFormat.JPEG);
             camera.setParameters(parameters);
            // camera.setPreviewDisplay(surfaceHolder);
             camera.startPreview();*/
            camera.takePicture(shutterCallback, rawCallback, myPictureCallback_JPG);
         } 
      });

    }


      // Called when shutter is opened
      ShutterCallback shutterCallback = new ShutterCallback() {
          public void onShutter() {
             //Log.d(TAG, "onShutter'd");
      }
    };

        PictureCallback rawCallback = new PictureCallback() {
            public void onPictureTaken(byte[] data, Camera camera) {
      } 
    };

        PictureCallback myPictureCallback_JPG = new PictureCallback(){
            public void onPictureTaken(byte[] arg0, Camera arg1) {

                int imageNum = 0;
                Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

                //Gets the Android external storage directory
                File imagesFolder = new File(Environment.getExternalStorageDirectory(), "Punch");
                imagesFolder.mkdirs(); // <----
                String fileName = "image_" + String.valueOf(imageNum) + ".jpg";
                File output = new File(imagesFolder, fileName);
                while (output.exists()){
                    imageNum++;
                    fileName = "image_" + String.valueOf(imageNum) + ".jpg";
                    output = new File(imagesFolder, fileName);
                }
                Uri uriSavedImage = Uri.fromFile(output);
                imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);


                OutputStream imageFileOS;
                try {
                    imageFileOS = getContentResolver().openOutputStream(uriSavedImage);
                    imageFileOS.write(arg0);
                    imageFileOS.flush();
                    imageFileOS.close();

                    Toast.makeText(Cam_bouton_save_picActivity.this, 
                            "Image saved: ", 
                            Toast.LENGTH_LONG).show();
                    camera.release() ;
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

         //       camera.startPreview();
            }};
}           

最佳答案

您的 LogCat 表示您在 Activity 类的第 36 行的 onClick 方法中收到了一个 NullPointerException:m Cam_bouton_save_picActivity.java:36

只是猜测,但也许您的 Camera 实例为空。发生这种情况最常见的原因是 androidManifest.xml 中缺少权限,因此请确保您已包含它:

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

另请注意,如果您想将拍摄的照片保存到 SD 卡中,您还需要其他权限:

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

编辑 1:感谢代码!

很明显,您需要初始化您的 camera 成员!如果不对其进行初始化,这就是最终导致 NullPointerException 的弱点。

在您的onCreate 方法中您应该有这一行:

camera = Camera.open();

如果正确执行,您将不会再获得 NPE。

编辑 2:对于相机预览:-已删除-

编辑 3: 如果您遇到新问题并需要帮助,请在未来提出新问题,而不是修改现有问题。此答案已与您的原始问题无关。

请记住,StackOverflow 是关于特定问题的答案,而不是解决特定人员的所有问题。

这是一个小型且非常有针对性的示例应用程序,展示了如何拍摄连续的相机照片并将它们保存在 SD 卡上:

public class AndroidCamera extends Activity implements 
    SurfaceHolder.Callback, View.OnClickListener
{
    private static final String TAG = "CS";
    private Camera camera;
    private SurfaceView surface;
    private SurfaceHolder holder;
    private boolean isPreview = false;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        surface = (SurfaceView) findViewById(R.id.preview);
        holder = surface.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        final Button shotButton = (Button) findViewById(R.id.btn_shot);
        shotButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View v)
    {
        camera.takePicture(shutterCallback, rawCallback, jpgCallback);
    }

    ShutterCallback shutterCallback = new ShutterCallback()
    {
        @Override
        public void onShutter()
        {}
    };

    PictureCallback rawCallback = new PictureCallback()
    {
        @Override
        public void onPictureTaken(byte[] arg0, Camera arg1)
        {}
    };

    PictureCallback jpgCallback = new PictureCallback()
    {
        @Override
        public void onPictureTaken(byte[] arg0, Camera arg1)
        {
            if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
            {
                final String imageDir =
                        Environment.getExternalStorageDirectory() + 
                        File.separator + "Punch" + File.separator;
                int counter = 0;
                String imageName = "image_" + counter + ".jpg";
                File outputFile = new File(imageDir, imageName);
                if (!outputFile.getParentFile().exists())
                    outputFile.getParentFile().mkdirs();
                while (outputFile.exists())
                {
                    counter++;
                    imageName = "image_" + counter + ".jpg";
                    outputFile = new File(imageDir, imageName);
                }
                Uri uriSavedImage = Uri.fromFile(outputFile);
                OutputStream imageFileOS;
                try
                {
                    imageFileOS = getContentResolver().openOutputStream(uriSavedImage);
                    imageFileOS.write(arg0);
                    imageFileOS.flush();
                    imageFileOS.close();

                    Log.w(TAG, "Image saved: " + uriSavedImage.toString());
                    camera.startPreview();
                }
                catch (FileNotFoundException e)
                {
                    Log.e(TAG, "onPictureTaken", e);
                }
                catch (IOException e)
                {
                    Log.e(TAG, "onPictureTaken", e);
                }
            }
        }
    };

    @Override
    public void surfaceChanged(SurfaceHolder sHolder, int format, int width, int height)
    {
        if (isPreview)
        {
            try
            {
                camera.stopPreview();
                isPreview = false;
            }
            catch (Exception e)
            {
                Log.e(TAG, "surfaceChanged", e);
            }
        }

        if (camera != null)
        {
            try
            {
                camera.setPreviewDisplay(holder);
                camera.startPreview();
                isPreview = true;
            }
            catch (IOException e)
            {
                Log.e(TAG, "surfaceChanged", e);
                releaseCamera();
            }
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder)
    {
        try
        {
            camera = Camera.open();
        }
        catch (Exception e)
        {
            Log.e(TAG, "surfaceCreated Camera.open()", e);
            releaseCamera();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder)
    {
        releaseCamera();
    }

    private void releaseCamera()
    {
        try
        {
            camera.stopPreview();
            camera.release();
            camera = null;
            isPreview = false;
        }
        catch (Exception e)
        {
            Log.e(TAG, "releaseCamera", e);
        }
    }
}

为此你只需要一个非常简单的布局(main.xml):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <SurfaceView android:id="@+id/preview"
        android:layout_width="fill_parent" android:layout_height="wrap_content"/>
    <Button android:id="@+id/btn_shot" android:text="Shot!"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true" />
</RelativeLayout>

我希望它足够清楚:)

关于android - 我需要帮助来使用 android cam 和理解 logcat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10585533/

相关文章:

java - 将 json 部分反序列化为 POJO,但保留一些原始 json 作为字段

ios - camera.activeFormat 未得到应用

android - 如何一次使用多个标签过滤 Android adb shell logcat?

android - IntelliJ/AS - 如何一键切换Logcat过滤器?

android - Listview 滚动 Android 上的问题

java - 如何在Android手机上制作RTSP服务器?

android - Android 上的 WebView 动画问题

c++ - Opengl 鼠标相机问题 (gluLookAt)

java - 安卓全屏摄像头

android - 崩溃/重新安装后 LogCat 不显示任何内容