简体   繁体   English

某些设备的Android相机意图问题

[英]Android camera intent issues with some devices

What I'm trying to do is take a photo using the camera intent, make a note of the URI (I will then use this later to upload the image via Firebase Storage), rotate the image if required, and then display the image in an ImageView . 我想做的是使用相机意图拍照,记下URI(稍后我将用它通过Firebase Storage上传图像),如果需要,旋转图像,然后在一个ImageView This is how I'm doing this at the moment, which works okay on an AVD and on a Sony Xperia Z2 running Marshmallow 6.0.1 . 目前,这就是我的操作方式,在AVD和运行Marshmallow 6.0.1Sony Xperia Z2正常工作。 However, when tested on a Samsung Galaxy S4 running Lollipop 5.0.1 , I have issues. 但是,在运行Lollipop 5.0.1Samsung Galaxy S4上进行测试时,出现了问题。 The code cannot find the image at the specified filepath. 代码无法在指定的文件路径中找到图像。 I have also tried setting the ImageView by using photoURI, and I have also tried commenting out the extras when creating the camera intent, and just getting the data via data.getData() - None of these methods are working. 我还尝试过使用photoURI设置ImageView ,并且还尝试在创建相机意图时注释掉了其他功能,并且仅通过data.getData()获取数据-这些方法均data.getData() I just need a way to get this image from this device without it crashing and ideally without compromising on device compatibility. 我只需要一种从该设备获取此映像而不会崩溃的方法,理想情况下又不会损害设备兼容性。

EDIT: Leading up to the camera intent taking over, both photoFilepath and photoURI have values. 编辑:导致相机意图接管,photoFilepath和photoURI都有值。 As soon as I get to the onActivityResult , both return null. 一旦到达onActivityResult ,两者都将返回null。

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    BitmapFactory.Options opt = new BitmapFactory.Options();
    opt.inSampleSize = 8;
    if (resultCode == RESULT_OK) {
        if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE){
            try {
                Bitmap bit = BitmapFactory.decodeFile(photoFilepath, opt);
                Bitmap rotated = rotateImg(bit, photoFilepath);
                userPhoto.setImageBitmap(rotated);
                contentsOfImageView = rotated;
            } catch (Exception e) {
                e.printStackTrace();
                Toast.makeText(this, "Error retrieving photo, please try again", Toast.LENGTH_LONG).show();
                contentsOfImageView = null;
            }
        } // else if here for handling getting images from gallery
        addBtn.setVisibility(View.INVISIBLE);
        clearBtn.setVisibility(View.VISIBLE);
    } else { // Result was a failure
        //Toast.makeText(this, "Picture wasn't taken!", Toast.LENGTH_SHORT).show();
    }

}

private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.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
            Log.d(TAG, ex.toString());
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            photoURI = FileProvider.getUriForFile(this,
                    "com.example.intheactualcodethisismypackagename",
                    photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
        }
    }
}

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

    // Save a file: path for use with ACTION_VIEW intents
    photoFilepath = image.getAbsolutePath();
    return image;
}

private Bitmap rotateImg(Bitmap before, String path) {
    ExifInterface exif = null;
    try {
        exif = new ExifInterface(path);
    } catch (IOException e) {
        e.printStackTrace();
    }
    int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
    Matrix matrix = new Matrix();
    switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            matrix.setRotate(90);
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            matrix.setRotate(180);
            break;
        case ExifInterface.ORIENTATION_ROTATE_270:
            matrix.setRotate(270);
            break;
        default:
            break;

    }
    return Bitmap.createBitmap(before, 0, 0, before.getWidth(), before.getHeight(), matrix, true);
}

As soon as I get to the onActivityResult, both return null. 一旦到达onActivityResult,两者都将返回null。

Most likely, your process was terminated while your app was in the background and the camera app was in the foreground. 最有可能的是,当您的应用程序在后台而相机应用程序在前台时,您的过程终止了。 This is perfectly normal, though whether it happens on any given ACTION_IMAGE_CAPTURE request will vary. 这是完全正常的,尽管它是否发生在任何给定的ACTION_IMAGE_CAPTURE请求上都会有所不同。

Make sure that you hold onto relevant things, like your Uri and/or File , in the saved instance state Bundle , such as in this sample app : 确保在已保存的实例状态Bundle保持相关的内容,例如Uri和/或File ,例如在此示例应用程序中

/***
 Copyright (c) 2008-2016 CommonsWare, LLC
 Licensed under the Apache License, Version 2.0 (the "License"); you may not
 use this file except in compliance with the License. You may obtain a copy
 of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
 by applicable law or agreed to in writing, software distributed under the
 License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
 OF ANY KIND, either express or implied. See the License for the specific
 language governing permissions and limitations under the License.

 From _The Busy Coder's Guide to Android Development_
 https://commonsware.com/Android
 */

package com.commonsware.android.camcon;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import java.io.File;
import java.util.List;

public class CameraContentDemoActivity extends Activity {
  private static final String EXTRA_FILENAME=
    "com.commonsware.android.camcon.EXTRA_FILENAME";
  private static final String FILENAME="CameraContentDemo.jpeg";
  private static final int CONTENT_REQUEST=1337;
  private static final String AUTHORITY=
    BuildConfig.APPLICATION_ID+".provider";
  private static final String PHOTOS="photos";
  private File output=null;
  private Uri outputUri=null;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent i=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    if (savedInstanceState==null) {
      output=new File(new File(getFilesDir(), PHOTOS), FILENAME);

      if (output.exists()) {
        output.delete();
      }
      else {
        output.getParentFile().mkdirs();
      }
    }
    else {
      output=(File)savedInstanceState.getSerializable(EXTRA_FILENAME);
    }

    outputUri=FileProvider.getUriForFile(this, AUTHORITY, output);

    if (savedInstanceState==null) {
      i.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);

      if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) {
        i.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
      }
      else {
        List<ResolveInfo> resInfoList=
          getPackageManager()
            .queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY);

        for (ResolveInfo resolveInfo : resInfoList) {
          String packageName = resolveInfo.activityInfo.packageName;
          grantUriPermission(packageName, outputUri,
            Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
              Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
      }

      startActivityForResult(i, CONTENT_REQUEST);
    }
  }

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    outState.putSerializable(EXTRA_FILENAME, output);
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode,
                                  Intent data) {
    if (requestCode == CONTENT_REQUEST) {
      if (resultCode == RESULT_OK) {
        Intent i=new Intent(Intent.ACTION_VIEW);

        i.setDataAndType(outputUri, "image/jpeg");
        i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        startActivity(i);
        finish();
      }
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM