1. 程式人生 > >上傳圖片功能實現

上傳圖片功能實現

1.如果沒有相機許可權,申請開啟相機許可權

if (!ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA)){
      ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},0);
}

2.如果相機許可權被關閉提示開啟許可權

if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
    != PackageManager.PERMISSION_GRANTED) {
    //申請WRITE_EXTERNAL_STORAGE許可權
    Toast.makeText(this,"請開啟相機許可權",Toast.LENGTH_SHORT).show();
    return;
}

3.startActivityForResult的使用方法

使用startActivityForResult(Intent intent, int requestCode)方法傳入一個請求碼(第二個引數)。請求碼相當於一個識別符號,根據不同的識別符號可以在onActivityResult中實現不同的邏輯處理。例如以下程式碼:

@Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         switch (requestCode) {
             case PHOTO_REQUEST_CAREMA:
                 if (resultCode == RESULT_OK) {
                     Intent intent = new Intent("com.android.camera.action.CROP");
                     intent.setDataAndType(imageUri, "image/*");
                     intent.putExtra("scale", true);
                     intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                     startActivityForResult(intent, CROP_PHOTO); // 啟動裁剪程式
                 }
                 break;
             case CROP_PHOTO:
                 if (resultCode == RESULT_OK) {
                     try {
                         Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver()
                                 .openInputStream(imageUri));
                         picture.setImageBitmap(bitmap);
                     } catch (FileNotFoundException e) {
                         e.printStackTrace();
                     }
                 }
                 break;
             case ARRAY_PHOTO:
                 if (resultCode == RESULT_OK) {
                     try {
                         if(data != null) {
                             Uri uri = data.getData();
                             imageUri = uri;
                         }
                         Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver()
                                 .openInputStream(imageUri));
                         picture.setImageBitmap(bitmap);
                     } catch (FileNotFoundException e) {
                         e.printStackTrace();
                     }
                 }
                 break;
             default:
                 super.onActivityResult(requestCode, resultCode, data);
                 break;
         }
     }

在以上onActivityResult方法中,根據startActivityForResult中傳入requestCode的不同實現不同的功能,例如以下程式碼傳入requestCode == ARRAY_PHOTO。

public void openGallery() {
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType("image/*");
    startActivityForResult(intent, ARRAY_PHOTO);
}

4.Enviroment類使用方法

其主要方法有:
getRootDirectory()---->/ 獲取根目錄
getDataDirectory()---->/data 獲取data目錄
getExternalStorageDirectory()—>/sdcard 獲取sd卡目錄
getDownloadCacheDirectory()—>/cache 獲取下載檔案的快取目錄
getExternalStorageState—>sdcard的狀態,removed,unmounted,checking,nofs,mounted,mounted_ro,shared,unmountable,bad_removal

5.ContentResolver類使用方法

ContentResolver提供的方法和ContentProvider提供的方法對應的有以下幾個方法。
public Uri insert(Uri uri, ContentValues values) 用於新增資料到指定Uri的ContentProvider中。
public int delete(Uri uri, String selection, String[] selectionArgs) 用於從指定Uri的ContentProvider中刪除資料。
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) 用於更新指定Uri的ContentProvider中的資料。
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) 用於查詢指定Uri的ContentProvider。

6.上傳圖片、從相簿選擇照片以及圖片裁剪功能實現

首先建立PhotoActivity類

public class PhotoActivity extends AppCompatActivity implements View.OnClickListener {
        public static final int PHOTO_REQUEST_CAREMA = 1;// 拍照
        public static final int CROP_PHOTO = 2;// 裁剪
        public static final int ARRAY_PHOTO = 3;// 相簿選取
        private Button takePhoto;
        private ImageView picture;
        private Uri imageUri;

        public static File tempFile;


        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.photo);

            takePhoto = (Button) findViewById(R.id.take_photo);
            picture = (ImageView) findViewById(R.id.picture);

            takePhoto.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.take_photo:
                    if (!ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA)){
                        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},0);
                    }
                    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                            != PackageManager.PERMISSION_GRANTED) {
                        //申請WRITE_EXTERNAL_STORAGE許可權
                        //Util.showToast(this,"請開啟相機許可權");
                        Toast.makeText(this,"請開啟相機許可權",Toast.LENGTH_SHORT).show();
                        return;
                    }
                    openCamera(this);//拍照獲取照片
                    //openGallery();//從相簿選擇照片
                    break;
            }
        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            switch (requestCode) {
                case PHOTO_REQUEST_CAREMA:
                    if (resultCode == RESULT_OK) {
                        Intent intent = new Intent("com.android.camera.action.CROP");
                        intent.setDataAndType(imageUri, "image/*");
                        intent.putExtra("scale", true);
                        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                        startActivityForResult(intent, CROP_PHOTO); // 啟動裁剪程式
                    }
                    break;
                case CROP_PHOTO:
                    if (resultCode == RESULT_OK) {
                        try {
                            Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver()
                                    .openInputStream(imageUri));
                            picture.setImageBitmap(bitmap);
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case ARRAY_PHOTO:
                    if (resultCode == RESULT_OK) {
                        try {
                            if(data != null) {
                                Uri uri = data.getData();
                                imageUri = uri;
                            }
                            Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver()
                                    .openInputStream(imageUri));
                            picture.setImageBitmap(bitmap);
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                default:
                    super.onActivityResult(requestCode, resultCode, data);
                    break;
            }
        }

        public void openCamera(Activity activity) {
            //獲取系統版本
            int currentapiVersion = android.os.Build.VERSION.SDK_INT;
            // 啟用相機
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            // 判斷儲存卡是否可以用,可用進行儲存
            if (hasSdcard()) {
                SimpleDateFormat timeStampFormat = new SimpleDateFormat(
                        "yyyy_MM_dd_HH_mm_ss");
                String filename = timeStampFormat.format(new Date());
                tempFile = new File(Environment.getExternalStorageDirectory(),
                        filename + ".jpg");
                if (currentapiVersion < 24) {
                    // 從檔案中建立uri
                    imageUri = Uri.fromFile(tempFile);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                } else {
                    //相容android7.0 使用共享檔案的形式
                    ContentValues contentValues = new ContentValues(1);
                    contentValues.put(MediaStore.Images.Media.DATA, tempFile.getAbsolutePath());
                    //檢查是否有儲存許可權,以免崩潰
                    if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                            != PackageManager.PERMISSION_GRANTED) {
                        //申請WRITE_EXTERNAL_STORAGE許可權
                        //Util.showToast(this,"請開啟儲存許可權");
                        Toast.makeText(this,"請開啟儲存許可權",Toast.LENGTH_SHORT).show();
                        return;
                    }
                    imageUri = activity.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                }
            }
            // 開啟一個帶有返回值的Activity,請求碼為PHOTO_REQUEST_CAREMA
            activity.startActivityForResult(intent, PHOTO_REQUEST_CAREMA);
        }

        /*
         * 判斷sdcard是否被掛載
         */
        public static boolean hasSdcard() {
            return Environment.getExternalStorageState().equals(
                    Environment.MEDIA_MOUNTED);
        }
        public void openGallery() {
            Intent intent = new Intent(Intent.ACTION_PICK);
            intent.setType("image/*");
            startActivityForResult(intent, ARRAY_PHOTO);
        }

    }

然後建立對應的photo.xml檔案

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/take_photo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Take Photo" />

    <ImageView
        android:id="@+id/picture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal" />

</LinearLayout>