앞선 글에서 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 명')하지 않아도 동작은 했었으나 일단 다음과 같이 코딩하였다.

public class FileRearrange extends AppCompatActivity{

    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이 가능해 진다.

<?xml version="1.0" encoding="utf-8"?>
<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 예시의 LongClickListener 부분을 다음과 같이 수정하였다.
      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들을 다시 살펴볼 필요가 있어 보인다.

     

  

 

+ Recent posts