B4A Library OS metrics: MSOS lib and OSStats and GetForegroundApp

MSOS Library

This library contains many OS functions from the Activity Manager.
This library is constantly evolving.
It consists of 2 librarys now. MSOS is java code, OSStats is B4A code. Both are packed jars.

Requirements:
At the moment getSystemTotalMemorySize works only on API 16+ thanks to google for implementing incomplete API. Courtesy testing (read bashing) of NJDude.

MSOS
Author:
thedesolatesoul
Version: 0.01
  • MSOS
    Fields:
    • IMPORTANCE_FOREGROUND As Int
    • IMPORTANCE_VISIBLE As Int
    Methods:
    • getForegroundApp (pImportance As Int) As List
    • getForegroundTask As List
    • getFormattedSystemAvailabeMemorySize As String
    • getFormattedSystemTotalMemorySize As String
    • getProcessMemoryInfo (pid As Int) As Int
    • getSystemAvailabeMemorySize As Long
    • getSystemTotalMemorySize As Long
    Permissions:
    • android.permission.GET_TASKS
    Properties:
    • NumCores As Int [read only]
      Gets the number of cores available in this device, across all processors.
      Requires: Ability to peruse the filesystem at "/sys/devices/system/cpu"
OSStats
  • Class_Globals
    Class module
  • EndStats
    Stop collecting the stats
    Call this in Activity_Pause
  • Initialize (Interval As Int, BufferSize As Int, Module As Object, EventName As String)
    Initializes the object.
    Interval is the gap to keep between capturing stats
    Buffer size is size of buffer to store stats (for graphing etc)
    Module is the parent object where the events will be delivered
    Eventname is th prefix of the events raised
  • StartStats
    Start collecting stats
    The eventname_Update(CpuEfficientcy() as Float,RAMUsage as Float) will be raised
  • getNumCores As Int
    Returns the number of CPU cores


It calculated the CPU Usage and Memory Usage.
You can start/stop tracking the OSStats.
This is stored in a buffer for graphing/smoothing etc.

I am trying to figure out out how to get which app is in the foreground or is visible.
This is so that I can use either a transparent activity or a service, and find out which app is on top.

//Ignore
getRunningApps: Uses this to find which apps have IMPORTANCE_FOREGROUND or IMPORTANCE_VISIBLE set
getRunningTasks: Uses this to find running tasks. tasks(0) will be the most recent one.
You can run these in a service and see what values they return.
I am still not sure which method is more accurate depending on what a 'task' and what an 'app' is.
For instance the last 'task' may have ended itself, whereas IMPORTANCE_VISIBLE will return whatever the user is viewing however this returns a number of items.
If someone could test this, and figure out what is doing what it would be great!
//
 

Attachments

  • OSStats.zip
    5.2 KB · Views: 517
  • MSOS.zip
    5.6 KB · Views: 552
Last edited:

bsnqt

Active Member
Licensed User
Longtime User
Thanks for the library.
I try to run the sample from NJDude but got error...
Is this related to what thedesolatesould mentioned "getSystemTotalMemorySize works only on API 16+"?
My test device is Xperia S (Android 4.1.2)
java.lang.NoSuchFieldError: android.app.ActivityManager$MemoryInfo.totalMem
at com.maximussoft.msos.MSOS.getSystemTotalMemorySize(MSOS.java:127)
at b4a.example.osstats._tmrstats_tick(osstats.java:363)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:170)
at anywheresoftware.b4a.objects.Timer$TickTack.run(Timer.java:105)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4441)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
at dalvik.system.NativeStart.main(Native Method)

When I run the sample, it just stopped with error "Unfortunately, MSOS Example has stopped".
 

thedesolatesoul

Expert
Licensed User
Longtime User
I have 4.1.1 and it is working for me.
API16 = 4.1 , I am not sure how it doesnt work on your 4.1.2
Nevertheless I am implementing an alternative method. Initially I was using the API version to determine which method to use, but may be I shall use try/catch and catch the NoSuchField exception and then use the alternate method (which may be blocked by Google in the future!)
 

cambopad

Active Member
Licensed User
Longtime User
@thedesolatesoul, @NJDude , and @Erel


How can I use this in a service? I tried to use it in a service, but MSOS seems to be an activity object. As a result I got the following message:

B4X:
Error description: Cannot access activity object from sub Process_Globals.
Occurred on line: 10
Dim xmsos As MSOS
Word: msos

Does anyone know how to fix this and get it working in a service? I need this feature for my upcoming project :(


Thanks you!
 

cambopad

Active Member
Licensed User
Longtime User
It doesnt need to be an ActivityObject. I have definitely used it in a service.
I might fix it one day.
Although be wary as most of this API is deprecated by Google in Android5, so I dont see a lot of point in putting any effort into this.

Can you provide sample code to use it in a service? Or does the lib need to be fixed by you first before I can use it in a service?
 

thedesolatesoul

Expert
Licensed User
Longtime User
@thedesolatesoul Thanks you! But are these two features also deprecated?

  • getForegroundApp
  • getForegroundTask
I really need this two features :(
Yes they are deprecated:
http://developer.android.com/reference/android/app/ActivityManager.html#getRecentTasks(int, int)
http://developer.android.com/reference/android/app/ActivityManager.html#getRunningTasks(int)

Can you provide sample code to use it in a service? Or does the lib need to be fixed by you first before I can use it in a service?
I would need to fix the lib.
Try the one attached.
 

Attachments

  • MSOS.jar
    4.7 KB · Views: 240

G-ShadoW

Active Member
Licensed User
Longtime User
Android 5.1.1 not working

B4X:
** Activity (main) Create, isFirst = true **
main_activity_create (B4A line: 68)
xOSStats.Initialize(400, 50, Me, "myStats")
java.lang.IncompatibleClassChangeError: The method 'int com.maximussoft.msos.MSOS.getNumCores()' was expected to be of type virtual but instead was found to be of type static (declaration of 'java.lang.reflect.ArtMethod' appears in /system/framework/core-libart.jar)
    at b4a.example.osstats._initialize(osstats.java:208)
    at njdude.msos.sample.main._activity_create(main.java:396)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
    at njdude.msos.sample.main.afterFirstLayout(main.java:100)
    at njdude.msos.sample.main.access$100(main.java:17)
    at njdude.msos.sample.main$WaitForLayout.run(main.java:78)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5289)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
** Activity (main) Resume **
WakeLock already held.
---- 1 ----
---- 2 ----
---- 3 ----
---- 4 ----
---- In onAdFailedToLoad ----Server Message: no results. Try again in 10 seconds
 

JohnC

Expert
Licensed User
Longtime User
Update (June 2016): The above GET_RUNNINGTASKS function sadly also no longer works (at least not in Android 5.0 and higher).
When you got the code running in your May 25, 2016 post, what version of OS were you running then?

I am trying to find out a way if the phone is currently displaying the homescreen or not (when running on android 5.x).
 

DonManfred

Expert
Licensed User
Longtime User
When you got the code running in your May 25, 2016 post, what version of OS were you running then?
Probably Android <5 as starting from 5 it does not work any longer.
 
Top