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.
Related
In my app I need to monitorize recently added or updated packages, but since Oreo this is a hard task.
To do it I have a service that runs every X time to detect the new installed/updated apps.
The main core of this service is to call the getChangedPackages function from the PackageManager, but this function always returns null, even if I install or update any app from or not from the Play Store in the interval between two consequtive calls to getChangedPackages.
https://developer.android.com/reference/android/content/pm/PackageManager.html#getChangedPackages(int)
I need to request any permission to call this function? Is the getChangedPackages buggy?
private void _doProcess()
{
try
{
PackageManager package_manager = getPackageManager();
int sequence_number = ApplicationPreferences.getInteger(this, GET_CHANGED_PACKAGES_SEQUENCE_NUMBER_KEY, 0);
ChangedPackages changed_packages = package_manager.getChangedPackages(sequence_number);
LogUtilities.show(this, String.format("Retrieve recently apps installs/updates using sequence number %d returns %s", sequence_number, changed_packages == null ? "null" : "a not null object"));
if (changed_packages == null) changed_packages = package_manager.getChangedPackages(0);
LogUtilities.show(this, String.format("Retrieve recently apps installs/updates using sequence number %d returns %s", sequence_number, changed_packages == null ? "null" : "a not null object"));
if (changed_packages != null)
{
List<String> packages_names = changed_packages.getPackageNames();
LogUtilities.show(this, String.format("%d recently installed/updated apps", packages_names == null ? 0 : packages_names.size()));
if (packages_names != null) for (String package_name : packages_names) PackagesUpdatedReceiver.doProcessPackageUpdate(this, new Intent(isNewInstall(package_manager, package_name) ? Intent.ACTION_PACKAGE_ADDED : Intent.ACTION_PACKAGE_REPLACED).setData(Uri.parse(String.format("package:%s", package_name))));
LogUtilities.show(this, String.format("Storing %s is the sequence number for next iteration", changed_packages.getSequenceNumber()));
ApplicationPreferences.putInteger(this, GET_CHANGED_PACKAGES_SEQUENCE_NUMBER_KEY, changed_packages.getSequenceNumber());
}
else
{
LogUtilities.show(this, String.format("Storing %s is the sequence number for next iteration", sequence_number + 1));
ApplicationPreferences.putInteger(this, GET_CHANGED_PACKAGES_SEQUENCE_NUMBER_KEY, sequence_number + 1);
}
}
catch (Exception e)
{
LogUtilities.show(this, e);
}
}
My experimental results so far have shown that this PackageManager API method getChangedPackages() is not reliable: quite often the returned ChangedPackages value contains many unchanged packages. So I’ve decided to implement a similar feature in a class called PackageUtils, as shown below. The idea is to poll for all the installed packages, as shown in method getInstalledPackageNames() below, and compare the string list with a previously saved one. This comparison boils down to comparing 2 string lists, as shown in method operate2StringLists() below. To get a set of removed packages, use GET_1_MINUS_2_OR_REMOVED as operation. To get a set of added packages, use GET_2_MINUS_1_OR_ADDED as operation.
public class PackageUtils {
public static final int GET_1_MINUS_2_OR_REMOVED = 0;
public static final int GET_2_MINUS_1_OR_ADDED = 1;
// Get all the installed package names
public static List<String> getInstalledPackageNames(Context context) {
List<String> installedPackageNames = new ArrayList<>();
try {
PackageManager packageManager = context.getPackageManager();
List<ApplicationInfo> appInfoList = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo appInfo : appInfoList) {
installedPackageNames.add(appInfo.packageName);
}
} catch (Exception e) {
e.printStackTrace();
}
return installedPackageNames;
}
// Compare 2 string lists and return differences.
public static Set<String> operate2StringLists(List<String> pkgList1, List<String> pkgList2, int operation) {
Set<String> result = null;
Set<String> pkgSet1 = new HashSet<String>(pkgList1);
Set<String> pkgSet2 = new HashSet<String>(pkgList2);
switch (operation) {
case GET_1_MINUS_2_OR_REMOVED:
pkgSet1.removeAll(pkgSet2);
result = pkgSet1;
break;
case GET_2_MINUS_1_OR_ADDED:
pkgSet2.removeAll(pkgSet1);
result = pkgSet2;
break;
default:
break;
}
return result;
}
}
The code has been tested on an Android Oreo device. It can reliably detect all added and removed packages between 2 time instances. However, it can’t detect updated packages in-between.
Finally got it. You have to create a variable called sequenceNumber, and update it every time you query changed packages.
private static int sequenceNumber = 0;
...
PackageManager pm = getContext().getPackageManager();
ChangedPackages changedPackages = pm.getChangedPackages(sequenceNumber);
if(changedPackages != null)
sequenceNumber = changedPackages.getSequenceNumber();
I am writing a code to extract the package name, application name, and icon from the last installed app on my phone. I can get the application common name and icon from the application info, but I can't seem to figure out how to get the package name. All the codes that I have found to get the package name give me the package name of MY app, not the last installed app.
It seems like I need to find a method to get the package name, where I can pass in the application info as the parameter (like I do for the application common name and icon).
final PackageManager pm = context.getPackageManager();
ApplicationInfo ai;
try {
ai = pm.getApplicationInfo(intent.getData().getSchemeSpecificPart(), 0);
Log.d("tag_name","Application Info" + ai);
PACKAGE_NAME = context.getApplicationContext().getPackageName();
Log.d("tag_name","Package Name" + PACKAGE_NAME);
} catch (final PackageManager.NameNotFoundException e) {
ai = null;
}
final String applicationName = (String) (ai != null ? pm.getApplicationLabel(ai) : "(unknown)");
Log.d("tag_name", "Application NAME" + applicationName);
// http://www.carbonrider.com/2016/01/01/extract-app-icon-in-android/
try {
Drawable icon = context.getPackageManager().getApplicationIcon(ai);
Log.d("tag_name", "ICON" + icon);}
catch (Exception e){}
Firstly receive all apps with this Code :
List<PackageInfo> packages = packageManager.getInstalledPackages(PackageManager.GET_META_DATA);
Then sort the packages list with this code :
Collections.sort(packages, new Comparator<PackageInfo>() {
#Override
public int compare(PackageInfo p1, PackageInfo p2) {
return Long.toString(p2.firstInstallTime).compareTo(Long.toString(p1.firstInstallTime));
}
});
Then you can receive the package Name of the latest installed app this way:
packages.get(0).packageName
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
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);
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);