Запускайте и получайте событие от широковещательного приемника, даже если приложение отключено

#android #service #broadcastreceiver #background-process #android-workmanager

#Android #Обслуживание #broadcastreceiver #фоновый процесс #android-workmanager

Вопрос:

Я хочу создать приложение, подобное TrueCaller. Для этого мне нужно получить событие входящего вызова. Для этого я создаю широковещательный приемник, и он отлично работает, пока приложение не будет отключено.

Итак, я хочу запустить свой широковещательный приемник, даже если приложение убито.

Ранее я использовал сервис для достижения этой цели, но после того, как служба Android O не работает. Я думал, что смогу заархивировать его с помощью WorkManager, но я не мог понять, как это сделать. Итак, я хочу, чтобы сервис был альтернативным или правильным способом архивирования этого.

Пожалуйста, помогите мне это сделать.

Заранее спасибо.

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);
  }
}
  

Комментарии:

1. Вы нашли решение своей проблемы?

2. Я также ищу решение той же проблемы .. мне нужно сохранить информацию о входящем вызове, когда приложение отключено

3. @dan51 и есть какая-нибудь удача в сентябре 2021 года?

4. @Prasath Прошло много времени с тех пор, как я работал над этим проектом. Я полагаю, что нашел решение, которое время от времени срабатывало, но на самом деле не помню. Мое решение можно найти здесь: github.com/CrazyDanyal1414/ReminderApp

Ответ №1:

Попробуйте что-то вроде этого. К сожалению, я могу предложить вам возможное решение вашей проблемы только в 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>
  

Комментарии:

1. С Kotlin проблем нет, но в первом классе широковещательного приемника у вас был менеджер выполнения работ, но будет ли широковещательный менеджер работать, если приложение отключено?

2. Я не совсем уверен в этом, я бы ответил «да» -> WorkManager будет выполнено, но я бы посоветовал вам попробовать это. Я отредактировал свой ответ — я добавил receiver регистрацию в AndroidManifest файл. Приветствия

3. Нет, это не работает, потому что, когда я отключаю широковещательный приемник приложения, он перестает работать, поэтому я не получаю событие в приемнике. Это сработает, если широковещательный приемник получит событие, даже если приложение отключено.