阅读我的整个代码。除了Marshmallow
和Lollipop
之外,它在每部手机上都能正常运行。在Marshmallow
和Lollipop
手机中data.getData()
仅在图片捕获的情况下返回null
时出现问题。如果我捕获视频,它工作正常。我有4个案例 -
从图库中选择图片并在Imageview
中显示其缩略图 - 工作正常。
从相机中捕捉图片,并在Imageview
和Marshmallow
及Lollipop
中的Imageview
- 不工作中显示其缩略图。
从图库中选择视频并在Imageview
中显示缩略图 - 工作正常。
3.从相机拍摄视频并在 @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
int THUMBSIZE = 120;
switch (requestCode){
case RESULT_LOAD_IMAGE:
if (resultCode==RESULT_OK){
String column_Name= MediaStore.Images.Media.DATA;
String picturePath=getPath(column_Name,data.getData());
Bitmap orientedBitmap = ExifUtil.rotateBitmap(picturePath, BitmapFactory.decodeFile(picturePath));
Drawable fullpic=new BitmapDrawable(getResources(),ThumbnailUtils.extractThumbnail(orientedBitmap, THUMBSIZE, THUMBSIZE));
thumbnailview.setBackground(fullpic);
editText.setText(picturePath);
picker.setVisibility(View.VISIBLE);
thumbnailview.setClickable(false);
}
break;
case REQUEST_IMAGE_CAPTURE:
if (resultCode==RESULT_OK){
String picturePath="";
String column_Name=MediaStore.Images.Media.DATA;
picturePath=getPath(column_Name,data.getData());
//My app Crashes here because in Marshmallow data.getData() is always null.
Bitmap orientedBitmap = ExifUtil.rotateBitmap(picturePath, BitmapFactory.decodeFile(picturePath));
Drawable fullpic=new BitmapDrawable(getResources(),ThumbnailUtils.extractThumbnail(orientedBitmap, THUMBSIZE, THUMBSIZE));
thumbnailview.setBackground(fullpic);
editText.setText(picturePath);
picker.setVisibility(View.VISIBLE);
thumbnailview.setClickable(false);
}
break;
case RESULT_LOAD_VIDEO:
if (resultCode==RESULT_OK){
String column_Name=MediaStore.Video.Media.DATA;
String videoPath=getPath(column_Name,data.getData());
Drawable fullpic=new BitmapDrawable(getResources(),ThumbnailUtils.createVideoThumbnail(videoPath,MediaStore.Video.Thumbnails.MINI_KIND));
thumbnailview.setBackground(fullpic);
editText.setText(videoPath);
picker.setVisibility(View.VISIBLE);
thumbnailview.setClickable(false);
}
break;
case REQUEST_VIDEO_CAPTURE:
if (resultCode==RESULT_OK){
String column_Name=MediaStore.Video.Media.DATA;
String videoPath=getPath(column_Name,data.getData());
Drawable fullpic=new BitmapDrawable(getResources(),ThumbnailUtils.createVideoThumbnail(videoPath,MediaStore.Video.Thumbnails.MINI_KIND));
thumbnailview.setBackground(fullpic);
editText.setText(videoPath);
picker.setVisibility(View.VISIBLE);
thumbnailview.setClickable(false);
}
break;
}
if (picker != null) {
picker.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
OpenDialog();
}
});
}
}
private String getPath(String column_Name,Uri uri){
String[] projection = {column_Name};
String path = "";
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
int column_index_data ;
if (cursor != null) {
column_index_data = cursor.getColumnIndexOrThrow(column_Name);
cursor.moveToFirst();
path = cursor.getString(column_index_data);
cursor.close();
}
return path;
}
private void OpenDialog(){
dialogBox.setTitle("Select an Action");
dialogBox.setMessage("Choose Picture or Video");
dialogBox.setPositiveButton("Picture", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (check_Permissions()){
OpenCameraDialog();
}
else {
request_Permissions();
CAMERA_DIALOG_PERMISSION=1;
}
}
});
dialogBox.setNegativeButton("Video", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (check_Permissions()){
OpenVideoDialog();
}
else {
request_Permissions();
VIDEO_DIALOG_PERMISSION=1;
}
}
});
dialogBox.show();
}
private void OpenCameraDialog(){
dialogBox.setTitle("Select an Action");
dialogBox.setMessage("Choose Picture From");
dialogBox.setPositiveButton("Gallery", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final Intent galleryintent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryintent, RESULT_LOAD_IMAGE);
}
});
dialogBox.setNegativeButton("Camera", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
});
dialogBox.show();
}
private void OpenVideoDialog(){
dialogBox.setTitle("Select an Action");
dialogBox.setMessage("Choose Video From");
dialogBox.setPositiveButton("Gallery", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final Intent galleryintent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryintent, RESULT_LOAD_VIDEO);
}
});
dialogBox.setNegativeButton("Camera", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE);
}
}
});
dialogBox.show();
}
private boolean check_Permissions(){
boolean GRANTED;
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) +
ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE) +
ContextCompat.checkSelfPermission(this,Manifest.permission.RECORD_AUDIO) +
ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED){
GRANTED=false;
}
else {
GRANTED=true;
}
return GRANTED;
}
private void request_Permissions(){
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO},
REQUEST_FOR_PERMISSION);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case REQUEST_FOR_PERMISSION:
if ((grantResults.length>0)&& (grantResults[0] +grantResults[1]+grantResults[2]+grantResults[3]== PackageManager.PERMISSION_GRANTED)){
if (CAMERA_DIALOG_PERMISSION==1){
OpenCameraDialog();
CAMERA_DIALOG_PERMISSION=0;
}
else if (VIDEO_DIALOG_PERMISSION==1){
OpenVideoDialog();
VIDEO_DIALOG_PERMISSION=0;
}
}
else {
Toast.makeText(this, "Please GRANT Permissions", Toast.LENGTH_SHORT).show();
}
}
}
中显示缩略图 - 工作正常。
现在有很多解决方案,但它们看起来都不令人满意,如果代码在视频捕获的情况下工作正常,那么为什么它不能用于图像捕获?这是一个Bug还是我在某处做错了?
这是我的代码。我已经评论了崩溃发生的一条线 -
frm_childForm obj_childForm = new frm_childForm(this);
obj_childForm.ShowDialog();
答案 0 :(得分:3)
当我们从Android中的Camera捕获图像时,Uri
或data.getdata()
为空。我们有两个解决方案来解决这个问题。
我将在这里实施所有方法,请仔细观察并阅读: -
首先我将讲述如何从Bitmap Image获取Uri: 完整的代码是:
首先我们将通过Intent捕获图像,这两个方法都是相同的,所以这段代码我只会在这里写一次:
// Capture Image
captureImg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, reqcode);
}
}
});
现在我们将实现OnActivityResult :-(对于以上两种方法都是一样的): -
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==reqcode && resultCode==RESULT_OK)
{
Bitmap photo = (Bitmap) data.getExtras().get("data");
ImageView.setImageBitmap(photo);
// CALL THIS METHOD TO GET THE URI FROM THE BITMAP
Uri tempUri = getImageUri(getApplicationContext(), photo);
\\ Show Uri path based on Image
Toast.makeText(LiveImage.this,"Here "+ tempUri, Toast.LENGTH_LONG).show();
\\ Show Uri path based on Cursor Content Resolver
Toast.makeText(this, "Real path for URI : "+getRealPathFromURI(tempUri), Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(this, "Failed To Capture Image", Toast.LENGTH_SHORT).show();
}
}
\现在我们将创建以上所有方法,通过类:
从Image和Cursor方法创建Uri现在来自位图图像的URI路径
private Uri getImageUri(Context applicationContext, Bitmap photo) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(LiveImage.this.getContentResolver(), photo, "Title", null);
return Uri.parse(path);
}
\ Uri来自保存图像的真实路径
public String getRealPathFromURI(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
亲爱的朋友复制并粘贴此代码,然后尝试理解。 如果您正在制作企业应用程序,我百分百肯定这对您更有利。 如果你喜欢我的代码,那就投票给我....
答案 1 :(得分:2)
除了Marshmallow和Lollipop之外,它在每部手机上都能完美运行
不,不是。当用户选择编写良好的相机应用程序来处理ACTION_IMAGE_CAPTURE
请求时,它会在许多Android版本上失败。
你的问题在于:
if (data.getData()!=null){
picturePath=getPath(column_Name,data.getData());}
else {
//My app Crashes here because in Marshmallow data.getData() is always null.
}
这里至少有两个缺陷。
最重要的是假设您从Uri
获得了ACTION_IMAGE_CAPTURE
。 That is not documented,相机应用无需返回Uri
。特别是,在您的结构中,您只能通过getExtra("data")
返回缩略图。如果您想要一张全尺寸的图片,请在EXTRA_OUTPUT
上使用Intent
,在这种情况下,您可以知道图片的存储位置 - 无论您在EXTRA_OUTPUT
中指示哪个位置。
另一个原因是您认为您获得的Uri
来自MediaStore
或其他MediaStore.Video.Media.DATA
列。相机应用不仅不必返回Uri
,而且Uri
不是来自MediaStore
或具有此类列。
答案 2 :(得分:0)
正如@CommonsWare所建议的那样 -
相机应用程序不需要返回uri。
此外,
您需要告诉Camera app在哪里写图像。
所以,我用 -
替换了我的代码 final Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
pictureUri=getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,pictureUri);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
并在onActivityResult
-
case REQUEST_IMAGE_CAPTURE:
if (resultCode==RESULT_OK){
String picturePath="";
String column_Name= MediaStore.Images.Media.DATA;
if (data!=null){
if (data.getData()!=null){
picturePath=getPathfromUri(column_Name,data.getData());}
else {
picturePath= pictureUri.getPath();
}
}
else {
picturePath= pictureUri.getPath();
}}
答案 3 :(得分:0)
您可以从 Bitmap 中获取 Uri
private Uri getImageUri(Context applicationContext, Bitmap bitmapImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.PNG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(MainActivity.this.getContentResolver(), bitmapImage, "Some Title", null);
return Uri.parse(path);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode==CAPTURE_IMAGE_CODE){
Bitmap bitmapImage = (Bitmap) data.getExtras().get("data");
//ImageView.setImageBitmap(photo);
Uri inputImageUri = getImageUri(getApplicationContext(),bitmapImage);
}
}
}
并添加调用此 onClick
private void takeImage(){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, CAPTURE_IMAGE_CODE);
}
}