转载请注明出处(万分感谢!):
https://blog.csdn.net/weixin_40790006/article/details/79963508
清单文件注册:
<!--配置内容提供者,注意:authorities,uri的权限--> <provider android:authorities="com.example.f405.cameraphotoalbum" android:name="android.support.v4.content.FileProvider" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths"/> </provider>
<?xml version="1.0" encoding="utf-8"?> <paths> <!--path,。,代表共用--> <root-path name="root_path" path="." /> <external-path name="my_imgs" path = ""/> </paths>
子项文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/tv_takePhoto" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:layout_marginTop="8dp" android:gravity="center" android:text="拍摄照片"/> <TextView android:id="@+id/tv_album" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:layout_marginTop="8dp" android:gravity="center" android:text="从相册选取"/> </LinearLayout>
XML文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.f405.cameraphotoalbum.ChangeTheAvatarActivity"> <ImageButton android:id="@+id/ib_HeadPortrait" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/v"/> </LinearLayout>
Main文件:
package com.example.f405.cameraphotoalbum; import android.Manifest; import android.content.ContentUris; 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.provider.DocumentsContract; import android.provider.MediaStore; import android.support.annotation.NonNull; import android.support.annotation.RequiresApi; 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.View; import android.widget.ImageButton; import android.widget.TextView; import android.widget.Toast; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; /* todo Constant expression required ,switch,必须是常量,不变;解决,+final 注意内容提供者的配置;版本问题——文件权限,uri的解析 */ public class ChangeTheAvatarActivity extends AppCompatActivity { private ImageButton ib_headPortrait; // activity请求码 final int TAKE_PHOTO= 1; final int SELECT_ALBUM= 2; // 权限请求码 final int REQUEST_PERMISSION= 3; private File file; private Uri pathUri; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_change_the_avatar); // 初始化控件 initView(); } private void initView() { ib_headPortrait = (ImageButton) findViewById(R.id.ib_HeadPortrait); // ib_headPortrait.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 弹出对话框,用户选择 createSelectDialog(); } }); } // todo 对话框 private void createSelectDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog dialog = builder.create(); // 子布局——父布局 View view = View.inflate(this,R.layout.item_select,null); TextView tv_takePhoto = (TextView) view.findViewById(R.id.tv_takePhoto); TextView tv_album = (TextView) view.findViewById(R.id.tv_album); // 监听事件 tv_takePhoto.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 拍照 takePhoto(); } }); tv_album.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 相册选择照片 selectAlbum(); } }); // dialog添加布局文件 dialog.setView(view); dialog.show(); } // todo 照相 private void takePhoto() { // 文件存储路径 Uri filePath = saveFile(); Intent take = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); take.putExtra(MediaStore.EXTRA_OUTPUT,filePath); startActivityForResult(take,TAKE_PHOTO); } // 返回类型,uri private Uri saveFile() { try { // 存储位置 file = new File(getExternalCacheDir(),System.currentTimeMillis()+"jasmine.png"); file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } // 判断版本,对应的uri if(Build.VERSION.SDK_INT >= 24){ // 内容提供者,要注册 pathUri = FileProvider.getUriForFile(this,"com.example.f405.cameraphotoalbum",file); }else { pathUri = Uri.fromFile(file); } return pathUri; } // 活动请求的回调 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // 判断请求码,相应的响应结果 switch (requestCode){ case TAKE_PHOTO: if (resultCode == RESULT_OK){ try { Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(pathUri)); ib_headPortrait.setImageBitmap(bitmap); } catch (FileNotFoundException e) { e.printStackTrace(); } } break; case SELECT_ALBUM: if(resultCode == RESULT_OK){ // 根据版本号,解析uri if (Build.VERSION.SDK_INT >= 19){ handleWithKitKat(data); }else { handleWithBeforeKitKat(data); } } break; } } // 19 版本以后 @RequiresApi(api = Build.VERSION_CODES.KITKAT) private void handleWithKitKat(Intent data) { String imagsPath = null; Uri uri = data.getData(); // if (DocumentsContract.isDocumentUri(this,uri)){ String docId = DocumentsContract.getDocumentId(uri); if ("com.android.providers.media.documents".equals(uri.getAuthority())){ // 解析出数字格式的id String id = docId.split(":")[1]; String selection = MediaStore.Images.Media._ID+"="+id; imagsPath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection); }else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())){ Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId)); imagsPath = getImagePath(contentUri,null); } } else if ("content".equalsIgnoreCase(uri.getScheme())){ imagsPath = getImagePath(uri,null); } else if ("file".equalsIgnoreCase(uri.getScheme())){ imagsPath = uri.getPath(); } // 根据图片路径,显示图片 setImageWithAlbum(imagsPath); } // 19 版本以前,4,4 private void handleWithBeforeKitKat(Intent data) { Uri uri = data.getData(); String filePath = getImagePath(uri,null); setImageWithAlbum(filePath); } private void setImageWithAlbum(String imagPath) { if (imagPath != null){ Bitmap bitmap = BitmapFactory.decodeFile(imagPath); ib_headPortrait.setImageBitmap(bitmap); }else { Toast.makeText(this, "failed to get imags", Toast.LENGTH_SHORT).show(); } } private String getImagePath(Uri uri, String selection) { String path = null; // 通过uri,selection,确定真实路径 Cursor cursor = getContentResolver().query(uri,null,selection,null ,null); if (cursor != null){ if (cursor.moveToFirst()){ path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)); } cursor.close(); } return path; } // todo 相册选择照片 private void selectAlbum() { // 权限判断 judgePermission(); } // 权限判断 private void judgePermission() { // 判断权限 if(ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ // 申请权限 ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUEST_PERMISSION); }else { album(); } } // 请求权限的回调 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode){ case REQUEST_PERMISSION: // 判断是否赋予权限 if (grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){ album(); } break; } } // 打开相册 private void album() { Intent intent = new Intent("android.intent.action.GET_CONTENT"); intent.setType("image/*"); startActivityForResult(intent,SELECT_ALBUM); } }