Android 10上动用相机和图库 并且返回裁剪图片遇到的问题 记录一下:各种报错,
1.exposed beyond app through Intent.getData()
2.java.lang.IllegalArgumentException: URI is not absolute
3.android.os.FileUriExposedException: file:///storage/emulated/0
4.exposed beyond app through ClipData.Item.getUri()
网上找了一大圈,报错原因 大概如下 ,动态权限没有申请, Android N(对应sdk24)(版本7.0)及以上对访问文件权限收回,还有其他之类的错误原因,直接上代码 ,在Android 10 ,Android 8.1,Android5.1真机上已验证ok
AndroidManifest.xml新增 code
file_paths文件 path=".",我的理解是Environment.getExternalStorageDirectory()所在的目录,name可以任意取
类代码
package test.xxx.com.myapplication;
import android.Manifest;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
public class AddM1Activity extends AppCompatActivity {
private EditText name1;
private EditText number1;
private ImageView icon;
private Button bt_save, bt_cancel;
private AlertDialog.Builder builder;
private AlertDialog dialog;
public static final int NONE = 0;
public static final int CAMERA = 11;// 拍照
public static final int PHOTO =22;
public static final int CAMERAZOOM = 33; // 相机拍照缩放
public static final int PHOTOZOOM = 44;//照片缩放
public static final int PHOTORESOULT = 55;// 结果
public static final String IMAGE_UNSPECIFIED = "image/*";
private static final String TAG = "AddM1Activity";
private static final int WRITE_PERMISSION = 0x01;
private Uri uritempFile=null;
private String cameraSavePath=null;
String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CAMERA,Manifest.permission.READ_EXTERNAL_STORAGE};
List mPermissionList = new ArrayList<>();
private static final int PERMISSION_REQUEST = 1010;
private void initPermission(){
mPermissionList.clear();
/**
* 判断哪些权限未授予
*/
for (int i = 0; i < permissions.length; i++) {
if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
mPermissionList.add(permissions[i]);
}
}
/**
* 判断是否为空
*/
if (mPermissionList.isEmpty()) {//未授予的权限为空,表示都授予了
} else {//请求权限方法
String[] permissions = mPermissionList.toArray(new String[mPermissionList.size()]);//将List转为数组
ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST);
}
}
private Message message = null;
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1000:
Bitmap bitmap = (Bitmap) msg.obj;
icon.setImageBitmap(bitmap);
break;
case 1001:
icon.setImageBitmap(BitmapFactory.decodeResource(
getResources(), R.mipmap.ic_add_contact_holo_light));
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_m1);
name1 = (EditText) findViewById(R.id.quick_name);
number1 = (EditText) findViewById(R.id.quick_number);
icon = (ImageView) findViewById(R.id.iv_icon);
bt_save = (Button) findViewById(R.id.bt_save);
bt_cancel = (Button) findViewById(R.id.bt_cancel);
initPermission();
File f = new File(Environment.getExternalStorageDirectory()
, "qwert.jpg");
if (f.exists()) {
// Bitmap bitmap=BitmapFactory.decodeFile(f.getPath());
// icon.setImageBitmap(bitmap);
}
name1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
number1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
icon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectOperator();
}
});
bt_save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
bt_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
}
private void saveimage(Bitmap bmp){
File f = new File(Environment.getExternalStorageDirectory()
, "qwert.jpg");
try {
FileOutputStream fos = new FileOutputStream(f);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
System.out.println("111111111111111111==="+f.length());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Intent intent =getIntent();
String action=intent.getStringExtra("android_manage_type");
if(action!=null)
{
if(action.equals("add"))
{
setTitle(R.string.add_m1_tilte);
name1.setText("");
number1.setText("");
}
}
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
if(dialog!=null){
dialog.dismiss();
}
}
private void openCamera(){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraSavePath =Environment.getExternalStorageDirectory()+ File.separator + "Android"+File.separator+"xx.jpg";
File f_camera =new File(cameraSavePath);
Uri uri_camera;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//test.xxx.com.myapplication.fileprovider 是在清单文件配置的 android:authorities
uri_camera = FileProvider.getUriForFile(this, "test.xxx.com.myapplication.fileprovider", f_camera);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
System.out.println("openCamera cameraSavePath length=="+f_camera.length());
}else {
uri_camera = Uri.fromFile(f_camera);
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri_camera);
startActivityForResult(intent, CAMERA);
}
private void choosePhoto() {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
IMAGE_UNSPECIFIED);
startActivityForResult(intent, PHOTO);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST:
break;
default:
break;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
private void startPhotoZoom2(Uri uri) {
// 调用系统中自带的图片剪裁
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
uritempFile = Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory()+ File.separator + "Android" + "/icon_temp1.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// outputX outputY 是裁剪图片宽高
intent.putExtra("outputX", 250);
intent.putExtra("outputY", 250);
intent.putExtra("return-data", true);
startActivityForResult(intent, PHOTOZOOM);
}
/**
* 调用系统裁剪的方法
*/
private void startPhoneZoom(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
intent.setDataAndType(uri, "image/*");
//是否可裁剪
intent.putExtra("corp", "true");
//裁剪器高宽比
intent.putExtra("aspectY", 1);
intent.putExtra("aspectX", 1);
//设置裁剪框高宽
intent.putExtra("outputX", 150);
intent.putExtra("outputY", 150);
// Uri temp =Uri.parse(cameraSavePath); //Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath() + "/" + System.currentTimeMillis() + ".jpg");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri temp =Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath()+ File.separator + "Android"+File.separator+"xx.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, temp);
}
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
//返回数据
intent.putExtra("return-data", true);
startActivityForResult(intent, CAMERAZOOM);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
System.out.println("onActivityResult== requestCode="+requestCode+" data ="+data);
// 读取相册缩放图片
if (requestCode == PHOTO) {
startPhotoZoom2(data.getData());
}else if(requestCode==PHOTOZOOM){
File file = null;
try {
file = new File(new URI(uritempFile.toString()));
} catch (URISyntaxException e) {
e.printStackTrace();
}
System.out.println("uritempFile.toString()=="+uritempFile.toString()+" "+file.length());
Bitmap photo = BitmapFactory.decodeFile(file.toString());
saveimage(photo);
message =new Message();
message.what=1000;
message.obj =photo;
handler.sendMessageDelayed(message, 100);
}else if(requestCode==CAMERAZOOM){
Bitmap photo=null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
File file = null;
Uri temp =Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath()+ File.separator + "Android"+File.separator+"xx.jpg");
try {
file = new File(new URI(temp.toString()));
} catch (Exception e) {
e.printStackTrace();
}
photo = BitmapFactory.decodeFile(file.toString());
}else{
File f =new File(cameraSavePath);
System.out.println("文件大小 =="+f.length());
photo = BitmapFactory.decodeFile(f.toString());
}
saveimage(photo);
message =new Message();
message.what=1000;
message.obj =photo;
handler.sendMessageDelayed(message, 100);
System.out.println("qqqqqqqqqq =");
}else if(requestCode==CAMERA){
//相机返回结果
File mAvatarFile = new File(cameraSavePath);
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//test.xxx.com.myapplication.fileprovider 是在清单文件配置的 android:authorities
uri = FileProvider.getUriForFile(this, "test.xxx.com.myapplication.fileprovider", mAvatarFile);
System.out.println("open camera 2222222 mAvatarFile length=="+mAvatarFile.length());
}else {
uri = Uri.fromFile(mAvatarFile);
}
startPhoneZoom(uri);
System.out.println("uritempFile.toString()==");
}
super.onActivityResult(requestCode, resultCode, data);
}
private void selectOperator(){
List list = new ArrayList();
list.add(0, getString(R.string.title_gallery));
list.add(1, getString(R.string.title_camera));
if (new Utils(this).icon_temp_01_exists()) {
list.add(2, getString(R.string.title_remove));
}
builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.slelect_title));
builder.setItems(list.toArray(new String[list.size()]), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0) {
choosePhoto();
} else if (which == 1) {
openCamera();
}else{
/*new Utils(AddM1Activity.this)
.deleteIcon_temp_01();
//deleteIcon_temp();
message =new Message();
message.what=1001;
handler.sendMessageDelayed(message, 100);*/
}
}
});
builder.setCancelable(true);//
builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
System.out.println("clicked----"+keyCode);
dialog.dismiss();
// finish();
return false;
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
System.out.println("click onCancel");
}
});
builder.create().show();
}
}