1. 程式人生 > >從本地相簿選擇和拍照、從開啟本地檔案選擇器

從本地相簿選擇和拍照、從開啟本地檔案選擇器

(一)從本地相簿選擇和拍照
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檔案管理器