Android - How to get application name? (Not package name) - android

In my manifest I have:
<application
android:name=".MyApp"
android:icon="#drawable/ic_launcher_icon"
android:label="#string/app_name"
android:debuggable="true">
How do I get the label element?
Note: My code is running inside of someone else's, so I don't have access to #string/app_name

There's an easier way than the other answers that doesn't require you to name the resource explicitly or worry about exceptions with package names. It also works if you have used a string directly instead of a resource.
Just do:
public static String getApplicationName(Context context) {
ApplicationInfo applicationInfo = context.getApplicationInfo();
int stringId = applicationInfo.labelRes;
return stringId == 0 ? applicationInfo.nonLocalizedLabel.toString() : context.getString(stringId);
}
Edit
In light of the comment from Snicolas, I've modified the above so that it doesn't try to resolve the id if it is 0. Instead it uses, nonLocalizedLabel as a backoff. No need for wrapping in try/catch.

If not mentioned in the strings.xml/hardcoded in AndroidManifest.xml for whatever reason like android:label="MyApp"
Java
public String getAppLable(Context context) {
ApplicationInfo applicationInfo = null;
try {
applicationInfo = context.packageManager.getApplicationInfo(context.getPackageManager().getApplicationInfo().packageName, 0);
} catch (final NameNotFoundException e) {
Log.d("TAG", "The package with the given name cannot be found on the system.");
}
return (applicationInfo != null ? packageManager.getApplicationLabel(applicationInfo) : "Unknown");
}
Or if you know the String resource ID then you can directly get it via
getString(R.string.appNameID);
UPDATE
Kotlin
fun getAppLable(context: Context): String? {
var applicationInfo: ApplicationInfo? = null
try {
applicationInfo = context.packageManager.getApplicationInfo(context.applicationInfo.packageName, 0)
} catch (e: NameNotFoundException) {
Log.d("TAG", "The package with the given name cannot be found on the system.")
}
return (if (applicationInfo != null) packageManager.getApplicationLabel(applicationInfo) else "Unknown")
}

Java
public static String getApplicationName(Context context) {
return context.getApplicationInfo().loadLabel(context.getPackageManager()).toString();
}
Kotlin (as extension)
fun Context.getAppName(): String = applicationInfo.loadLabel(packageManager).toString()

From any Context use:
getApplicationInfo().loadLabel(getPackageManager()).toString();

In Kotlin its simple:
val appLabel = context.applicationInfo.nonLocalizedLabel.toString()

In Kotlin, use the following codes to get Application Name:
// Get App Name
var appName: String = ""
val applicationInfo = this.getApplicationInfo()
val stringId = applicationInfo.labelRes
if (stringId == 0) {
appName = applicationInfo.nonLocalizedLabel.toString()
}
else {
appName = this.getString(stringId)
}

If you need only the application name, not the package name, then just write this code.
String app_name = packageInfo.applicationInfo.loadLabel(getPackageManager()).toString();

You can use this
JAVA
ApplicationInfo appInfo = getApplicationContext().getApplicationInfo();
String applicationLabel = getApplicationContext().getPackageManager().getApplicationLabel(appInfo).toString();

Get Appliction Name Using RunningAppProcessInfo as:
ActivityManager am = (ActivityManager)this.getSystemService(ACTIVITY_SERVICE);
List l = am.getRunningAppProcesses();
Iterator i = l.iterator();
PackageManager pm = this.getPackageManager();
while(i.hasNext()) {
ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo)(i.next());
try {
CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(info.processName, PackageManager.GET_META_DATA));
Log.w("LABEL", c.toString());
}catch(Exception e) {
//Name Not FOund Exception
}
}

By default you have a string resource called "app_name" generated by AndroidStudio. Why not simply use that? Or any other string resource created for this purpose. Much easier than calling several internal methods to come up with a value you have to set yourself in the first place.

Okay guys another sleek option is
Application.Context.ApplicationInfo.NonLocalizedLabel
verified for hard coded android label on application element.
<application android:label="Big App"></application>
Reference:
http://developer.android.com/reference/android/content/pm/PackageItemInfo.html#nonLocalizedLabel

The source comment added to NonLocalizedLabel directs us now to:
return context.getPackageManager().getApplicationLabelFormatted(context.getApplicationInfo());

Kotlin
A simple function to get the name of the application in kotlin
fun getApplicationName() : String{
var applicationName = ""
try {
val applicationInfo = application.applicationInfo
val stringId = applicationInfo.labelRes
if (stringId == 0) {
applicationName = applicationInfo.nonLocalizedLabel.toString()
}
else {
applicationName = application.getString(stringId)
}
} catch (e: Exception) {
e.printStackTrace()
}
return applicationName
}

Have you tried using the PackageManager#getActivityInfo() method? There will be a field that should contain the name of the application.
See the answer to a very similar question here.

If "don't have access" means you don't get the expected value... Try This:
String appName = getString(R.string.app_name);

Related

Get human-readable name of default keyboard (not package name)

Is there a possibility in Android (API 24 - 29) to get the human-readable name of the current default keyboard? When I use the following code
String keyboard = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
I'm getting
com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME
But I would like to have Gboard instead (i.e. the name that is displayed in the keyboard selection menu and not the package name).
That result is the String form of a ComponentName, so we can use the unflattenFromString() method to easily parse out the package name, and then retrieve the package's label – i.e., the human-readable name – from its ApplicationInfo obtained with PackageManager. For example, in a simple Java utility method:
public static CharSequence getCurrentImeLabel(Context context) {
CharSequence readableName = null;
String keyboard = Settings.Secure.getString(context.getContentResolver(), DEFAULT_INPUT_METHOD);
ComponentName componentName = ComponentName.unflattenFromString(keyboard);
if (componentName != null) {
String packageName = componentName.getPackageName();
try {
PackageManager packageManager = context.getPackageManager();
ApplicationInfo info = packageManager.getApplicationInfo(packageName, 0);
readableName = info.loadLabel(packageManager);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
return readableName;
}
And an equivalent Kotlin extension on Context:
fun Context.getCurrentImeLabel() : CharSequence? {
val keyboard = Settings.Secure.getString(contentResolver, DEFAULT_INPUT_METHOD)
return ComponentName.unflattenFromString(keyboard)?.let {
packageManager.getApplicationInfo(it.packageName, 0).loadLabel(packageManager)
}
}
If all you need is that human-readable name, then this seems to be the most direct approach, as InputMethodManager doesn't appear to have any public method that returns the current IME.
However, if you need additional IME-specific information, it seems that it will have to be pulled from the List<InputMethodInfo> returned from InputMethodManager's getInputMethodList() or getEnabledInputMethodList() methods. In both cases, you would need to iterate over the List, checking for which InputMethodInfo#getId() equals that String returned from Settings.
The InputMethodInfo class also has a loadLabel(PackageManager) method available, so if you're using this method, or otherwise have the necessary InputMethodInfo already, then you can use that directly, rather than making an unnecessary getApplicationInfo() call.

Preventing an android app being cloned by an app cloner

Created an app that used the device's uniqueID which is fetched by the following code snippet
String deviceId = Settings.Secure.getString(getContentResolver(),
Settings.Secure.ANDROID_ID);
When the user tries to clone the app by app cloner, then it creates a different deviceID and the app is not allowed to work
Is there any way to make our app non clonable
or
Any possible way to have the same deviceId even if the app instance is cloned?
Is there any way to find out whether the app is running in a cloned instance?
Applications like Cloner usually change your application's package name so you can retrieve package name and check if it is changed or not.
if (!context.getPackageName().equals("your.package.name")){
// close the app or do whatever
}
Also they usually sign cloned apk so the signature might be different from yours, you can check if signature is changed or not. I usually use this function:
#SuppressLint("PackageManagerGetSignatures")
public static int getCertificateValue(Context ctx){
try {
Signature[] signatures = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
try {
signatures = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), PackageManager.GET_SIGNING_CERTIFICATES).signingInfo.getApkContentsSigners();
}catch (Throwable ignored){}
}
if (signatures == null){
signatures = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
}
int value = 1;
for (Signature signature : signatures) {
value *= signature.hashCode();
}
return value;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
public static boolean checkCertificate(Context ctx, int trustedValue){
return getCertificateValue(ctx) == trustedValue;
}
Before releasing your app call getCertificateValue(context) and write down the value and alongside with package name, check if that value matches the value that you get in runtime.
PS: as #vladyslav-matviienko said hackers will always find a way so try to make cloning harder by running some obfuscations on hardcoded package name and that value. Also try to tangle and spread these kind of logics all around the source code.
I found a story in proandroiddev by Siddhant Panhalkar and with some minor changes it's work perfectly in Mi device I did checked in Mi phones default Dual apps and some third party apps from playstore and it prevents from cloning (means not working properly after clone).
private const val APP_PACKAGE_DOT_COUNT = 3 // number of dots present in package name
private const val DUAL_APP_ID_999 = "999"
private const val DOT = '.'
fun CheckAppCloning(activity: Activity) {
val path: String = activity.filesDir.getPath()
if (path.contains(DUAL_APP_ID_999)) {
killProcess(activity)
} else {
val count: Int = getDotCount(path)
if (count > APP_PACKAGE_DOT_COUNT) {
killProcess(activity)
}
}
}
private fun getDotCount(path: String): Int {
var count = 0
for (element in path) {
if (count > APP_PACKAGE_DOT_COUNT) {
break
}
if (element == DOT) {
count++
}
}
return count
}
private fun killProcess(context: Activity) {
context.finish()
android.os.Process.killProcess( android.os.Process.myPid())
}

Custom Keyboard Android get current App

I wish to get name/packageName of current app using my customKeyboard service.
Is there anyway to do so?
You have to rely on getCurrentInputEditorInfo(), a method in InputMethodService, to achieve this:
String packageName = getCurrentInputEditorInfo().packageName;
Found answer in this topic: How to check current running applications in Android?
If app is running its obviosuly the one calling my keyboard.
private String getApplicationName() {
final PackageManager pm = mActivity.getApplicationContext()
.getPackageManager();
ApplicationInfo ai;
String appName;
try {
ai = pm.getApplicationInfo(mActivity.getPackageName(), 0);
appName = (String) pm.getApplicationLabel(ai);
} catch (final NameNotFoundException e) {
appName = "(unknown)";
}
return appName;
}
use this method to get Appname/Package name

Correct name of installed applications

I am getting the names for my installed applications with below code and use them to see if any updates for this application is available.
But sometimes an incorrect name (MX Speler instead of MX Player) is being provided, as a result no updates are found.
Is there any better code i can/should use?
{
final PackageInfo pi = installedInfo != null ? installedInfo : downloadedInfo;
final PackageManager pm = getApplicationContext().getPackageManager();
ApplicationInfo ai;
try {
ai = pm.getApplicationInfo(pi ??, 0); //How to set the name of the installed application?
} catch (final NameNotFoundException e) {
ai = null;
}
final String applicationName = (String) (ai != null ? pm.getApplicationLabel(ai) : "(unknown)");
System.out.println("Application name : "+ applicationName);
}
You should not use labels as it may be different for every language or changed on each update. You should only rely on application's id (packageId) as this id stays unchanged for the whole life of the application.

How to get the name of the application in android?

I want to get the name of my application. How can i get that?
Thanks in advance.
You can use PackageItemInfo -> nonLocalizedLabel to get application name.
val applicationName = context.applicationInfo.nonLocalizedLabel.toString()
[Old Answer]
Usually, we do add the application name with app_name string resource, so you can write below code to access the app name
String applicationName = getResources().getString(R.string.app_name);
Reference : Resource Types
But note that, this resource name is not mandatory and can be changed to any other string name. In that case, the code will not work. See the first code snippet which uses PackageItemInfo -> nonLocalizedLabel above for a better solution.
You can use PackageManager class to obtain ApplicationInfo:
final PackageManager pm = context.getPackageManager();
ApplicationInfo ai;
try {
ai = pm.getApplicationInfo(packageName, 0);
} catch (final NameNotFoundException e) {
ai = null;
}
final String applicationName = (String) (ai != null ? pm.getApplicationLabel(ai) : "(unknown)");
EDIT: CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(info.processName,PackageManager.GET_META_DATA));
This would return the application name as defined in <application> tag of its manifest.
you can use PackageManager#getApplicationInfo()
For getting the Application Name for all packages installed in the device.
Assuming you have your current Context object ctx
Resources appR = ctx.getResources();
CharSequence txt = appR.getText(appR.getIdentifier("app_name",
"string", ctx.getPackageName()));
Context has function getString(int resId): Context
so you can use it easily like this.
context.getString(R.string.app_name);

Categories

Resources