About ACTION_PACKAGE_NEEDS_VERIFICATION intent, the android docs says:
`Sent to the system package verifier when a package needs to be verified. The data contains the package URI.
This is a protected intent that can only be sent by the system.`
Found at https://developer.android.com/reference/android/content/Intent.html#ACTION_PACKAGE_NEEDS_VERIFICATION
But what kind of verification does it means? In what kinds of occasions or scenarios will android broadcast this intent?
Looking at the recent source code (around line 10669), it appears that the system will broadcast this intent during the installation of a new package if there are any package verifier installed:
/*
* Determine if we have any installed package verifiers. If we
* do, then we'll defer to them to verify the packages.
*/
As for an explanation of what package verifiers are and what they do, my understanding is that they will need to have the PACKAGE_VERIFICATION_AGENT permission (reserved for system apps) which gives them the ability to respond to the broadcast to accept or reject the installation of the new package. The Google Play Store app is a verification agent that appears to use Google's online app verification service to perform this function.
Here is a page that has a lot of interesting information on the subject (along with several other pages that comes up if you do a "android package verifier" search online).
Related
I update my app using a local downloaded .apk, via DownloadManager, using this code:
val installIntent = Intent(Intent.ACTION_VIEW)
installIntent.setDataAndType(localUri, "application/vnd.android.package-archive")
installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
this.startActivity(installIntent)
Although most of the time it works, sometimes, only some of the users get the "There was a problem parsing the package error" popup.
I'm interested if there is any callback that we can get in our app, whenever this happens, or user press 'OK' in the popoup . I found here for instance, a callback that checks if the package exists (meaning that it was installed) but I'm more interested for updates, in this case I already know that the app was previously installed.
Is there a callback (maybe startActivityForResults) for this specific intent, so we know that it was successfully installed or it failed?
ACTION_VIEW is not designed to return a result. On Android 5.0 and higher, PackageInstaller gives you a direct API for installing apps, where you can provide a callback (in the form of an IntentSender) to find out about how the installation proceeds.
This sample project shows the basics of using PackageInstaller, and you should be able to find open source apps that use it in a more sophisticated fashion. For example, the F-Droid client probably uses PackageInstaller.
My play store account has over 100 apps published and all of them have this common user generation process which includes OTP verification. Interesting to note is all the apps have same user object with same properties for a particular OTP verified number, which gets stored in the respective SharedPreferences as string.
For better User Experience I would like to trim down the user generation process if there is any one app installed in the device and has done OTP verification. I want to share this user object, which is saved as string in each app's SharedPreferences.
So here's what I want when I install com.domain.app.cX app:
1) com.domain.app.cX -> (Do you have a verified user?) -> com.domain.app.cY
2.1) com.domain.app.cY -> (Yes I have, here is it "user json") -> com.domain.app.cX
or
2.2) com.domain.app.cY -> (No I don't have any user) -> com.domain.app.cX
3) Move to check if com.domain.app.cZ is installed and do over from step 1
Options I have:
1) I have read about ContentProvider and understood that you need to put in a URI of ContentProvider which is package name specific.
2) Use package name with createPackageContext and get SharedPreferences for any app.
In both the solutions I don't know which app is already installed on device and hence URIs of all ContentProvider and package name of the app.
Is there any solution in which I can leverage the signature of the app, since all the app are signed with same certificate.
Using Broadcast receivers and Custom Broadcasts.
with redundant common data across all apps with shared preferences.
All the apps contain a pair of broadcast receiver and sender.
The app which wants verification status will send a broadcast.
The other apps which listen to the broadcast will receive it and add the verification status in the intent and send again as a broadcast.
Now the 1st app which send the broadcast for verification status will receive the latest status and update the UI accordingly. If the default value is false then show the verification screen.
I'm using Branch lib an Android to generate links that I send afterwards via sms. If user has no app installed on the phone, your link correctly transfers to Play Store ( the link in the dashboard ). After installing and running the application it receives all data from the link as expected.
However, if I have the app already installed on the phone, pressing the link does not open the app but redirects me again to Play Store. If I press the "Open" button there, the app receives the information but how about running the application directly from browser? I saw our iOS implementation of the same lib and it works flawlessly - i.e. when I have the app and I press the link it opens the app without sending me to store.
Perhaps I did something wrong in my declaration in the manifest?
Thanks in advance,
Kalin
Chrome requires an intent string that matches what's defined inside your Android Manifest to properly open an application found on your device. If something's off, Chrome wont open the app. If you're using Branch for deeplinks, you need to make sure the following match:
TL;DR, make sure these match on Branch dashboard and Manifest
package name on branch dashboard is the same as your app build's
host="open" on Activity, because Branch formats intent strings as scheme://open
URI scheme registered on Branch is the same that's found in your AndroidManifest.xml
The same Activity has the following property: android.intent.category.BROWSABLE
The longer explanation is that Branch takes the link tied to your account, and constructs an Intent string that looks like the following:
intent:
HOST/URI-path // Optional host
#Intent;
package=[string];
action=[string];
category=[string];
component=[string];
scheme=[string];
end;
When Branch does the redirect, we pull the scheme and package from your account, and assume you have set android:host as open:
intent://open#Intent;scheme=scheme;package=package;end"
And place that inside window.location. If the registered scheme on your dashboard or package don't match, or open isn't specified in the android:host key, then you'll be taken to Chrome.
It's also important to specify the following android.intent.category.BROWSABLE as a category filter. More information on intent strings here.
I've searched and cannot find this, though mainly a challenge of knowing what to search for, I'm sure it's been asked before.
How does an app deduce whether it is running on a "Google Android" device, or an AOSP device (e.g. Kindle Fire etc)?
You can try to enumerate an existing accounts on device using AccountManager class: getAccountsByType(), passing com.google as desired account type. If there is no accounts of this type, this mean either it is AOSP device or the user didn't create Google account yet.
If it is not enough for you, you can use PackageManager class and query some Google-specific package using getPackageInfo() method. For example, com.android.vending - Google Play app.
But pay attention that no one of these methods can guaranty you that target device is running AOSP.
This is not trivial, but most apps do not need to even care. If you do, then it usually means you need some unique features therefore it's simpler to check if certain feature is present or not, instead of what label is on the device. You may also check for presence of certain packages (like Google Play), but lack of it does not mean automatically it is i.e. Fire.
You can check whether you can open market urls by using an Intent.
Documentation on the intent's extras is here.
The Intent would look like this:
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("market://details?id=com.example.android"));
//you can use any package identifier for the check.
startActivity(intent);
} catch (ActvitiyNotFoundException anfe) {
//There's no market installed.
//So you can guess that you're not on a device with Google experience
}
The downside of this method would be, that the user will be taken to the Play Store if it's available.
How to find data usage of newly installed application?
getUidTxBytes(int uid) and getUidRxBytes(int uid) are used to get the data usage, but in case if a new app is installed and using the data, how can I identify that the new app is installed? And also how come I know the newly installed app getting data usage?
I am pretty new to this topic.
You can register for Broadcast Intents from the system like ACTION_PACKAGE_ADDED and ACTION_PACKAGE_CHANGED to be notified when new applications are installed or updgraded. The UID of the package is always passed with these Intents as an extra.
SDK Docs link for more information.
HTH