티스토리 뷰

크리에이티브 커먼즈 라이선스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시 2.0 대한민국 라이선스에 따라 이용하실 수 있습니다.
본문

 Android Settings를 컨트롤 할 수 있는 Provider가 있습니다. JellyBean 4.2부터는 Global속성이 추가되었고, 이 속성은 기존의 Settings.System 또는 Settings.Secure 변수들이 모두 Settings.Global로 통합 이관되었습니다. 소스코드 작성을 하다보면 Settings.System 또는 Settings.Secure로 작성하게되면 줄이 그어집니다. 줄이 그어지는 이유야 추후에 삭제될 수도 있는 변수의 표시이니 Settings.Global로 동작하게하면 될 것 같습니다. 제가 작성한 API 버전은 4.2인 API 17 버전입니다.

 해당 내용은 아래 사이트로 접속하여 Global 로 검색하시면 확인 가능합니다.

   http://developer.android.com/about/versions/android-4.2.html


 그리고 4.2버전부터는 해당 속성을 통한 몇 몇 메소드들의 접근이 제한되게 됩니다. 일단은 제가 확인한 속성은 AirplaneMode의 접근이 제한되었습니다. 무조건 4.2 이상에서는 Android 설정에 접근하여 직접 수정을 해야 합니다. 그 외 다른 속성들은 각각의 Manager를 통해서 접근이 가능하기에 문제되지 않습니다. 위의 내용을 참고하면 4.2에서는 워닝 메시지가 표시됩니다. 워닝 메시지는 아래와 같고 실제로 동작하지 않습니다. 그러니 Version 체크를 통한 간단한 예외처리를 작성해주시면 됩니다.


Android Settings API

  http://developer.android.com/reference/android/provider/Settings.html

Android Settings.Global API

  http://developer.android.com/reference/android/provider/Settings.Global.html


예제를 작성하기에 몇가지 문제

 Settings.Global로 이관이 되었다고하여 최신 API 17을 적용하고 코드를 작성하였습니다. API 17이전 API에서 동작을 할까의 문제가 발생합니다. 실제로 2.3.3에서 실행하면 찾을 수 없는 정의로 에러가 표시됩니다. 

Settings.Global.putInt(getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);

위와 같이 처리하면 4.2 이전에서는 아래와 같이 정의되지 않은 타입의 에러가 표시됩니다.


 4.2의 JellyBean에서는 아래와 같이 "<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />"을 AndroidManifest.xml에 추가하라고 합니다.


AndroidManifest.xml에 해당 퍼미션을 추가하면 아래와 같이 "Permission is only granted to system apps"이란 오류가 포함됩니다. 시스템에서 승인한 앱에서만 접근이 가능하다고 하여 설정을 할 수 없습니다.

 해당 퍼미션을 삭제하고 4.2 이전 버전으로 코딩을 하게 되면 이클립스에서는 곧 삭제될 수도 있는 변수타입이니 사용하지 말라는 표시가 추가됩니다. putInt 부분은 정상적으로 표시가 되지만 다음 부분은 "Settings.System.AIRPLANE_MODE_ON" 처럼 표시가 됩니다.


 최종적으로 4.2 이전버전에서도 호환이 되도록 설정하려면 아래와 같이 작성하면 됩니다. 단, 4.2에서는 실제로 동작하지 않습니다.

Settings.System.putInt(getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);

 위와 같이 코드를 작성하고나면 Airplane Mode가 ON이 됩니다. 2.3.3에서 테스트하면 정상으로 동작하지만 4.2 JellyBean에서 테스트하면 아래와 같이 워닝 메시지가 표시됩니다.

이 문제는 Android 이슈로 등록이 되어 있다고 하고, 지금의로서의 해결방법은 안드로이드 Airplane Mode 설정창을 뛰워서 해결하는 방법밖에 없다고 합니다. 이 방법을 적용하여 예외처리하는 예제코드를 작성하였습니다.


사용 Method

 Settings.System.putInt(ContentResolver cr, String name, int value) - 비행모드를 셋팅합니다.

 Settings.System.getInt(ContentResolver cr, String name) - 현재 비행모드 상태를 가져옵니다.

 Settings.Global.AIRPLANE_MODE_ON - Airplane Mode On이라는 String 값을 가져옵니다. (스트링 값이기에 "airplane_mode_on"라고 작성해도 됩니다. 하지만 추후에 이름이 변경될 수도 있으니 API에서 제공해주는 코드를 작성하는게 좋겠죠.

 Intent - Intent를 통해 AirplaneMode 상태를 변환하게 됩니다.


예제코드

 예제코드는 간단하며 기존의 Settings.System 또는 Settings.Secure로 작성하지 않고 새롭게 이관된 Settings.Global를 사용하였습니다. Global로 작성한다고해서 2.3.3에서 동작하지 않는건 아닙니다. API 버전이 17이니깐 문제없이 동작합니다.

 간단한 예제코드로서 Version이 JellyBean 4.2 이라면 Android 설정창의 AirplaneMode 페이지로 이동하고 그렇지 않다면 토글되게 됩니다.

MainActivity.java - 메인 코드입니다. 버튼에 따라서 동작하지만 필요한 중요 코드만 추가하였습니다.

//지원되는 버전인지 체크하고, 비행모드 On/OFF에 따라서 설정 변경
private void setAirplaneMode(int mode) {
	if (!getAndroidVersionCheck()) {
		goToAirplaneModeSettings();
		return;
	}
		
	Settings.System.putInt(getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, mode);
	Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        intent.putExtra("state", mode);
        sendBroadcast(intent);
}
	
//Android 비행모드 설정창으로 이동
private void goToAirplaneModeSettings() {
	getToastMessage(R.string.airplaneMode_toggle_notSupport);
	Intent intent = new Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS);
	startActivity(intent);
}
	
//JellyBean 4.2 (JellyBean MR1)보다 낮은 Version Check
private boolean getAndroidVersionCheck() {
	if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) return true;
	return false;
}
	
//비행모드 ON/OFF Check
private boolean getAirplaneModeCheck(int mode) {
	if (Settings.System.getInt(getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, AIRPLANEMODE_OFF) == mode) {
		return true;
	}
	return false;
}

AndroidManifest.xml - 아래와 같이 Permission을 추가하여야 합니다.

<uses-permission android:name="android.permission.WRITE_SETTINGS" />

샘플 코드 화면

 예제 코드의 화면은 아래와 같이 구성하였습니다. 현재의 On/OFF 상태를 가지고 와서 상태에 맞는 값을 동작하게 합니다. 단, 4.2 이상에서는 On/OFF 설정이 불가능하기 때문에 안드로이드 설정창으로 이동하는 코드를 작성하였습니다.

마무리

 JellyBean 4.2 이전까지는 잘 동작하던 AirplaneMode Chagne가 4.2 부터는 적용이 불가능하여 작성한 예제코드입니다. 4.2 이전에는 문제가 없지만 Global로 이관된 부분까지 모두 추가하여 작성하여 보았습니다. 소스코드는 아래 소스코드 다운로드 부분에서 다운 받으시면 됩니다.


소스코드 다운로드

  https://www.dropbox.com/s/tghg95a8g42lqkn/AirplaneModeExample.zip?dl=0



개인 광고 영역


댓글
  • 프로필사진 BlogIcon 젠틀캣 안녕하세요? 지금 이 고민중에 이포스팅을 보게 되었습니다.
    4.2이후 버전 4.3 4.4등도 역시 안되는건가요? 현재 4.3으로 테스트중인데.. WRITE_SECURE_SETTINGS 퍼미션 메시지가 나오고 있는 상태입니다
    2014.11.22 05:01 신고
  • 프로필사진 BlogIcon taehwan 권한이 수정된 부분으로 4.2 이상 버전에서는 동일하게 동작하지 않게 됩니다. 다른 권한과는 다르게 관리자 권한으로 상승해버러셔.. 적용이 어렵습니다. 2014.11.23 22:52 신고
  • 프로필사진 비밀댓글입니다 2014.12.29 15:36
  • 프로필사진 BlogIcon taehwan 링크가 깨져있었군요. 주소는 : https://www.dropbox.com/s/tghg95a8g42lqkn/AirplaneModeExample.zip?dl=0 입니다. 2014.12.29 21:51 신고
댓글쓰기 폼