Mục lục bài viết

Mẹo Hướng dẫn Call broadcast receiver android Chi Tiết

Cập Nhật: 2021-11-23 07:33:58,You Cần kiến thức và kỹ năng về Call broadcast receiver android. You trọn vẹn có thể lại Thảo luận ở cuối bài để Admin đc lý giải rõ ràng hơn.

781

Question

I’m trying to make an app listen to calls (incoming and outgoing), what I have done for now is just register the receiver in the manifest, which worked perfectly in Android below 9.0. However the problem occurred when I tested the app on Android oreo, I know that some of the broadcasts have been disabled. I tried to make a foreground service which register a receiver and listen to this broadcasts, yet again it worked on versions below oreo.

Tóm lược đại ý quan trọng trong bài

I don’t know what else to do, I have to get it work, I don’t care if it will be in an inelegant way, I don’t post this app I just need it for private use.

Summary: I need to listen to calls in Android pie even when the app is not currently active

manifest

MyReceiver

public class MyReceiver extends BroadcastReceiver {
private static Date callStartTime;
private static boolean isIncoming;
private static int lastState;
private static String savedNumber;
private static String savedOutgoingNumber;
private TelephonyManager tm;
@Override
public void onReceive(Context context, Intent intent)
//We listen to two intents. The new outgoing call only tells us of an outgoing call. We use it to get the number.
if (intent.getAction().equals(“android.intent.action.NEW_OUTGOING_CALL”))
savedNumber = intent.getExtras().getString(“android.intent.extra.PHONE_NUMBER”);

else
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
int state = 0;
if(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE))
state = TelephonyManager.CALL_STATE_IDLE;

else if(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
state = TelephonyManager.CALL_STATE_OFFHOOK;

else if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING))
state = TelephonyManager.CALL_STATE_RINGING;

onCallStateChanged(context, state, number);

The problem is that it isnt even getting called on android oreo Edit : I got it to work on android oreo but it have problems in android pie

Another edit :

@Override
public void onCreate()
super.onCreate();
createNotificationChannel();
IntentFilter filter = new IntentFilter();
filter.addAction(“android.intent.action.PHONE_STATE”);
filter.addAction(“android.intent.action.NEW_OUTGOING_CALL”);
BroadcastReceiver receiver = new BroadcastReceiver()
@Override
public void onReceive(Context context, Intent intent)
CallListenerService.this.onReceive(intent);

;
registerReceiver(receiver, filter);

public void onReceive(Intent i)
if (i.getAction().equals(“android.intent.action.NEW_OUTGOING_CALL”))
savedNumber = i.getExtras().getString(“android.intent.extra.PHONE_NUMBER”);

else
String stateStr = i.getExtras().getString(TelephonyManager.EXTRA_STATE);
String number = i.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
int state = 0;
if(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE))
state = TelephonyManager.CALL_STATE_IDLE;

else if(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
state = TelephonyManager.CALL_STATE_OFFHOOK;

else if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING))
state = TelephonyManager.CALL_STATE_RINGING;

onCallStateChanged(this, state, number);

The rest doesnt matter it just start an activity on call end to test if it wokrs

I have added an fourground service which register recievers , This works on android oreo but still have issues on android pie.

Edit : the solution was to mix a bunch of the answers until it worked on every device. I wrote the decleration manifest like this :

don’t really know if that what did it. Further more I used the normal broad cast receiver and not a service, again I don’t know what happend but suddenly it worked on some devices.

now there is the final touch, I found out that I can get the phone number by reading the call log, so what I did was to add this code :

protected void onMissedCall(final Context ctx, String number, Date start)
if (PreferenceManager.getDefaultSharedPreferences(ctx).getBoolean(“missed_calls”, false))
if (number == null)
new Handler().postDelayed(new Runnable()
@Override
public void run()
final String phoneNumber = getLastCallNumber(ctx);
if (phoneNumber != null)
Intent intent = new Intent(ctx, Dialog.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(“number”, phoneNumber);
intent.putExtra(“missed_call”, true);
ctx.startActivity(intent);
else
Toast.makeText(ctx, “cannot get phone number”, Toast.LENGTH_SHORT).show();

, 2000);
else
Intent intent = new Intent(ctx, Dialog.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(“number”, number);
intent.putExtra(“missed_call”, true);
ctx.startActivity(intent);

private String getLastCallNumber(Context context)
Uri contacts = CallLog.Calls.CONTENT_URI;
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED)
Toast.makeText(context, “Permission denied can not get phone number”, Toast.LENGTH_SHORT).show();

Cursor managedCursor = context.getContentResolver().query(
contacts, null, null, null, null);
int number = managedCursor.getColumnIndex( CallLog.Calls.NUMBER );
String phoneNumber = null;
if( managedCursor.moveToLast() == true )
phoneNumber = managedCursor.getString( number );

managedCursor.close();
return phoneNumber;

I added the if line which checks if the number is null, and if so it launch an handler to run 2 seconds from than, when the handler starts I read the last number from the call log. The 2 seconds delay is for the number to get into the call log, if you try to read it right away it doesn’t work.

Answer 1:

i also created a CallReceiver :-

public class CallReceiver extends BroadcastReceiver
private static int lastState = TelephonyManager.CALL_STATE_IDLE;
private static Date callStartTime;
private static boolean isIncoming;
private static String savedNumber;
public static MyCallsAppDatabase myCallsAppDatabase;
@Override
public void onReceive(Context context, Intent intent)
if (intent.getAction().equals(“android.intent.action.NEW_OUTGOING_CALL”))
savedNumber = intent.getExtras().getString(“android.intent.extra.PHONE_NUMBER”);
else
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
int state = 0;
if (stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE))
state = TelephonyManager.CALL_STATE_IDLE;
else if (stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
state = TelephonyManager.CALL_STATE_OFFHOOK;
else if (stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING))
state = TelephonyManager.CALL_STATE_RINGING;

onCallStateChanged(context, state, number, intent);

public void onCallStateChanged(Context context, int state, String number, Intent intent)
if (lastState == state)
//No change, debounce extras
return;

switch (state)
case TelephonyManager.CALL_STATE_RINGING:
isIncoming = true;
callStartTime = new Date();
onIncomingCallStarted(context, number, callStartTime, intent);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
//Transition of ringing->offhook are pickups of incoming calls. Nothing done on them
if (lastState != TelephonyManager.CALL_STATE_RINGING)
isIncoming = false;
callStartTime = new Date();
onOutgoingCallStarted(context, number, callStartTime, intent);

break;
case TelephonyManager.CALL_STATE_IDLE:
//Went to idle- this is the end of a call. What type depends on previous state(s)
if (lastState == TelephonyManager.CALL_STATE_RINGING)
//Ring but no pickup- a miss
onMissedCall(context, number, callStartTime, intent);
else if (isIncoming)
onIncomingCallEnded(context, number, callStartTime, new Date(), intent);
else
onOutgoingCallEnded(context, number, callStartTime, new Date(), intent);

break;

lastState = state;
Intent intent1 = new Intent(“CallApp”);
context.sendBroadcast(intent1);

protected void onIncomingCallStarted(Context ctx, String number, Date start, Intent intent)
// Toast.makeText(ctx, “calling from ” + number, Toast.LENGTH_SHORT).show();

protected void onOutgoingCallStarted(Context ctx, String number, Date start, Intent intent)
// Toast.makeText(ctx, “calling to ” + number, Toast.LENGTH_SHORT).show();

protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end, Intent intent)
// Toast.makeText(ctx, “calling from ” + number + ” ended “, Toast.LENGTH_SHORT).show();
saveData(ctx, number, intent, “Incoming Call”);

protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end, Intent intent)
// Toast.makeText(ctx, “calling to ” + number + ” ended “, Toast.LENGTH_SHORT).show();
saveData(ctx, number, intent, “Outgoing Call”);

protected void onMissedCall(Context ctx, String number, Date start, Intent intent)
// Toast.makeText(ctx, “missed call from ” + number + ” sim “, Toast.LENGTH_SHORT).show();
saveData(ctx, number, intent, “Missed Call”);

@SuppressLint(“ServiceCast”)
protected void saveData(Context ctx, String number, Intent intent, String callType)
myCallsAppDatabase = Room.databaseBuilder(ctx, MyCallsAppDatabase.class, “calldb”)
.allowMainThreadQueries()
.build();
number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
number = filterNumber(number);
SimpleDateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd hh:mm:ss aaa”);
String dateString = dateFormat.format(new Date(System.currentTimeMillis()));
CallLog callLog = new CallLog();
callLog.setMobile(number);
callLog.setCallType(callType);
callLog.setTime(dateString);
myCallsAppDatabase.myCallDao().addCallDetails(callLog);

in Manifest.xml file :-

Answer 2:

Change code in Manifest file as below and setPriority to high. I thinks this menifest code needs when the app is in background.

This programatic code needs to wake ups the Reciever when app is foreground ie. when the the User is dealing with the actions of BroadcasteReciever from Activity. (The Reciever needs to registerReceiver() in onResume() && unregisterReceiver() in onDestroy() )

IntentFilter filter = new IntentFilter();
filter.addAction(“android.intent.action.PHONE_STATE”);
filter.addAction(“android.intent.action.NEW_OUTGOING_CALL”);
filter.setPriority(1000);
BroadcastReceiver receiver = new BroadcastReceiver()
@Override
public void onReceive(Context context, Intent intent)
CallListenerService.this.onReceive(intent);

;
registerReceiver(receiver, filter);

Answer 3:

Which android device are you using? I had also encountered such an error which broadcasts are received only when the app is running. Then I discovered that my device is in power saving mode which restricts broadcast and we can customize these settings for specific app in settings> Battery Management. My device is Honor 9 lite with android version Pie. If the problem still persists, try to make a toast as first line of onReceive() method in broadcast receiver. if you receive the toast, your app is receiving broadcasts but problem will be with in your code.

Try to run the same code in different devices. May be the problem would be with your device settings.

来源:stackoverflow/questions/55794020/listen-to-calls-broadcast-receiver-in-android-pie

I am building an application in android, which will perform an action when any phone call will come in my phone. I have tried this with broadcast receiver and phone state listener. But it is not working. If i use activity then phone state listener works well and good but it is not working with Broadcast receiver. What i am doing wrong? Please any body toàn thân help….

Thanks & Regards

Video full hướng dẫn Share Link Download Call broadcast receiver android ?

– Một số Keyword tìm kiếm nhiều : ” Video full hướng dẫn Call broadcast receiver android tiên tiến và phát triển nhất , Share Link Download Call broadcast receiver android “.

Hỏi đáp vướng mắc về Call broadcast receiver android

You trọn vẹn có thể để lại phản hồi nếu gặp yếu tố chưa hiểu nhé.
#Call #broadcast #receiver #android