1. 程式人生 > >安卓開發-拍照或相簿選擇頭像和執行時動態獲取許可權

安卓開發-拍照或相簿選擇頭像和執行時動態獲取許可權

專案中都會用到頭像設定,所以記錄一下

效果圖:


在android 6.0推出了執行時許可權,我們獲取使用者手機許可權就沒那麼方便了,先說說執行時許可權:

Permission,執行時許可權

授權許可權
*如果裝置執行的是Android 6(API Level 23)或更高,和應用程式的targetSdkVersion是23或更高,應用程式要求的許可權由使用者在執行時。使用者可以在任何時間撤銷許可權,所以在每次執行時應用程式需要檢查是否有許可權。

許可權可以分為危險許可權和正常許可權,還有特殊許可權、自定義許可權。 正常許可權(PROTECTION_NORMAL)對使用者的隱私或安全沒有大的風險的許可權在AndroidManifest.xml聲明裡,如果應用需要一個正常的許可權,在安裝的時候系統自動授予該許可權。在

使用的時候系統不提示使用者,使用者也不能撤銷這些許可權。


\

危險許可權,需要使用時要檢查有沒有授權。如果沒有就彈個對話方塊詢問使用者授權。這類許可權被分組了,同一組的任何一個許可權被授權了,其他許可權也自動被授權。如下表:


比如你需要android.permission.READ_CONTACTS ,去讀聯絡人。這個許可權被使用者授權,然後你用到寫入通訊錄許可權permission:android.permission.WRITE_CONTACTS和permission:android.permission.GET_ACCOUNTS 時,就是授權過的,去申請就不會彈框。

然後如果使用者手機系統高於5.0以上也就是6.0或者7.0,那麼我們在清單檔案AndroidManifest中宣告的許可權就不好使了還需要程式碼獲取許可權

程式碼:

點選按鈕之後是個popuwindow彈窗

change.setOnClickListener(new View.OnClickListener() {
    @Override
public void onClick(View v) {
        bottomPopupOption = new BottomPopupOption(MainActivity.this);
bottomPopupOption.setItemText("拍照","相簿");
bottomPopupOption.showPopupWindow();
bottomPopupOption.setItemClickListener(new 
BottomPopupOption.onPopupWindowItemClickListener() { @Override public void onItemClick(int position) { bottomPopupOption.dismiss(); switch (position){ case 0: Toast.makeText(MainActivity.this,"拍照",Toast.LENGTH_SHORT).show(); choseHeadImageFromCameraCapture(); break; case 1: Toast.makeText(MainActivity.this,"相簿",Toast.LENGTH_SHORT).show(); choseHeadImageFromGallery(); break; } } }); } });

拍照方法

// 啟動手機相機拍攝照片作為頭像
private void choseHeadImageFromCameraCapture() {
    //6.0以上動態獲取許可權
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
        //申請許可權,REQUEST_TAKE_PHOTO_PERMISSION是自定義的常量
ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.CAMERA},
REQUEST_TAKE_PHOTO_PERMISSION);
} else {
        Intent intentFromCapture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 判斷儲存卡是否可用,儲存照片檔案
if (hasSdcard()) {

            intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT, Uri
                    .fromFile(new File(Environment
                            .getExternalStorageDirectory(), IMAGE_FILE_NAME)));
}
        startActivityForResult(intentFromCapture, CODE_CAMERA_REQUEST);
}

}

相簿方法

// 從本地相簿選取圖片作為頭像
private void choseHeadImageFromGallery() {
    Intent intentFromGallery = new Intent();
// 設定檔案型別
intentFromGallery.setType("image/*");
intentFromGallery.setAction(Intent.ACTION_PICK);
startActivityForResult(intentFromGallery, CODE_GALLERY_REQUEST);
}
activity回撥
  @Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {

        // 使用者沒有進行有效的設定操作,返回
if (resultCode == RESULT_CANCELED) {
//            Toast.makeText(getApplication(), "取消", Toast.LENGTH_LONG).show();
return;
}

        switch (requestCode) {
            case CODE_GALLERY_REQUEST:
                cropRawPhoto(intent.getData());
                break;
            case CODE_CAMERA_REQUEST:
                if (hasSdcard()) {
                    File tempFile = new File(
                            Environment.getExternalStorageDirectory(),
IMAGE_FILE_NAME);
cropRawPhoto(Uri.fromFile(tempFile));
} else {
                    Toast.makeText(MainActivity.this,"沒有sd",Toast.LENGTH_SHORT).show();
}

                break;
            case CODE_RESULT_REQUEST:
                if (intent != null) {
                    setImageToHeadView(intent);
File file = new File(
                            Environment.getExternalStorageDirectory(),
IMAGE_FILE_NAME);
                    if (file.exists()&&!file.isDirectory()){
                        file.delete();
}
                }

                break;
}

        super.onActivityResult(requestCode, resultCode, intent);
}
裁剪圖片
 /**
     * 裁剪原始的圖片
*/
public void cropRawPhoto(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", output_X);
intent.putExtra("outputY", output_Y);
intent.putExtra("return-data", true);
startActivityForResult(intent, CODE_RESULT_REQUEST);
}
    String url = "http://000.000.00.00:8080/ffd/dfdf/fgdfg.do";//測試地址需換自己的伺服器地址
/**
     * 提取儲存裁剪之後的圖片資料,並設定頭像部分的View
     */
private void setImageToHeadView(Intent intent) {
        Bundle extras = intent.getExtras();
        if (extras != null) {
            photo = extras.getParcelable("data");
//            photo = intent.getParcelableExtra("data");
circleImageView.setImageBitmap(photo);
circleImageView2.setImageBitmap(photo);
File nf = new File(Environment.getExternalStorageDirectory()+"/test");
nf.mkdir();
//在根目錄下面的ASk資料夾下 建立okkk.jpg檔案
File f = new File(Environment.getExternalStorageDirectory()+"/test", IMAGE_FILE_NAME);
FileOutputStream out = null;
            try {      //開啟輸出流 將圖片資料填入檔案中
out = new FileOutputStream(f);
photo.compress(Bitmap.CompressFormat.PNG, 90, out);
                try {
                    out.flush();
out.close();
} catch (IOException e) {
                    e.printStackTrace();
}

            } catch (FileNotFoundException e) {
                e.printStackTrace();
}

            File file = new File(HeadPortrait_PATH);
            if (!file.exists()){
                Toast.makeText(MainActivity.this,"檔案不存在",Toast.LENGTH_SHORT).show();
}
            try {

                OkHttpUtils.post(url)
                        .params("userid","")
                        .params("file",file)
                        .execute(new StringCallback() {
                            @Override
public void onSuccess(String s, okhttp3.Call call, Response response) {
                                Toast.makeText(MainActivity.this,"上傳成功",Toast.LENGTH_SHORT).show();
}
                        });
} catch (Exception e) {
                e.printStackTrace();
}
        }
    }
還有執行時獲取許可權
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == REQUEST_TAKE_PHOTO_PERMISSION) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            //申請成功,可以拍照
choseHeadImageFromCameraCapture();
} else {
            Toast.makeText(MainActivity.this,"你拒絕了許可權,該功能不可用\n可在應用設定裡授權拍照哦",Toast.LENGTH_SHORT).show();
}
        return;
}
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

demo地址:

https://github.com/PangHaHa12138/MyUploadPhotodmo"