简体   繁体   English

android oreo 获取服务中的来电号码

[英]android oreo get incoming call number in service

I am implementing code to get incoming call number in android Oreo.我正在实现代码以获取 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.我不确定这里的根本原因,但是,您实际上不需要PhoneStateListener来获取传入号码。 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.例如,在设备上总是有 2 个没有数字的意图,而第 3 个意图将与数字一起交付。 Also, it was always empty in PhoneStateListener.此外,它在 PhoneStateListener 中始终为空。 You can get the number from the intent, save it, and use your own saved number in the PhoneStateListener later if needed.您可以从 Intent 中获取号码,保存它,如果需要,稍后在 PhoneStateListener 中使用您自己保存的号码。

Please try if this works for you.请尝试这是否适合您。

BroadcastReceiver.java 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 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.从 android 9 开始,需要读取通话记录权限。 The permissions were missing.缺少权限。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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