Problems testing APK expansion library

被刻印的时光 ゝ 提交于 2019-12-03 19:56:08

问题


I've integrated the APK Expansion file download library from Google into my project, and it works more or less OK (except a few minor gotchas, which have been reported by others on SO already).

However, I have a hard time testing it. When I was first testing it, I uploaded my signed APK + main expansion file version 1 to Google Play, and it worked well.

However, when I upgraded my application, together with main expansion file version 2, the application could no longer download the file - the library immediately returns with NO_DOWNLOAD_REQUIRED, but the file is not there! I started debugging the LVL check passes, but the downloadable files table was empty! While I was trying to debug the details... it suddenly started to work again!

I assumed this was a sort of temporary glitch and continued my work, just to hit the same issue again, after updating my APK and expansion file again. Application passes the LVL check, but again library assumes there are no files to download.

Is it a known problem with Google's library? Or perhaps I need to wait some time until the files is available on Google's cloud?

EDIT: It just started working OK. It really seems it needs some time for the file to somehow propagate on Google's side. One bad thing about the library is that once it validates the license, it never checks the download list again, so I had to reinstall the app. Weird... Why the heck is it so complex?


回答1:


A little thread necromancy, but since I had so much trouble getting the OBB downloading to work I wanted to put all the problems in one place. Quite how - or indeed why - Google managed to make downloading a file from t'internet quite this complicated is beyond me.

Adding the Libraries to Android Studio

The official instructions proudly brought to you by the Ministry of Misinformation (https://developer.android.com/google/play/expansion-files.html) are simply wrong.

Before importing the libraries, go to sdk\extras\google\market_apk_expansion\downloader_library and edit project.properties to remove the "android.library.0" line entirely. You may also need to update the android target version line in the same file to match your existing project's target version.

Following the installation instructions on the page linked above, "Preparing to use the Downloader Library" Step 2 should be "File > New > Import Module" and not "File > New > New Module".

After importing both modules, go to "File > Project Structure" and add dependencies:

  • Your app should have a "Module Dependency" on both the licensing and downloader libraries
  • The downloader library should have a "Module Dependency" on the licensing library

The step that says "You must update the BASE64_PUBLIC_KEY value to be the public key belonging to your publisher account." is also wrong. You need the public key for this specific app, not your account, which is in the online Developer Console under "Services & APIs" after you've selected the app.

Both the License Validation Library and the Downloader Library have dependencies on a now-removed package "org.apache.http"

Replace two instances of "decodeExtras" method (one in APKExpansionPolicy.java, one in ServerManagedPolicy.java) with:

private Map<String, String> decodeExtras(String extras) {
    Map<String, String> results = new HashMap<String, String>();

    UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
    sanitizer.setAllowUnregisteredParamaters(true);
    sanitizer.setUnregisteredParameterValueSanitizer(new UrlQuerySanitizer.IllegalCharacterValueSanitizer(
            UrlQuerySanitizer.IllegalCharacterValueSanitizer.URL_LEGAL));
    sanitizer.parseQuery(extras);

    for (UrlQuerySanitizer.ParameterValuePair item : sanitizer.getParameterList()) {
        String name = item.mParameter;
        int i = 0;
        while (results.containsKey(name)) {
            name = item.mParameter + ++i;
        }
        results.put(name, item.mValue);
    }

    return results;
}

Crash at runtime, saying "Service Intent must be explicit"

See the answer at https://stackoverflow.com/questions/24480069.

W/LicenseValidator: Error contacting licensing server

The license validation library won't work on an emulator, and this is the error it throws. If you're on a real device, it may just be a genuine timeout.

Debug versions fail a signature check (Signature verification failed), so are denied access.

The binary that is calling the license verification service must be a correctly-signed, release version. If you're running a debug copy that won't be the case, so the license checks fail.

  • Go to your online Developer Console, Settings, Account Details
  • Change the "License Test Response" to "LICENSED" (or whatever you're testing)
  • Enter your email address under "Gmail accounts with testing access".

Downloader returns "STATE_COMPLETED" but download is not done.

This is a side-effect of the previous change. You are licensed, but the APK extension files are still not provided because you're not really licensed. This step is what allows you to actually test the downloads as they happen after distribution, instead of manually placing files onto your test devices.

  • Create a promo code for the app.
  • Create a new user on your device, for a totally new GMail account.
  • Log in to your device as the new user, redeem the promo code. You are now a genuine app owner.
  • Add the new gmail account under "Gmail accounts with testing access", as in the previous section.

You can't do this with the developer's account because purchasing or redeeming will fail, which means you can never own a copy of your own product, which means that the OBB download will never work.

Now that you have a second account, with a genuine Play Store copy of the app and which is registered as a test account with a 'fake' LICENSED status, you can run a debug copy of your code, get the LICENSED status, and have the downloads work as you'd expect.

W/LVLDL: Aborting request for download whavever.obb: while writing destination file: java.io.FileNotFoundException:

Since Android v23 it's been necessary to explicitly request permissions to write to "external storage", whether it's an SD card or not, and on top of having the permission listed in your manifest. See https://developer.android.com/guide/topics/permissions/requesting.html .

The "File not found" is referring to the directory on the external storage that the downloader library wants to put the OBB file into, which it has been unable to create. An exception gets raised if it can't create the file, but it fails silently if it can't create the directory. See processResponseHeaders() in DownloadThread.java .

W/LVLDL: Aborting request for download main.whatever.obb: http error 410

Your app's version number must match one from a current APK that Google knows about otherwise your download request will be rejected with error 410.

Library will not re-check the license if it's found to be valid once.

If you're testing, chances are you need to re-do things a few times. The License Verification Library caches it's state after it's been found to be LICENSED. You can clear this without totally uninstalling your app:

DownloadsDB db = DownloadsDB.getDB(my_app_context);
db.updateMetadata(0, 0);

It also keeps the downloaded OBB in place, which can be found and cleared using:

final String dlName = Helpers.getExpansionAPKFileName(my_app_context, true, expansionVersion);
final String dlFullPath = Helpers.generateSaveFileName(my_app_context, dlName);
File dlFile = new File(dlFullPath);
if (dlFile.exists())
{
    dlFile.delete();
}

Now, if you'll excuse me, I'm off to a spiritual retreat for a month or so.




回答2:


The APK + Expansion workflow has other non-intuitive and undocumented gotchas, besides the propagation time described by the author:

  1. Increase the APK versionCode but keep using the same (old) Expansion file. It seems that if you do not upload the new APK to your developer console, the download won't work from the updated app (directly installed using adb). The error message is not helpful either: "download failed because the resources could not be found". To me it looks like Google is saying "Ok, I know about this Expansion file version, but I don't know about this app version". I didn't find any reference to this requirement in the current documentation.

  2. New APK uploaded to developer console seems to "capture" the Expansion file association from the old APK. Example: If you delete the new APK (but keeping the old, which has the same version as the Expansion), the Expansion file seems to go away as well. Perhaps they thought the workflow would be "we must associate the Expansion with the new APK, so the developer is free to erase the old APK without any problem". Still this is another gotcha that doesn't seem to be described anywhere.

These are preliminary notes. I submitted a support request which might confirm these findings so I will post updates here when (if?) they reply...




回答3:


There are two standard ways to get the expansion files.(you can take it as assumption).

  1. Assume you don't have expansion file at the beginning when your application starts.
  2. Check if the file is present in the obvious locationor not.

This way your app will behave as usual. The best part of this approach is you have an option to place a request to download the files.

these are the notes from developer site.

Note: The URL that Google Play provides for your expansion files is unique for every download and each one expires shortly after it is given to your application.

Note: Whether your application is free or not, Google Play returns the expansion file URLs only if the user acquired your application from Google Play.

Here is how to use
Here is how to place download request

Hope this will help you to get the result.




回答4:


If you are using complete code from sample app, have you changed the version code in below piece of code:-

private static final XAPKFile[] xAPKS = {
        new XAPKFile(
                true, // true signifies a main file
                <Version code here>, // the version of the APK that the file was uploaded
                   // against
                49597391L // the length of the file in bytes
        ),

};


来源:https://stackoverflow.com/questions/11933508/problems-testing-apk-expansion-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!