개발 관련/Android

[TIP] Activity 활성화 및 비활성화.

snoworca 2014. 9. 15. 16:06

  우선 AndroidManifest.xml 에서 액티비티를 설정할 때, 속성값으로 액티비티 활성화/비활성화 값을 줄 수 있다. 만약 액티비티 비활성화를 한다면, Context 내의 startActivity 메소드를 이용하여 비활성화 된 액티비티를 호출시 앱은 ActivityNotFoundException 을 발생시키고 크래쉬가 발생하게 된다.  또 런처에서 실행시키기 위하여 <activity> 내부의 설정 앨리먼트 <intent-filter> 로  <action android:name="android.intent.action.MAIN"/> 과  <category android:name="android.intent.category.LAUNCHER"/> 옵션을 지정해줬다고 해도 런처내에 액티비티의 아이콘이 표시되지 않는다. 


     그리고, 이 것을 Manifest 파일에서만이 아닌 코드상에서도 PackageManager 의  setComponentEnabledSetting 으로 제어할 수 있다.

    사용법은 무지 간단한데, 만약 Activity 내부에서 호출한다면 다음과 같은 코드를 사용하면 된다.


액티비티 비활성화:

PackageManager pm = getPackageManager(); pm.setComponentEnabledSetting(new ComponentName(getApplicationContext(), HiddenActivity.class), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);


    만약 두 번째 인자를 COMPONENT_ENABLED_STATE_ENABLED 로 준다면 비활성화된 액티비티는 다시 활성화가 된다. 

    세 번째 인자를 0으로 준다면 이 설정이 종료된 시점에서 액티비티가 강제 종료되게 되는데, 만약 이 인자값을 PackageManager.DONT_KILL_APP 를 주게 된다면 앱은 종료되지 않은 상태로 설정값만 바뀌게 된다. 다만 어떻게 동작할지 모르니 주의하여 사용하여야 한다. (안드로이드 API 레퍼런스 바로가기 링크)  또 한가지 주의할 점은, 만약 setComponentEnabledSetting 메소드의 세 번째 인자값을 0으로 줬을 때 이 메소드의 호출이 종료되는 시점에 앱이 종료된다는 것이다. 


    이 메소드를 통하여 설정한 액티비티의 활성화/비활성화 속성은 저장되어,  앱을 강제종료하거나 재부팅을 하여도 계속 유지된다.

  

    다음 예제를 통하여 어떻게 동작하는지 한 번 살펴보자.    

    우선 액티비티를 두 개를 만들고, 액티비티에 서로 다른 아이콘을 붙여놓았다.





 좌측의 아이콘 이름은 ic_launcher_1

우측의 아이콘 이름은  ic_launcher_2



AndroidManifest.xml:

... 생략

        <activity android:name="MainActivity"
            android:icon="@drawable/ic_launcher_1">
            <intent-filter >
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        
        <activity android:name="HiddenActivity"
            android:icon="@drawable/ic_launcher_2"
            android:label="Hidden"
            android:enabled="false">
            <intent-filter >
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>



HiddenActivity.java:

public class HiddenActivity extends MainActivity{
}


MainActivity.java:

public class MainActivity extends Activity {
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 프레임 레이아웃을 만들고, 
		// 여기에 버튼을 하나 생성한다.
		// 그리고 프레임 레이아웃을 Context View 로 정의한다.
		FrameLayout layout = new FrameLayout(getApplicationContext());
		Button buttonHiddenActivityEnable = new Button(this);
		buttonHiddenActivityEnable.setText(isThisHiddenActivity()?"Disable this Activity":"Enable HiddenActivity");
		FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
		params.gravity = Gravity.CENTER;
		buttonHiddenActivityEnable.setLayoutParams(params);
		layout.addView(buttonHiddenActivityEnable);
		buttonHiddenActivityEnable.setOnClickListener(mOnClickListener);
		setContentView(layout);
		setTitle((isThisHiddenActivity()?"Hidden Activity":"Main Activity"));
	}
	
	private OnClickListener mOnClickListener = new OnClickListener() {
		@Override
		public void onClick(View v) {
			finish();
			PackageManager pm = getPackageManager();
			pm.setComponentEnabledSetting(new ComponentName(getApplicationContext(), HiddenActivity.class), 
			(isThisHiddenActivity()?PackageManager.COMPONENT_ENABLED_STATE_DISABLED:PackageManager.COMPONENT_ENABLED_STATE_ENABLED), 0);
		}
	};
	
	private boolean isThisHiddenActivity() {
		return this instanceof HiddenActivity;
	}
}



  좀 귀찮아서 하나의 액티비티에 구현 코드를 몰아넣었다. 어쨌든 액티비티는 두개다. 

  이 코드를 실행하면 액티비티 실행 아이콘이 하나만 존재한다. 

  매니페스트 파일에서 android:enable 값을 false 로 준 HiddenActivity 는 런처에 아이콘조차 표시되지 않는다.




  만약 앱을 실행시켜서 다음 스샷에 있는 버튼을 누른다면 앱이 완전히 종료되고, HiddenActivity 를 띄울수 있는 아이콘이 표시된다.

  

   


  


     이 버튼은 누르면 앱이 종료되고, HiddenActivity 를 띄울 수 있게 된다.



이제 HiddenActivity 를 띄워서 버튼을 누르면 다시 HiddenActivity 는 disabled 되고 버튼은 감춰진다.

(다시 enable 하기전 까지는 사용할 수 없게 된다.)