從本地相簿選擇和拍照、從開啟本地檔案選擇器
阿新 • • 發佈:2019-02-07
(一)從本地相簿選擇和拍照
1、呼叫本地相簿:
Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); intent.putExtra("crop", "true");//選擇圖片後進行裁剪 intent.putExtra("aspectX", 1);//裁剪的寬高比 intent.putExtra("aspectY", 1);//裁剪的寬高比
intent.putExtra("outputX", 180);//輸出的圖片寬
intent.putExtra("outputY", 180);//輸出的圖片高 intent.putExtra("return-data", true); mContext.startActivityForResult(intent, ALBUM);
//ALBUM為activity的onActivityResult中的處理標誌
2、呼叫拍照:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment .getExternalStorageDirectory(), "camera.jpg")));
//拍出來的照片放在主目錄下,名為camera.jpg intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); mContext.startActivityForResult(intent, CAMERA);
//CAMERA為activity的onActivityResult中的處理標誌
2.2若是拍照後的圖片有裁剪要求,則在onActivityResult中再發出裁剪指令
3、呼叫系統裁剪:
private void cropImageUri(Uri uri, int outputX, int outputY) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); intent.putExtra("crop", "true"); intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); intent.putExtra("outputX", outputX); intent.putExtra("outputY", outputY); intent.putExtra("scale", true); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); intent.putExtra("return-data", false); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); intent.putExtra("noFaceDetection", true); // no face detection startActivityForResult(intent, CameraDialog.CROP); }
4、onActivityResult的響應:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) { switch (requestCode) { case CameraDialog.CAMERA:
//發出裁剪指令(指定檔案路徑、裁剪的輸入寬高)
cropImageUri(Uri.fromFile(new File(Environment .getExternalStorageDirectory(), "camera.jpg")), 180, 180); return; case CameraDialog.ALBUM: bitmap = (Bitmap) data.getExtras().get("data"); break; case CameraDialog.CROP: bitmap = BitmapUtil.decodeUriAsBitmap(mActivity, Uri.fromFile(new File(Environment .getExternalStorageDirectory(), "camera.jpg"))); break; } if (bitmap == null) { Toast.makeText(mActivity, mActivity.getString(R.string.error_pickimg), Toast.LENGTH_SHORT).show(); return; } //將獲取到的bitmap進行上傳伺服器等業務處理 } super.onActivityResult(requestCode, resultCode, data); }
實踐基本如下(附上上述的onActivityResult和裁剪函式即可):
public class CameraDialog extends AlertDialog { BaseActivity mContext; public static final int CAMERA = 10; public static final int ALBUM = 11; public static final int CROP = 12; public CameraDialog(BaseActivity context) { super(context); mContext = context; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); applyCompat(); setContentView(R.layout.dialog_camera); TextView tip1 = (TextView) findViewById(R.id.camera); TextView tip2 = (TextView) findViewById(R.id.album); tip1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //開啟Camera Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment .getExternalStorageDirectory(), "camera.jpg"))); intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); mContext.startActivityForResult(intent, CAMERA); dismiss(); } }); tip2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //開啟相簿(Intent.ACTION_GET_CONTENT存在機型獲取不到資料的情況,改用Intent.ACTION_PICK改善) // Intent intent = new Intent(Intent.ACTION_GET_CONTENT); // intent.addCategory(Intent.CATEGORY_OPENABLE); Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); intent.putExtra("crop", "true"); intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); intent.putExtra("outputX", 180); intent.putExtra("outputY", 180); intent.putExtra("return-data", true); mContext.startActivityForResult(intent, ALBUM); dismiss(); } }); getWindow().setBackgroundDrawable(new ColorDrawable()); } private void applyCompat() { if (Build.VERSION.SDK_INT < 19) { return; } getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); }
(二)開啟本地檔案選擇器
1、呼叫本地檔案選擇器
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("*/*");//設定型別,我這裡是任意型別,任意字尾的可以這樣寫。呼叫指定檔案型別的檔案選擇器,參考下文“另外” intent.addCategory(Intent.CATEGORY_OPENABLE); startActivityForResult(intent,1);//1為標誌,可在onActivityResult進行回撥區分
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) {//是否選擇,沒選擇就不會繼續 Uri uri = data.getData();//得到uri,後面就是將uri轉化成file的過程。 //避免獲取path時,Cursor為null的解決方案:scheme進行判斷 String scheme = uri.getScheme(); String path = null; if (scheme == null) path = uri.getPath(); else if (ContentResolver.SCHEME_FILE.equals(scheme)) { path = uri.getPath(); } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) { String[] proj = {MediaStore.Images.Media.DATA}; Cursor actualimagecursor = getContentResolver().query(uri, proj, null, null, null); if (actualimagecursor != null && actualimagecursor.moveToFirst()) { int actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); path = actualimagecursor.getString(actual_image_column_index); } actualimagecursor.close(); } if (path != null) Toast.makeText(PickActivity.this, path, Toast.LENGTH_SHORT).show(); } }
發出呼叫請求後,效果如下:
2、另外
實踐效果:
通過intent的type設定不同,發出不同的響應
intent.setType(“image/*”); //intent.setType(“audio/*”); //選擇音訊 //intent.setType(“video/*”); //選擇視訊 (mp4 3gp 是android支援的視訊格式) //intent.setType(“video/*;image/*”);//同時選擇視訊和圖片
圖片、視訊、同時選擇視訊圖片:
音訊:(直接打開了檔案管理器)
(以上實踐均為堅果手機效果)
參考:
1.《android圖片檔案的路徑地址與Uri的相互轉換》
2.Android呼叫系統自帶的檔案管理器進行檔案選擇並獲得路徑,android檔案管理器