即使应用被杀死,也可以从广播接收器运行并获取事件

问题描述

我想制作像TrueCaller这样的应用程序。为此,我需要获取来电事件。 为此,我制作了broadcast Receiver,它可以正常运行,直到应用程序被杀死为止。

因此,即使应用被杀死,我也希望运行我的广播接收器。

以前,我使用 Service 来实现此目的,但是在之后,Android O Service无法正常工作。 我以为可以使用WorkManager对其进行存档,但是我不知道该怎么做。 因此,我想使用 Service 替代或正确的方式对此进行存档。

请帮助我。

谢谢。

CallEventbroadcastReceiver.java

public class CallEventbroadcastReceiver extends broadcastReceiver {
@Override
public void onReceive(Context context,Intent intent) {
  TelephonyManager telephonyManager = (TelephonyManager) 
context.getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(new PhonestateListener() {
    @Override
    public void onCallStateChanged(int state,String phoneNumber) {
        super.onCallStateChanged(state,phoneNumber);
        try {
            if (state == TelephonyManager.CALL_STATE_RINGING) {
                Log.e("phoneNumber",phoneNumber);
            }
        } catch (Exception e) {
            e.printstacktrace();
        }
      }
    },PhonestateListener.LISTEN_CALL_STATE);
  }
}

解决方法

尝试类似这样的方法。不幸的是,我只能在Kotlin中为您的问题提供可能的解决方案。

private lateinit var workManager: WorkManager

override fun onReceive(context: Context,intent: Intent) {
        super.onReceive(context,intent)
        val state = intent.getStringExtra(TelephonyManager.EXTRA_STATE)
        state?.let { it ->
            if (it == TelephonyManager.EXTRA_STATE_RINGING) {
                val incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER)
                incomingNumber.let { number ->
                            val data = Data.Builder()
                                .putString("phoneNumber",number)
                                .build()
                            workManager = WorkManager.getInstance(context)
                            val notificationBuilder = OneTimeWorkRequest.Builder(NotifyWorker::class.java)
                                .setInputData(data)
                                .build()
                            workManager.enqueue(notificationBuilder)
                }
            }
       }
}

还有NotifyWorker类:

class NotifyWorker(context: Context,params: WorkerParameters) : Worker(context,params) {

    companion object {
        const val CHANNEL_ID = "NotificationChannel"
        const val CHANNEL_NAME = "Notification"
    }

    private val mContext = context

    override fun doWork(): Result {
        triggerNotification()
        return Result.success()
    }

    private fun triggerNotification() {
        val notificationManager =
            mContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,CHANNEL_NAME,NotificationManager.IMPORTANCE_HIGH)
            notificationManager.createNotificationChannel(channel)
        }

        val notificationIntent = Intent(mContext,MainActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(mContext,1,notificationIntent,PendingIntent.FLAG_UPDATE_CURRENT)
        val notification = NotificationCompat.Builder(mContext,CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_phone_call)
            .setContentTitle("incoming call")
            .setContentText(inputData.getString("phoneNumber"))
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setCategory(NotificationCompat.CATEGORY_CALL)
            .setFullScreenIntent(pendingIntent,true)
            .setAutoCancel(true)

        notification.setContentIntent(pendingIntent)
        notificationManager.notify(1,notification.build())
    }
}

receiver文件中添加AndroidManifest

<receiver
            android:name=".receiver.IncomingCallReceiver"
            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>