Android 項(xiàng)目實(shí)戰(zhàn)之頭像選擇功能
一、圖片選擇
1.1 目標(biāo)
1.實(shí)現(xiàn)如圖所示功能:能夠出現(xiàn)相冊(cè)和相機(jī)選項(xiàng)
2.能夠?qū)x擇的圖片進(jìn)行裁剪
1.2 功能實(shí)現(xiàn)
1.2.1 Intent工具類封裝
封裝圖片選擇和圖片裁剪的工具類
/**
* 選擇圖片(從相冊(cè)或相機(jī))
* @param uri 相機(jī)存儲(chǔ)uri
* @return
*/
public static Intent getPhotoSelectIntent(Uri uri){
Intent take = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
take.addCategory(Intent.CATEGORY_DEFAULT);
take.putExtra(MediaStore.EXTRA_OUTPUT, uri);
Intent pics = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent chose= Intent.createChooser(pics,"選擇圖片");
chose.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{take});
return chose;
}
/**
* 圖片裁剪
* @param inputUri 需要裁剪的圖片
* @param outputUri 裁剪后存儲(chǔ)位置
* @param width 裁剪寬度
* @param height 裁剪高度
* @return
*/
public static Intent getImageCropIntent(Uri inputUri, Uri outputUri, int width, int height) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(inputUri, "image/*");
// 下面這個(gè)crop=true是設(shè)置在開(kāi)啟的Intent中設(shè)置顯示的VIEW可裁剪
intent.putExtra("crop", "true");
intent.putExtra("scale", true); // 去黑邊
intent.putExtra("scaleUpIfNeeded", true); // 去黑邊
// aspectX aspectY 裁剪框?qū)捀弑壤?
intent.putExtra("aspectX", width); // 輸出是X方向的比例
intent.putExtra("aspectY", height);
// outputX outputY 輸出圖片寬高,切忌不要再改動(dòng)下列數(shù)字,會(huì)卡死
intent.putExtra("outputX", width); // 輸出X方向的像素
intent.putExtra("outputY", height);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
intent.putExtra("return-data", false); // 設(shè)置為不返回?cái)?shù)據(jù)
return intent;
}
1.2.2 添加點(diǎn)擊圖片選擇事件
b.ivAvatar.setOnClickListener {
mTakePhotoFile = File(getPicPath() + File.separator + System.currentTimeMillis() + ".jpeg")
val uri = Uri.fromFile(mTakePhotoFile)
startActivityForResult(IntentUtils.getPhotoSelectIntent( uri), TAKE_PHOTO_REQ)
}
1.2.3 處理圖片選擇和裁剪反饋
圖片裁剪所需的Uri類似: content:// 的形式,因此需要封裝一個(gè)獲取content Uri的工具類
public static Uri getContentUri(Context context, File file) {
String filePath = file.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.Media._ID },
MediaStore.Images.Media.DATA + "=? ",
new String[] { filePath }, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor
.getColumnIndex(MediaStore.MediaColumns._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
} else {
if (file.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, filePath);
return context.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}
處理反饋結(jié)果
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(resultCode != -1) {
return
}
when (requestCode) {
TAKE_PHOTO_REQ -> {
// 處理圖片選擇結(jié)果
mCutPhotoFile = File(getPicPath() + File.separator + "avatar_" + System.currentTimeMillis() + "jpeg")
val cutUri = Uri.fromFile(mCutPhotoFile)
if (data != null){
startActivityForResult(IntentUtils.getImageCropIntent(data.data, cutUri, 200, 200), CUT_PHOTO_REQ)
} else {
val uri = UriUtils.getContentUri(applicationContext, mTakePhotoFile)
startActivityForResult(IntentUtils.getImageCropIntent(uri, cutUri, 200, 200), CUT_PHOTO_REQ)
}
}
CUT_PHOTO_REQ -> {
// 處理圖片裁剪結(jié)果
}
}
}
1.2.4 Android 7.0適配
1. res/xml/provider_paths.xml路徑自行更換
<paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path path="Android/data/com/example/sunmoon/images" name="sdcard_files" /> <external-files-path path="Android/data/com/example/sunmoon/images" name="camera_has_sdcard"/> <files-path path="Android/data/com/example/sunmoon/other" name="camera_no_sdcard"/> <external-path path="Android/data/com/example/sunmoon" name="files_root" /> <external-path path="." name="external_storage_root" /> </paths>
2. manifests配置包名自行更換
...
<application>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.sunmoon.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
...
</application>
...
總結(jié)
以上所述是小編給大家介紹的Android 項(xiàng)目實(shí)戰(zhàn)之頭像選擇功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- Android實(shí)現(xiàn)調(diào)用系統(tǒng)圖庫(kù)與相機(jī)設(shè)置頭像并保存在本地及服務(wù)器
- Android實(shí)現(xiàn)個(gè)人資料頁(yè)面頭像背景模糊顯示包(狀態(tài)欄)
- Android使用CircleImageView實(shí)現(xiàn)圓形頭像的方法
- Android中使用CircleImageView和Cardview制作圓形頭像的方法
- Android獲取聯(lián)系人頭像的方法
- Android實(shí)現(xiàn)用戶頭像更換操作
- Android實(shí)現(xiàn)從本地圖庫(kù)/相機(jī)拍照后裁剪圖片并設(shè)置頭像
相關(guān)文章
超過(guò)百萬(wàn)的StackOverflow Flutter 20大問(wèn)題(推薦)
這篇文章主要介紹了超過(guò)百萬(wàn)的StackOverflow Flutter 問(wèn)題,有的問(wèn)題在stackoverflow上有幾十萬(wàn)的閱讀量,說(shuō)明很多人都遇到了這些問(wèn)題,把這些問(wèn)題整理分享給大家需要的朋友可以參考下2020-04-04
AlertDialog點(diǎn)擊按鈕不消失的實(shí)現(xiàn)方法
我有一個(gè)文本輸入對(duì)話框,當(dāng)我點(diǎn)擊對(duì)話框上的“是”按鈕,它會(huì)驗(yàn)證輸入,然后關(guān)閉對(duì)話框,但是,如果輸入錯(cuò)誤,我想停留在同一個(gè)對(duì)話框中。怎么實(shí)現(xiàn)此功能呢?下面通過(guò)本文給大家分享下2017-01-01
Android Broadcast 和 BroadcastReceiver的權(quán)限限制方式
這篇文章主要介紹了Android Broadcast 和 BroadcastReceiver的權(quán)限限制方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03
Android實(shí)現(xiàn)Activity之間通信的方法
這篇文章主要介紹了Android實(shí)現(xiàn)Activity之間通信的方法,涉及Android中Activity實(shí)現(xiàn)數(shù)據(jù)的發(fā)送及接收相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09
使用ViewPager實(shí)現(xiàn)android軟件使用向?qū)Чδ軐?shí)現(xiàn)步驟
現(xiàn)在的大部分android軟件,都是使用說(shuō)明,就是第一次使用該軟件時(shí),會(huì)出現(xiàn)向?qū)?,可以左右滑?dòng),然后就進(jìn)入應(yīng)用的主界面了,下面我們就實(shí)現(xiàn)這個(gè)功能2013-11-11

