I have an App which provides you a list of various apps that you can download and install from Play Store to earn goodies. Now, I don't want a user to uninstall a previously installed app and download it again through my app and earn goodies.
Is there a way to find out if a specific app was previously installed on the user's device?
Update
I am interested in all the apps installed/uninstalled, regardless of when my app was installed. I don't want to store any data about any app installs on my end, I want to know if this data is already stored on the device somewhere for further reference.
Note
I am also interested in the apps that we uninstalled. Can I get this data too?
I can see where you are trying to go, but I think you need to rethink the approach a bit. You should always allow your users to install and uninstall as they wish. But you can put a check in the app to see when the app was first installed.
PackageInfo info = pm.getPackageInfo(packageName, 0);
long firstInstallTime = info.firstInstallTime;
This will store the time the app was first installed in firstInstallTime
This time stamp will not change with any number of subsequent uninstalls and re-installs.
The PackageInfo class provides a bunch of other useful info about your app on the device and is well worth getting to know.
You can compare this to the timestamp when the apps source directory was last modified (in other words when the app was most recent installed), which you can obtain with:
ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(packageName, 0);
long mostRecentInstallTime = new File(appInfo.sourceDir).lastModified();
I've also used this approach to give users a 1 week trial of an apps full features before reverting to the lesser "free mode", and they can't trip it up by uninstalling and re-installing.
Additional:
In response to your comment...
You are not just restricted to getting PackageInfo for your own app or apps installed after yours was. You can get PackageInfo for all apps currently on the device, regardless of when they were installed in the "devices lifetime".
This slightly modified version of the code found here will give you the firstInstallTime for all apps on the device:
// Get PackageInfo for each app on the device
List<PackageInfo> packageInfoInstalledPackages = getPackageManager().getInstalledPackages(0);
// Now iterate through to get the info you need.
long[] firstInstallTimes = long[packageInfoInstalledPackages.size()];
for(int i=0;i<packageInfoInstalledPackages.size();i++) {
PackageInfo p = packageInfoInstalledPackages.get(i);
if (p.versionName != null) {
firstInstallTimes[i] = p.firstInstallTime;
}
}
You can also get the ApplicationInfo so you should have all you need.
This snippet will log all the main activities of the apps installed on you device, you just have to check that list for a given app
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final List <ResolveInfo> pkgAppsList = getPackageManager().queryIntentActivities( mainIntent, 0);
for(ResolveInfo resolve : pkgAppsList)
{
Log.d("MY_APP", resolve.toString());
}
Hope it helps!
Related
I want to get a list of all apps installed on my device. My code is below:
PackageManager pm = getApplicationContext().getPackageManager();
List<PackageInfo> list = pm.getInstalledPackages(0);
When I try multiple user registered on my device (i.e. Android for Work), the API returns a list from the same user space/managed profile, which makes sense.
My question is, is there an option to get a list of all apps from the device (like Settings - Apps - All apps), no matter where the app is installed?
Use LauncherApps (only can get apps will shown in launcher), you can see how Launcher3 use it
https://developer.android.com/reference/android/content/pm/LauncherApps.html
I'd like to determine which version of my Android app a user originally purchased from the Google Play Store. I need this info to help support moving from a paid app model to a freemium model.
In iOS7 onwards, you can do this by using [NSBundle appStoreReceiptURL] which returns a URL of the App Store receipt that can be examined.
Is there an equivalent in the Google APIs?
Getting Time and Date Install
You can get the time and date of the first install of the app by using
long installTime = context.getPackageManager()
.getPackageInfo("com.some.package.name", 0)
.firstInstallTime;
And the version with
PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
version = pInfo.versionName;
Unfortunately this date will reset whenever the app is uninstalled and reinstalled.
If you go with
PackageManager pm = context.getPackageManager();
ApplicationInfo appInfo = pm.getApplicationInfo("app.package.name", 0);
String appFile = appInfo.sourceDir;
long installed = new File(appFile).lastModified();
you will also find out the date when an application was installed, but the time returned will change every time the package is updated.
Suggested Solution
A solution could be an online database for your application, where you can store each user's ID using AccountPicker, their first-time-install with the methods described above and use them at login. You can also use the App Licensing Service.
http://developer.android.com/reference/android/content/pm/PackageInfo.html#firstInstallTime
I want to prevent launching of task manager and Settings applications in my application. For this, I tried to obtain currently running application and checked whether their package name is allowed or not .If it is not allowed then show a new activity.
When work out it is show that the package name of default android Settings application is com.android.settings. Now I have some doubts
Is the Settings application has package name com.android.settings in all android versions? If not, which are they?
How to find package name of Task Manager?
try this
private String querySettingPkgName() {
Intent intent = new Intent(android.provider.Settings.ACTION_SETTINGS);
List<ResolveInfo> resolveInfos = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (resolveInfos == null || resolveInfos.size() == 0) {
return "";
}
return resolveInfos.get(0).activityInfo.packageName;
}
For this,I tried to obtain currently running application and checked whether their package name is allowed or not .If it is not allowed then show a new activity.
Fortunately, for the users affected by your app, this will be unreliable.
Is the Settings application has package name com.android.settings in all android versions?
Not necessarily. More importantly, any given firmware can have any number of applications that modify settings, supplied by the firmware author. Some settings can be modified even without being part of the firmware, particularly on rooted devices.
If not,which are they?
You are welcome to make a list of all device manufacturers and ROM mod authors and ask them that question.
How to find package name of Task Manager?
There are any number of "task manager" apps included in devices, ROM mods, and available on the Play Store and other distribution points. You are welcome to make a list of all of them and ask their authors that question.
shell into the device using adb, and invoke:
pm list packages
this will provide you a list of pacakges. from there you will should see:
com.android.settings
final PackageManager pm = getPackageManager();
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo packageInfo : packages) {
Log.d("Packages", "" + packageInfo.packageName);
}
above code should help you
It's not totally clear what is the scenario.
I guess it is something along the lines of showing off devices to public but not have them f'up the device for others.
Maybe it would be better to do a whitelist instead of a blacklist. Meaning the shop should state which apps should be testable on the devices and then you start your activity if it is any other.
But this again will need maintenance: package names of popular apps may also change. You better provide a way of updating the settings of your app via an online service so you can change the needed packages without physical access to the devices and without having to download and install the complete app.
If you just need a device that goes through many hands and should not be tempered with I suggest using a modified device. I only know of Sonim: they provide a library (needs a Sonim provided hash key in your manifest to use that). With it you can prohibit the altering of many settings without preventing access to the whole settings app.
If I uninstall an app from my Android device and reinstall it, does the user id change? For example, if the user was app-60 before, will it be app-60 (uid 60) again after reinstallation?
Excerpt from Security and Permissions "At install time, Android gives each package a distinct Linux user ID. The identity remains constant for the duration of the package's life on that device. On a different device, the same package may have a different UID; what matters is that each package has a distinct UID on a given device."
When installing an app, Android by default(1) creates a UID specifically for that package, so that it can have its private resources / storage space. When no packages are using anymore that UID, the UID is deleted.
So I believe it changes. You can use Pratik's code to checkout and determine the difference after successive installs.
Here is the code for the Package Manager service. Could be a starting point to dig in deep.
You can obtain UID within your application
String your app_selected = "your package name";
final PackageManager pm = getPackageManager();
//get a list of installed apps.
List<ApplicationInfo> packages = pm.getInstalledApplications(
PackageManager.GET_META_DATA);
int UID;
//loop through the list of installed packages and see if the selected
//app is in the list
for (ApplicationInfo packageInfo : packages) {
if(packageInfo.packageName.equals(app_selected)){
//get the UID for the selected app
UID = packageInfo.uid;
}
}
I am creating a method to displays the installed applications in android. I gave the following lines of code to get the application list
PackageManager packageManager=this.getPackageManager();
List<PackageInfo> applist=packageManager.getInstalledPackages(0);
Iterator<PackageInfo> it=applist.iterator();
while(it.hasNext())
{
PackageInfo pk=(PackageInfo)it.next();
if(PackageManager.PERMISSION_GRANTED==packageManager.checkPermission(Manifest.permission.INTERNET, pk.packageName)) //checking if the package is having INTERNET permission
{
//some processing
}
}
}
Here everything is working fine but the list includes the system packages too. I need to get only the list of user installed packages. Is there any way to do??
What flag should we set in getInstalledPackages() to get the user installed packages?
The ApplicationInfo object will have FLAG_SYSTEM if it is installed on the firmware, so you can use that to filter those out.