What is the InstallerPackageName when app is in "pending publication" phase and used/reviewed by reviewers/testers (Google Play Store)?
Asked Answered
G

2

15

SITUATION

I have a set of functionalities in my app which changes based on the store it is installed from. E.g. I want to have a more restricted set of advertisements displayed for family audiences and children to be eligible for the Google Play for Education category. In other stores i still want to restrict but don't want to be as stringent as I will be in filtering out the ads.

General observation at my end is that if I opt-in for "Google Play for Education" category it takes a few more hours to get published because of the following (as stated on the developer console):

Checking this box submits this app for inclusion in the "educator recommended" section of Google Play for Education. The final decision on which apps to recommend is made by a 3rd party network of teachers. If your app is selected, we will notify you by e-mail. If not, your app will still be searchable in Google Play for Education.

Now before the app gets published in this category the network of teachers, I assume, download and test/verify if the guidelines are met and there are no violations.

PROBLEM

To differentiate between the store installed from I'm obviously using this:

    PackageManager packageManager = context.getPackageManager();
    String installer = packageManager.getInstallerPackageName(packageName);

    if (installer == null) installer = ""; //to avoid NPE

    if (installer.equals("com.android.vending")) {
        //It is installed from Google Play store
        //PROBLEM: THIS DOES NOT SEEM TO BE THE PACKAGE NAME RETURNED
        //WHEN GOOGLE PLAY REVIEWERS/TESTERS ARE USING THE APP
    }
    else ... 
    ....
    ....
    //similarly handling other stores here
    ....
    ....
    ....
    //After that also checking by installed app stores
    ....
    ....

What is happening: After being published things app properly identifies that it is downloaded from play store i.e. it gets com.android.vending as the installerPackageName. But, when it is being reviewed or tested by the network of teachers it appears to be getting a different installerPackageName. This is causing the app to think it has been downloaded from an app store other than Google Play Store. And because of this my app is rejected from the Education category. I need to know this installer package name to handle the scenario correctly.

How do i know this: I have a dedicated ad unit id to use when the detected app store is Google Play and all requests post successful publication (i.e. from the regular play store users) come to this google dedicated ad unit id. But, in the short span of time after submitting the app/update and before the app or and update is published, a few requests come to the non-google ad unit ids, causing the app to fail adherence to the guidelines to be eligible for "Google Play for Education" category. Because, the level of ad filtering in the non-google ad unit ids is slightly less. Hence the teachers evaluating/testing the app see some ads that they think are not as per guidelines and reject it.

Also, here is an article to support the fact that the app gets reviewed manually as well as by automated script before it is actually published to the store.

Current fix or limitation: I've disabled all other ad networks and have to use only admob. The setting of filters even at the strictest level in other ad networks doesn't seem to filter all ads that Google reviewers think are not suitable for children and family audiences. When using only admob the process is smooth and I always qualify.

What I'm looking for to overcome this problem: If i get to know the installerPackageName that is returned when the app is installed from where ever the reviewing network of teachers install the app from, I can handle that case exactly as i handle when i get com.android.vending and everything will be just fine. I could not find any documentation or reference to obtain this information.

Also, if there is any other way i can identify it the app is in pending publication stage, I force all requests to go to the google ad unit id.

ASSUMPTION: There is a separate installer app for the reviewers and testers (automated/manual what ever it may be in the background) whose installerPackageName is NOT com.android.vending. If there is some Google guy around and can help confirm this (if allowed by Google), do comment. :-)

Other possibilities which i do not want to go with

Disable all other networks manually while the app is in pending publication phase and re-enable them once published. But, I don't want to do this because this would be like bluffing google and I don't want to go that way. I want my app logic to take care of it so that the same thing that is reviewed is let out in market.

I permanently stick with only admob. But this would be foolish as there are no such restrictions in other stores that I'm publishing my apps to and I will terribly lose on fill rate.

I there anyone who has had this issue before OR knows the installerPackageName for the review's download place OR knows how to determine if the app is currently in 'pending publication` state on playstore?

I can also possibly filter all by packagenames starting with com.android or com.google, but I want to keep that as last option. Also, would like to know if the installerPackage name is not set at all in case of those users. In that case I'll need to look at a completely different situation to handle the situation.

Gwendolin answered 1/1, 2016 at 14:34 Comment(3)
Another possible approach is to have different build variants, instead of relying on runtime conditions (this will also help in terms of apk size).Mcguigan
Filtering by package name without knowing the package name is likely to fail. It could be com.android... or com.googleplex... or even com.example...Mcguigan
Build variants already using. Not possible to use for this purpose in my caseGwendolin
S
1

I find one thing that can help you in this case. It's analytics. Just create your custom event eg. INSTALLER_STRING in some of analytics systems and log that event when appropriate. Here is the example of event logging in Fabric Answers.

  public static final String EVENT_OPEN_TOP_TRENDS = "EVENT_OPEN_TOP_TRENDS";
  public static final String TOP_TRENDS_TYPE = "TOP_TRENDS_TYPE";
  public static final String TYPE_TOP_TRENDS_IMAGES = "TYPE_TOP_TRENDS_IMAGES";

  public static void logEvent(String eventId, String attributeName, String name) {
    Answers.getInstance().logCustom(new CustomEvent(eventId).putCustomAttribute(attributeName, name));
  }

  logEvent(EVENT_OPEN_TOP_TRENDS, TOP_TRENDS_TYPE, TYPE_TOP_TRENDS_IMAGES);

Later on, you can see what are the sources your app was installer from on fabric website.

Socinus answered 8/1, 2016 at 9:38 Comment(12)
Sure that's a way but I dont want to include libraries and push and update (or perhaps publish a dummy app) just for this reason. I was still planning on this approach as the last means. But, thanks for your inputs.Gwendolin
Yes, you're right. Although if you're using Crashlytics (many developers do), you already have Answers included.Socinus
Other option os build flavors, so you create separate apks for different stores with the same base logic and different advertising logicSocinus
But talking about app verification on google play, I guess that at least automated testing is done using adb, where installer is going to be null (empty), so you should check your if statement for empty installer string case.Socinus
Already using build flavors for other kind of differentiation. The problem is that I have 30 flavors. If I add separate for app stores they multiply by the number of stores which is huge and will become a problem to manage. Hence the logic to identify store from the app itself so that I can use the same apk for all stores.Gwendolin
Manual testing is done by a network of teachers for the education category apps. Check the article link in my post and the quote from play store and that is where the type of ads are judged.Gwendolin
And is it possible in your situation to modify the if statement to be like (preudocode) if (playStore) { secureAds() } else if (amazonStore) { regularAds() } else if (someOtherStoreYouPublishing) { regularAds() } else if (localInstall) { regularAds() } else { secureAds() //unknown store } (although, it's better to use switch-case with java 7 in this case)Socinus
Sure, I'll do that in some time. But how will it help?Gwendolin
You just need to come from the opposite side. You probably now where you're going to distribute your app so 90+% of your installs are going to be from those sources, right? So you can than specify your logic not in a manner of GooglePlay and NonGooglePlay installation, but as (AmazonInstallation, GooglePlayInstallation and so on), LocalInstallation (apk) and UnknownInstallation. And in this case you can specify for example that for UnknownInstallation and GooglePlayInstallation app will be using secureAds() and for AmazonInstallation and LocalInstallation it will be showing regularAds()Socinus
Basically, just put secureAds for unknown installation sourcesSocinus
I have 11 stores that i publish to and except for the major ones every other store returns null when trying to get the installerPackageName (which basically means unknown installation source) :-)Gwendolin
The bounty is about to end and your inputs have been great although not exactly what I'm looking for. I'll award the bounty to this answer as it is my final fall back answer. But, I'll still wait a few more days before accepting the answer, in case someone happens to find a source giving out the exact package name. Thanks for all your inputs. Appreciated.Gwendolin
R
0

Check which results you will show using this log for all app you use do detect installer package name:

final PackageManager pm = getPackageManager();

        //get a list of installed apps.
        List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);

        for (ApplicationInfo packageInfo : packages) {
            String is = pm.getInstallerPackageName(packageInfo.packageName);//getPackageName());
            Log.d(TAG,  (packageInfo.packageName==null?"":packageInfo.packageName)  + " : " + (is==null?"":is));

        }

You will see the full list of installed apps & package sources, or log this data in your way your want. EDIT @Virus, i just want to give you a simple idea. if you want to know package installer name, you can just grab this data when you app is launched and send it to your own server using simple http GET request in order to detect the installer name. Republish you apo with this simple frabber. I think this the one solution.

Roadhouse answered 8/1, 2016 at 13:44 Comment(2)
Thanks for the input, but I think you did not get what in looking for.Gwendolin
Yes that's an option but I dont want to put something in the app that is not a functionality. I'll want to figure it the right way. Like my comment in the other answer, this is an approach I'd want to use as the last means.Gwendolin

© 2022 - 2024 — McMap. All rights reserved.