I currently have a periodic issue where I get an IllegalArgumentException
when I call Activity.startLockTask()
. My app has a device owner app installed which has allowed my package to automatically pin itself.
The code below is checking to make sure my package can lock itself. If it can then it pins itself.
Code:
if (dpm.isLockTaskPermitted(getPackageName())) {
super.startLockTask();
}
Logcat:
java.lang.IllegalArgumentException: Invalid task, not in foreground
at android.os.Parcel.readException(Parcel.java:1544)
at android.os.Parcel.readException(Parcel.java:1493)
at android.app.ActivityManagerProxy.startLockTaskMode(ActivityManagerNative.java:5223)
at android.app.Activity.startLockTask(Activity.java:6163)
The issue is my app needs to occasionally restart itself. So we unpin, finish the activity and start it again with a new task, and then exit our process. When the activity comes back up it tries to pin itself - sometimes it works - sometimes it doesn't. I believe how we restart is probably the reason the exception is thrown but it shouldn't matter since the new activity IS in the foreground and IS focused.
Once the activity fails to pin it will continue to fail as long as it tries: If I sit there and try and pin the task every 5 seconds it will continue to fail each time. I've tried pinning in onCreate
, onWindowFocusChanged
, onResume
, and onStart
.
Does anyone know what the issue might be?
For reference:
Line 8853: https://android.googlesource.com/platform/frameworks/base/+/android-5.0.2_r1/services/core/java/com/android/server/am/ActivityManagerService.java
I have the same issue, I haven't found a proper solution yet. But this is what I currently do.
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
try {
if (dpm.isLockTaskPermitted(getPackageName())) {
super.startLockTask();
}
}catch (Exception exception) {
Log.v("KioskActivity","startLockTask - Invalid task, not in foreground");
}
}
},1500);
It seems that the application requesting the lock hasn't yet received focus even though the onWindowFocusChanged is fired. By delaying the call to startLocktask by some time it will work. How ever there is a small period of time where the app won't be pinned/locked. I've solved this by some additional security measures (I have a long running service in the background that prevents notification shade pull downs and will close the settings window if opened).
Btw, did you ever manage to solve this in a adequate way?
I had this issue and resolved it using the logic taken from the answers in this post: How can you tell when a layout has been drawn?
Basically it just ensures that the UI has been drawn first then attempts to pin.
Example Code (Put this in your onCreate method):
> findViewById(R.id.your_view).post( new Runnable() {
> @Override
> public void run() {
>
> // Run pinning code here
> }
> });
I know this is quite an old question, but I ran into it as well and here's how I solved it. The key is this sentence in the docs for startLockTask()
(the same goes for stopLockTask()
too)
Note: this method can only be called when the activity is foreground. That is, between onResume() and onPause()
I had some code paths that ended up trying to call startLockTask()
before onResume()
. I fixed it by ensuring the right activity state (using AndroidX lifecycle)
if(lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
startLockTask()
}
This was sufficient for my case. You might need to do some additional logic like this (pseudocode):
if(not yet resumed) {
doWhenResumed { // Implement this as a helper function that executes when your Activity is resumed
startLockTask()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With