442

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)?

2
  • 7
    Accepted answer will cause your application to occasionally CRASH - read comments by AddDev & Turbo and thanks to them both for suggesting solutions. Commented Jul 18, 2012 at 7: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. Commented Jul 15, 2013 at 5:10

16 Answers 16

576

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.

Sign up to request clarification or add additional context in comments.

14 Comments

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.
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.
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
If the app goes to the background, aren't the variables kept in memory? onCreate() just needs to be called once.
@Turbo, if Android kills the process, onCreate will have to be called again anyway, so this solution still shouldn't be a problem.
|
389

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.

9 Comments

That is the proper way, should be the accepted answer.
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ツ 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
Be careful if using this in a library project - this will not work.
Be careful if using this in multiple modules inside a project as well.
|
71

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.

5 Comments

This isn't thread safe, but you can probably get away with it if the background thread is started by this activity later on.
It is thread safe since the reference to instance is the first thing set when the app is launched
Per this issue: 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.
The documentation on Application.onCreate() 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)".
This should be the selected answer, because the context will never die out no matter what activity is running.
46

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

4 Comments

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 For those who want to know the nuances in a bit more detail tools.android.com/tech-docs/new-build-system/…
@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 (:
@kevinze Entirely accurate! I ran a test to double-check. Thanks for the clarification/correction.
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.

1 Comment

which code did you use? please provide the exact error you got.
12

Just use this code

val packageName = context.packageName 

Comments

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; } 

Comments

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. 

Comments

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/ .

Comments

3
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.

Comments

2

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

Example: String PackageName = BuildConfig.APPLICATION_ID;

1 Comment

if you are in a library/module, this will get the library application id.
1

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.

Comments

1

In jetpack compose Just use the context in any composable function as below to get the app package name

 val context = LocalContext.current val appPackageName = context.applicationInfo.packageName 

1 Comment

Nice and easy way!
0

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

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

Comments

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\"") } 

Comments

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) } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.