昨天我们介绍了Android Market新的付费软件保护机制-LVL我们今天一起来看看如何集成密钥以及LVL库到Android项目中,这样做目前可以有效保证及时是Root权限的设备也无法正常的使用。
1. 在项目的androidmanifest.xml文件中加入<uses-permission android:name="com.android.vending.CHECK_LICENSE">权限,使其Market客户端可以检测授权状态。
2.制定一个策略Policy,本质上 Android Market licensing 服务并没有判断给用户赋予什么样的权限,在Policy接口中提供了两个方法分别为allowAccess() 和 processServerResponse() 他们均被 LicenseChecker 从服务器响应权限信息明确时被回调。
processServerResponse() 的原始定义 lets you preprocess the raw response data received from the licensing server, prior to determining whether to grant access.
allowAccess() 的解释为determines whether to grant the user access to your application, based on any available license response data (from the licensing server or from cache) or other application-specific information.
3. 添加导入
使用默认的策略时导入
import com.android.vending.licensing.LicenseChecker;
import com.android.vending.licensing.LicenseCheckerCallback;
当然我们自定义策略,比如ServerManagedPolicy或AESObfuscator则应该导入
import com.android.vending.licensing.ServerManagedPolicy;
import com.android.vending.licensing.AESObfuscator;
4. 我们实现LicenseCheckerCallback接口为一个私有的内部类,比如代码
private class MyLicenseCheckerCallback implements LicenseCheckerCallback {
public void allow() {
if (isFinishing()) {
return;
}
displayResult(getString(R.string.allow));
}
public void dontAllow() {
if (isFinishing()) {
return;
}
displayResult(getString(R.string.dont_allow));
}
}
上面仅实现allow和dontAllow两个方法,但是可能会有网络错误或Market服务器问题,所以我们还要重写applicationError()方法获取错误信息,服务器主要的响应有LICENSED、LICENSED_OLD_KEY、NOT_LICENSED、ERROR_CONTACTING_SERVER、ERROR_SERVER_FAILURE、ERROR_INVALID_PACKAGE_NAME、ERROR_NON_MATCHING_UID、ERROR_NOT_MARKET_MANAGED具体的方法,可以通过类似
public boolean allowAccess() {
long ts = System.currentTimeMillis();
if (mLastResponse == LicenseResponse.LICENSED) {
// Check if the LICENSED response occurred within the validity timeout.
if (ts <= mValidityTimestamp) {
// Cached LICENSED response is still valid.
return true;
}
} else if (mLastResponse == LicenseResponse.RETRY &&
ts < mLastResponseTime + MILLIS_PER_MINUTE) {
// Only allow access if we are within the retry period or we haven’t used up our
// max retries.
return (ts <= mRetryUntil || mRetryCount <= mMaxRetries);
}
return false;
}
5. 处理逻辑
private Handler mHandler;
@Override
public void onCreate(Bundle savedInstanceState)
{
mHandler = new Handler();
//dosomething
}
private void displayResult(final String result)
{
mHandler.post(new Runnable()
{
public void run()
{
mStatusText.setText(result);
setProgressBarIndeterminateVisibility(false);
mCheckLicenseButton.setEnabled(true);
}
});
}
有关主类的Activity这样添加
public class MainActivity extends Activity {
private LicenseCheckerCallback mLicenseCheckerCallback;
private LicenseChecker mChecker;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLicenseCheckerCallback = new MyLicenseCheckerCallback(); // Construct the LicenseChecker with a Policy.
mChecker = new LicenseChecker( this, new ServerManagedPolicy(this, new AESObfuscator(SALT, getPackageName(), deviceId)), BASE64_PUBLIC_KEY // Your public licensing key. );
//dosomething
}}
上面代码中BASE64_PUBLIC_KEY是你从Market账户发布页面上获取的公钥我们定义 private static final String BASE64_PUBLIC_KEY = "CWJdfeksdfadf….."; ,上面的SALT为20个随机的字节,比如我们任意选20个字节样本来做RSA运算
private static final byte[] SALT = new byte[] { -46, 65, 30, -128, -103, -57, 74, -64, 51, 88, -95, -45, 77, -117, -36, -113, -11, 32, -64, 89 };
最后有关检测的过程,我们可以这样写
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
doCheck();
}
private void doCheck()
{
mCheckLicenseButton.setEnabled(false);
setProgressBarIndeterminateVisibility(true);
mStatusText.setText(R.string.checking_license);
mChecker.checkAccess(mLicenseCheckerCallback);
}
最后做清理,我们重写onDestory方法在Activity中
@Override
protected void onDestroy() {
super.onDestroy();
mChecker.onDestroy();
}
现在来看Android Market的许可服务看上去复杂,其实如果使用默认策略直接加入库引用代码还是很简单的,Android123推荐大家实际尝试下,整个的代码在SDK和AVD更新工具后SDK根目录会有LVL的完整的samples代码,明天Android开发网继续我们的游戏开发之旅系列教程。
RSS