我们使用Google Play扩展APK机制获得了大约600MB的扩展文件。我们还必须解压缩此文件以供实际使用。整个应用程序加数据因此需要大约1.4 GB的存储空间。
据我所知,Google Play坚持将.obb下载到“内部”SD,似乎无法改变这种情况。我们有很多用户在他们的“外部”SD卡上有很多可用空间,但内部空间有限。他们尖叫着应用程序占用了这么多空间。我们能做些什么吗?
我们目前将.obb文件扩展为:
getExternalStorageDirectory()/ Android设备/数据
我想我们可以问用户他们想要的地方,他们可以选择真正的外部SD卡。然而,这仍然会在内部SD卡上留下(基本上无用的).obb文件,Google Play说我们无法删除它。
有没有人对如何正确处理这个问题有任何建议?
答案 0 :(得分:2)
根据Expansion File Storage Location documentation,扩展文件存储在
中<shared-storage>/Android/obb/<package-name>/
其中shared-storage
是getExternalStorageDirectory()
返回的内容,对于拥有SD卡的用户,应该在SD卡上。
不幸的是,如同一页上所述:
为确保正常行为,您不得删除,移动或重命名扩展文件。
我会特别注意这一段:
如果您必须解压缩扩展文件的内容,不要之后删除.obb扩展文件,不要将解压缩的数据保存在同一目录中。您应该将解压缩的文件保存在getExternalFilesDir()指定的目录中。但是,如果可能,最好使用扩展文件格式,允许您直接从文件中读取,而不是要求您解压缩数据。例如,我们提供了一个名为APK Expansion Zip Library的库项目,它直接从ZIP文件中读取数据。
答案 1 :(得分:1)
将OBB文件放在其他任何地方的问题是,当用户卸载您的应用程序时,它们将不会被删除,这往往会使他们心情不好,温和地说明。但是,如果您认为收益超过成本,则没有任何技术可以阻止您更改存储位置,因为执行OBB文件的源代码下载和提供验证,您可以修改其行为以满足您的需求。
例如,存储OBB文件的路径由com.google.android.vending.expansion.downloader.Helpers
:
static public String getSaveFilePath(Context c) {
File root = Environment.getExternalStorageDirectory();
String path = root.toString() + Constants.EXP_PATH + c.getPackageName();
return path;
}
(还需要修改getFilesystemRoot(String path)
&amp; isFilenameValid(String filename)
)
如果您同时使用Google的扩展zip文件库,那么您还需要在com.android.vending.expansion.zipfile.APKExpansionSupport
中更改指定Environment.getExternalStorageDirectory()
作为根目录的3个方法。
这些改变至少应该让你到那里一半。
另请注意,外置SD卡的问题在于它们的速度变化很大,通常情况下内部SD至少会有不错的速度。也许您可以将OBB分成2个文件(假设您不需要更新文件功能),并将其中一个移动到外部SD。
答案 2 :(得分:0)
我遇到了同样的问题,但我找到了解决问题的方法。
如果删除OBB,则didFileExist(在Helpers.java中)将返回false。在ExpDownloaderActivity中,检查expansionFilesDelivered,您将使用此信息重新下载OBB。
我已经改变了didFileExist和expandFilesDelivered,其方式是不返回布尔值,而是返回具有以下含义的整数:
fileStatus == 0:缺少OBB(必须下载)
fileStatus == 1:OBB可用,可以解压缩到其他地方
fileStatus == 2:OBB中的数据已经存储到另一个地方
现在te技巧: 在将数据从OBB解压缩到我喜欢的位置后,我将原始OBB替换为同名文件,该文件只包含原始OBB的文件大小作为字符串。这释放了SD卡上占用的空间。
对didFileExist和expansionFilesDelivered的进一步调用将返回filestatus = 2,这意味着,不需要任何操作。
以下是我在Helpers.java中的更改:
static public int doesFileExist(Context c, String fileName, long fileSize,
boolean deleteFileOnMismatch) {
// the file may have been delivered by Market --- let's make sure
// it's the size we expect
File fileForNewFile = new File(Helpers.generateSaveFileName(c, fileName));
if (fileForNewFile.exists()) {
if (fileForNewFile.length() == fileSize) {
return 1;
} else if (fileForNewFile.length() < 100) {
// Read the file and look for the file size inside
String content = "";
long isSize = 0;
FileInputStream fis = null;
try {
fis = new FileInputStream(fileForNewFile);
char current;
while (fis.available() > 0) {
current = (char) fis.read();
content = content + String.valueOf(current);
}
} catch (Exception e) {
Log.d("ReadOBB", e.toString());
} finally {
if (fis != null)
try {
fis.close();
} catch (IOException ignored) {
}
}
try {
isSize = Long.parseLong(content);
} catch(NumberFormatException nfe) {
Log.d("ReadOBBtoInt", nfe.toString());
}
if (isSize == fileSize) {
return 2;
}
}
if (deleteFileOnMismatch) {
// delete the file --- we won't be able to resume
// because we cannot confirm the integrity of the file
fileForNewFile.delete();
}
}
return 0;
}
如果OBB的文件大小不匹配,我读取OBB并与存储在其中的文件大小进行比较(这就是filesize应该是什么)。如果这给出匹配,我知道该文件已经处理完毕。
这是我对ExpDownloaderActivity的更改:
int expansionFilesDelivered() {
int fileStatus = 0;
for (XAPKFile xf : xAPKS) {
if (xf.mFileSize > 0) {
String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsMain, xf.mFileVersion);
fileStatus = Helpers.doesFileExist(this, fileName, xf.mFileSize, false);
if (fileStatus==0)
return 0;
}
}
return fileStatus;
}
在ExpDownloaderActivity的onCreate中:
initializeDownloadUI();
int fileStatus = expansionFilesDelivered();
if (fileStatus==0) { // OBB is missing
// ... Download the OBB file, same as on Downloader example
} else if (fileStatus==1) {
validateXAPKZipFiles(); // and, if OBB has no errors, unpack it to my favorite place
// if done, create a new OBB file with the original name
// and store a string with the original filesize in it.
} else {
finish(); // No action required }
所以我把数据解压缩到任何我想要的地方 - 正如OP提到的那样 - 不需要sdcard上的空间来获得完整的OBB 和解压缩的数据。