关于Google Play商店中obb文件意外情况下无法下载的处理
上面讲了如何加载obb文件,相信大家应该也大致知道obb是什么了。
在Google Play后台上传apk的时候,apk大小有一个限制,不能够超过100M(应用我不太清楚,但最起码游戏是这样的),那么对于游戏来说,这可能不是个好消息,因为游戏随随便便就可以超过100M,那么我们需要把资源抽出来,单独打包成obb文件,在后台上传apk的时候,同时上传obb文件。
审核通过之后,用户在Google Play中可以下载到我们的app,商店中显示的实际大小应该是apk+obb的大小,也就是说实际上在帮用户下载apk的同时,Google Play也一起下载了obb。但是Google的官方文档注明,不能保证百分之百成功下载,所以需要开发者在启动app前,判断一下本地是否有相应的obb,如果没有,那么需要重新下载。
那么如何在启动时,判断是否需要下载obb呢。首先要提到之前说的Google Play APK Expansion library和Google Play Licensing Library。上篇文章中描述了如何下载这两个库,但是不推荐使用Android SDK Manager下载到的Google Play APK Expansion library库。因为官方应该已经很久没维护过了,所以有些类已经被废弃掉,不适用新版本的Android SDK。(传送门:下载)下载之后,我们需要在工程中引用apkx_library、zip_file和market_licensing/library三个module。《关于Google Play商店中obb文件的加载》中已经提到了zip_file,这里不再赘述。
注意:apkx_library依赖market_licensing/library,所以需要在build.gradle中设置依赖。导入module大的时候不要忘记在setting.gradle中include。
引用后需要修改一些文件:
com.google.android.vending.licensing.LicenseChecker类的checkAccess()
public synchronized void checkAccess(LicenseCheckerCallback callback) { |
com.google.android.vending.expansion.downloader.DownloaderClientMarshaller.Stub类的connect()
|
修改完成后,如果要自己开发下载界面的话,按照apkx_library文件夹中的AndroidManifest.xml添加即可。本文这里使用的是apkx_sample文件夹中提供的demo,AndroidManifest.xml文件也按照demo添加即可。
把src下的java文件和res拷贝到主工程中(如有冲突,自行合并),在主工程的build.gradle中引用这几个support库。dependencies {
compile fileTree(include: '*.jar', dir: 'libs')
compile project(':plugin:plugins:GooglePlayObbService:downloader_obb')
compile project(':plugin:plugins:GooglePlayObbService:market_licensing')
compile project(':plugin:plugins:GooglePlayObbService:zip_file')
//-------------add-------------
compile 'com.android.support:appcompat-v7:26.0.0'
compile 'com.android.support:design:26.0.0'
compile 'com.android.support:support-compat:25.2.0'
//-------------add-------------
}
在主工程的AndroidManifest.xml文件中添加如下代码:<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--Google Play OBB Download Begin-->
<activity
android:name="[文件所在包名].SampleDownloaderActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/Base.Theme.AppCompat" />
<activity
android:label="@string/app_name"
android:name="[文件所在包名].SampleVideoPlayerActivity"
android:theme="@style/VideoFullScreen"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboard|keyboardHidden" >
</activity>
<!--
In order to start the service, it must be uniquely registered with
the package manager here.
-->
<service android:name="[文件所在包名].SampleDownloaderService" />
<!--
In order for the alarm manager to contact the downloader script, the receiver
must be uniquely registered with the package manager here.
-->
<receiver android:name="[文件所在包名].SampleAlarmReceiver" />
<!--
Providers must have a unique authority per application.
Change the android:authorities line to something unique to your
application (such as its package name) if you wish to use the
provider.
The format will be content://com.example.google.play.apkx/[zipfilepath].
-->
<provider
android:authorities="[文件所在包名]"
android:exported="false"
android:multiprocess="true"
android:name="[文件所在包名].SampleZipFileProvider">
<meta-data android:name="mainVersion" android:value="3"/>
</provider>
<!--Google Play OBB Download End-->
还有几处java文件的修改:
MainActivity.java
protected void onCreate(Bundle savedInstanceState){ |
SampleDownloaderActivity.java
//修改为自己需要的参数 |
在void validateXAPKZipFiles()中,validationTask对象调用execute方法时,我把它加入了UiThread。(虽然不知道有没有用,但是在别的帖子中看到有人说这个问题。于是就加上了。)this.runOnUiThread(new Runnable() {
public void run() {
validationTask.execute(new Object());
}
});
加入onResume方法。/**
* Connect the stub to our service on resume.
*/
protected void onResume() {
if (null != mDownloaderClientStub) {
mDownloaderClientStub.connect(this);
}
super.onResume();
}
startMovie是在验证文件结束后,界面上有一个确定按钮,点击事件中会调用这个方法。应该是demo中的骚操作,但我们这里不需要,所以我改成了以下内容,重新跳转回游戏activity。private void startMovie() {
// launch the movie player activity
// Uri mediaUri = Uri.withAppendedPath(SampleZipFileProvider.ASSET_URI,
// "big_buck_bunny_720p_surround.m4v");
// Intent intent = new Intent();
// intent.setData(mediaUri);
// intent.putExtra(Intent.EXTRA_TITLE, mediaUri.getLastPathSegment());
// intent.setClass(this, SampleVideoPlayerActivity.class);
// startActivity(intent);
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
SampleDownloaderService.java
//替换为自己的KEY,在Google后台查询自己的RSA公共密钥 |
SampleZipFileProvider.java
// must match what is declared in the Zip content provider in |
在依赖这些module的时候,可能会遇到这样一个无法import的问题。
请尝试在build.gradle中做如下修改。
android { |
到此,修改基本完成。在测试之前,请先确认不添加下载逻辑的情况下,使用本地挂载方式,把obb放到/storage/emulated/0/Android/obb/[包名]路径下是否能够正常读取。
在测试下载逻辑之前,请先将手机安装Google Play全家桶。并将已添加为测试账号的Google Play账号在手机上登陆(因为只有测试账号才能看到内测版App),并进入Google Play中下载已提审通过的内测版App。之后如有修改,安装相同签名以及包名的apk即可直接调试,不用再次提交审核。
参考文献:
https://blog.csdn.net/androidworkor/article/details/70226726