이번에는 갤러리를 통해 사진을 가져와 이미지뷰에 보여주는 것을 해보겠습니다!
1. 권한을 추가해줍니다 - AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2. 이미지뷰를 만들어줍니다 - activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="300dp"
android:layout_height="300dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="#123123" />
</androidx.constraintlayout.widget.ConstraintLayout>
일정한 크기로 가져오기 위해 width와 height를 지정해주었습니다.
3. MainActivity.java를 작성해줍니다
먼저 권한설정을 위한 함수를 만들어줍니다
public void checkSelfPermission() {
String temp = ""; //권한에 대한 상수값
//파일 읽기 권환 확인
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
temp += Manifest.permission.READ_EXTERNAL_STORAGE;
}
//파일 쓰기 권환 확인
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
temp += Manifest.permission.WRITE_EXTERNAL_STORAGE;
}
if(TextUtils.isEmpty(temp) == false){ //temp가 비어있지 않으면
ActivityCompat.requestPermissions(this, temp.trim().split(" "), 1);
}
else {
//권한허용을 했는데 작동을 안할경우 추가해줌
}
}
temp는 권한에 대한 상수값을 저장해주는 변수입니다.
checkSelfPermission()으로 권한을 자가 진단합니다. 권한이 승인되어 있지 않으면 temp에 권한을 추가합니다.
PackageManager.PERMISSION_GRANTED은 상수값으로 권한이 승인되어있다는 의미입니다.
Log를 통해 temp를 확인해보면 READ_EXTERNAL_STORAGE 와 WRITE_EXTERNAL_STORAGE 권한 문자열이 같이 들어가있습니다. 문자열이 붙어있기 때문에 split하여 분리해줘야 합니다. Log에서는 공백이 없어보이지만 두 문자열에 사이에 공백이 들어가있습니다
ActivityCompat.requestPermissions(this, temp.trim().split(" "), 1); - temp의 공백을 제거한 후 문자열을 분리하여 두 개의 권한을 추가해줍니다. 1은 requestCode입니다.
사용자가 시스템 권한 대화상자에 응답하면 시스템은 앱의 onRequestPermissionsResult() 구현을 호출합니다
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == 1) {
int length = permissions.length;
for(int i=0; i<length; i++) {
if(grantResults[i] == PackageManager.PERMISSION_GRANTED) {
//허용 확인 되었을 때의 동작
}
else {
}
}
}
}
아까 requestCode가 1이었으므로 requestCode == 1일 경우로 동작을 구현해줍니다. 이 코드에서는 딱히 동작을 정의해주지는 않았습니다.
변수를 정의해주고 onCreate()를 구현해줍니다.
ImageView iv;
private static final int GET_FROM_GALLERY = 101; //requestCode
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkSelfPermission();
iv = (ImageView)findViewById(R.id.imageView);
iv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent();
i.setType(MediaStore.Images.Media.CONTENT_TYPE);
i.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(i, GET_FROM_GALLERY);
}
});
}
i.setType(MediaStore.Images.Media.CONTENT_TYPE); - 갤러리를 열어줍니다
i.setAction(Intent.ACTION_GET_CONTENT); - 갤러리에서 사진을 가져옵니다
startActivityForResult(i, GET_FROM_GALLERY); - 액티비티를 실행합니다. requestCode는 위에서 정의해준 상수값을 사용합니다. 숫자값으로 직접쓸 경우 외부에서 접근이 가능하므로 상수값으로 정의해서 접근하지 못하도록 해줍니다.
다음은 메인액티비티에서 갤러리로 넘어갔다가 다시 메인액티비티로 돌아올 때 호출되는 메소드입니다.
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 101 && resultCode == RESULT_OK) { //startActivityForResult 정상 동작했다면
try {
InputStream is = getContentResolver().openInputStream(data.getData());
Bitmap bm = BitmapFactory.decodeStream(is);
is.close();
iv.setImageBitmap(bm);
} catch (Exception e) { //예외처리
e.printStackTrac();
}
}
else if(requestCode == 101 && resultCode == RESULT_CANCELED) { //정상 동작하지않는다면
Toast.makeText(this,"취소", Toast.LENGTH_LONG).show();
}
}
InputStream is = getContentResolver().openInputStream(data.getData()); - contentResolver()는 내장데이터에 접근하기 위한 메소드입니다. InputStream을 통해 데이터를 가져옵니다.
Bitmap bm = BitmapFactory.decodeStream(is); - is는 이미지파일이 아니라 데이터 타입이므로 비트맵으로 변환해줍니다.
iv.setImageBitmap(bm); - 갤러리에서 가져온 이미지를 이미지뷰에 넣어줍니다.
'Android' 카테고리의 다른 글
[Android] Room 데이터 베이스 (0) | 2020.12.18 |
---|---|
[Android] 7주차 스터디 (Camera) (0) | 2020.11.29 |
[Android] 5주차 스터디 (RecyclerView) (0) | 2020.11.25 |
[Android] Bottom Navigation and Fragment with Jetpack (0) | 2020.11.04 |
[Android] ViewHolder 패턴 (0) | 2020.10.29 |