选择一张照片或拍照并使用 onActivityResult() 两者都不起作用
Posted
技术标签:
【中文标题】选择一张照片或拍照并使用 onActivityResult() 两者都不起作用【英文标题】:Pick a photo or take a photo and use onActivityResult() for both not working 【发布时间】:2015-09-29 00:33:20 【问题描述】:我正在尝试创建一个可以拍摄新照片或使用现有照片的应用。我让这两个功能分开工作,但不能一起工作。 Uri imageUri = data.getData();
运行时应用程序崩溃。
代码如下:
public void btnPhotoClicked(View v)
//Use to invoke a Camera
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//Create a variable with the filepath generated by the android operating system, Like a baws
File pictureDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
if (pictureDirectory.exists())
File test1 = new File(pictureDirectory, "100MEDIA/");
if (test1.exists())
pictureDirectory = test1;
else
File test2 = new File(pictureDirectory, "100ANDRO/");
if (test2.exists())
pictureDirectory = test2;
else
File test3 = new File(pictureDirectory, "Camera/");
if (!test3.exists())
test3.mkdirs();
pictureDirectory = test3;
else
pictureDirectory = new File(pictureDirectory, "Camera/");
pictureDirectory.mkdirs();
String pictureName = getPictureName();
File imageFile = new File(pictureDirectory, pictureName);
Uri pictureUri = Uri.fromFile(imageFile);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, pictureUri);
//Start intent and anticipate result
startActivityForResult(cameraIntent, CAMERA_RESULT);
这是protected void onActivityResult(int requestCode, int resultCode, Intent data)
的代码
protected void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK)
//if we are here everything processed successfully
if (requestCode==IMAGE_GALLERY_REQUEST)
//If we are here we came from the Välj existerande build
Log.d("MainActivity", data.toString());
Toast.makeText(this, "IMAGE GALLERY_REQUEST", Toast.LENGTH_LONG).show();
//the address of the image on the device SD-card
Uri imageUri = data.getData();
//Declare a stream to read the image data from the SD-card
InputStream inputStream;
//Getting a Input stream based upon the image uri
try
//if it execute flawlessly
inputStream = getContentResolver().openInputStream(imageUri);
Bitmap image = BitmapFactory.decodeStream(inputStream);
//show the image to the user
mImageView.setImageBitmap(image);
catch (FileNotFoundException e)
//show massage saying if the image is unavailable
Toast.makeText(this, "Could not open image", Toast.LENGTH_LONG).show();
else if (requestCode == CAMERA_RESULT)
//We are here because we have received a result from the camera
Toast.makeText(this, "CAMERA RESULT", Toast.LENGTH_LONG).show();
Log.d("MainActivity", data.toString());
//the address of the image on the device SD-card
Uri imageUri = data.getData();
//Declare a stream to read the image data from the SD-card
InputStream inputStream;
//Getting a Input stream based upon the image uri
try
//if it execute flawlessly
inputStream = getContentResolver().openInputStream(imageUri);
Bitmap image = BitmapFactory.decodeStream(inputStream);
//show the image to the user
mImageView.setImageBitmap(image);
catch (FileNotFoundException e)
//show massage saying if the image is unavailable
Toast.makeText(this, "Could not open image", Toast.LENGTH_LONG).show();
【问题讨论】:
会发生什么?你有什么错误吗?你能在这里分享错误的logcat吗? :) 赢得死亡:窗口4333a8f8 u0 com.example.akerberge.greifincident/com.example.akerberge.greifincident.MainActivity 【参考方案1】:试试这个代替图片uri
if (resultCode == RESULT_OK)
if (requestCode == 1)
File f = new File(Environment.getExternalStorageDirectory().toString());
for (File temp : f.listFiles())
if (temp.getName().equals(tempFile))
f = temp;
//File photo = new File(Environment.getExternalStorageDirectory(), tempFile);
break;
try
Bitmap bitmap;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeFile(f.getAbsolutePath(),bitmapOptions);
final int THUMBNAIL_SIZE = 100;
bitmap = Bitmap.createScaledBitmap(bitmap,THUMBNAIL_SIZE, THUMBNAIL_SIZE, false);
img.setImageBitmap(bitmap);
String path = android.os.Environment.getExternalStorageDirectory()+ File.separator;
File file = new File(path,tempFile);
updPath=file.toString();
imgSel = true;
success=true;
catch (Exception e)
Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
else if (requestCode == 2)
try
Uri selectedImage = data.getData();
String[] filePath = MediaColumns.DATA ;
Cursor c = getContentResolver().query(selectedImage,filePath, null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePath[0]);
String picturePath = c.getString(columnIndex);
c.close();
File outputPath= new File(android.os.Environment.getExternalStorageDirectory(), tempFile);
updPath = outputPath.toString();
copyFile(picturePath, updPath);
Bitmap thumbnail = (BitmapFactory.decodeFile(updPath));
final int THUMBNAIL_SIZE = 100;
thumbnail = Bitmap.createScaledBitmap(thumbnail,THUMBNAIL_SIZE, THUMBNAIL_SIZE, false);
ByteArrayOutputStream bytearroutstream = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 100,bytearroutstream);
img.setImageBitmap(thumbnail);
imgSel = true;
success=true;
catch (Exception e)
Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
【讨论】:
使用 File 类代替 Uri 不要使用整个代码,只需尝试其中的一部分并相应地更改您的代码【参考方案2】:只有在返回的 Intent 中传回缩略图时,默认的 Android 相机应用才会返回非空 Intent。如果您将 EXTRA_OUTPUT
与要写入的 URI 一起传递,它将返回 null
意图,并且图片在您传入的 URI 中。
您可以通过查看 GitHub 上的相机应用源代码来验证这一点:
https://github.com/android/platform_packages_apps_camera/blob/gingerbread-release/src/com/android/camera/Camera.java#L1186其中您的应用程序崩溃。因为getContentResolver().openInputStream(imageUri)
调用空对象的方法。 imageUri
为空。
来自documentation:
公共静态最终字符串EXTRA_OUTPUT
在 API 级别 3 中添加Intent-extra 的名称,用于指示用于存储请求的图像或视频的内容解析器 Uri。
常量值:“输出”
所以,你调用 ACTION_IMAGE_CAPTURE
意图,你应该像这样传递额外的:
Intent photo = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri uri = Uri.parse("file:///sdcard/photo.jpg");
photo.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(takePicture,requestCode);
然后在onActivityResult:
if (requestCode == CAMERA_REQUEST_CODE)
if (resultCode == Activity.RESULT_OK)
File file = new File(Environment.getExternalStorageDirectory().getPath(), "photo.jpg");
Uri uri = Uri.fromFile(file);
Bitmap bitmap;
try
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
bitmap = crupAndScale(bitmap, 300); // if you mind scaling
pofileImageView.setImageBitmap(bitmap);
catch (FileNotFoundException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
更新
【讨论】:
在这个答案中图片是什么-----> picture.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);Uri uri = Uri.parse("file:///sdcard/photo.jpg");
- 这是您的图像文件的 URI。在此文件中将保存来自相机的图像数据
对不起。我修正了这个错误
这里的问题是我无法从 else if 中接收到照片,因为我需要知道确切的名称
@EdvardÅkerberg,什么名字?您可以将其定义为常量,例如public static final String BUFFER_PHOTO_FILE = "file:///sdcard/blablabla.jpg"
,并在需要时使用它。我不明白你的问题。请更详细地描述它。我真的很想帮助你,但是,我不明白你。为什么需要知道确切的名称以及为什么不能使用像 BUFFER_PHOTO_FILE 这样的默认名称?以上是关于选择一张照片或拍照并使用 onActivityResult() 两者都不起作用的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法将 segue 操作延迟到用户通过他们的照片库选择图像或拍照之后?迅速