Add Phonestatelistener

Add PhoneStateListener

You have to create a receiver to catch phone calls.

To do this, add this in your in manifest.xml:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

<receiver android:name=".ServiceReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>

and create these classes:

import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.webkit.WebView;

public class MyPhoneStateListener extends PhoneStateListener {

public static Boolean phoneRinging = false;

public void onCallStateChanged(int state, String incomingNumber) {

switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
Log.d("DEBUG", "IDLE");
phoneRinging = false;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d("DEBUG", "OFFHOOK");
phoneRinging = false;
break;
case TelephonyManager.CALL_STATE_RINGING:
Log.d("DEBUG", "RINGING");
phoneRinging = true;

break;
}
}

}
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;

public class ServiceReceiver extends BroadcastReceiver {
TelephonyManager telephony;

public void onReceive(Context context, Intent intent) {
MyPhoneStateListener phoneListener = new MyPhoneStateListener();
telephony = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}

public void onDestroy() {
telephony.listen(null, PhoneStateListener.LISTEN_NONE);
}

}

Calling PhoneStateListener in a thread inside a service

This code works fine inside onCreate

Because it using Looper of Android Main Thread, when you put your code into Thread, Looper not available there, you need make your own Looper. Try this

final class phoneStateThread implements Runnable
{

@Override
public void run() {

Looper.prepare()
Log.v(TAG,"Starting telephony");
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
Log.v(TAG,"Starting listener");
phoneStateListener = new PhoneStateListener(){
@Override
public void onCallStateChanged(int state, String incomingNumber) {
Log.v(TAG,"Starting CallStateChange");
switch (state){

//=====Phone ringing. Pause music=====
case TelephonyManager.CALL_STATE_OFFHOOK:
case TelephonyManager.CALL_STATE_RINGING:
if(mediaPlayer!=null) {
pauseMedia();
isPausedInCall=true;
}

break;

//=====Phone idle. start music=====
case TelephonyManager.CALL_STATE_IDLE:
if(mediaPlayer!=null){
if(isPausedInCall){
isPausedInCall=false;
playMedia();
}
}
break;
}

}

};

telephonyManager.listen(phoneStateListener,PhoneStateListener.LISTEN_CALL_STATE);
Looper.loop()
}
}

Does android PhoneStateListener run on background?

Ok, so I've solved the issue.

The short answer is no, the PhoneStateListener doesn't run in background.
By default the listener runs only when the application is in foreground for what I've seen.

Maybe there's a way to run it in a service but I couldn't get it to work.
Instead I solved the problem with a BroadcastReceiver.

So, for the solution

The CallStateMonitor stayed the same as it was before, I just moved it from where it was.
For the service, as I said, I replaced it for a broadcast receiver:

class CallBroadcastReceiver : BroadcastReceiver() {

override fun onReceive(context: Context?, intent: Intent?) {
val telephonyManager = context?.getSystemService(TELEPHONY_SERVICE) as TelephonyManager
val monitor = StateMonitor()
telephonyManager.listen(monitor, LISTEN_CALL_STATE)
}

private val tag = "STATE_MONITOR"

private inner class StateMonitor : PhoneStateListener() {
override fun onCallStateChanged(state: Int, phoneNumber: String?) {
when (state) {
TelephonyManager.CALL_STATE_IDLE -> Log.d(tag, "IDLE")
TelephonyManager.CALL_STATE_OFFHOOK -> Log.d(tag, "OFF-HOOK")
TelephonyManager.CALL_STATE_RINGING -> Log.d(tag, "RINGING")
}
}
}
}

The rest is just starting the receiver from the main activity:

class CallMonitorActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
registerReceiver(CallBroadcastReceiver(), IntentFilter(ACTION_CONFIGURATION_CHANGED))
Log.d(ACTIVITY_TAG, "Registered call receiver.")
}
}

And that's it, hope it can help someone else ^-^

How to start PhoneStateListener programmatically?

you have to used this code and it is 100% work.

(1) you have to start services

startService(new Intent(this, CallServices.class));

(2) you have to make CallServices class and start your contentobser.

public class CallServices extends Service{
private static final String TAG = "CallService";
Context mContext;

@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind");
return null;
}

@Override
public void onCreate() {
Log.d(TAG, "onCreate");
mContext=getApplicationContext();
}

@Override
public void onStart(Intent intent, int startId) {
//super.onStart(intent, startId);
Log.d(TAG, "onStart services is started");
Uri mediaUri = Uri.parse("content://call_log/calls");
Handler handler = new Handler(){};
CustomContentObserver custObser = new CustomContentObserver(handler,mContext);
mContext.getContentResolver().registerContentObserver(mediaUri, true, custObser);
}

}

(3) make CustomContentObserver class to getting you to call log.

public class CustomContentObserver extends ContentObserver {
long lastTimeofCall = 0L;
long lastTimeofUpdate = 0L;
long threshold_time = 10000;

public CustomContentObserver(Handler handler,Context con) {
super(handler);
this.mContext=con;
System.out.println("Content obser");
callflag=true;
}
@Override
public boolean deliverSelfNotifications() {
return false;
}

public void onChange(boolean selfChange) {
super.onChange(selfChange);

lastTimeofCall = System.currentTimeMillis();
if(lastTimeofCall - lastTimeofUpdate > threshold_time){
if(callflag){

System.out.println("Content obser onChange()");
Log.d("PhoneService", "custom StringsContentObserver.onChange( " + selfChange + ")");
//if(!callFlag){
String[] projection = new String[]{CallLog.Calls.NUMBER,
CallLog.Calls.TYPE,
CallLog.Calls.DURATION,
CallLog.Calls.CACHED_NAME,
CallLog.Calls._ID};
Cursor c;
c=mContext.getContentResolver().query(CallLog.Calls.CONTENT_URI, projection, null, null, CallLog.Calls._ID + " DESC");
if(c.getCount()!=0){
c.moveToFirst();
lastCallnumber = c.getString(0);
lastCallnumber=FormatNumber(lastCallnumber);
String type=c.getString(1);
String duration=c.getString(2);
String name=c.getString(3);
String id=c.getString(4);
System.out.println("CALLLLing:"+lastCallnumber+"Type:"+type);

Database db=new Database(mContext);
Cursor cur =db.getFirstRecord(lastCallnumber);
System.out.println("CUSTOM GALLARY..."+cur.getCount());
final String endCall=lastCallnumber;
//checking incoming/outgoing call
if(type.equals("1")){
//incoming call code

}else if(type.equals("2")){
//outgoing call code
} else{
//missed call code
}
}

lastTimeofUpdate = System.currentTimeMillis();
}
}

}

}

in this way you have to read call log data.
i am using content Observer because of in htc device can not read phonestateListner that's way.



Related Topics



Leave a reply



Submit