B4A Library Physical Activity Recognition Detection

Status
Not open for further replies.

Erel

Administrator
Staff member
Licensed User
Class updated on May 2020.

This class allows you to monitor the user / device physical state (walking, running, still, etc.).

The state detection is based on Android location services which use low power sensors to try to detect the current activity. Once you connect your app to these services you will receive notifications even when your app is in the background (similar to static intent filters).

Configuration steps:
1. Add this line to the main activity:
B4X:
#AdditionalJar: com.google.android.gms:play-services-location
2. Add to manifest editor:
B4X:
CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)
AddPermission(com.google.android.gms.permission.ACTIVITY_RECOGNITION)
AddPermission(android.permission.ACTIVITY_RECOGNITION)
Recognition Service

Add a service named RecognitionService (must be this name) to your project. This service will receive the activity detection notifications.
The code should be similar to:
B4X:
Sub Process_Globals

End Sub
Sub Service_Create

End Sub

Sub Service_Start (StartingIntent As Intent)
    For Each ev As TransitionEvent In Starter.client.GetTransitionEvents(StartingIntent)
        Log(ev) 'ignore
        ToastMessageShow("" & ev, True)
    Next
    Service.StopAutomaticForeground
End Sub
The service will receive intents with the detection information. The intent includes two lists with the possible states and confidence levels. Both lists are sorted from the most probable activity to the least probably activity.


Listening for events

B4X:
'from an activity
Dim p As Phone
If p.SdkVersion >= 29 Then
    rp.CheckAndRequest("android.permission.ACTIVITY_RECOGNITION")
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result = False Then
        ToastMessageShow("No permission", True)
        Return
    End If
End If
Dim activities As List = Array("IN_VEHICLE", "ON_BICYCLE", "ON_FOOT", "STILL", "WALKING", "RUNNING")
Wait For (Starter.client.RequestTransitionUpdates(activities)) Complete (Success As Boolean)
Log(Success)

Notes

- Android may kill the process and then recreate it when a notification is delivered. This means that it is better to run the app in Release mode. Otherwise it will fail when the process is recreated.

History

V3.00 - Completely new version, released as a class instead of a library. It is based on a new Google API. Not backward compatible.
 

Attachments

Last edited:

GMan

Well-Known Member
Licensed User
Hoi Erel,
what is the difference between on foot and walking ?
 

udg

Expert
Licensed User
Hi GMan,

it seems there's no such a big difference..
Read here.

Umberto
 

Ratna Fang

Member
Licensed User
you came just exactly when i need at most :)
thanks, erel.
i'll give it a try tonight for sure
:beer:
 

FreeWolF

Active Member
Licensed User
Excuse me but I can't find in the Android SDK Manager the download for the play services....Where is located?
 

GMan

Well-Known Member
Licensed User

Ratna Fang

Member
Licensed User
Excuse me but I can't find in the Android SDK Manager the download for the play services....Where is located?
example:
E:\androidsdk\adt-bundle-windows-x86_64\adt-bundle-windows\sdk\extras\google\google_play_services\libproject\google-play-services_lib\libs
where E:\androidsdk\adt-bundle-windows-x86_64\adt-bundle-windows is your SDK directory.

*you should be easier to find out the /sdk\extras\google\google_play_services\libproject\google-play-services_lib\libs folder from there :)
 

FreeWolF

Active Member
Licensed User
example:
E:\androidsdk\adt-bundle-windows-x86_64\adt-bundle-windows\sdk\extras\google\google_play_services\libproject\google-play-services_lib\libs
where E:\androidsdk\adt-bundle-windows-x86_64\adt-bundle-windows is your SDK directory.

*you should be easier to find out the /sdk\extras\google\google_play_services\libproject\google-play-services_lib\libs folder from there :)
Ok, thank you very much!!! :)
 

NJDude

Expert
Licensed User
Does the interval has any effect? (ar.Connect(5000)) it seems to me that no matter what value is entered the detection time is always slow.
 

MaxApps

Active Member
Licensed User
Hi

How do I get the values, received in the service module, to the activity module?

Kind regards
Jakob
 

NJDude

Expert
Licensed User
The attached sample uses this new library and displays the results on an activity, when the HOME key it pressed, the results will show on the status bar via a notification.

There's room for improvement, but this code might give you an idea.
 

Attachments

GMan

Well-Known Member
Licensed User
On my devices (2.1 and 4.2) the App breaks...on the 4.2 device at start, on the 2.1 device after pressing stop (when start pressed)
Log from the 2.1 device:
B4X:
Connected: false
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
java.lang.NoClassDefFoundError: com.google.android.gms.location.ActivityRecognitionClient
    at anywheresoftware.b4a.objects.ActivityRecognition.Stop(ActivityRecognition.java:66)
    at njdude.activityrecognition.sample.main._stopbutton_click(main.java:372)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:174)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:162)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:158)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:66)
    at android.view.View.performClick(View.java:2408)
    at android.view.View$PerformClick.run(View.java:8816)
    at android.os.Handler.handleCallback(Handler.java:587)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:4627)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
    at dalvik.system.NativeStart.main(Native Method)
 
Last edited:

NJDude

Expert
Licensed User
It works on most of my devices, but not on the ones running older versions of Android, maybe the library is meant to run only on the latest ones.

I'm assuming that the inaccuracies you are referring to is due to the way you get the results, like I mentioned on my previous post, it is a little slow but seems to work.
 

NJDude

Expert
Licensed User
Well, it seems the new Google Play Services update (ver 18) breaks this lib, now I'm getting this error as soon as the app starts.
B4X:
main_process_globals (java line: 370)

java.lang.NoClassDefFoundError: anywheresoftware.b4a.objects.ActivityRecognition

	at njdude.activityrecognition.sample.main._process_globals(main.java:370)
	at njdude.activityrecognition.sample.main.initializeProcessGlobals(main.java:345)
	at njdude.activityrecognition.sample.main.afterFirstLayout(main.java:94)
	at njdude.activityrecognition.sample.main.access$100(main.java:16)
	at njdude.activityrecognition.sample.main$WaitForLayout.run(main.java:76)
	at android.os.Handler.handleCallback(Handler.java:733)
	at android.os.Handler.dispatchMessage(Handler.java:95)
	at android.os.Looper.loop(Looper.java:136)
	at android.app.ActivityThread.main(ActivityThread.java:5001)
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:515)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
	at dalvik.system.NativeStart.main(Native Method)
 

walterf25

Expert
Licensed User
Well, it seems the new Google Play Services update (ver 18) breaks this lib, now I'm getting this error as soon as the app starts.
B4X:
main_process_globals (java line: 370)

java.lang.NoClassDefFoundError: anywheresoftware.b4a.objects.ActivityRecognition

    at njdude.activityrecognition.sample.main._process_globals(main.java:370)
    at njdude.activityrecognition.sample.main.initializeProcessGlobals(main.java:345)
    at njdude.activityrecognition.sample.main.afterFirstLayout(main.java:94)
    at njdude.activityrecognition.sample.main.access$100(main.java:16)
    at njdude.activityrecognition.sample.main$WaitForLayout.run(main.java:76)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5001)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
    at dalvik.system.NativeStart.main(Native Method)
Of Course, leave it to google to break stuff!
 

GMan

Well-Known Member
Licensed User
Hoi Erel,
also with 3.82 no change - exact the same actions on both devices
 
Status
Not open for further replies.
Top