또 오래되면 잊어버릴지 모르니 일단 정리해 볼까 한다.
물론 기본적으로 구글 개발자 페이지에 잘정리 되어있다. 그 내용을 바탕으로 요약 및 단축하여 작성하겠다.
- 구글 개발자 페이지 링크 : http://developer.android.com/google/play/licensing/index.html
1. LVL이란?
우선 지금부터 사용할 라이브러리는 약어로 LVL(Licensing Verification Library)이다. 위의 페이지에 동작원리가 나와있다. 시간이 되면 한번 읽어보자. 안읽어봐도 적용하는데는 상관없지만 뭐 읽어두어 보자~~- LVL의 키 Interface
총 두가지이다.
Policy
LicenseCheckerCallback
2. 사전 조건
이 라이브러리가 나온지 아주 오래되어 사실 조건은 별다를게 없다.- API Level 3이상
- 인터넷 억세스 가능(라이센스 서버와 통신하므로)
3. 환경설정
- 에뮬레이터나 실기기 모두 가능하다고 나온다.- 일단 나는 실기기에서 바로 테스트 했다. 에뮬레이터에서 테스트 하려면 조금더 복잡한 과정이 필요하니 이부분은 필요하면 위의 개발자페이지를 참고하자.
- LVL의 다운로드
- 구글이 업데이트를 잘안한다. SDK Manager를 띄워서 아래의 항목을 확인한다.
- 안되어있다면 설치
- 받았다면, <sdk>/market_licensing/library/ 내부에 존재하는 라이브러리 소스를 import 해오든지 하여 library project로 이클립스 등에 가져온다.
- 가져왔다면 내가 적용시키기 원하는 프로젝트의 프로퍼티에서 해당 라이브러리를 포함시켜준다.
- 뭔말인고 하니 아래화면에서 추가해주면 된다는 이야기다.
- 이제 환경 설정은 끝났다.
4. 실제 적용
- 실제적용은 위에서 받은 Library 패키지 안의 샘플을 보면 쉽게 적용이 가능하다.- 사실 샘플 그대로 써도 대부분 무방하다고 보면된다.
- Manifest 파일.
<!-- Required permission to check licensing. --> <uses-permission android:name="com.android.vending.CHECK_LICENSE" />위의 권한을 추가해준다.
- MainActivity
가장 front의 액티비티만 고쳐주면된다. 즉 Manifest와 MainActivity 두 개만 수정하면됨
> 멤버변수 선언부
- 공개 키를 넣어주고, SALT에 임의의 숫자들을 넣어준다.
private static final String BASE64_PUBLIC_KEY = "디벨롭퍼 콘솔에서 생성된값을 여기에";// Generate your own 20 random bytes, and put them here.private static final byte[] SALT = new byte[] { -46, 11, 11, -128, -11,-57, 74, -64, 51, 88, -95, -45, 77, -22, -36, -11, -11, 11, -11,89 };private LicenseCheckerCallback mLicenseCheckerCallback;private LicenseChecker mChecker;
private Handler mHandler;
> onCreate 함수 내부.
> Inner Class 추가. Callback함수이다. 액티비티가 직접 implement 해도 된다.protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);setContentView(R.layout.activity_main);mHandler = new Handler();// Try to use more data here. ANDROID_ID is a single point of attack.String deviceId = Secure.getString(getContentResolver(),Secure.ANDROID_ID);// Library calls this when it's done.mLicenseCheckerCallback = new MyLicenseCheckerCallback();// Construct the LicenseChecker with a policy.mChecker = new LicenseChecker(this, new ServerManagedPolicy(this,new AESObfuscator(SALT, getPackageName(), deviceId)),BASE64_PUBLIC_KEY);doCheck();...
private class MyLicenseCheckerCallback implements LicenseCheckerCallback {public void allow(int policyReason) {if (isFinishing()) {// Don't update UI if Activity is finishing.return;}// Should allow user access.displayResult(getString(R.string.allow));}public void dontAllow(int policyReason) {if (isFinishing()) {// Don't update UI if Activity is finishing.return;}displayResult(getString(R.string.dont_allow));displayDialog(policyReason == Policy.RETRY);}public void applicationError(int errorCode) {if (isFinishing()) {// Don't update UI if Activity is finishing.return;}String result = String.format(getString(R.string.application_error), errorCode);displayResult(result);}}
> Dialog Method들 추가. - 이부분은 dialog가 fragment로 구현되는 요즘 버전이 아닌 옛날 버전으로 되어있다. 구글에서 샘플업데이트를 안했다. 그래서 deprecated된 함수를 그대로 쓰고 있다. 각자 고쳐서 팝업 처리하도록 하자.
protected Dialog onCreateDialog(int id) {
final boolean bRetry = id == 1;
return new AlertDialog.Builder(this)
.setTitle(R.string.unlicensed_dialog_title)
.setMessage(
bRetry ? R.string.unlicensed_dialog_retry_body
: R.string.unlicensed_dialog_body)
.setPositiveButton(
bRetry ? R.string.retry_button : R.string.buy_button,
new DialogInterface.OnClickListener() {
boolean mRetry = bRetry;
public void onClick(DialogInterface dialog, int which) {
if (mRetry) {
doCheck();
} else {
Intent marketIntent = new Intent(
Intent.ACTION_VIEW,
Uri.parse("http://market.android.com/details?id="
+ getPackageName()));
startActivity(marketIntent);
} }
})
.setNegativeButton(R.string.quit_button,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
finish();
}
}).create();
}
private void doCheck() {
// mCheckLicenseButton.setEnabled(false);
setProgressBarIndeterminateVisibility(true);
// mStatusText.setText(R.string.checking_license);
mChecker.checkAccess(mLicenseCheckerCallback);
}
private void displayResult(final String result) {
mHandler.post(new Runnable() {
public void run() {
// mStatusText.setText(result);
setProgressBarIndeterminateVisibility(false);
// mCheckLicenseButton.setEnabled(true);
}
});
}
private void displayDialog(final boolean showRetry) {
mHandler.post(new Runnable() {
public void run() {
setProgressBarIndeterminateVisibility(false);
showDialog(showRetry ? 1 : 0);
// mCheckLicenseButton.setEnabled(true);
}
});
}
> 마지막으로 onDestroy를 Override하여 아래 코드 추가.
@Overrideprotected void onDestroy() {super.onDestroy();// License 적용시mChecker.onDestroy();}
5. 완료
- 이로써 모든 적용이 끝났다. 사실 두개의 파일만 고치면 간단히 적용할 수 있다.
- 테스트는 일단 알파 혹은 베타 버전으로 apk를 업로드하고 이것을 다운받아서 실행해본다.
- 개발자 콘솔의 좌측 설정에서 계정세부정보 아래쪽을 보면 라이선스 테스트를 할 수 있다.
- Not_licensed, Licensed등으로 바꾸면서 테스트 해본다.