2017-07-07 37 views
0

此代码在所有Android版本上无法正常工作如何正确获取捕获的位图的uri?

在Android 4.x上正常工作,但在7.0上,此代码无效。代码可以捕获和保存图像,但关于裁剪图像的最后一步:我得到balck屏幕,意味着uri丢失。请在下面的代码后检查截图。

这里是我的演示:

import android.content.ActivityNotFoundException; 
import android.content.Intent; 
import android.graphics.Bitmap; 
import android.net.Uri; 
import android.provider.MediaStore; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.ImageView; 
import android.widget.Toast; 

import java.io.IOException; 

public class CameraCrop1 extends AppCompatActivity { 
    Uri picUri; 
    Bitmap bitmap, bitmap2; 
    ImageView img, img_original; 

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

     img=(ImageView)findViewById(R.id.imageView); 
     img_original=(ImageView)findViewById(R.id.imageView_original); 
    } 

    public void Capture(View view) { 
     Capture_Cam(); 
    } 

    private void Capture_Cam() { 
     Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
     startActivityForResult(cameraIntent, 1); 

    } 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 


     if (requestCode == 1 && resultCode == RESULT_OK && data != null) { 

      picUri = data.getData(); 
      try { 
       // bitmap2 = MediaStore.Images.Media.getBitmap(this.getContentResolver(), picUri); // bitmap2 = original before cur 
       bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse("file://"+picUri)); 
       img_original.setImageBitmap(bitmap); 

      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      performCrop(); 

     } else if (requestCode == 2) { 

      bitmap2=(Bitmap) data.getExtras().get("data"); 
      img.setImageBitmap(bitmap2); 

     }else{ 
      super.onActivityResult(requestCode, resultCode, data); 
     } 

    } 

    private void performCrop(){ 
     try { 

      Intent cropIntent = new Intent("com.android.camera.action.CROP"); 
      //indicate image type and Uri 
      cropIntent.setDataAndType(picUri, "image/*"); 
      cropIntent.putExtra("crop", "true"); 
      cropIntent.putExtra("aspectX", 1); 
      cropIntent.putExtra("aspectY", 1); 
      cropIntent.putExtra("outputX", 100); 
      cropIntent.putExtra("outputY", 100); 
      cropIntent.putExtra("scale", true); 
      cropIntent.putExtra("return-data", true); 
      startActivityForResult(cropIntent, 2); 
      Toast toast = Toast.makeText(this, "Done", Toast.LENGTH_SHORT); 
     } 
     catch(ActivityNotFoundException anfe){ 
      //display an error message 
      String errorMessage = "Whoops - your device doesn't support the crop action!"; 
      Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT); 
      toast.show(); 
     } 

    } 

} 

这里是XML:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/activity_camera_crop1" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="Test.testing.CameraCrop1"> 

    <ImageView 
     android:layout_width="400px" 
     android:layout_height="400px" 
     app:srcCompat="@color/colorAccent" 
     android:id="@+id/imageView" 
     android:layout_alignParentTop="true" 
     android:layout_centerHorizontal="true" /> 

    <Button 
     android:text="Capture Camera" 
     android:onClick="Capture" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/button4" 
     android:layout_alignParentBottom="true" 
     android:layout_centerHorizontal="true" /> 

    <ImageView 
     android:layout_width="400px" 
     android:layout_height="400px" 
     app:srcCompat="@color/wallet_highlighted_text_holo_dark" 
     android:id="@+id/imageView_original" 
     android:layout_below="@+id/imageView" 
     android:layout_alignLeft="@+id/imageView" 
     android:layout_alignStart="@+id/imageView" /> 
</RelativeLayout> 

Screenshot

回答

0

您有FileProvider.getUriForFile(Context, String, File)得到图片的URI得到的URI像content://

对于更多针对Android 7.0(API级别24)及更高版本的应用, 跨包边界传递file:// URI会导致 FileUriExposedException。

看看here,描述如何实现这一点。

+0

我现在得到的路径的这个错误: '无法找到配置的根包含/存储/模拟/ 0 /安卓/数据/测试。测试/文件/图片/ JPEG_20170708_191838_1889413611.jpg' – Biblio

+0

@Biblio你创建了文件提供程序并将其添加到清单中,如教程所示?确保将示例中的软件包替换为应用的实际软件包名称。 – pablobu

0

@pablobu,如果我使用那里的梅索德我得到这个错误:

显示java.lang.NullPointerException:试图调用虚拟方法android.content.res.XmlResourceParser android.content.pm.ProviderInfo

Uri photoURI = FileProvider.getUriForFile(this, // error is here 

:.loadXmlMetaData(android.content.pm.PackageManager,java.lang.String中)”空对象在由该行引用

错误

private void Capture_Cam() { 
    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 

     } 
     // Continue only if the File was successfully created 
     if (photoFile != null) { 
      Uri photoURI = FileProvider.getUriForFile(this, // error is here 
        "com.example.android.fileprovider", 
        photoFile); 
      takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); 
      startActivityForResult(takePictureIntent, 1000); 
     } 
    } 
} 


private File createImageFile() throws IOException { 
    // Create an image file name 
    String timeStamp = null; 
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { 
     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 */ 
    ); 

我修复了错误。新的SDK版本不支持uri格式:“file://”我的意思是TargetVersion。直到版本23支持“文件://” 来源:Found here

+0

你应该更新你的问题或添加评论,而不是添加另一个问题作为答案。 – pablobu

+0

我修复了错误。问题是** TargetVersion **。新版本不支持**“file://”**的更多形式。我已经将版本从25更改为23,然后运行。 – Biblio

+0

这听起来不像一个长期的解决方案 – pablobu