目前在Android 应用中几乎都会有个人中心的界面,那么也就会有修改头像的基础功能,下面是我从项目中抽取的头像修改的核心代码,实现了拍照、图库两种方式,实现了裁剪功能,并且适配了7.0、8.0、9.0的系统。
1、在AndroidManifest.xml中配置
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.thinta.testwork.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths_public" />
</provider>
2、在res中配置
在res目录下新建xml文件夹,新建一个名为file_paths_public的xml文件,文件内容如下:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
3、核心代码
/**
* 获取图片
* @param activity 上下文
* @param i 0为图库 1为拍照
*/
private fun getPhoto(activity: Activity, i: Int) {
when (i) {
0 -> {
var intent = Intent()
intent.setType("image/*")
intent.setAction(Intent.ACTION_GET_CONTENT);
activity.run {
startActivityForResult(intent, 100)
}
}
1 -> {
var cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (cameraIntent.resolveActivity(mActivity.getPackageManager()) != null) {
mTmpFile =
File(FileUtils.createRootPath(mActivity) + "/" + System.currentTimeMillis() + ".jpg")
FileUtils.createFile(mTmpFile)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
cameraIntent.putExtra(
MediaStore.EXTRA_OUTPUT,
FileProvider.getUriForFile(
mActivity,
"com.thinta.testwork.fileprovider",
mTmpFile
)
);
} else {
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTmpFile));
}
activity.startActivityForResult(cameraIntent, 101)
}
}
}
}
fun getPhotoPath(requestCode: Int, resultCode: Int, data: Intent?) {
if(resultCode == Activity.RESULT_OK){
when(requestCode){
100 -> {
val imagePath: String? = handleImage(data)
crop(imagePath!!)
}
101 -> {
crop(mTmpFile.absolutePath)
}
102 -> {
mphotoView.setImageURI(Uri.fromFile(mCropImageFile))
}
}
}
}
//获取裁剪的图片保存地址
fun getmCropImageFile(): File? {
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES),"temp.jpg");
val file = File(
mActivity.getExternalCacheDir(),
System.currentTimeMillis().toString() + ".jpg"
)
return file
}
return null
}
fun getImageContentUri(file: File): Uri? {
var filePath = file.absolutePath;
var cursor = mActivity.contentResolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
arrayOf(MediaStore.Images.Media._ID),
MediaStore.Images.Media.DATA + "=? ",
arrayOf(filePath), null
)
if (cursor != null && cursor.moveToFirst()) {
var id = cursor.getInt(
cursor
.getColumnIndex(MediaStore.MediaColumns._ID)
)
var baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
} else {
if (file.exists()) {
var values = ContentValues();
values.put(MediaStore.Images.Media.DATA, filePath);
return mActivity.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values
);
} else {
return null;
}
}
}
fun crop(imagePath: String) {
mCropImageFile = getmCropImageFile()!!
val intent = Intent("com.android.camera.action.CROP");
intent.setDataAndType(getImageContentUri(File(imagePath)), "image/*");
intent.putExtra("crop", true);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 500);
intent.putExtra("outputY", 500);
intent.putExtra("scale", true);
intent.putExtra("return-data", false);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mCropImageFile))
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
mActivity.startActivityForResult(intent, 102);
}
fun getImagePath(uri: Uri?, selection: String?): String {
var path= "" ;
var cursor = mActivity.getContentResolver().query(uri, null, selection, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)) as String
}
cursor.close();
}
return path;
}
fun handleImage(data: Intent?): String {
var uri = data!!.getData();
var imagePath = "";
if (Build.VERSION.SDK_INT >= 19) {
if (DocumentsContract.isDocumentUri(mActivity, uri)) {
var docId = DocumentsContract.getDocumentId(uri);
if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
var id = docId.split(":")[1];
var selection = MediaStore.Images.Media._ID + "=" + id;
imagePath =
getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection)
} else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
var contentUri = ContentUris.withAppendedId(Uri.parse("" +
"content://downloads/public_downloads"), docId.toLong(10))
imagePath = getImagePath(contentUri, null)
}
} else if ("content".equals(uri.getScheme())) {
imagePath = getImagePath(uri, null)
}
} else {
imagePath = getImagePath(uri, null)
}
return imagePath;
}
4、FileUtils工具类
package com.thinta.testwork.util;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.util.Log;
import java.io.File;
/*****************************************************
* 版权信息:
* 创建作者:
* 创建日期:
* ****************************************************
* 更改记录: 更新人: 更新时间: 更新概要:
*
* ****************************************************
* 类功能说明:
* ****************************************************/
public class FileUtils {
private static final String TAG = FileUtils.class.getSimpleName();
/**
* 创建根缓存目录
*
* @return
*/
public static String createRootPath(Context context) {
String cacheRootPath = "";
if (isSdCardAvailable()) {
// /sdcard/Android/data/<application package>/cache
cacheRootPath = context.getExternalCacheDir().getPath();
} else {
// /data/data/<application package>/cache
cacheRootPath = context.getCacheDir().getPath();
}
return cacheRootPath;
}
public static boolean isSdCardAvailable() {
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
}
/**
* 递归创建文件夹
*
* @param dirPath
* @return 创建失败返回""
*/
public static String createDir(String dirPath) {
try {
File file = new File(dirPath);
if (file.getParentFile().exists()) {
Log.i(TAG, "----- 创建文件夹" + file.getAbsolutePath());
file.mkdir();
return file.getAbsolutePath();
} else {
createDir(file.getParentFile().getAbsolutePath());
Log.i(TAG, "----- 创建文件夹" + file.getAbsolutePath());
file.mkdir();
}
} catch (Exception e) {
e.printStackTrace();
}
return dirPath;
}
/**
* 递归创建文件夹
*
* @param file
* @return 创建失败返回""
*/
public static String createFile(File file) {
try {
if (file.getParentFile().exists()) {
Log.i(TAG, "----- 创建文件" + file.getAbsolutePath());
file.createNewFile();
return file.getAbsolutePath();
} else {
createDir(file.getParentFile().getAbsolutePath());
file.createNewFile();
Log.i(TAG, "----- 创建文件" + file.getAbsolutePath());
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public static String getApplicationId(Context appContext) throws IllegalArgumentException {
ApplicationInfo applicationInfo = null;
try {
applicationInfo = appContext.getPackageManager().getApplicationInfo(appContext.getPackageName(), PackageManager.GET_META_DATA);
if (applicationInfo == null) {
throw new IllegalArgumentException(" get application info = null, has no meta data! ");
}
Log.d(TAG, appContext.getPackageName() + " " + applicationInfo.metaData.getString("APP_ID"));
return applicationInfo.metaData.getString("APP_ID");
} catch (PackageManager.NameNotFoundException e) {
throw new IllegalArgumentException(" get application info error! ", e);
}
}
}