앞선 글에서 Activity 생애주기(Life Cycle)를 고려하여 gallery와 gallery adapter를 onCreate()가 아니라 onStart()에 생성 및 연결을 했을 경우, camera intent 호출 후 새로 찍은 사진이 gallery에 정상 반영됨을 확인했다. 이를 보면서 사진을 삭제한 후에도 onStart()를 불러온다면 문제가 해결되겠다는 생각이 들었는데, 이를 구현하기 위해서 사진을 삭제하는 과정 자체를 새 intent로 불러왔다가 종료하여 MainActivity가 onRestart()가 되도록 해야했다. 그래서 이번에는 App. 내부에 새로운 activity를 추가해 intent로 활용하는 방법을 알아봤다.
1. 목적 : Intent를 만들어 activity의 작동 구조를 이해하여 보자.
2. 개발 환경
- PC : Windows 7, Android Studio 1.4.1(64-bit)
- Phone : LG G pro Lollipop(API 21)
3. 참고자료
1) Android Developers - Intent Reference (http://developer.android.com/reference/android/content/Intent.html)
2) Android Developers - 인텐트 및 인텐트 필터 (http://developer.android.com/intl/ko/guide/components/intents-filters.html)
4. 과정
일반적인 Intent 생성 및 작동 예제에 내가 필요한 기능을 추가했다.
1) 새로 추가할 intent의 layout이 될 .xml 파일을 다음과 같이 '/layout' directory 밑에 생성한다. 필요에 따라 layout_main.xml을 활용하듯이 Button, ImageView, TextView 등을 추가하여 새로운 activity를 구성하면 된다.
2) Intent가 될 새 Activity를 생성한다. 'extends Activity'한 class java file을 다음과 같이 '/java' 밑에 만들고 MainActivity에서 onCreate() 내부에 내용을 쓰듯이 원하는 동작을 작성하면 된다. 나 같은 경우에는 단순히 AlertDialog를 사용하기 위해 intent를 불러오므로 따로 setContentView(R.layout.'intent layout file 명')하지 않아도 동작은 했었으나 일단 다음과 같이 코딩하였다.
String delFilePath = null; // MainActivity에서 삭제할 file의 경로를 받을 String 변수 선언
@Override
protected void onCreate(Bundle savedIntanceState){
super.onCreate(savedIntanceState);
setContentView(R.layout.activity_file_rearrange);
final Intent receiveIntent = getIntent(); // MainActivity에서 intent를 받음
delFilePath = receiveIntent.getStringExtra("delFilePath"); // MainActivity의 intent에서 추가한 data 참조
/* 이하 AlertDialog 활용 */
AlertDialog.Builder builder = new AlertDialog.Builder(FileRearrange.this);
builder.setTitle("파일을 삭제하시겠습니까?");
builder.setNegativeButton("아니오", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss(); // 해당 AlertDialog의 dismiss() 및
finish(); // receiveIntent의 finish();
}
});
builder.setPositiveButton("예", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
File file = new File(delFilePath);
file.delete(); // receive 받은 data를 활용해 file 삭제 후
finish(); // receiveIntent의 finish();
}
});
Dialog dialog = builder.create();
dialog.show();
}
}
3) AndroidMainfest.xml 에 (2)에서 만든 Activity를 <application>...</application> 내부에 다음과 같이 <activity>...</activity>하여 선언한다. 이를 통해 App. 내부 Activity같의 communication이 가능해 진다.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.zip.customcameragalleryexample" >
<uses-feature android:name="android.hardware.camera2" android:required="false" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:hardwareAccelerated="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 이하 activity 추가 부분 -->
<activity android:name=".FileRearrange"> <!-- 위의 activity class명과 동일 -->
<intent-filter>
<action android:name="com.example.zip.customcameragalleryexample.filerearrange"/> <!-- intent 생성시 참조 -->
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<!-- 이상 activity 추가 부분 -->
</application>
</manifest>
4) MainActivity.java 에서 파일을 삭제하고자 할 때 FileRearrange로 넘어가도록 다음과 같이 intent를 생성 및 추가한다. Intent 의 생성 → 필요할 경우 data 추가 → 해당 Intent의 start 순서로 넘어감을 이해하면 된다.
customGallery.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
final int tmpPosition = position;
final String delFilePath = basePath + File.separator + imgs[tmpPosition];
Intent intent = new Intent(MainActivity.this, FileRearrange.class);
intent.putExtra("delFilePath", delFilePath);
startActivity(intent);
return false;
}
});
(위 Code의 실행 결과)
원하는 동작이 오류 없이 실행되긴 했으나, 새로 intent를 불러오니 MainActivity 가 보이지 않았다. 그래서 OnItemLongClick 내부에서 file 삭제 후 다시 gallery를 불러오도록 해당 method를 재선언을 하자니 이 방법은 재귀적이라 app 자체가 비정상적으로 종료해서 쓸 수가 없었다. 아무래도 Adapter에서 배열의 변화를 감지하여 update가 되도록 notifyDataSetChanged() 와 같은 adapter의 method들을 다시 살펴볼 필요가 있어 보인다.
'개발일지' 카테고리의 다른 글
[Android 기초] GridView를 이용한 Image Gallery(List) 제작 (0) | 2015.12.12 |
---|---|
[Android 기초] Adapter에 대한 이해 (1) | 2015.12.11 |
[Android 기초] Application의 Activity Life Cycle(Activity 생애 주기) 01 - 이론 (0) | 2015.12.08 |
[Android 기초] AlertDialog를 활용한 알림창 띄우기 02 - Custom AlertDialog (0) | 2015.12.08 |
[Android 기초] AlertDialog을 활용한 알림창 띄우기 01 - 기본 (0) | 2015.12.08 |