problem using reflection

melamoud

Active Member
Licensed User
Longtime User
I'm trying to run this code (in java)
B4X:
Intent batteryIntent = context.getApplicationContext().registerReceiver(Null,new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
Int rawlevel = batteryIntent.getIntExtra("level", -1);
so I wrote this code in b4a
B4X:
Dim  r1 As Reflector 
   Dim v As Object 
   v = r1.CreateObject2("android.content.IntentFilter",Array As Object("ACTION_BATTERY_CHANGED"),Array As String("java.lang.String"))
   Log ("object created:" & v) 

   Dim  r As Reflector 
   r.Target = r.GetContext
   Dim rr As Object 
   rr = r.RunMethod3("registerReceiver",Null, "android.content.BroadcastReceiver",v,"android.content.IntentFilter")
    'rr = r.RunMethod4("registerReceiver", Array As Object(0, v), Array As String("android.content.BroadcastReceiver", "android.content.IntentFilter"))

   
   Log ("registerReceiver runned:" & rr)
   r.Target = rr
   Dim rawlevel As Int
   rawlevel = r.RunMethod3("getIntExtra","level","java.lang.String",-1,"java.lang.int")
   Log ("battery level is" & rawlevel)
and I get this exception int the first runMethod3 call
B4X:
object created:android.content.IntentFilter@4057a1c8

main_getbatterylevel (java line: 404)


java.lang.IllegalArgumentException: argument type mismatch
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:507)
   at anywheresoftware.b4a.agraham.reflection.Reflection.runmethod(Reflection.java:205)
   at anywheresoftware.b4a.agraham.reflection.Reflection.RunMethod4(Reflection.java:846)
   at appsright.testapp.main._getbatterylevel(main.java:404)
   at appsright.testapp.main._activity_create(main.java:251)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:507)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:167)
   at appsright.testapp.main.afterFirstLayout(main.java:89)
   at appsright.testapp.main.access$100(main.java:16)
   at appsright.testapp.main$WaitForLayout.run(main.java:74)
   at android.os.Handler.handleCallback(Handler.java:587)
   at android.os.Handler.dispatchMessage(Handler.java:92)
   at android.os.Looper.loop(Looper.java:130)
   at android.app.ActivityThread.main(ActivityThread.java:3806)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:507)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
   at dalvik.system.NativeStart.main(Native Method)
java.lang.IllegalArgumentException: argument type mismatch

what am I doing wrong ?
What I'm trying to do is write a service that will not run if battery is lower than X% I tried using phoneEvents it did not work (seperate thread)

thanks
 

NJDude

Expert
Licensed User
Longtime User
The attached sample is a service that it will stop if the battery level goes below 100%, you can modify it to suit your needs.

I'm using PhoneEvents.

I hope is what you're looking for.
 

Attachments

  • ServiceSample.zip
    9.7 KB · Views: 237
Upvote 0

melamoud

Active Member
Licensed User
Longtime User
I think this is not what I'm looking for, I only get the batterchange event some time after the service started, so I cant really relay on it to be updated before the service started to prevent the server from starting

for you it is easier since you want to stop the service

I can use the same approch and check the battery all the time, and stop after a while, but the point was not to start at all.
 
Upvote 0

NJDude

Expert
Licensed User
Longtime User
I can use the same approach and check the battery all the time, and stop after a while, but the point was not to start at all.

But how are you going to find out the level if you don't start and check?, even if you set the service to start at boot, you have to start the service, if the battery is below the level you determine then stop.

Am I missing something?
 
Upvote 0

melamoud

Active Member
Licensed User
Longtime User
But without the event I get the value in the next line so I will not have timing issues where the event runs after the next line right ? (Which is what happening to me)
 
Upvote 0

melamoud

Active Member
Licensed User
Longtime User
thats not good, cause it will fire everytime the battery change state and I do not want to service to run all the time,

Do you know whats wrong with the reflection code I wrote ?
 
Upvote 0

melamoud

Active Member
Licensed User
Longtime User
thanks, but I do not have a java environment setup to do that, i'm sure it will be helpful to others as well

anyone ?
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Do you know whats wrong with the reflection code I wrote ?
RunMethod2 and RunMethod3 are intended for use with primitives and take Strings as arguments and coerce the string values to the correct primitive type. They cannot cope with reference types.

Your commented out RunMethod4 is incorrect it should be
B4X:
   rr = r.RunMethod4("registerReceiver", Array As Object(Null, v), Array As String("android.content.BroadcastReceiver", "android.content.IntentFilter"))
This runs OK but returns null in rr so getIntExtra fails with a null pointer exception. The docs for registerReceiver say it returns
The first sticky intent found that matches filter, or null if there are none.
 
Upvote 0
Top