Search code examples
androidandroid-intentandroid-package-managers

When to use application ID or package name a.k.a. is the PackageManager#getLaunchIntentForPackage method name incorrect?


When do I use 'application ID' or 'package'?

(or is it 'package name'?)

My confusion in a practical situation:

One way to switch from one app to another is to get a launch intent for the app, which could be done using (given some context):

PackageManager manager = context.getPackageManager();
Intent intent = manager.getLaunchIntentForPackage(packageName);

Note that the parameter's name is called packageName and that even the method name mentions 'package'. However, this is not the package name! It is the application ID we should be using here!

For example, if I have a debug build type that instead of the release application ID com.example has a debug suffix, e.g. it is com.example.debug, I have to use "com.example.debug" as the parameter to getLaunchIntentForPackage. But the app's package namespace remains unchanged (by default): it is still com.example! If I don't have my non-debug app installed, the getLaunchIntentForPackage method returns null, because application ID com.example isn't installed.

So what am I looking at here? I would think that com.example is my package name and that com.example.debug is my application ID. But why does the PackageManager#getLaunchIntentForPackage method mention 'package' and 'package name', while would think that it should mention 'application ID' instead?

Is this just an incorrectly named method in the Android SDK, or am I misunderstanding something?

I base my question on the following information.

From the documentation on application IDs, I quote:

Every Android app has a unique application ID that looks like a Java package name, such as com.example.myapp. This ID uniquely identifies your app on the device and in Google Play Store. If you want to upload a new version of your app, the application ID (and the certificate you sign it with) must be the same as the original APK—if you change the application ID, Google Play Store treats the APK as a completely different app. So once you publish your app, you should never change the application ID.

[...]

When you create a new project in Android Studio, the applicationId exactly matches the Java-style package name you chose during setup. However, the application ID and package name are independent of each other beyond this point. You can change your code's package name (your code namespace) and it will not affect the application ID, and vice versa (though, again, you should not change your application ID once you publish your app). However, changing the package name has other consequences you should be aware of, so see the section about modifying the package name.

So the application ID uniquely identifies you app on the Play Store. The package name is the namespace of subpackages and classes in your application code base. So far so good, I understand this.

However, at the end of this documentation page we have the following even more confusing highlight:

One more thing to know: Although you may have a different name for the manifest package and the Gradle applicationId, the build tools copy the application ID into your APK's final manifest file at the end of the build. So if you inspect your AndroidManifest.xml file after a build, don't be surprised that the package attribute has changed. The package attribute is where Google Play Store and the Android platform actually look to identify your app; so once the build has made use of the original value (to namespace the R class and resolve manifest class names), it discards that value and replaces it with the application ID.

So here we have multiple contradictions on one page!

  1. Google Play identifies app by application ID vs. package.
  2. The manifest's package name can differ from the application ID vs. at compile time the package is overwritten by the application ID by the build tools.

From this highlight, at least the statement about the build tools overwriting the package name by the application seems to be incorrect, because:

When creating an intent for activity com.example.MainActivity in app com.example.debug I have to specify com.example.debug as the application ID and com.example.MainActivity as the component name. At runtime, the component name hasn't changed its package name to the application ID, so it seems that the package namespace isn't changed by the build tools?

I hope that...

...somebody can create a nice answer with various examples that show when an application ID and package (name) are the same, or when they are not, and where the Android system and Google Play actually use which. Please also consider an example with a library dependency: as far as I understand, the library's package namespace doesn't change, but it runs with your application ID, am I right?


Solution

  • The android:package attribute in the <manifest> is what we are talking about here. It used to be referred to as "package name", and is still referred to as "package name" in some older documentation. It is NOT a Java package name, even though it looks like one, and it has nothing to do with the Java package names in your source code.

    Recently this attribute is referred to as "Application ID", especially in documentation related to Firebase, Play store, etc.

    It is the same thing. "package name" is "application ID".

    Refer to https://developer.android.com/guide/topics/manifest/manifest-element.html#package

    NOTE:

    There is one place where things might get confusing and that is the shorthand notation for component names within the manifest. For example:

        <activity
                android:name=".ui.activities.MainActivity">
        </activity>
    

    in this case, the android:name attribute specifies the "fully qualified Java class name of the Activity". However, if the name begins with a period (as in this example), the application's "package name" (from the android:package attribute of the <manifest> tag) is prepended to the name of the class to form the fully qualified Java class name of the Activity.

    If you have a situation where the android:package attribute is changed for different build variants (as in your example using debug in the package name), you should NOT use the shorthand notation for component names within the manifest! You should always use the fully qualified name, like this:

        <activity
                android:name="com.mycompany.mypackage.ui.activities.MainActivity">
        </activity>