【问题标题】:Camera crashing on Android 10 when launching intent启动 Intent 时相机在 Android 10 上崩溃
【发布时间】:2020-02-02 06:30:10
【问题描述】:

我正在尝试将拍照功能添加到我的应用中,这应该相当简单,但是由于某种原因我在 android 10 上遇到了问题。

我遵循https://developer.android.com/training/camera/photobasics 的实现细节(到目前为止,我只实现了应该启动相机应用并返回缩略图位图的基本功能)

这一切都适用于较旧的模拟设备,但是当我在我的物理 Google Pixel 和模拟 Pixel 2(都运行 Android 10)上测试它时,我在调用 startActivity 后崩溃了:

btnCam.setOnClickListener(v -> {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
    }
});

问题是,崩溃的不是我的应用程序,而是相机应用程序。如果我在崩溃后查看 logcat,我会收到以下消息:

2020-02-02 17:11:29.059 15592-15592/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.google.android.GoogleCamera, PID: 15592
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.google.android.GoogleCamera/com.google.android.apps.camera.legacy.app.activity.CaptureActivity}: java.lang.NullPointerException: Attempt to get length of null array
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
     Caused by: java.lang.NullPointerException: Attempt to get length of null array
        at com.google.android.apps.camera.legacy.app.activity.CaptureActivity.onCreate(PG:12)
        at android.app.Activity.performCreate(Activity.java:7802)
        at android.app.Activity.performCreate(Activity.java:7791)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1306)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7356) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 

逻辑上考虑到它与java.lang.NullPointerException: Attempt to get length of null array 崩溃,我想它期待某种我没有提供的输入形式,但是我没有发现任何提及必须提供任何额外参数(我知道你可以指定可选参数指定将生成的照片写入的位置,但没有人说这是必需的)

有人知道这个问题以及如何在 Android 10 上解决它吗?

谢谢

【问题讨论】:

  • 尝试不同的相机应用。店里有很多。
  • 这不是一个真正的选择,我不能强迫我的应用程序的所有用户安装第三方应用程序只是为了使用相机
  • 当然,您只会为自己这样做。只是测试,所以你会知道。用户可以更喜欢不同的相机应用程序,然后您的应用程序也应该可以工作。
  • 是的,但绝大多数用户将拥有默认的相机应用程序,所以这是我需要支持的,而不是随机的第三方应用程序(第三方应用程序是否有效并不重要)
  • 您找到解决问题的方法了吗?我有一个空指针问题,但是当我使用 android 9 和 9 以下而不是 android 10 和 11 时它工作正常,为什么?

标签: android


【解决方案1】:

根据another post,这是相机应用程序中的一个错误,最近已更正。当您使用相机应用拍照时,您的应用无需请求使用相机的权限。

但是,如果您需要在错误修复推出之前让您的应用在 API 29 模拟器或设备上运行,您可以在 AndroidManifest.xml 中添加<uses-permission> 以获得任何类型的权限(甚至是虚假权限) :

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

</manifest>

【讨论】:

  • 伙计!!...你是我的英雄!!!...我已经浪费了很多时间来寻找解决这个尴尬问题的方法!!
【解决方案2】:

首先,您必须检查相机权限,还要在清单文件中添加相机权限。检查代码如下

  1. 在AndroidManifest.xml文件中添加

  2. 检查相机权限。

private static final int CAMERA_REQUEST = 100;  
if(ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA)!=PackageManager.PERMISSION_GRANTED){
      ActivityCompat.requestPermissions(this,
      newString[]{
        Manifest.permission.CAMERA
      },
      MY_CAMERA_PERMISSION_CODE);
    }else{
        Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(cameraIntent, CAMERA_REQUEST);
    }
  1.     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    
            switch (requestCode) {
    
                case MY_CAMERA_PERMISSION_CODE: {
                    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        showPictureDialog();
                    } else {
                        Snackbar snackbar = Snackbar
                                .make(relativeLayout, "Please Allow Permission", Snackbar.LENGTH_LONG)
                                .setAction("Setting", new View.OnClickListener() {
                                    @Override
                                    public void onClick(View view) {
                                        Intent intent = new Intent();
                                        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                        Uri uri = Uri.fromParts("package", getPackageName(), null);
                                        intent.setData(uri);
                                        startActivity(intent);
                                    }
                                });
                        snackbar.show();
                    }
                }
            }
        }
    

4.

     @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        callbackManager.onActivityResult(requestCode, resultCode, data);

         if (requestCode == CAMERA_REQUEST) {
            Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
            circleImageView.setImageBitmap(thumbnail);
            saveImage(thumbnail);
            Toast.makeText(SignUpActivity.this, "Image Saved!", Toast.LENGTH_SHORT).show();
        }
    }
  1. 将图像保存到存储中
    public String saveImage(Bitmap myBitmap) {

        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
        File wallpaperDirectory = new File(Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY);
        // have the object build the directory structure, if needed.
        if (!wallpaperDirectory.exists()) {
            wallpaperDirectory.mkdirs();
        }

        try {
            File f = new File(wallpaperDirectory, Calendar.getInstance()
                    .getTimeInMillis() + ".jpg");
            f.createNewFile();
            FileOutputStream fo = new FileOutputStream(f);
            fo.write(bytes.toByteArray());
            MediaScannerConnection.scanFile(this,
                    new String[]{f.getPath()},
                    new String[]{"image/jpeg"}, null);
            fo.close();
            Log.d("TAG", "File Saved::--->" + f.getAbsolutePath());

            return f.getAbsolutePath();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        return "";
    }

【讨论】:

  • 好吧,现在我很生气,我可以发誓我已经更新了清单文件,并且考虑到它在旧模拟器上运行,我什至没有想过要检查,但就是这样,我错过了愚蠢的相机许可。无论如何,谢谢您的详细回答,我也忘记了请求运行时权限是一件事,所以感谢那个例子。
  • 虽然这个答案确实有关于如何请求权限的有用信息,但提供的解决方案是错误的,因为它不需要相机权限来通过意图调用相机应用程序。接受的答案应该是正下方的@tronman!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多