투케이2K

145. (AndroidStudio/android/java) Scoped Storage 사용해 이미지 파일 저장 및 호출 - ContentResolver , MediaStore 본문

Android

145. (AndroidStudio/android/java) Scoped Storage 사용해 이미지 파일 저장 및 호출 - ContentResolver , MediaStore

투케이2K 2021. 5. 14. 12:51

/* =========================== */

[ 개발 환경 설정 ]

개발 툴 : AndroidStudio

개발 언어 : java

/* =========================== */

/* =========================== */

[소스 코드]

 

//TODO [사전 퍼미션 요청 필요함]
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>





//TODO [인텐트 요청 및 요청 결과 확인 위함]
Uri photoUri;
private static final int PICK_FROM_CAMERA = 1; // [카메라 촬영으로 사진 가져오기]
private static final int PICK_FROM_ALBUM = 2; // [앨범에서 사진 가져오기]
private static final int CROP_FROM_CAMERA = 3; // [가져온 사진을 자르기 위한 변수]





//TODO [파일 경로 설명]
//콘텐츠 파일 경로 (사진 불러오기) : content://media/external/images/media/37353
//절대 파일 경로 (서버에 사진 등록) : /storage/emulated/0/Pictures/.pending-1621513927-PT20210513213207.JPG





//TODO [갤러리 앨범 메소드 호출 실시]
goGallary();





//TODO [앨범 갤러리 열기 수행]
public void goGallary(){
	Log.d("---","---");
	Log.d("//===========//","================================================");
	Log.d("","\n"+"[A_ScopePicture > goGallary() 메소드 : 갤러리 인텐트 이동 실시]");
	Log.d("//===========//","================================================");
	Log.d("---","---");
	try {
		//Intent intent = new Intent(Intent.ACTION_PICK); //[기존]
		Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); //[변경]
		intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
		intent.setType(MediaStore.Images.Media.CONTENT_TYPE);
		startActivityForResult(intent, PICK_FROM_ALBUM);
		overridePendingTransition(0, 0);
	}
	catch (Exception e){
		e.printStackTrace();
	}
}





//TODO [갤러리에서 선택한 이미지 응답 확인]
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	super.onActivityResult(requestCode, resultCode, data);
	//TODO [정장 응답이 아닌 경우]
	if (resultCode != RESULT_OK) {
		Toast.makeText(getApplication(), "다시 시도해주세요 ... ", Toast.LENGTH_SHORT).show();
	}
	//TODO [갤러리에서 응답을 받은 경우]
	if (requestCode == PICK_FROM_ALBUM) {
		Toast.makeText(getApplication(), "잠시만 기다려주세요 ... ", Toast.LENGTH_SHORT).show();
		if (data == null) {
			return;
		}
		photoUri = data.getData();

		Log.d("---","---");
		Log.w("//===========//","================================================");
		Log.d("","\n"+"[A_ScopePicture > onActivityResult() 메소드 : 갤러리 응답 확인 실시]");
		Log.d("","\n"+"[파일 경로 : "+String.valueOf(photoUri)+"]");
		Log.w("//===========//","================================================");
		Log.d("---","---");
		try {
			// [선택한 이미지에서 비트맵 생성]
			InputStream in = getContentResolver().openInputStream(data.getData());
			Bitmap img = BitmapFactory.decodeStream(in);
			in.close();

			// [이미지 뷰에 이미지 표시]
			imageView.setImageBitmap(img);

			// [파일 저장 실시 후 > 다시 사진 불러오기 진행 > 서버로 등록 요청]
			saveFile(getNowTime24(), imageView, String.valueOf(photoUri));
		}
		catch (Exception e){
			e.printStackTrace();
		}
	}
}





//TODO [MediaStore 파일 저장 실시]
private void saveFile(String fileName, ImageView view, String fileRoot) {
	String deleteCheck = S_Preference.getString(getApplication(), "saveImageScopeContent");
	if(deleteCheck != null && deleteCheck.length() > 0){ //TODO 이전에 저장된 파일이 있을 경우 지운다
		try {
			ContentResolver contentResolver = getContentResolver();
			contentResolver.delete(
				Uri.parse(S_Preference.getString(getApplication(), "saveImageScopeContent")),
				null,
				null);
			Log.d("---","---");
			Log.e("//===========//","================================================");
			Log.d("","\n"+"[A_ScopePicture > saveFile() 메소드 : 이전에 저장된 파일 삭제 실시]");
			Log.d("","\n"+"[콘텐츠 파일 경로 : "+String.valueOf(deleteCheck)+"]");
			Log.d("","\n"+"[절대 파일 경로 : "+S_Preference.getString(getApplication(), "saveImageScopeAbsolute")+"]");
			Log.e("//===========//","================================================");
			Log.d("---","---");
		}
		catch (Exception e){
			e.printStackTrace();
		}
	}
	Log.d("---","---");
	Log.d("//===========//","================================================");
	Log.d("","\n"+"[A_ScopePicture > saveFile() 메소드 : MediaStore 파일 저장 실시]");
	Log.d("","\n"+"[파일 이름 : "+String.valueOf(fileName)+"]");
	Log.d("","\n"+"[원본 경로 : "+String.valueOf(fileRoot)+"]");
	Log.d("//===========//","================================================");
	Log.d("---","---");

	//TODO [저장하려는 파일 타입, 이름 지정]
	ContentValues values = new ContentValues();
	values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName+".JPG");
	values.put(MediaStore.Images.Media.MIME_TYPE, "image/*");
	if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
		values.put(MediaStore.Images.Media.IS_PENDING, 1);
	}
	ContentResolver contentResolver = getContentResolver();
	Uri item = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

	try {
		//TODO [쓰기 모드 지정]
		ParcelFileDescriptor pdf = contentResolver.openFileDescriptor(item, "w", null);

		if (pdf == null) {
			Log.d("---","---");
			Log.e("//===========//","================================================");
			Log.d("","\n"+"[A_ScopePicture > saveFile() 메소드 : MediaStore 파일 저장 실패]");
			Log.d("","\n"+"[원인 : "+String.valueOf("ParcelFileDescriptor 객체 null")+"]");
			Log.e("//===========//","================================================");
			Log.d("---","---");
		} else {
			//TODO [이미지 뷰에 표시된 사진을 얻어온다]
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inSampleSize = 4;
			//Bitmap bitmap= BitmapFactory.decodeFile(filePath, options);
			Bitmap bitmap = ((BitmapDrawable) view.getDrawable()).getBitmap();

			//TODO [이미지 리사이징 실시]
			int width = 354; // [축소시킬 너비 (증명사진 크기 기준)]
			int height = 472; //[축소시킬 높이 (증명사진 크기 기준)]
			float bmpWidth = bitmap.getWidth();
			float bmpHeight = bitmap.getHeight();

			if (bmpWidth > width) {
				// [원하는 너비보다 클 경우의 설정]
				float mWidth = bmpWidth / 100;
				float scale = width/ mWidth;
				bmpWidth *= (scale / 100);
				bmpHeight *= (scale / 100);
			} else if (bmpHeight > height) {
				// [원하는 높이보다 클 경우의 설정]
				float mHeight = bmpHeight / 100;
				float scale = height/ mHeight;
				bmpWidth *= (scale / 100);
				bmpHeight *= (scale / 100);
			}

			//TODO [리사이징 된 파일을 비트맵에 담는다]
			//Bitmap resizedBmp = Bitmap.createScaledBitmap(bitmap, (int) bmpWidth, (int) bmpHeight, true); //TODO [해상도 맞게 표시]
			Bitmap resizedBmp = Bitmap.createScaledBitmap(bitmap, (int) width, (int) height, true); //TODO [무조건 증명 사진 기준]
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			resizedBmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
			byte[] imageInByte = baos.toByteArray();

			//TODO [이미지를 저장하는 부분]
			FileOutputStream outputStream = new FileOutputStream(pdf.getFileDescriptor());
			outputStream.write(imageInByte);
			outputStream.close();

			//TODO [경로 저장 실시]
			//[콘텐츠 : 이미지 경로 저장]
			S_Preference.setString(getApplication(), "saveImageScopeContent", String.valueOf(item));

			//[절대 : 이미지 경로 저장]
			Cursor c = getContentResolver().query(Uri.parse(String.valueOf(item)), null,null,null,null);
			c.moveToNext();
			String absolutePath = c.getString(c.getColumnIndex(MediaStore.MediaColumns.DATA));
			S_Preference.setString(getApplication(), "saveImageScopeAbsolute", absolutePath);

			Log.d("---","---");
			Log.w("//===========//","================================================");
			Log.d("","\n"+"[A_ScopePicture > saveFile() 메소드 : MediaStore 파일 저장 성공]");
			Log.d("","\n"+"[콘텐츠 파일 경로 : "+S_Preference.getString(getApplication(), "saveImageScopeContent")+"]");
			Log.d("","\n"+"[절대 파일 경로 : "+S_Preference.getString(getApplication(), "saveImageScopeAbsolute")+"]");
			Log.w("//===========//","================================================");
			Log.d("---","---");

			//TODO [다시 사진 표시 실시]
			readFile(imageView, S_Preference.getString(getApplication(), "saveImageScopeContent"));

			//TODO [서버에 사진 등록 요청 실시]
			//postRegisterPicture(postUrl, postData);
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}





//TODO [MediaStore 파일 불러오기 실시]
private void readFile(ImageView view, String path) {
	Log.d("---","---");
	Log.d("//===========//","================================================");
	Log.d("","\n"+"[A_ScopePicture > readFile() 메소드 : MediaStore 파일 불러오기 실시]");
	Log.d("","\n"+"[콘텐츠 파일 경로 : "+String.valueOf(path)+"]");
	Log.d("//===========//","================================================");
	Log.d("---","---");
	Uri externalUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
	String[] projection = new String[]{
		MediaStore.Images.Media._ID,
		MediaStore.Images.Media.DISPLAY_NAME,
		MediaStore.Images.Media.MIME_TYPE
	};

	Cursor cursor = getContentResolver().query(externalUri, projection, null, null, null);

	if (cursor == null || !cursor.moveToFirst()) {
		Log.d("---","---");
		Log.e("//===========//","================================================");
		Log.d("","\n"+"[A_ScopePicture > readFile() 메소드 : MediaStore 파일 불러오기 실패]");
		Log.d("","\n"+"[원인 : "+String.valueOf("Cursor 객체 null")+"]");
		Log.e("//===========//","================================================");
		Log.d("---","---");
		return;
	}

	//TODO [특정 파일 불러오기 실시]
	String contentUrl = path;
	try {
		InputStream is = getContentResolver().openInputStream(Uri.parse(contentUrl));
		if(is != null){
			// [선택한 이미지에서 비트맵 생성]
			Bitmap img = BitmapFactory.decodeStream(is);
			is.close();

			// [이미지 뷰에 이미지 표시]
			view.setImageBitmap(img);
			Log.d("---","---");
			Log.w("//===========//","================================================");
			Log.d("","\n"+"[A_ScopePicture > readFile() 메소드 : MediaStore 파일 불러오기 성공]");
			Log.d("","\n"+"[콘텐츠 파일 경로 : "+String.valueOf(contentUrl)+"]");
			Log.w("//===========//","================================================");
			Log.d("---","---");
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}





//TODO [현재 시간 알아오는 메소드]
public static String getNowTime24() {
	long time = System.currentTimeMillis();
	//SimpleDateFormat dayTime = new SimpleDateFormat("hh:mm:ss");
	SimpleDateFormat dayTime = new SimpleDateFormat("yyyyMMddkkmmss");
	String str = dayTime.format(new Date(time));
	return "PT"+str; //TODO [PT는 picture 의미]
}

/* =========================== */

/* =========================== */

[결과 출력]

/* =========================== */

반응형
Comments