Android 在 KitKat 上拍摄后相机强制关闭

Android Camera force close after capturing on KitKat

目前我正在创建允许用户拍照并将其显示给 ImageView 的应用程序。它在 Android 5.1.1 Sony M2 Dual 上就像魅力一样。 但是在Kitkat 4.4.2 Samsung Galaxy Tab 3 和KitKat 4.4.4 小米Redmi 2 上,拍照后强制关闭相机

我不知道这是否有用,但我意识到相机可能会强制关闭,因为在捕获后,在这两个 KitKat 设备上,会提示用户是否接受捕获的图片,然后如果被接受,它将回到我现在的 Activity.

因为在我的索尼 5.1.1 上,用户不会被提示拍摄图片,它会直接返回到我当前的 Activity。

这里我包含了相应的代码。

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

    bAddPhoto = (TextView) findViewById(R.id.bAddPhoto);
    bSaveJOLine = (TextView) findViewById(R.id.bSaveJOLine);

    editDescription = (EditText) findViewById(R.id.editDescription);
    editQty = (EditText) findViewById(R.id.editQty);
    editPrice = (EditText) findViewById(R.id.editPrice);
    ivImage = (ImageView) findViewById(R.id.imageTaken);

    Intent intent = getIntent();
    jobId = intent.getIntExtra("jobId", 0);
    docNo = intent.getStringExtra("docNo");

    bAddPhoto.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intentCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            if (intentCamera.resolveActivity(getPackageManager()) != null) {
                // Create the File where the photo should go
                File photoFile = null;
                try {
                    photoFile = createImageFile();
                } catch (IOException ex) {
                    // Error occurred while creating the File
                    Toast.makeText(OJobOrderLineFormActivity.this, "Create file failed!",
                            Toast.LENGTH_SHORT).show();
                }
                // Continue only if the File was successfully created
                if (photoFile != null) {
                    Uri photoURI = FileProvider.getUriForFile(OJobOrderLineFormActivity.this,
                            "com.opentoko.opentokolaundry.fileprovider",
                            photoFile);
                    System.out.println(photoURI);
                    intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                    startActivityForResult(intentCamera, 360);
                }
            }
        }
    });

    bSaveJOLine.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Snackbar.make(v, "Item has been saved!", Snackbar.LENGTH_LONG)
                    .setAction("OK", null).show();
        }
    });

}

创建临时文件函数:

    private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmm").format(new Date());
    String imageFileName = docNo + "_" + timeStamp + "_";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );
    System.out.println(storageDir);
    System.out.println(image);

    // Save a file: path for use with ACTION_VIEW intents
    currentPhotoPath = image.getAbsolutePath();
    System.out.println(currentPhotoPath);

    return image;
}

在Activity结果:

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case 360:
            if(resultCode == RESULT_OK) {
                int targetW = ivImage.getWidth();
                int targetH = ivImage.getHeight();

                // Get the dimensions of the bitmap
                BitmapFactory.Options bmOptions = new BitmapFactory.Options();
                bmOptions.inJustDecodeBounds = true;
                BitmapFactory.decodeFile(currentPhotoPath, bmOptions);
                int photoW = bmOptions.outWidth;
                int photoH = bmOptions.outHeight;

                // Determine how much to scale down the image
                int scaleFactor = Math.min(photoW/targetW, photoH/targetH);

                // Decode the image file into a Bitmap sized to fill the View
                bmOptions.inJustDecodeBounds = false;
                bmOptions.inSampleSize = scaleFactor;
                bmOptions.inPurgeable = true;

                Bitmap bitmap = BitmapFactory.decodeFile(currentPhotoPath, bmOptions);
                ivImage.setImageBitmap(bitmap);
            }
    }
}

我无法真正弄清楚是什么原因造成的,因为在 logcat 中似乎根本没有错误,我的构建仍然像往常一样 运行。 这是我的 logcat 输入当前 activity 拍照后:

D/TextLayoutCache: Enable myanmar Zawgyi converter
D/TextLayoutCache: Enable myanmar Zawgyi converter
D/TextLayoutCache: Enable myanmar Zawgyi converter
D/TextLayoutCache: Enable myanmar Zawgyi converter
I/System.out: /storage/emulated/0/Android/data/com.opentoko.opentokolaundry/files/Pictures
I/System.out: /storage/emulated/0/Android/data/com.opentoko.opentokolaundry/files/Pictures/A-00003_20170127_1758_-1345208956.jpg
I/System.out: /storage/emulated/0/Android/data/com.opentoko.opentokolaundry/files/Pictures/A-00003_20170127_1758_-1345208956.jpg
I/System.out: content://com.opentoko.opentokolaundry.fileprovider/my_images/A-00003_20170127_1758_-1345208956.jpg
W/IInputConnectionWrapper: showStatusIcon on inactive InputConnection

这个logcat已经在这个确切的时间点开始打开相机了。捕获后,没有添加到 logcat.

这是我的一部分 Android-Manifest.xml :

    <uses-feature android:name="android.hardware.camera" android:required="true" />

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

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.opentoko.opentokolaundry.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths">
        </meta-data>
    </provider>

这里有人和我有过或有同样的问题吗?任何解决方案?任何帮助将不胜感激。

我通过反复试验找到了在 KitKat 上关闭 intent camera force close 的解决方案。 看来我根本不需要 FileProvider。

我将 createImageFile() 中的 storageDir 更改为:

File storageDir = getExternalFilesDir("Pictures");

并将 photoURI 添加到此:

Uri photoURI = Uri.fromFile(photoFile);

现在我也可以在 KitKat 上显示正确的全屏图像了。

然后我从我的清单中删除了提供商。现在我在 Android/data/my.package.name/files/Pictures/ folder.

中有了我捕获的图像文件