Android 圓形頭像 相簿和拍照裁剪選取
知識點:
- 在官方7.0的以上的系統中,嘗試傳遞 file://URI可能會觸發FileUriExposedException
- google官方FileProvider
- 呼叫系統裁剪的過程中涉及到兩個 Uri 物件:inputUri 和 outputUri
- 零時賦權
(1)Context.grantUriPermission(package, Uri, mode_flags)Context.grantUriPermission(package, Uri, mode_flags)
(2)Intent.setFlags() - 自動建立Android/data/你的包名/files檔案
this.getExternalFilesDir(null).getAbsolutePath()
- file 轉化 content://uri
String mTempPhotoPath = this.getExternalFilesDir(null).getAbsolutePath() + File.separator + "photo.jpeg";
File file=new File(mTempPhotoPath);
Uri uri=FileProvider.getUriForFile(MainActivity.this, MainActivity.this.getApplicationContext().getPackageName() + ".fileprovider", file);
//(重點)第三個引數為要共享的檔案,並且這個檔案一定位於path 檔案中新增的子目錄裡面。
檔案的絕對路徑與第二步指定的檔案目錄保持一致:(假設包名為com.ysx.fileproviderserver)。如上邊的程式碼的檔案的絕對路徑為/data/data/com.ysx.fileproviderserver/files/text/hello.txt,對應paths中的內容為:。getUriForFile()的第二個引數是authority,與manifest檔案中宣告的authorities保持一致。這時候,我們得到的URI的串為:content://com.ysx.fileproviderserver.fileprovider/my_files/hello.txt。
- 在paths節點內部支援以下幾個子節點,分別為:
<root-path/> 代表裝置的根目錄new File("/");
<files-path/> 代表context.getFilesDir()
<cache-path/> 代表context.getCacheDir()
<external-path/> 代表Environment.getExternalStorageDirectory()
<external-files-path>代表context.getExternalFilesDirs()
<external-cache-path>代表getExternalCacheDirs()
- FileProvider基本使用流程
(1)定義一個 FileProvider
(2)指定共享目錄
(3)為檔案生成有效的 Content URI
(4)申請臨時的讀寫許可權
(5)傳送 Content URI 至其他的 App
主要程式碼
package com.example.administrator.popupwindow;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.databinding.DataBinderMapper;
import android.databinding.DataBindingUtil;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
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.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import de.hdodenhof.circleimageview.CircleImageView;
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
import static android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
public class MainActivity extends BaseActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
private static final String IMAGE_FILE_LOCATION = "file:///sdcard/temp.jpg";//temp file
Uri imageUri_crop = Uri.parse(IMAGE_FILE_LOCATION);//The Uri to store the big bitmap
private CircleImageView circleImageView;
private String mTempPhotoPath;
private String mTempPhotoPath2;
private Uri imageUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
circleImageView = (CircleImageView) findViewById(R.id.profile_image);
circleImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showTypeDialog();
}
});
}
@Override
public void onClick(View view) {
}
private void showTypeDialog() {
//顯示對話方塊
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIcon(R.mipmap.ic_launcher);
builder.setTitle("選擇頭像");
final String[] items = {"相簿", "相機"};
builder.setCancelable(true);
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Toast.makeText(getApplicationContext(), "You clicked " + items[i], Toast.LENGTH_SHORT).show();
if (i == 0) {
Intent intent1 = new Intent(Intent.ACTION_PICK, null);
//開啟檔案
intent1.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent1, 1);
dialogInterface.dismiss();
}
if (i == 1) {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //許可權還沒有授予,需要在這裡寫申請許可權的程式碼
// 第二個引數是一個字串陣列,裡面是你需要申請的許可權 可以設定申請多個許可權
// 最後一個引數是標誌你這次申請的許可權,該常量在onRequestPermissionsResult中使用到
Log.e(TAG, "onClick: " + "未授權");
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
2);
} else { //許可權已經被授予,在這裡直接寫要執行的相應方法即可
takePhoto();
}
dialogInterface.dismiss();
}
}
});
final AlertDialog dialog = builder.create();
dialog.show();
}
private void takePhoto() {
// 跳轉到系統的拍照介面
Intent intentToTakePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 指定照片儲存位置為sd卡本目錄下
// 這裡設定為固定名字 這樣就只會只有一張temp圖 如果要所有中間圖片都儲存可以通過時間或者加其他東西設定圖片的名稱
// File.separator為系統自帶的分隔符 是一個固定的常量
mTempPhotoPath = this.getExternalFilesDir(null).getAbsolutePath() + File.separator + "photo1.jpeg";//android/data 自動建立目錄
mTempPhotoPath2 = Environment.getExternalStorageDirectory() + File.separator + "photo2.jpeg";
Log.e(TAG, "takePhoto: " + mTempPhotoPath);
Log.e(TAG, "takePhoto2: " + mTempPhotoPath2);
// 獲取圖片所在位置的Uri路徑
imageUri = FileProvider.getUriForFile(MainActivity.this, MainActivity.this.getApplicationContext().getPackageName() + ".fileprovider", new File(mTempPhotoPath2));
Log.e(TAG, "takePhoto3: " + imageUri);
//下面這句指定呼叫相機拍照後的照片儲存的路徑,如果沒有這句程式碼,則不儲存照片
intentToTakePhoto.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
// intentToTakePhoto.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
// intentToTakePhoto.addFlags(FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(intentToTakePhoto, 2);
}
public void cropPhoto(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
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.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(FLAG_GRANT_WRITE_URI_PERMISSION);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri_crop);
intent.putExtra("return-data", false);
startActivityForResult(intent, 3);
}
private Bitmap decodeUriAsBitmap(Uri uri) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
return bitmap;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case 1:
if (resultCode == RESULT_OK) {
Uri uri = data.getData();
cropPhoto(uri);
}
break;
case 2:
if (resultCode == RESULT_OK) {
if (imageUri != null) {
Log.e(TAG, "onActivityResult: " + imageUri.toString());
cropPhoto(imageUri);
}
}
break;
case 3:
if (imageUri_crop != null) {
Bitmap bitmap = decodeUriAsBitmap(imageUri_crop);//decode bitmap
circleImageView.setImageBitmap(bitmap);
}
break;
}
}
}
相關文章
- android裁剪圓型頭像Android
- android圓形頭像的選擇和剪下並儲存出圓形圖片Android
- u3d 呼叫android相機和相簿裁剪成圓形3DAndroid
- 《Android開發卷——設定圓形頭像,Android擷取圓形圖片》Android
- Android之圓形頭像裁切Android
- Android 自定義圓形頭像Android
- Android自定義圓形頭像Android
- Android 圓形頭像 自己動手Android
- Flutter 圓形/圓角頭像Flutter
- android實現拍照、相簿選圖、裁剪功能,相容7.0以及小米Android
- Android 用MultiImageSelector實現上傳頭像的拍照跟相簿Android
- Android中呼叫攝像頭拍照儲存,並在相簿中選擇圖片顯示Android
- Android 呼叫系統相機拍照 . 選取本地相簿Android
- Android呼叫攝像頭拍照Android
- Android 呼叫攝像頭拍照Android
- Swift相簿選擇和拍照功能Swift
- Android 拍照、選擇圖片並裁剪Android
- Android提供的攝像頭拍照Android
- 微信小程式獲取使用者頭像修改為圓形微信小程式
- 基於 GD 庫生成圓形頭像
- 自定義圓形ImageView(仿QQ頭像)View
- 【Android】【opencv】實現攝像頭拍照和錄影AndroidOpenCV
- 自定義ImageView完成圓形頭像自定義View
- CircleImageView 圓形圖片頭像實現View
- 直播平臺搭建,Android手機拍照和手機相簿選取圖片的工具Android
- 照片系列之android呼叫攝像頭拍照Android
- Android開發之呼叫攝像頭拍照Android
- Android 拍照及相簿選取圖片功能,已適配Android6.0、7.0、8.0Android
- 直播平臺軟體開發,Android 10 拍照和相簿選擇Android
- Android呼叫系統相簿和相機拍照Android
- Android呼叫攝像頭拍照並顯示照片Android
- Android 呼叫攝像頭功能【拍照與視訊】Android
- 安卓呼叫攝像頭拍照安卓
- ios Image裁剪成圓形的方法iOS
- Android 自定義圓形旋轉進度條,仿微博頭像載入效果Android
- 微信小程式裁剪圖片成圓形微信小程式
- Android上傳圖片之呼叫系統拍照和從相簿選擇圖片Android
- Android拍照,相簿選擇圖片以及Android6.0許可權管理Android