I will prevent some application to be deleted from the phone.
Now, I can get current top activity name using ActityManager and check if it is com.android.packageinstaller.UninstallerActivity, than do additional logic for checking which package will be deleted. but I can't get UninstallerActivity object, and more - I can't get Intent passed to com.android.packageinstaller.UninstallerActivity (which will provide package name for me).
Seems like this isn't possible with standart Android API way. maybe it's possible using hidden API and reflection.
Any ideas?
Edit: I'm writing Launcher application, which will be distributed manually in hotels. I will have functionality which prevents from deleting my Launcher application from the phone, because mobile phones will be given in rent, and Launcher replacement isn't possible.
Note: The phone will be rooted!
Related
I am working on app locker to show lock on selected apps by getting top applications's package name. For this purpose I'm calling the method in my service every 1 second to check which application is on top. I have implemented the answers given in these links https://stackoverflow.com/a/28066580/13005440 , https://stackoverflow.com/a/38829083/13005440. Its not working properly in my pixel 2 (Android 10) device. The above methods return correct package name for some apps like youtube when it opens first time / after minimize but not for other apps like messages, playstore etc. I want to implement my app lock on app minimize.
Note: When applications (messages, playstore etc) open 1st time it returns correct package name, but when that application goes to background by minimize then re-open app the method will not return its package name.
I have searched a lot but didn't find any way that will work on android 10 properly
As someone pointed out in the thread you got your solution from, are you giving the right permissions?
You need this one:
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
There are apps (such as https://play.google.com/store/apps/details?id=com.teslacoilsw.launcher) that are free, but whose paid features can be enabled by buying another app (in this case, this one https://play.google.com/store/apps/details?id=com.teslacoilsw.launcher.prime)
How does this work?
My guess is that the free apps launches an explicit Intent and can detect if the app is present via a try/catch structure. The downside of this is that this could be easily circunvented by someone who creates an app with the same package name and specifies all possible Intent filters.
Is this how it works, or is it some other way?
There are various ways to do that. One way is to query a content provider which will be protected with a special permission.
I have released quite long ago on Github a library which helps doing this: Android Unlocker Library.
That's a good option if you are dealing with devices outside the Google ecosystem, however, from a developer experience, in-app purchases offer a much better user experience (and thus drive more sales) according to me.
The easiest way is to use startActivityForResult(...) from app A against an Activity of app B, that must be configured with an IntentFilter in order to be used from an outer app. Inside the B called activity you can also check who's calling with getCallingActivity(). You can find an example here.
Before starting the Activity, you can test that B is installed (using the PackageManager) or you can just start the activity and catch the Exception.
In the called Activity, you can check the signature of the calling package using the PackageManager.checkSignature(String,String) method. Pass the package name of A and B and if the signature matches, execute the logic.
I've been searching and I couldn't find a topic that could clarify me 100%.
My question is: How can I launch an android's app preferences activity (from Contacts, Messages, ...) on my own app?
I give an example:
Imagine I'm developing an app which allows the user to quickly access to Message's Settings. I don't need to send or receive any information, I only need to open the activity, create a shortcut for it.
Someone knows if this can be done and even opening specific locations of the apps?
You don't need to know any specific locations or specific apps for these actions, simply look into Intent.ACTION_PICK.
Picking a Contact: get contact info from android contact picker
Picking a picture: How to pick an image from gallery (SD Card) for my app?
The best answer in this thread has the solution:
android: how do i open another app from my app?
Also check:
http://android-developers.blogspot.com/2009/01/can-i-use-this-intent.html
To open settings, you can try:
startActivityForResult(new Intent(android.provider.Settings.ACTION_SETTINGS, 0));
There is no difference in writing in code an Explicit Intent which will go to a specific activity of your app and using the same format to go to a specific activity some other app. A few things to be aware of: (1) The receiving activity may be expecting particular data and fail otherwise. (2) The standard apps you are considering like Contacts, Messages while you can find the source for them in the Android Open Source Project (AOSP) may be changed by the manufacturers so that the activity names and necessary extra data could be different.
In order to maintain as much compatibility between all of the different Android manufacturers, you should stick to the standard implicit intent with the appropriate action/data.
This is a theoretical situation:
I am writing an app to detect the presence of another on the phone
The classpath, name, Activity names etc. of the target app have been randomized, I can't just check if it's there (it is semantically the same but syntactically unique)
I have root access to the phone
The app is open source, and (apart from the package name and application name) I know everything about it.
The app generates no Log output.
I've been thinking of ways to detect whether this other app is present on the phone (assuming it is actually run from time to time), are the following methods feasible at all?
Look periodically for the presence of certain classes in memory
Search for known chunks of the compiled code in each installed apk
Detect the app running by inspecting the memory of the device at certain intervals and look for usage patterns matching the app
Are there any other ways of detecting another app under these circumstances?
Use PackageManager. It has a method returning info about all the apps, installed on the system: getInstalledPackages().
If I want to create custom address book (which overrides my phone's default address book), and if I want it to be used by all applications, what should be my intent-filter? Does Android allow me to do such a thing considering the fact that such a third-party app could potentially be malicious?!
And, if I want to have yet another address book application, I suppose the second app also has same intent-filter, isn't it? How does the framework decide which app to pick if I click on Contacts button when making a call? In other words, how does the framework resolve intents in case,there is a conflict between multiple intent-filters?
You can replace any application on Android platform, even Home. Android documentation explains everything there is to know about Intents and Intent Filters and there is a section called Intent Resolution that answers your question. Intent Resolution section for Intent class has some additional information.
As far as I can tell Android doesn't try to resolve a conflict. It ask the user which application to run and gives them the choice to mark this Activity as the default for this Intent. They give an example about mail app here.
While Mr. Smiljanić is basically correct, there is no Contacts application in Android for you to replace. There is Dialtacts, which is the application supporting the contacts, call log, and dialer. That application cannot be replaced, mostly because the dialer cannot be replaced.
So, while you may be able to override some intent filters and get control on some contacts-related requests, you will be unable to get the contacts portion of Dialtacts overridden, which will confuse users.