Step 1: Open my app
Step 2: Open system settings(My app is still alive, not killed)
Step 3: Choose a permission of my app(e.g. camera or location), which state is allow and turn it to deny
Step 4: Open my app
My app dead in Step3, and in Step4 it start a new thread. It also happened on other apps. I try these on android 10 and android 12 emulator.
Other apps I' ve tried on emulator: WeChat, Google Photos, Chrome. For most kinds of permission they dead, and for some permissions they still alive. (My WeChat dead when denied camera permission, but for "Draw over other apps" permission, it did not)
Why did the thread die? There is no useful log in the dead thread. The new thread says: Redefining intrinsic method java.lang.Thread java.lang.Thread.currentThread(). This may cause the unexpected use of the original definition of java.lang.Thread java.lang.Thread.currentThread()in methods that have already been compiled.
When your app is alive. if you revoke permission from the settings page. The app process will be recreated. it will go to the exact screen where you are before the app gets killed. but viewmodel and all objects would be null at this point.
Refer:
Crash when disable permission and go back to the app
Related
Flutter app crashes when user manually changing location perimssion from allow to deny. Is this a normal behavior ?, i've tried to change manually the permissions of other popular apps, they all restart and not crash. But my app after changing permission says Lost Connection to Device and thats it
Actually this is a normal behavior on debugging mode , once you change app permission from settings it automatically kills the app and you have to re run it in order for the new settings to take effect
for more info you can read this GitHub issue discussion
https://github.com/Baseflow/flutter-permission-handler/issues/166
My app main usage is overlay, the overlay is running from a service.
Android Security add the nice "Screen Overlay Detected"
I want to avoid "Screen Overlay Detected" when user tries to change permissions. so... I've add an AccessiblityService that detects:
if ( event.getPackageName().equals("com.google.android.packageinstaller") ){
stopService(myServiceIntent);
}
However, even now I see this message popping. (when my service is stopped...).
I saw Twilight does it without problem.
What am I missing?
p.s. - I've also tried building a signed apk but saw exact same behavior.
It seems I've been able to resolve this.
a) stopService isn't assured your service will be stopped.
as described here :
It will not be destroyed until all of these bindings are removed. See > the Service documentation for more details on a service's lifecycle.
b) I was able to kill my service by sending intent that called stopSelf().
However process killing/starting can be slow.
c) Best resolution: so it seems Android checks for view visibility. no need to kill services or do anything more complicated.
Current way I'm doing it:
- AccessibilityService (already used by my app) monitor "com.google.android.packageinstaller" though it can be refined to class: "com.android.packageinstaller.permission.ui.ManagePermissionsActivity"
Once detected in this class, we send Intent to "duck", and when we're out, we send another intent that we're back on.
The service handles those calls by:
[ourView].setVisibility(View.INVISIBLE); // when permission settings shown
[ourView].setVisibility(View.VISIBLE); // when normal flow
As long as Android 6.x is buggy on some devices where this "overlay alert" is displayed without any reason (on 2 to 5% of the devices according to my analytics data), the best solution is to avoid the whole permission process by defining the targetSdk to 22. Take care that you can't downgrade the target sdk for a new version or this will induce a INSTALL_FAILED_PERMISSION_DOWNGRADE error when the user updates requiring an unisntall/install of the app.
(in reference to the new Android M runtime permissions system) Everywhere I look, it says that if a permission is taken away while the app is running, my app will be killed (or restarted). However, when I try this, my app is not killed/restarted, and when I got back to the app, it crashes because the permission is taken away.
the device I'm testing on is a nexus 5, running android 6.0.1
once i get my hands on a different device to test on, I will update.
note: I didnt include any code or error log becuase I want the focus to be on why my app is not getting killed by the system like everyone says, and not on why it's crashing.
I don't recall seeing anything about apps being killed in Android 6. Just all the dire warnings about apps crashing when the OS suddenly starts throwing exceptions that pre-M apps took for granted.
Just handle exceptions whenever you do something that requires a "dangerous" permission.
https://developer.android.com/training/permissions/requesting.html#perm-check
https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous
I'm looking into porting some existing code to take Android M's new way of dealing with permissions into consideration. However the permission API needs to have an activity associated with it (for example the requestPermissions() method's first parameter is an activity).
So how should a service that needs to check if a permissions has been granted and request for permissions use this new API if the service doesn't have an activity?
Is it possible for the service to create a dummy invisible activity just for use with the permissions API? (if its possible I don't like the thought of doing that anyway though).
Or suppose its not a service but a model class that needs to perform a permissions check, in MVC a model shouldn't have any knowledge of the Vs and Cs and yet now either it has to in order to know which Activity to use with the permission API. Or potentially lots of code might have to migrate from model code into Activity code.
Any thoughts on how to migrate non activity based code that needs to check/prompt for permissions over to Android 6.0?
Update: I left out an important piece of information - this is code that is pre-installed (our company provides code that device manufacture's place in rom) and often may be run at device boot time and run in the background. Therefore the usual situation of a user being prompted for permission when they launch the app or later (and there therefore being an activity at that point) does not necessarily apply.
So how should a service that needs to check if a permissions has been granted and request for permissions use this new API if the service doesn't have an activity?
There is almost always an activity, except for pre-installed apps and plugins for other apps. Otherwise, your service is unlikely to ever run, as nothing will have used an explicit Intent to start up one of your app's components, so it will remain in the stopped state.
For the ~99.9% of Android apps that have an activity already, if the permissions are needed for the whole operation of the app, request them on first run. As Snild Dolkow notes, if the user later revokes the permission through Settings, you can detect that without an activity, then use other UI options (e.g., Notification, app widget) to let the user know that operation is suspended until they grant you the permissions again, which they would then do through your activity.
Is it possible for the service to create a dummy invisible activity just for use with the permissions API?
Presumably you can have a Theme.NoDisplay activity use requestPermissions(). However, from the user's standpoint, it will not make much sense, unless there's some alternative UI (app widget?) that they are interacting with. Popping up a permission dialog out of nowhere is unlikely to make you popular.
UPDATE 2019-06-15: Note that Android Q bans services popping up activities frmo the background. Please use a notification instead.
in MVC a model shouldn't have any knowledge of the Vs and Cs and yet now either it has to in order to know which Activity to use with the permission API
Do not touch the models until you have requested the permission, and gracefully fail if the permission is revoked. You already have to gracefully fail in other circumstances (out of disk space, no Internet connection, etc.), so a revoked permission should be handled in much the same way.
using this new 6.0 API seems like an recipe for bad design and tight coupling
You are welcome to your opinion. Based on what I have read, the Android engineers believe that asking the user for permissions is part of the user experience and is best handled at the UI layer as a result.
Again: the vast majority of Android apps will not have a problem with this, as they have a user interface. Apps that do not have a user interface and need dangerous permissions are in for some amount of rework.
this is code that is pre-installed (our company provides code that device manufacture's place in rom) and often may be run at device boot time
First, please understand that this is so far from normal that you can't even see normal from where you are due to the curvature of the Earth. :-) You can't really complain that Google did not optimize this particular scenario.
As I understand it, even system apps should be asking for runtime permissions. The Camera app did, for example, on the 6.0 preview. That being said, there's gotta be some database on the device somewhere that is tracking what has been granted, and presumably there is some way to pre-populate it. However, the user could still revoke it from Settings, presumably. But, the manufacturer could pull some stunts (e.g., messing with the Settings app) to possibly even preclude that scenario. I'd be looking in the same area as "how do I get it so my app cannot be force-stopped?" that device manufacturers can do.
Your alternatives would be to get rid of the dangerous permissions or to migrate your app off the SDK and into a standard Linux binary that would be run as part of the boot process and be put into a Linux user group that has access to the stuff that you need.
Ask for it when the user enables whatever feature your service provides. They'll be in one of your activities at the time. Yes, it means that your activities need knowledge of what permissions your services will require.
The service can always check for the permission by itself, though, since checkSelfPermission() is available in all Context instances. So you don't need an activity for that.
I guess an alternative would be to have your service post a notification saying "feature X requires you to approve more permissions". Actually, that may be a good idea regardless, in case the user goes into settings and revokes any permissions after the fact. That notification would then take the user to some activity with an "enable feature X" button/checkbox -- ask for the permission when that is selected.
You can send a notification. Look this library to manage the permissions: permission library
This question already has answers here:
Listen to own application uninstall event on Android
(3 answers)
Closed 7 years ago.
Recently i've seen a funny app - Photo Wonder.
When this app is uninstalled, it shows a web survey page asking for the reason of app uninstall. Now, here is the problem.
As far as I know, after an app has been removed, the system broadcasts ACTION_PAKAGE_REMOVED intent.
But this funny app was able to show my the web page although the official doc says
"The package that is being installed does not receive this Intent."
Anyhow, I could find a process checking some kind of status of the app.
Now here is the question. Can the native app catch the broadcasted intent from android system?
If it is possible, please let me know how! :-(
I believe I've got the main idea of how they did it. Here is the pieces of the puzzle.
Any Android application can start a process by calling Runtime.exec() function.
Runtime.getRuntime().exec("chmod 755 '/data/data/my.app/files'/native_code");
After this line of code gets executed there is another process spawned. This process runs under the same linux user as the application itself.
When a user opens Settings -> Apps -> My App and presses "Force stop" button, main application process gets killed, but the process hosting native program (see above) still runs. I personally believe this is a security issue and I am going to report it back to AOSP.
Such native program can run infinitely and do nothing - just sleeping. But before going to sleep, it registers a termination signal handler which will be called when process is about to be terminated by the system.
int main(void) {
signal(SIGTERM, termination_handler);
while(1) {
sleep(10);
}
}
void termination_handler(int sig) {
// handle termination signal here
}
Now you should already know what the last piece is, right? My native termination_handler should be able to launch a browser. I didn't try this in code, but I assume this is possible, because I can do it using adb shell as following
adb shell am start -a android.intent.action.VIEW -d http://www.google.com
Now back to the question about how Dolphin Browser does it. Install the app and launch it at least once. Once started, it registers a native uninstall watcher using the principles described above. To see it, connect to the device and open adb shell. Then call ps to see list of processes. You will see two processes similar to following
u0_a109 315 ... mobi.mgeek.TunnyBrowser
u0_a109 371 ... /data/data/mobi.mgeek.TunnyBrowser/files/watch_server
As you can see it starts a watch_server native program, which is a part of its apk-file. Now open App info page of Dolphin Browser and press "Force Stop". Switch back to terminal and call ps again. You will see there is no mobi.mgeek.TunnyBrowser process anymore, but watch_server still runs.
By the way this approach will only work, if watcher server runs all the time. To
make sure it is always up, both apps require "run at startup"
permission, where they start their watchers.
Now, when you uninstall the app, Android stops all processes belonging to this application. Watcher receives termination signal and opens browser with predefined URL and then shuts down.
I might look a bit different in some details, but the main concept behind this hack must be as described.
There could be a tricky thing like that application is also having watcher service.
You can check the permission used by that app may contain INSTALL and UNINSTALL permissions.
HOW IT WORKS:
instead of single app that may have 2 app bundle.
as and when you install it, this app is also installing some service that is watching your app status
When you try to uninstall that app the system broadcast is called which is handled by that service and will check that if your package is exist in installed application or not.
as soon as this service finds that your package is not in the list it calls an intent with action view with the web url to open the brawser.