430

I am aware of the availability of Context.getApplicationContext() and View.getContext(), through which I can actually call Context.getPackageName() to retrieve the package name of an application.

They work if I call from a method to which a View or an Activity object is available, but if I want to find the package name from a totally independent class with no View or Activity, is there a way to do that (directly or indirectly)?

user12205
  • 2,684
  • 1
  • 20
  • 40
ef2011
  • 10,431
  • 12
  • 49
  • 67
  • 7
    Accepted answer will cause your application to occasionally CRASH - read comments by AddDev & Turbo and thanks to them both for suggesting solutions. – nikib3ro Jul 18 '12 at 07:16
  • 1
    You may not have another option, but as a matter of best practice I'd say it's better to pass this into the class you need it in from your last Context point in some way. You're accessing runtime context information from a class that doesn't know about Contexts in a static way - smells bad to me. Another approach would be to hard-code it somewhere. – Adam Jul 15 '13 at 05:10

15 Answers15

571

An idea is to have a static variable in your main activity, instantiated to be the package name. Then just reference that variable.

You will have to initialize it in the main activity's onCreate() method:

Global to the class:

public static String PACKAGE_NAME;

Then..

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    PACKAGE_NAME = getApplicationContext().getPackageName();
}

You can then access it via Main.PACKAGE_NAME.

John Leehey
  • 22,052
  • 8
  • 61
  • 88
  • 3
    This seems the most practical solution for me right now but it does require me to create a subclass of the activity... +1 for now. – ef2011 Jul 05 '11 at 23:12
  • 1
    Just found a similar reference: http://stackoverflow.com/questions/2002288/static-way-to-get-context-on-android – ef2011 Jul 06 '11 at 15:57
  • 14
    My understanding is that `final` makes it immutable, initialize-able **only in a constructor** and **only once**. `onCreate()` is not a constructor. Please correct if I am mistaken. – ef2011 Jul 06 '11 at 16:31
  • You're correct. onCreate() is perfectly capable of being called more than once. My mistake. Thanks for clarifying that. – John Leehey Jul 06 '11 at 17:01
  • 95
    This approach is incorrect. For example if your application goes to the background when you are on a secundary activty, and then is restored. The onCreate() of your main activity could not be called and your PACKAGE_NAME will be null!. Additionally what if your application have 10 entry points and there is no a clear "main activity"? You can check my answer at this question for the correct approach – Addev Feb 25 '12 at 15:50
  • 1
    If the app goes to the background, aren't the variables kept in memory? onCreate() just needs to be called once. – John Leehey Feb 27 '12 at 18:08
  • 2
    @JohnLeehey, if the app goes to the background, there's a chance the Android system will kill the process at some point, causing the static variables to be reset. I've run into a few problems in Android because of this behavior, and have thus tried to only use static variables to store non-persistent data. – Tony Chan Jul 13 '12 at 20:37
  • 4
    @Turbo, if Android kills the process, `onCreate` will have to be called again anyway, so this solution still shouldn't be a problem. – John Leehey Jul 13 '12 at 21:22
  • 1
    @JohnLeehey That's what I thought too, but I've noticed a slightly different behavior beginning with ICS (at least on my Nexus S). I believe it's true that `onCreate` should be called again after the process is killed, but I think starting with ICS the application will continue in whatever Activity it left off in. Say you launch an Application and go from Activity A -> Activity B, then leave the app and do some memory intensive stuff, then come back, it will still be in Activity B and any static variables you set in Activity A will be reset/null. I'm not sure what ICS changes cause this. – Tony Chan Jul 18 '12 at 02:03
  • Won't it cause memory leaks? A static `String` holds the same reference that a string returned by `getApplicationContext().getPackageName()` does. – Maksim Dmitriev Nov 14 '13 at 07:46
  • 1
    @MaksimDmitriev the static variable will only remain as long as the application exists in memory. The context of the static variable is inside that of the application. Once the application is destroyed, I believe the static reference to the package name string will be removed. – John Leehey Nov 14 '13 at 07:54
  • I always prefer to use `BuildConfig.APPLICATION_ID` – TapanHP May 11 '18 at 05:30
  • NOTE: Package name (Java package name declared in manifest) and Application ID (Play Store Unique name) are NOT the same things. The api names are now wrong, as pointed out in the docs: `Note: The application ID used to be directly tied to your code's package name; so some Android APIs use the term "package name" in their method names and parameter names, but this is actually your application ID. For example, the Context.getPackageName() method returns your application ID. There's no need to ever share your code's true package name outside your app code.` – Brendon Whateley Nov 15 '18 at 16:48
  • @JohnLeehey I have an App2 which is downloaded from App1, how can I get the version of App1? (You can imagine this as downloading App from play store but in actual the App1 is not play store) – Astha Garg May 09 '22 at 07:57
375

If you use the gradle-android-plugin to build your app, then you can use

BuildConfig.APPLICATION_ID

to retrieve the package name from any scope, incl. a static one.

Flow
  • 23,572
  • 15
  • 99
  • 156
Billda
  • 5,707
  • 2
  • 25
  • 44
  • 33
    That is the proper way, should be the accepted answer. – aberaud Sep 16 '15 at 17:29
  • 7
    Note: With multi-flavor builds this will return (depending on the import used to get access to the BuildConfig class) the package name of the default configuration not the package name of the flavor. – Rolf ツ Jun 29 '16 at 14:29
  • 2
    @Rolfツ That is not true, it will return the right package name of application ;) maybe you are mistaking it with package name of your java classes – Billda Jun 29 '16 at 15:17
  • Nope I'm not, APPLICATION_ID will only return the correct packagename if you included the auto generated BuildConig class from your flavor (e.g. com.example.myapp.flavor1.BuildConfig instead of com.example.myapp.BuildConfig) – Rolf ツ Jun 29 '16 at 15:20
  • 37
    Be careful if using this in a library project - this will not work. – zyamys Jun 07 '17 at 21:22
  • 9
    Be careful if using this in multiple modules inside a project as well. – user802421 Oct 25 '17 at 05:06
  • If using a library, you can always use a Context object and then call getPackageName(). See answers below or https://stackoverflow.com/questions/42769004/how-to-get-main-applicationid-inside-code-in-the-library-module – narko Feb 22 '18 at 10:28
  • 2
    @aberaud It's not the proper way or the accepted answer because it relies on a specific configuration, whereas the accepted answer uses the platform API. – Abandoned Cart Jun 08 '19 at 00:40
  • I wounder why it has so many votes? The author asked for package name, not Application ID! – Leo DroidCoder Sep 05 '21 at 21:07
70

If with the word "anywhere" you mean without having an explicit Context (for example from a background thread) you should define a class in your project like:

public class MyApp extends Application {
    private static MyApp instance;

    public static MyApp getInstance() {
        return instance;
    }

    public static Context getContext(){
        return instance;
        // or return instance.getApplicationContext();
    }

    @Override
    public void onCreate() {
        instance = this;
        super.onCreate();
    }
}

Then in your manifest you need to add this class to the Name field at the Application tab. Or edit the xml and put

<application
    android:name="com.example.app.MyApp"
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    .......
    <activity
        ......

and then from anywhere you can call

String packagename= MyApp.getContext().getPackageName();

Hope it helps.

Pratik Butani
  • 60,504
  • 58
  • 273
  • 437
Addev
  • 31,819
  • 51
  • 183
  • 302
  • This isn't thread safe, but you can probably get away with it if the background thread is started by this activity later on. – tomwhipple Dec 12 '11 at 19:46
  • 3
    It is thread safe since the reference to instance is the first thing set when the app is launched – Addev Feb 25 '12 at 16:01
  • 18
    Per this issue: http://code.google.com/p/android/issues/detail?id=8727 ContentProvider objects are created prior to the Application object, apparently contrary to documentation, but also apparently by and according to design. This could result in your instance still being unset if getInstance() were called during a ContentProvider's initialization. – Carl Jun 26 '12 at 18:51
  • 3
    The documentation on [`Application.onCreate()`](http://developer.android.com/reference/android/app/Application.html#onCreate%28%29) has been changed to reflect this: it now specifically states "Called when the application is starting, before any activity, service, or receiver objects (excluding content providers)". – Paul Lammertsma Nov 01 '13 at 15:03
  • 2
    This should be the selected answer, because the context will never die out no matter what activity is running. – Elad Nava Dec 12 '13 at 13:03
46

If you use gradle build, use this: BuildConfig.APPLICATION_ID to get the package name of the application.

Youngjae
  • 24,352
  • 18
  • 113
  • 198
Mahendra Liya
  • 12,912
  • 14
  • 88
  • 114
  • 7
    Application ID and package name are different things. Application ID is defined via the gradle.build file, and package name is defined in the Manifest. While they often have the same value, they also often differ, in more complex build scenarios. One can assign different application IDs to different build configurations while the package name remains unchanged. – Uli Feb 08 '16 at 22:35
  • 3
    @Uli For those who want to know the nuances in a bit more detail http://tools.android.com/tech-docs/new-build-system/applicationid-vs-packagename – Kevin Lee Apr 08 '16 at 12:32
  • 11
    @Uli That being said, even if the applicationId in app.gradle defers from the packageName inside of the AndroidManifest.xml, calling context.getPackageName() returns the applicationId and not the packageName inside of AndroidManifest.xml. The point of the new build system was to decouple both, so applicationId is the app's actual package name known to Google Play and to the device it is installed on - it cannot change after deployment. My point is, it is ok to use BuildConfig.APPLICATION_ID. Do let me know if I'm mistaken (: – Kevin Lee Apr 08 '16 at 15:47
  • 2
    @kevinze Entirely accurate! I ran a test to double-check. Thanks for the clarification/correction. – Uli Apr 09 '16 at 17:35
13

For those who are using Gradle, as @Billda mentioned, you can get the package name via:

BuildConfig.APPLICATION_ID

This gives you the package name declared in your app gradle:

android {
    defaultConfig {
        applicationId "com.domain.www"
    }
}

If you are interested to get the package name used by your java classes (which sometimes is different than applicationId), you can use

BuildConfig.class.getPackage().toString()

If you are confused which one to use, read here:

Note: The application ID used to be directly tied to your code's package name; so some Android APIs use the term "package name" in their method names and parameter names, but this is actually your application ID. For example, the Context.getPackageName() method returns your application ID. There's no need to ever share your code's true package name outside your app code.

user1506104
  • 6,554
  • 4
  • 71
  • 89
11

Just use this code

val packageName = context.packageName 
Daniel Park
  • 268
  • 3
  • 8
6
private String getApplicationName(Context context, String data, int flag) {

   final PackageManager pckManager = context.getPackageManager();
   ApplicationInfo applicationInformation;
   try {
       applicationInformation = pckManager.getApplicationInfo(data, flag);
   } catch (PackageManager.NameNotFoundException e) {
       applicationInformation = null;
   }
   final String applicationName = (String) (applicationInformation != null ? pckManager.getApplicationLabel(applicationInformation) : "(unknown)");
   return applicationName;

}
davegson
  • 8,205
  • 4
  • 51
  • 71
bala7s
  • 61
  • 1
  • 1
4

You can get your package name like so:

$ /path/to/adb shell 'pm list packages -f myapp'
package:/data/app/mycompany.myapp-2.apk=mycompany.myapp

Here are the options:

$ adb
Android Debug Bridge version 1.0.32
Revision 09a0d98bebce-android

 -a                            - directs adb to listen on all interfaces for a connection
 -d                            - directs command to the only connected USB device
                                 returns an error if more than one USB device is present.
 -e                            - directs command to the only running emulator.
                                 returns an error if more than one emulator is running.
 -s <specific device>          - directs command to the device or emulator with the given
                                 serial number or qualifier. Overrides ANDROID_SERIAL
                                 environment variable.
 -p <product name or path>     - simple product name like 'sooner', or
                                 a relative/absolute path to a product
                                 out directory like 'out/target/product/sooner'.
                                 If -p is not specified, the ANDROID_PRODUCT_OUT
                                 environment variable is used, which must
                                 be an absolute path.
 -H                            - Name of adb server host (default: localhost)
 -P                            - Port of adb server (default: 5037)
 devices [-l]                  - list all connected devices
                                 ('-l' will also list device qualifiers)
 connect <host>[:<port>]       - connect to a device via TCP/IP
                                 Port 5555 is used by default if no port number is specified.
 disconnect [<host>[:<port>]]  - disconnect from a TCP/IP device.
                                 Port 5555 is used by default if no port number is specified.
                                 Using this command with no additional arguments
                                 will disconnect from all connected TCP/IP devices.

device commands:
  adb push [-p] <local> <remote>
                               - copy file/dir to device
                                 ('-p' to display the transfer progress)
  adb pull [-p] [-a] <remote> [<local>]
                               - copy file/dir from device
                                 ('-p' to display the transfer progress)
                                 ('-a' means copy timestamp and mode)
  adb sync [ <directory> ]     - copy host->device only if changed
                                 (-l means list but don't copy)
  adb shell                    - run remote shell interactively
  adb shell <command>          - run remote shell command
  adb emu <command>            - run emulator console command
  adb logcat [ <filter-spec> ] - View device log
  adb forward --list           - list all forward socket connections.
                                 the format is a list of lines with the following format:
                                    <serial> " " <local> " " <remote> "\n"
  adb forward <local> <remote> - forward socket connections
                                 forward specs are one of:
                                   tcp:<port>
                                   localabstract:<unix domain socket name>
                                   localreserved:<unix domain socket name>
                                   localfilesystem:<unix domain socket name>
                                   dev:<character device name>
                                   jdwp:<process pid> (remote only)
  adb forward --no-rebind <local> <remote>
                               - same as 'adb forward <local> <remote>' but fails
                                 if <local> is already forwarded
  adb forward --remove <local> - remove a specific forward socket connection
  adb forward --remove-all     - remove all forward socket connections
  adb reverse --list           - list all reverse socket connections from device
  adb reverse <remote> <local> - reverse socket connections
                                 reverse specs are one of:
                                   tcp:<port>
                                   localabstract:<unix domain socket name>
                                   localreserved:<unix domain socket name>
                                   localfilesystem:<unix domain socket name>
  adb reverse --norebind <remote> <local>
                               - same as 'adb reverse <remote> <local>' but fails
                                 if <remote> is already reversed.
  adb reverse --remove <remote>
                               - remove a specific reversed socket connection
  adb reverse --remove-all     - remove all reversed socket connections from device
  adb jdwp                     - list PIDs of processes hosting a JDWP transport
  adb install [-lrtsdg] <file>
                               - push this package file to the device and install it
                                 (-l: forward lock application)
                                 (-r: replace existing application)
                                 (-t: allow test packages)
                                 (-s: install application on sdcard)
                                 (-d: allow version code downgrade)
                                 (-g: grant all runtime permissions)
  adb install-multiple [-lrtsdpg] <file...>
                               - push this package file to the device and install it
                                 (-l: forward lock application)
                                 (-r: replace existing application)
                                 (-t: allow test packages)
                                 (-s: install application on sdcard)
                                 (-d: allow version code downgrade)
                                 (-p: partial application install)
                                 (-g: grant all runtime permissions)
  adb uninstall [-k] <package> - remove this app package from the device
                                 ('-k' means keep the data and cache directories)
  adb bugreport                - return all information from the device
                                 that should be included in a bug report.

  adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]
                               - write an archive of the device's data to <file>.
                                 If no -f option is supplied then the data is written
                                 to "backup.ab" in the current directory.
                                 (-apk|-noapk enable/disable backup of the .apks themselves
                                    in the archive; the default is noapk.)
                                 (-obb|-noobb enable/disable backup of any installed apk expansion
                                    (aka .obb) files associated with each application; the default
                                    is noobb.)
                                 (-shared|-noshared enable/disable backup of the device's
                                    shared storage / SD card contents; the default is noshared.)
                                 (-all means to back up all installed applications)
                                 (-system|-nosystem toggles whether -all automatically includes
                                    system applications; the default is to include system apps)
                                 (<packages...> is the list of applications to be backed up.  If
                                    the -all or -shared flags are passed, then the package
                                    list is optional.  Applications explicitly given on the
                                    command line will be included even if -nosystem would
                                    ordinarily cause them to be omitted.)

  adb restore <file>           - restore device contents from the <file> backup archive

  adb disable-verity           - disable dm-verity checking on USERDEBUG builds
  adb enable-verity            - re-enable dm-verity checking on USERDEBUG builds
  adb keygen <file>            - generate adb public/private key. The private key is stored in <file>,
                                 and the public key is stored in <file>.pub. Any existing files
                                 are overwritten.
  adb help                     - show this help message
  adb version                  - show version num

scripting:
  adb wait-for-device          - block until device is online
  adb start-server             - ensure that there is a server running
  adb kill-server              - kill the server if it is running
  adb get-state                - prints: offline | bootloader | device
  adb get-serialno             - prints: <serial-number>
  adb get-devpath              - prints: <device-path>
  adb remount                  - remounts the /system, /vendor (if present) and /oem (if present) partitions on the device read-write
  adb reboot [bootloader|recovery]
                               - reboots the device, optionally into the bootloader or recovery program.
  adb reboot sideload          - reboots the device into the sideload mode in recovery program (adb root required).
  adb reboot sideload-auto-reboot
                               - reboots into the sideload mode, then reboots automatically after the sideload regardless of the result.
  adb sideload <file>          - sideloads the given package
  adb root                     - restarts the adbd daemon with root permissions
  adb unroot                   - restarts the adbd daemon without root permissions
  adb usb                      - restarts the adbd daemon listening on USB
  adb tcpip <port>             - restarts the adbd daemon listening on TCP on the specified port

networking:
  adb ppp <tty> [parameters]   - Run PPP over USB.
 Note: you should not automatically start a PPP connection.
 <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1
 [parameters] - Eg. defaultroute debug dump local notty usepeerdns

adb sync notes: adb sync [ <directory> ]
  <localdir> can be interpreted in several ways:

  - If <directory> is not specified, /system, /vendor (if present), /oem (if present) and /data partitions will be updated.

  - If it is "system", "vendor", "oem" or "data", only the corresponding partition
    is updated.

environment variables:
  ADB_TRACE                    - Print debug information. A comma separated list of the following values
                                 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp
  ANDROID_SERIAL               - The serial number to connect to. -s takes priority over this if given.
  ANDROID_LOG_TAGS             - When used with the logcat option, only these debug tags are printed.
user8128167
  • 6,929
  • 6
  • 66
  • 79
3

You can use undocumented method android.app.ActivityThread.currentPackageName() :

Class<?> clazz = Class.forName("android.app.ActivityThread");
Method method  = clazz.getDeclaredMethod("currentPackageName", null);
String appPackageName = (String) method.invoke(clazz, null);

Caveat: This must be done on the main thread of the application.

Thanks to this blog post for the idea: http://blog.javia.org/static-the-android-application-package/ .

Alexei Khlebnikov
  • 2,126
  • 1
  • 21
  • 21
2
PackageInfo pinfo = this.getPackageManager().getPackageInfo(getPackageName(), 0);
         String sVersionCode = pinfo.versionCode; // 1
         String sVersionName = pinfo.versionName; // 1.0
         String sPackName = getPackageName(); // cz.okhelp.my_app
         int nSdkVersion = Integer.parseInt(Build.VERSION.SDK); 
         int nSdkVers = Build.VERSION.SDK_INT; 

Hope it will work.

Juboraj Sarker
  • 947
  • 1
  • 9
  • 13
2

Use: BuildConfig.APPLICATION_ID to get PACKAGE NAME anywhere( ie; services, receiver, activity, fragment, etc )

Example: String PackageName = BuildConfig.APPLICATION_ID;

pharid
  • 59
  • 3
0

Create a java module to be initially run when starting your app. This module would be extending the android Application class and would initialize any global app variables and also contain app-wide utility routines -

public class MyApplicationName extends Application {

    private final String PACKAGE_NAME = "com.mysite.myAppPackageName";

    public String getPackageName() { return PACKAGE_NAME; }
}

Of course, this could include logic to obtain the package name from the android system; however, the above is smaller, faster and cleaner code than obtaining it from android.

Be sure to place an entry in your AndroidManifest.xml file to tell android to run your application module before running any activities -

<application 
    android:name=".MyApplicationName" 
    ...
>

Then, to obtain the package name from any other module, enter

MyApp myApp = (MyApp) getApplicationContext();
String myPackage = myApp.getPackageName();

Using an application module also gives you a context for modules that need but don't have a context.

Marko
  • 20,385
  • 13
  • 48
  • 64
Earl Allen
  • 19
  • 1
0

Just import Android.app,then you can use: <br/>Application.getProcessName()<br/>

Get the current Application Process Name without context, view, or activity.

Jodast
  • 1,279
  • 2
  • 18
  • 33
untitled
  • 161
  • 1
  • 5
0

BuildConfig.APPLICATION_ID and package may not always be the same. Use "buildConfigField" to have gradle add package to the BuildConfig and access as BuildConfig.PACKAGE. https://developer.android.com/studio/build/gradle-tips

defaultConfig {
    applicationId "com.example.app.name"
    minSdkVersion 24
    targetSdkVersion 29
    versionCode 1
    versionName '0.1.0'
    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    buildConfigField("String", "PACKAGE", "\"com.example.app\"")
}
0

This works for me in kotlin

       override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
       
        var packageName=applicationContext.packageName // need to put this line
        Log.d("YourTag",packageName)
}
Aalishan Ansari
  • 641
  • 6
  • 8