简体   繁体   中英

android oreo get incoming call number in service

I am implementing code to get incoming call number in android Oreo. For that I am using broadcast receiver in service. Here is the code that I have done so far.

public class CallService extends Service {
private static final int ID_SERVICE = 101;
BroadcastReceiver brSms;

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
        telephony.listen(new PhoneStateListener(){
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                super.onCallStateChanged(state, incomingNumber);
                System.out.println("incomingNumber : "+incomingNumber);
                Toast.makeText(context,""+incomingNumber,Toast.LENGTH_LONG).show();
            }
        },PhoneStateListener.LISTEN_CALL_STATE);
    }
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);
    return START_STICKY;
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    super.onCreate();



    IntentFilter filter = new IntentFilter();
    filter.addAction("android.intent.action.PHONE_STATE");
    brSms = new MyReceiver();
    registerReceiver(brSms, filter);




    // Create the Foreground Service
    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    String channelId = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? createNotificationChannel(notificationManager) : "";
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId);
    Notification notification = notificationBuilder.setOngoing(true)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setPriority(PRIORITY_MIN)
            .setCategory(NotificationCompat.CATEGORY_SERVICE)
            .build();

    startForeground(ID_SERVICE, notification);
}

@RequiresApi(Build.VERSION_CODES.O)
private String createNotificationChannel(NotificationManager notificationManager){
    String channelId = "my_service_channelid";
    String channelName = "My Foreground Service";
    NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
    channel.setImportance(NotificationManager.IMPORTANCE_NONE);
    channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
    notificationManager.createNotificationChannel(channel);
    return channelId;
}
@Override
public void onDestroy() {
    unregisterReceiver(brSms);

 }
}

The code is not working. I tried various options given in stack overflow. I have added permission for foreground service in my manifest file. How can I get incoming call number even if the app is closed or killed by user?

I'm not sure about the root cause here, but, you actually don't need the PhoneStateListener to get the incoming number. Although it is supposed to return the number but on some devices it returns empty string several times or maybe always. What you can do is to get number from the intent:

if(intent.getExtras() != null){
    String number = 
    intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER, "-1")
}
if(!number.equals(-1) || !number.equals("")){
    //Toast it or do stuff here
}

This intent might be delivered with no number or empty string, so check for those before do whatever you wish. Eventually an intent with the incoming number will be delivered. You should just ignore other intents. It is quite dependent on the device. For example on a device it was always 2 intents with no numbers and the 3rd would be delivered with the number. Also, it was always empty in PhoneStateListener. You can get the number from the intent, save it, and use your own saved number in the PhoneStateListener later if needed.

Please try if this works for you.

BroadcastReceiver.java

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
        if (state != null) {
           if (state == TelephonyManager.EXTRA_STATE_RINGING) {
              String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
              if (incomingNumber != null) {
               Log.d("incomingNumber", incomingNumber);
               // do what you want with the incomingNumber
              }
           }
        }
    }
}

AndroidManifest.xml

<receiver
    android:name=".MyReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
         <action android:name="android.intent.action.PHONE_STATE" />
    </intent-filter>
         <intent-filter>
             <action android:name="android.intent.action.READ_CALL_LOG" />
         </intent-filter>
</receiver>

From android 9, read call log permission is required. The permissions were missing.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM