안드로이드 노트

[프로젝트1] 카메라, 갤러리 권한 및 firebase storage 사용한 방법

devRobin 2022. 3. 19. 10:27

1. AndroidManifest.xml

 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.CAMERA"/>


 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

2. arrays of permissions to be requested

 String cameraPermissions[];
 String storagePermission[];
 
   //init arrays of permissions
        cameraPermissions = new String[]{Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE};
        storagePermission = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};

3. showImagePicDialog()

 profileIv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                pd.setMessage("Updating Profile Picture");
                profilePhoto = "image";
                showImagePicDialog();
            }
        });
        
 
  private void showImagePicDialog(){
        //show dialog containing options camera and Gallery to pick the image
        String options[]={"Camera","Gallery"};
        AlertDialog.Builder builder = new AlertDialog.Builder(EditActivity.this);
        builder.setTitle("Pick Image From");
        builder.setItems(options,(dialog, i) -> {
                //handle dialog item clicks
                if(i == 0){
                    //Camera clicked
                    if(!checkCameraPermission()){
                        requestCameraPermission();
                    }
                    else{
                        pickFromCamera();
                    }
                }
                else if(i == 1){
                    //Gallery clicked
                    if(!checkStoragePermission()){
                        requestStoragePermission();
                    }
                    else {
                        pickFromGallery();
                    }
                }

        });

        //create and show dialog
        builder.create().show();
    }
AlertDialog.Builder

참고: https://developer.android.com/guide/topics/ui/dialogs?hl=ko 

 

 

4. Check if storage permission is enabled or not.

return true if enabled

return false if not enabled

 private boolean checkStoragePermission(){
        boolean result = ContextCompat.checkSelfPermission(EditActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE)==(PackageManager.PERMISSION_GRANTED);
        return result;
    }
    private void requestStoragePermission(){
        //request runtime storage permission
        ActivityCompat.requestPermissions(EditActivity.this,storagePermission,STORAGE_REQUEST_CODE);
    }
앱에 이미 권한이 부여되었는지 확인
사용자가 이미 앱에 특정 권한을 부여했는지 확인하려면 ContextCompat.checkSelfPermission() 메서드에 권한을 전달합니다. 이 메서드는 앱에 권한이 있는지에 따라 PERMISSION_GRANTED 또는 PERMISSION_DENIED를 반환합니다.

참고:https://developer.android.com/training/permissions/requesting?hl=ko

 

5. checkCameraPermission()

private boolean checkCameraPermission(){
        //return true if enabled
        //return false if not enabled
        boolean result = ContextCompat.checkSelfPermission(EditActivity.this,Manifest.permission.CAMERA)==(PackageManager.PERMISSION_GRANTED);
        boolean result1 = ContextCompat.checkSelfPermission(EditActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE)==(PackageManager.PERMISSION_GRANTED);
        return result && result1;

    }
    private void requestCameraPermission(){
        ActivityCompat.requestPermissions(EditActivity.this,cameraPermissions,CAMERA_REQUEST_CODE);
    }

6.onRequestPermissionsResult

This method called when user press Allow or Deny from permission request dialog

Here we will handle permission cases (allowed & denied)

  @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
      
        switch (requestCode){
            case CAMERA_REQUEST_CODE:{
                //picking from camera, first check if camera and storage permissions allowed or not
                if(grantResults.length>0){
                    boolean cameraAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                    boolean writeStorageAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
                    if(cameraAccepted && writeStorageAccepted){
                        //permissions enabled
                        pickFromCamera();
                    }
                    else {
                        //permissions denied
                        Toast.makeText(EditActivity.this,"Please enable camera & Storage permission",Toast.LENGTH_SHORT);
                    }
                }

            }
            case STORAGE_REQUEST_CODE:{
                //picking from gallery, first check if storage permissions allowed or not
                if(grantResults.length>0){
                    boolean writeStorageAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
                    if(writeStorageAccepted){
                        //permissions enabled
                        pickFromGallery();
                    }
                    else {
                        //permissions denied
                        Toast.makeText(EditActivity.this,"Please enable storage permission",Toast.LENGTH_SHORT);
                    }
                }
            }

        }

        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
 권한 허가 요청 후 가져오기

 

7. pickFromCamera()

 private void pickFromCamera(){
        //Intent of picking image from device camera
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.TITLE,"Temp Pic");
        values.put(MediaStore.Images.Media.DESCRIPTION,"Temp Description");

        //put image uri
        image_uri = this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values);
        
        //intent to start camera
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
        startActivityForResult(cameraIntent, IMAGE_PICK_CAMERA_CODE);


    }
ContentValues란?
  이 클래스는 ContentResolver가 처리 할수 있는  값 집합을 저장하는데 사용됩니다.
  ContentResolver는 콘텐트 프로바이더(ContentProvider)와 비즈니스 로직의 중계자 역할을 하고 있습니다.
  ContentValues는 ContentResolver가 사용하는 데이터 운송 수단이라고 생각하시면 좋을 것 같습니다.

ContentValues 사용 순서

참고: https://choidev-1.tistory.com/57

 

startActivity vs. startActivityForResult
startActivity : 새 액티비티를 열어줌 (단방향)
startActivityForResult : 새 액티비티를 열어줌 + 결과값 전달 (쌍방향)

출처: https://jhshjs.tistory.com/49

 

8. pickFromGallery()

 private void pickFromGallery(){
        //pick from gallery
        Intent galleryIntent = new Intent(Intent.ACTION_PICK);
        galleryIntent.setType("image/*");
        startActivityForResult(galleryIntent,IMAGE_PICK_GALLERY_CODE);

    }

 

9.onActivityResult

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        //This method will be called after picking image from camera or Gallery
        if(resultCode == RESULT_OK){

            if(requestCode == IMAGE_PICK_GALLERY_CODE){
                //image is picked from gallery, get uri of image
                image_uri = data.getData();
                uploadProfilePhoto(image_uri);
            }
            if(requestCode == IMAGE_PICK_CAMERA_CODE){
                //image is picked from camera, get uri of image

                uploadProfilePhoto(image_uri);
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
액티비티간 데이터 주고받기

출처: https://scshim.tistory.com/50

 

10. uploadProfilePhoto(Uri uri)

    private void uploadProfilePhoto(Uri uri) {


        //show progress
        pd.show();

        String filePathAndName = storagePath+""+profilePhoto+"_"+user.getUid();
        
        StorageReference storageReference2nd = storageReference.child(filePathAndName);
        storageReference2nd.putFile(uri)
                .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                        //image is uploaded to storage, now get it's uri and store in user's database
                        Task<Uri> uriTask = taskSnapshot.getStorage().getDownloadUrl();
                        while(!uriTask.isSuccessful());
                        Uri downloadUri = uriTask.getResult();

                        //check if image is uploaded or not and uri is received
                        if(uriTask.isSuccessful()){
                            //image uploaded
                            //add/update uri in user's database
                            HashMap<String, Object> results = new HashMap<>();

                            results.put(profilePhoto, downloadUri.toString());

                            databaseReference.child(user.getUid()).updateChildren(results)
                                    .addOnSuccessListener(new OnSuccessListener<Void>() {
                                        @Override
                                        public void onSuccess(Void unused) {
                                            //uri in database of user is added successfully
                                            //dismiss progress bar
                                            pd.dismiss();
                                            Toast.makeText(EditActivity.this,"Image Updated...",Toast.LENGTH_SHORT).show();
                                        }
                                    })
                                    .addOnFailureListener(new OnFailureListener() {
                                        @Override
                                        public void onFailure(@NonNull Exception e) {
                                            //error adding url in database of user
                                            //dismiss progress bar
                                            pd.dismiss();
                                            Toast.makeText(EditActivity.this,"Error Updating Image...",Toast.LENGTH_SHORT).show();
                                        }
                                    });

                        }


                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                    //there were some error(s), get and show error message, dismiss progress dialog
                        pd.dismiss();
                        Toast.makeText(EditActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                });
        }