I'm looking for a way to get the current active user in Android. I'm building a system app so I can use hidden methods, but specifically it has to be the current ACTIVE user, and not the user for a given process.
For instance, if you install an app using ADB the process is going to say the user id is the owner. This means that UserHandle.myUserId() will not work for what I need :(
So I found a method that does exactly what I need it to do. There is a static method in ActivityManager that is hidden (so you need to work some magic to have access to it) but here it is:
ActivityManager.getCurrentUser();
That's all there is to it.
Related
I'm building some general testing tool for Android apps and trying to get the activity name (e.g. com.android.calculator/.Calculator, the com.android.calculator can be obtained through UiDevice.currentPackageName, the pain is from the second part) during the testing. This is to say that my tool may test other apps that are not in the same package as mine. For example, testing the stock calculator app.
Here is a list of attempts I have made:
the UiDevice.currentActivityName is deprecated and it does not provide the accurate information
InstrumentationRegistry.getInstrumentation().targetContext.getSystemService<ActivityManager>(), then access the ActivityManager.getRunningTasks(1).get(0).topActivity, which always returns the same value even though the view has switched (and this is deprecated too)
Similar to 2, I tried ActivityManager.getAppTasks().get(0).getTaskInfo().topActivity, but this keeps giving me null
ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(RESUMED). This gives me an empty collection
Application.ActivityLifecycleCallbacks. I registered it with the application, but no callback is received.
(Kinda works, but not perfect) using adb dumpsys activity then find it there. But this way I have to wait for some arbitrary time until the view is updated, otherwise the result is still inaccurate
So I am currently in a cul-de-sac now, and I appreciate any help on this issue. I try to avoid reflection, because as I know it does not work on newer devices. So any clue will be appreciated.
As there is no answer posted, I wanna share my current strategy, which is not perfect, but somewhat helpful.
So first of all, as UiDevice.getActivityName is deprecated, I can only obtain the activity name through adb. Specifically, I use adb shell dumpsys activity top for API lower than 28 and adb shell dumpsys activity activities otherwise.
Then I subscribed to AccessibilityEventListener callbacks. Specifically, I run the adb command whenever I receive callbacks with type AccessibilityEvent.TYPE_WINDOWS_CHANGED. You can set up AccessibilityEventListener using this method: setOnAccessibilityEventListener
in my app I am using push notifications to notify the user about something.Based on different app state I have to assign different activities to click event of notification. If the user press home button and app is in background i have to handle that scenario as well. But here the issue come when user clear the app instance from memory. If user do that I have to consider it as app closed. But i dont know how to get that app instance clear event. Please help me.
The task you are willing to solve is equivalent to protection against the task manager. I am not sure that your app knows better than the user whether or not to show the ads. Please do not create malware.
Try the UncaughtExceptionHandler stuff like setUncaughtExceptionHandler(). I am not sure it will be necessarily called, and it may depend on the Android version, but it is something to start with.
Another possibility is to use one or more remote service(s). The processes will not die all at once, there's a good chance that one process may notice the death of another process. There should be some kind of wait-for-process-to-complete at least on the JNI level.
One more possibility is to use two applications, one monitoring the other...
After you solve this problem, please post your own answer telling the world what you did.
I want to know how to detect when an external app runs one of this methods. I'm working with some classmates in a project where we want to examinate the response time of other applications. The idea is to measure the time between the run of each method to get an aproximation of the response time when opening the app.
Is this possible to achieve?
Android apps are sandboxed and only expose content that they intend to expose. The methods you name are part of components that cannot be accessed directly from the "outside" world. In other ways, if an app wanted you to know when those methods are being called, they will expose that information (i.e. sending a Broadcast or maybe storing the information in a ContentProvider). You can try and see if you can get some information out of the logcat, but I cannot assure how accurate and consistent it will be.
This is imprecise, but I would monitor logcat activity. Depending on the device/VM/AVD logcat is super active during transitions (such as back-grounding and foregrounding) and idle when an app is awaiting user input.
EDIT:
Other than that, if you can do your analysis off the device, perhaps look into using DDMS?
Is there a way in android to get the name of the activity (package.activityclass) of whatever activity has focus? I don't have root permissions, but I'm willing to write this with Device Admin or Accessability if it calls for it.
For example, if the camera is up, you would get "com.android.camera.CameraActivity" (or whatever the class is.)
If such a facility doesn't exist, that would make sense too, considering the security issues that come with it.
I think the best you can do is use the ActivityManager APIs, like getRunningTasks()
I want to determine whether my application being run for the first time, and so it will be hard to pass around it.
The preferences or empty file approaches are not going to work because you can simply clear the application data or delete the empty file.
Also I want to do it offline so no server checking is going to work either.
Maybe it's possible to add some code to the installation of the apk so it will only run once.
So my best bet is spawning a lot of empty files all around and hope the user won't find them, but this is pretty messy.
Has anyone ever done this somehow before? Any suggestions?
The preferences or empty file approaches are not going to work because you can simply clear the application data or delete the empty file.
One possibility is to have a BroadcastReceiver, registered in your manifest, that you do not actually use for anything. On first run of your app, disable that receiver via PackageManager and setComponentEnabledSetting(). On future runs, you can determine if that BroadcastReceiver is already disabled via PackageManager and getReceiverInfo().
If the user uninstalls and reinstalls the app, the app will return to its original state. Rooted device users can also get past this. Otherwise, this should be reasonably solid.
I know you said you dont want files, but if you create them as local internal storage then the user can not delete them as they wont have access unless it is rooted phone. Clearing data "may" delete them.
There is another solution but it is lengthy one. Use SQLite database.IT is local and I dont think it can be deleted otherwise the whole application will crash