创buildAPK扩展文件的步骤
我已经开发应用程序并成功地工作。
我已将应用程序许可function用于我的应用程序。 现在我要上传一个谷歌播放应用程序。
请让我知道的步骤,如何使用应用程序的授权,以及如何创buildAPK扩展文件?
扩展文件取消了上传超过50MB的apk大小的限制。 上传apk文件时必须附上这个文件。 每个应用程序可以为每个APK提供高达4GB(2GB – 主,2GB – 补丁)的附加数据。
在创build扩展文件时,您必须遵循命名惯例
[main|patch].<expansion-version>.<package-name>.obb
注意:
-
main
– 这些文件没有这个你的应用程序将不会运行 -
patch
– 是那些额外的文件,没有这个应用程序可以运行 -
expansion-version
– 你给apk的版本,以便不同版本的扩展文件不会冲突 -
package-name
– 这是您唯一的包名称
.obb
我们不是附加的,它会在上传的时候隐式附加在Google上
假设你有当前目录中的所有内容,所以只需select所有的内容,并将其制作成一个名为main.2.com.xyz.abc.zip
的zip main.2.com.xyz.abc.zip
,并在上传apk文件时添加它
这一切上传部分,现在下载部分
首先,您需要通过点击SDK-Manager来下载Google额外的软件包
现在从现有的源创build新项目, 并从pathsdk-path / extras / google导入market_licensing , play_apk_expansion
请记住:免费的应用程序不需要授权,但需要扩展的概念,您只需要不经意地参考market_licensing到您的项目就可以隐式pipe理。
play_apk_expansion
包含三个项目downloader_library
, zip_file
, downloader_sample
。
downloader_library本身具有Market_licensing的参考。
现在你只需要把注意力集中在downloader_sample
首先将包名称(用于testing)更改为你的包名(包名与上传的apk相同)
很重要
在SampleDownloaderActivity
导航到…
private static final XAPKFile[] xAPKS = { new XAPKFile( true, // true signifies a main file 2, // the version of the APK that the file was uploaded // against xxxxxxxxxxxL // the length of the zipfile in bytes right click on you expansion file and get the size in bytes, size must be same as zip size ), };
现在这个活动将下载扩展文件,并将其存储在sdcard/Android/obb/[main|patch].<expansion-version>.<package-name>.obb
忽略obb,只需解压缩到任何你想要的文件( sdcard/Android/data
推荐,因为它卸载时,你的应用程序被删除)。
有最新的设备直接从Play商店下载扩展文件,它存储在sdcard/Android/obb/
所以你必须非常小心检查所有的情况下
- Obb已经下载了
- 有效内存
- 下载但不解压缩
- 要select的内存(请参阅内存情况)
记忆案例:
如果你采取任何新的设备或前。 micromax的funbook,那么它有三个内存
- / data / data /(手机内存) getFilesDirectory()
- / mnt / sdcard /(手机的内部sdcard) Environment.getExternalStorageDirectory()
- / mnt / extsd /(外部sdcard) / mnt / extsd
希望这会帮助你,并会满足你的要求。
还有一件事使用下面的ZipHelper
来解压缩内容。
ZipHelper.java
public class ZipHelper { boolean zipError=false; public boolean isZipError() { return zipError; } public void setZipError(boolean zipError) { this.zipError = zipError; } public void unzip(String archive, File outputDir) { try { Log.d("control","ZipHelper.unzip() - File: " + archive); ZipFile zipfile = new ZipFile(archive); for (Enumeration e = zipfile.entries(); e.hasMoreElements(); ) { ZipEntry entry = (ZipEntry) e.nextElement(); unzipEntry(zipfile, entry, outputDir); } } catch (Exception e) { Log.d("control","ZipHelper.unzip() - Error extracting file " + archive+": "+ e); setZipError(true); } } private void unzipEntry(ZipFile zipfile, ZipEntry entry, File outputDir) throws IOException { if (entry.isDirectory()) { createDirectory(new File(outputDir, entry.getName())); return; } File outputFile = new File(outputDir, entry.getName()); if (!outputFile.getParentFile().exists()){ createDirectory(outputFile.getParentFile()); } Log.d("control","ZipHelper.unzipEntry() - Extracting: " + entry); BufferedInputStream inputStream = new BufferedInputStream(zipfile.getInputStream(entry)); BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile)); try { IOUtils.copy(inputStream, outputStream); } catch (Exception e) { Log.d("control","ZipHelper.unzipEntry() - Error: " + e); setZipError(true); } finally { outputStream.close(); inputStream.close(); } } private void createDirectory(File dir) { Log.d("control","ZipHelper.createDir() - Creating directory: "+dir.getName()); if (!dir.exists()){ if(!dir.mkdirs()) throw new RuntimeException("Can't create directory "+dir); } else Log.d("control","ZipHelper.createDir() - Exists directory: "+dir.getName()); } }
首先,假设您正在使用/assets/helloworld.jpg中的helloworld.jpg进行扩展
- 创build一个zip文件,但使用以下文件模式,结束文件扩展名.obb:
`[main|patch].{expansion-version}.{package-name}.obb`
例如,如果您的pkg名称是“com.earth.helloworld”和版本= 1
那么你的输出扩展文件名应该是: patch.1.com.earth.helloworld.obb
这是一个包含helloworld.jpg的zip文件
在创buildzip文件之后,请注意文件大小: 2.然后在你的SD卡上创build这个文件夹如果不存在:
/ mnt / sdcard / Android / obb / {你的包名} /
即/mnt/sdcard/Android/obb/com.earth.helloworld/
-
然后上传你的obb文件到你的SD卡,例如/mnt/sdcard/Android/obb/com.earth.helloworld/patch.1.com.earth.helloworld.obb
-
然后创build一个方法来获取扩展文件
public ZipResourceFile getExpansionFile() { String fileName = Helpers.getExpansionAPKFileName(this, false, 1); int filesize = 445461159; if (Helpers.doesFileExist(this, fileName, , false)) { try { return APKExpansionSupport.getAPKExpansionZipFile( getBaseContext(), 1, 1); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; }
-
最后使用这两行来获取helloworld.jpg
InputStream istr = getExpansionFile().getInputStream(strName);
Bitmap bitmap = BitmapFactory.decodeStream(istr);
在这篇文章中,最后一些人的一些helfull信息,因为有一些事情改变了apk扩展的工作方式,也是如果你使用Android Studio使图书馆工作。
注1
您不能再使用草稿作为链接来获取扩展文件将不会被激活。 您必须首先使用扩展文件将版本上传到Alpha或Beta。 (添加一个扩展文件只能从你上传和下载的第二个apk文件中获得)所以当你点击APK下的开发者发布部分的详细信息时,请确保你看到了apk扩展文件。
笔记2
如果你正在使用android studio,并且想要使用下载器库,不要将包名和java文件复制到你自己的应用程序src目录中。 在eclipse中导入下载器库并selectexport => gradle构build文件。 之后,您可以将该库作为android studio中的模块导入。
注3
不知道这一点,但我也认为这是至关重要的下载应用程序一次通过游戏商店,并有权访问它与您的testing设备上的帐户。 所以,如果你正在使用alpha创build一个谷歌+testing组,并添加自己或其他testing设备。
BTW
有了这些库,实现apk扩展下载非常容易,只要确保:
-
您的活动(下载没有自动完成时要实现下载扩展包的活动)实现IDownloaderClient。
-
你设置了服务和接收器,并将其设置在清单中。
-
服务类中的BASE64_PUBLIC_KEY是正确的。 上传第一个apk =>在开发者控制台中的服务和API中查看您的应用程序=>此应用的许可代码。
此代码用于查看是否可以在设备上find扩展文件:
boolean expansionFilesDelivered() { for (XAPKFile xf : xAPKS) { String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsMain, xf.mFileVersion); Log.i(TAG, "Expansion filename " +fileName); if (!Helpers.doesFileExist(this, fileName, xf.mFileSize, false)) return false; } return true; }
它使用XAPKS类来表示一个扩展文件,无论是主文件还是修补文件,都有一个文件大小(字节),并与一个apk版本(最初添加的文件)相关联。
private static class XAPKFile { public final boolean mIsMain; // true public final int mFileVersion; //example 4 public final long mFileSize; //example 126515695L // example => main expansion that was first introduced in apk version 4 and is 126515695 bytes in size XAPKFile(boolean isMain, int fileVersion, long fileSize) { mIsMain = isMain; mFileVersion = fileVersion; mFileSize = fileSize; } }
使用google提供的zip工具(com.android.vending.zipfile),也可以直接从扩展文件中读取电影文件和其他内容。
首先使用库中提供的方法获取扩展文件,参数是代表您的主要扩展apk版本(您需要的扩展包第一次添加的apk版本)和补丁apk版本的整数。
ZipResourceFile expansionFile = APKExpansionSupport.getAPKExpansionZipFile(context, APKX_MAIN_APK, APKX_PATCH_APK);
video
从这个zipresourcefile直接播放video:
AssetFileDescriptor a = expansionFile.getAssetFileDescriptor(pathToFileInsideZip);
现在从这个assetFileDescriptor中你可以得到一个FileDescriptor,并在你的mediaplayer中使用它,正确的语法让你的mediaplayer播放video也需要第二个和第三个参数。不pipe它是从AssetFileDescriptor得到的起始偏移量和长度。
player.setDataSource(a.getFileDescriptor(), a.getStartOffset(), a.getLength());
其他
对于所有其他的东西(如图像),你可以得到一个zip文件的inputstream:
expansionFile.getInputStream(pathToFileInsideZip);`
此外,请确保你不压缩在这个压缩video工作! 例如不要压缩.mp4文件:
zip -n .mp4 -r zipfile.zip . -x ".*" -x "*/.*"
只是想添加一些我在实现这个过程中学到的东西:
1)截至目前,你不需要实现下载器库和所有的XAPKFile的东西,所有你需要做的是复制/粘贴在https://developer.android.com/google/play上列出的所有权限/expansion-files.htmljoin你的清单文件。; 也许您曾经这么做过,但Google Play商店会为您处理下载和安装。 您需要处理源代码中的实际下载的唯一原因是用户手动进入Android / obb并删除了您的扩展文件。
2)上传您的.zip文件时,不必将其命名为main.version.package.obb约定。 只需上传您的.zip文件的原始名称,它将被重新命名,无论你。
3)要访问压缩文件,请转至文件>新build>导入模块,然后导入与下载器和许可证库位于相同目录中的zip_file库。 确保添加到您的应用程序的build.gradle文件中的依赖项:compile project(':zip_file')。 这使得你可以在你的项目中导入这些库。
我希望这是有帮助的。 我基本上花了数小时的时间来实现网站上列出的(复杂的)下载库代码,最后我删除了所有的代码,只保留了清单中的权限,并且工作正常。
在Eclipse中您的项目,请单击鼠标右键,请按照以下步骤操作:Android工具 – >导出签名的应用程序包 – > ….