[英]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.1
的Sony Xperia Z2
正常工作。 However, when tested on a Samsung Galaxy S4
running Lollipop 5.0.1
, I have issues. 但是,在运行Lollipop 5.0.1
的Samsung 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.