Android Question Continually check for PhoneStateChanged.ANDROID 8

petr4ppc

Well-Known Member
Licensed User
Longtime User
Dear friends, please,

I am trying to read PhoneStateChanged with button or with timer.

The trouble is, that if I listen PhoneStateChanged in my CHECKMYPHONE service, I can get result.
But when the Phone is ringing, the app is going to background and then I am trying to chceck the PhoneStateChanged in STARTER service.
But I can only wait to killcall = I am reading Phone state only when I Kill the call, because Phone state is changed.

But I need to know which state of phone (ringing. etc) is each 5 second.

It is possible to run phonestatechanged via timer,please?

B4X:
Sub PE_PhoneStateChanged (State As String, IncomingNumber As String, Intent As Intent)
 Log("PhoneStateChanged, State = " & State & ", IncomingNumber = " & IncomingNumber)
    Log(Intent.ExtrasToString)
End Sub

Thank you
p4ppc
 
Last edited:

petr4ppc

Well-Known Member
Licensed User
Longtime User
LMASTR in the tread you sent is writing phonenumber to text file if phoneevents detect the change. This I can do and this I undestand,

I am using in manifest editor:
B4X:
AddReceiverText(checkphonestate,
<intent-filter>
    <action android:name="android.intent.action.PHONE_STATE" />
    <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>)

Everything is OK with this.

BUT

I not understand how to detect Phone state in moment when I want to do this - with pushing button for example.
 
Upvote 0

Semen Matusovskiy

Well-Known Member
Licensed User
I am not aware how to retrieve current phone state by own initiative. But:

1) You can monitor state changes and to keep last state in a process_global variable
As I remember, this works in background also, at least, if to use "native" BroadcastReceiver inside the service.

2) Initial phone state.
There is enough unusual way to detect that a phone is in call.
B4X:
AudioManager manager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
if(manager.getMode()==AudioManager.MODE_IN_CALL){ ....}
 
Upvote 0

petr4ppc

Well-Known Member
Licensed User
Longtime User
Dear Semen,

I am using SDK26, Android 8,

1)
I have variable in STARTER service but if I save value to this variable then in state - RINGING PHONE the service STARTER is restarted and
the value is not in variable (I hope that this I am describing right)

2)
If you mean this:
B4X:
    Dim r As Reflector
    r.Target=r.GetContext
    r.target=r.RunMethod2("getSystemService","audio_service","java.lang.String")
    Log(r.RunMethod("getMode"))

then in Android 8, SDK 26 I get this error:
main_btn_run_click (java line: 393)
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
at anywheresoftware.b4a.agraham.reflection.Reflection.runmethod(Reflection.java:205)
at anywheresoftware.b4a.agraham.reflection.Reflection.RunMethod(Reflection.java:802)
at com.nma.incomingph.main._btn_run_click(main.java:393)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:191)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:171)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
at android.view.View.performClick(View.java:6291)
at android.view.View$PerformClick.run(View.java:24931)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:101)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7425)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference

Do you know please, how to update code in point 2 for SDK 26 and how to get "AudioManager.MODE_IN_CALL" value?
Best regards
p4ppc
 
Last edited:
Upvote 0

Semen Matusovskiy

Well-Known Member
Licensed User
Simple example (tested under SDK 26 emulator only, but should work in all Android 4+)

B4X:
Sub Process_Globals
    Dim Timer1 As Timer
End Sub

Sub Globals
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Timer1.Initialize ("Timer1", 1000)
    Timer1.Enabled = True  
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub Timer1_Tick  
    Dim jo As JavaObject
    jo.InitializeContext
    If jo.RunMethod ("IsPhoneInCall", Null) Then Activity.Color = Colors.Red Else Activity.Color = Colors.Green
End Sub

#If JAVA
import android.content.Context;
import android.media.AudioManager;

public boolean IsPhoneInCall ()
    {
    AudioManager manager = (AudioManager) getSystemService (Context.AUDIO_SERVICE);
    if (manager.getMode () == AudioManager.MODE_IN_CALL) { return true; } else {return false; }
    }
#End If

How to check in emulator. Run a program.
Click "..." in emulator's panel. Then "Phone", "Call device". "Answer".
Return to the app (key Back at the bottom of the screen)
Activity becomes red.

Click "End call". Activity becomes green.
 
Last edited:
Upvote 0

petr4ppc

Well-Known Member
Licensed User
Longtime User
SEMEN-
thank you very much.

it can recognize "IS IN CALL" (as is in Java code) - the APP is GREEN in CALL state. This is Perfect.

THANK YOU VERY MUCH

Best regards
p4ppc
 
Last edited:
Upvote 0

Semen Matusovskiy

Well-Known Member
Licensed User
Ringtone - yellow
B4X:
Sub Process_Globals
    Dim Timer1 As Timer
End Sub

Sub Globals
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Timer1.Initialize ("Timer1", 1000)
    Timer1.Enabled = True   
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub Timer1_Tick   
    Dim jo As JavaObject
    jo.InitializeContext
    If jo.RunMethod ("IsPhoneInCall", Null) Then
        Activity.Color = Colors.Red
    Else If jo.RunMethod ("IsRingtone", Null) Then
        Activity.Color = Colors.Yellow   
    Else
        Activity.Color = Colors.Green
    End If
End Sub

#If JAVA
import android.content.Context;
import android.media.AudioManager;

public boolean IsPhoneInCall ()
    {
    AudioManager manager = (AudioManager) getSystemService (Context.AUDIO_SERVICE);
    if (manager.getMode () == AudioManager.MODE_IN_CALL) { return true; } else { return false; }
    }
public boolean IsRingtone ()
    {
    AudioManager manager = (AudioManager) getSystemService (Context.AUDIO_SERVICE);
    if (manager.getMode () == AudioManager.MODE_RINGTONE) { return true; } else { return false; }
    }   
#End If
 
Upvote 0

petr4ppc

Well-Known Member
Licensed User
Longtime User
THANK YOU VERY MUCH SEMEN
- now ISRINGING and INCALL state I see perfect on my phone

One question - can you give me advice if code:
B4X:
#If JAVA
public boolean IsPhoneInCall ()
    {
    AudioManager manager = (AudioManager) getSystemService (Context.AUDIO_SERVICE);
    if (manager.getMode () == AudioManager.MODE_IN_CALL) { return true; } else {return false; }
    }
#End If
is possible to put in the SERVICE module? Do you know please which way is the best?

Best regards
p4ppc
 
Last edited:
Upvote 0

Semen Matusovskiy

Well-Known Member
Licensed User
Starter
B4X:
Sub Process_Globals
    Private Timer1 As Timer
    Private joStarter As JavaObject
End Sub

Sub Service_Create       
    Dim cls As String = Me   
    cls = cls.SubString("class ".Length)
    joStarter.InitializeNewInstance (cls, Null)
    joStarter.GetField ("processBA")
   
    Timer1.Initialize ("Timer1", 1000)
    Timer1.Enabled = True
End Sub

Sub Service_Start (StartingIntent As Intent)
End Sub

Sub Service_TaskRemoved
    'This event will be raised when the user removes the app from the recent apps list.
End Sub

'Return true to allow the OS default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub

Sub Service_Destroy

End Sub

Sub Timer1_Tick
    If joStarter.RunMethod ("IsPhoneInCall", Null) Then
        Log ("Red")
    Else If joStarter.RunMethod ("IsRingtone", Null) Then
        Log ("Yellow")
    Else
        Log ("Green")
    End If
End Sub
   
#IF Java
import android.content.Context;
import android.media.AudioManager;

public boolean IsPhoneInCall ()
    {   
    AudioManager manager = (AudioManager) processBA.context.getSystemService (Context.AUDIO_SERVICE);
    if (manager.getMode () == AudioManager.MODE_IN_CALL) { return true; } else { return false; }   
    }
public boolean IsRingtone ()
    {
    AudioManager manager = (AudioManager) processBA.context.getSystemService (Context.AUDIO_SERVICE);
    if (manager.getMode () == AudioManager.MODE_RINGTONE) { return true; } else { return false; }
    }       
#End If
 
Last edited:
Upvote 0
Top