Невозможно отобразить плавающее окно в приложении Android во время изменения состояния вызова.JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Невозможно отобразить плавающее окно в приложении Android во время изменения состояния вызова.

Сообщение Anonymous »


Я работаю над приложением для Android, в котором мне нужно показывать плавающее окно во время изменения состояния вызова и отправлять события в приложение React Native. Без плавающего окна события отправляются успешно, но при попытке показать плавающее окно возникает следующая ошибка:

ФАТАЛЬНОЕ ИСКЛЮЧЕНИЕ: основное Процесс: com.arunkavale.test, PID: 19533. java.lang.RuntimeException: невозможно запустить приемник com.arunkavale.test.CallReceiver: java.lang.NullPointerException: попытка вызвать виртуальный метод 'java.lang.Object com.facebook.react.bridge.ReactApplicationContext.getSystemService(java.lang) .String)' по нулевой ссылке на объект в android.app.ActivityThread.handleReceiver(ActivityThread.java:4905) в android.app.ActivityThread.-$$Nest$mhandleReceiver (неизвестный источник: 0) в android.app.ActivityThread$H.handleMessage(ActivityThread.java:2498) в android.os.Handler.dispatchMessage(Handler.java:106) в android.os.Looper.loopOnce(Looper.java:230) в android.os.Looper.loop(Looper.java:319) в android.app.ActivityThread.main(ActivityThread.java:8893) в java.lang.reflect.Method.invoke (собственный метод) на com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608) на com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103) Вызвано: java.lang.NullPointerException: попытка вызвать виртуальный метод «java.lang.Object com.facebook.react.bridge.ReactApplicationContext.getSystemService(java.lang.String)» по ссылке на нулевой объект. на com.arunkavale.test.CallModule.showFloatingWindow(CallModule.java:51) на com.arunkavale.test.CallModule.sendEvent(CallModule.java:40) на com.arunkavale.test.CallReceiver.sendEventToReactNative(CallReceiver.java:60) на com.arunkavale.test.CallReceiver.onReceive(CallReceiver.java:48) в android.app.ActivityThread.handleReceiver(ActivityThread.java:4896) Вот файл AndroidManifest

Вот CallReceiver

пакет com.arunkavale.test; // CallReceiver.java импортировать android.app.ActivityManager; импортировать android.content.BroadcastReceiver; импортировать android.content.Context; импортировать android.content.Intent; импортировать android.telephony.TelephonyManager; импортировать android.util.Log; импортировать android.widget.Toast; импортировать android.content.BroadcastReceiver; импортировать android.content.Context; импортировать android.content.Intent; импортировать android.telephony.TelephonyManager; импортировать android.util.Log; публичный класс CallReceiver расширяет BroadcastReceiver { @Override public void onReceive (контекст контекста, намерение намерения) { Строковое действие = намерение.getAction(); if (действие!= null && action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) { Состояние строки = намерение.getStringExtra(TelephonyManager.EXTRA_STATE); если (состояние != ноль) { если (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { // Обработка входящего звонка Строка phoneNumber = Intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER); если (phoneNumber!= ноль) { sendEventToReactNative (контекст, «INCOMING_CALL», номер телефона); } } Еще если (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) { // Обработка исходящего вызова или текущего вызова Строка phoneNumber = Intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER); если (phoneNumber!= ноль) { sendEventToReactNative (контекст, «OUTGOING_CALL», номер телефона); } } Еще если (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) { // Обработка завершения вызова Строка phoneNumber = Intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER); если (phoneNumber!= ноль) { sendEventToReactNative (контекст, «CALL_ENDED», номер телефона); } } } } } Private void sendEventToReactNative (Контекст контекста, событие String, String phoneNumber) { Log.d("CallReceiver", "sendEvent " + событие + ", номер телефона: " + номер телефона); // Используйте свой собственный собственный модуль для отправки событий в React Native CallModule.sendEvent(событие, номер телефона); // Запускаем фоновую службу, только если она еще не запущена if (!isServiceRunning(context, CallBackgroundService.class)) { Намерение serviceIntent = новое намерение (контекст, CallBackgroundService.class); context.startService(serviceIntent); } } частное логическое значение isServiceRunning (контекст контекста, класс класс обслуживания) { Менеджер ActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); для (службаActivityManager.RunningServiceInfo:manager.getRunningServices(Integer.MAX_VALUE)) { if (serviceClass.getName().equals(service.service.getClassName())) { вернуть истину; } } вернуть ложь; } } Вот модуль вызова

пакет com.arunkavale.test; импортировать android.content.Context; импортировать android.graphics.PixelFormat; импортировать android.os.Build; импортировать android.util.Log; импортировать android.view.Gravity; импортировать android.view.LayoutInflater; импортировать android.view.View; импортировать android.view.WindowManager; импортировать android.widget.TextView; импортировать com.facebook.react.bridge.ReactApplicationContext; импортировать com.facebook.react.bridge.ReactContextBaseJavaModule; импортировать com.facebook.react.bridge.ReactMethod; импортировать com.facebook.react.modules.core.DeviceEventManagerModule; публичный класс CallModule расширяет ReactContextBaseJavaModule { частный статический ReactApplicationContext responseContext; частный статический просмотр overlayView; public CallModule (контекст ReactApplicationContext) { супер (контекст); реакцияКонтекст = контекст; } @Override публичная строка getName() { вернуть «ВызовМодуля»; } @ReactMethod public void makeCall (String phoneNumber) { //Реализуем код для совершения исходящих вызовов } static void sendEvent(String eventName, String phoneNumber) { Log.d("CallModule", "sendEvent " + eventName + "НомерТелефона" +НомерТелефона); showFloatingWindow (номер телефона); РеагироватьКонтекст .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit(имясобытия, номер телефона); } static void showFloatingWindow(String phoneNumber) { // Получаем службу WindowManager WindowManager windowManager = (WindowManager) actContext.getSystemService(Context.WINDOW_SERVICE); // Раздуваем макет плавающего окна LayoutInflater инфлятор = (LayoutInflater) actContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); overlayView = inflater.inflate(R.layout.floating_window_layout, null); // Добавьте свою собственную логику для обновления содержимого плавающего окна TextView textView = overlayView.findViewById(R.id.textView); textView.setText("Вызов" + номер телефона); // Устанавливаем параметры окна Параметры WindowManager.LayoutParams; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { параметры = новый WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, ПиксельФормат.ТРАНСЛЮЦЕНТ); } еще { параметры = новый WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, ПиксельФормат.ТРАНСЛЮЦЕНТ); } параметры.гравитация = Гравитация.TOP | Гравитация.СТАРТ; параметры.х = 0; параметры.у = 100; // Добавляем представление в оконный менеджер windowManager.addView(overlayView, параметры); } } Вот вызовBackgroundService

пакет com.arunkavale.test; импортировать android.app.Service; импортировать android.content.Intent; импортировать android.os.IBinder; импортировать android.util.Log; // CallBackgroundService.java импортировать android.app.Service; импортировать android.content.BroadcastReceiver; импортировать android.content.Context; импортировать android.content.Intent; импортировать android.content.IntentFilter; импортировать android.os.IBinder; импортировать android.telephony.PhoneStateListener; импортировать android.telephony.TelephonyManager; импортировать android.util.Log; публичный класс CallBackgroundService расширяет сервис { частный TelephonyManager telephonyManager; частный CustomPhoneStateListener phoneStateListener; частный CallReceiver callReceiver; @Override общественная недействительность onCreate() { супер.onCreate(); // Здесь инициализируем все необходимое для службы // Регистрируем широковещательный приемник для пользовательских событий зарегистрироватьПолучатель(); // Начинаем прослушивать изменения состояния телефона startListeningForPhoneState(); } @Override public int onStartCommand (Намерение, int flags, int startId) { // Здесь запустите вашу фоновую логику sendEventToReactNative("BACKGROUND_EVENT", "Событие из фоновой службы"); вернуть START_STICKY; } @Override public IBinder onBind (Намерение) { вернуть ноль; } @Override общественная недействительность onDestroy () { супер.onDestroy(); // Очистка или освобождение ресурсов при необходимости // Отменяем регистрацию приемника вещания и прекращаем прослушивание изменений состояния телефона отменить регистрациюReceiver(); stopListeningForPhoneState(); } частный недействительный startListeningForPhoneState () { telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); PhoneStateListener = новый CustomPhoneStateListener (); telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); } частный недействительный stopListeningForPhoneState () { if (telephonyManager != null && phoneStateListener != null) { telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE); } } частный недействительный RegisterReceiver() { callReceiver = новый CallReceiver(); IntentFilter IntentFilter = новый IntentFilter("ваше-настраиваемое-событие"); RegisterReceiver (callReceiver, IntentFilter); } частная пустота unregisterReceiver() { если (callReceiver!= ноль) { unregisterReceiver(callReceiver); } } Private void sendEventToReactNative (событие String, данные String) { // Используйте свой собственный собственный модуль для отправки событий в React Native CallModule.sendEvent(событие, данные); } // Пользовательский PhoneStateListener для обработки изменений состояния вызова частный класс CustomPhoneStateListener расширяет PhoneStateListener { @Override public void onCallStateChanged (int state, String phoneNumber) { переключатель (состояние) { случай TelephonyManager.CALL_STATE_RINGING: // Обработка входящего звонка sendEventToReactNative("INCOMING_CALL", phoneNumber); перерыв; случай TelephonyManager.CALL_STATE_OFFHOOK: // Обработка исходящего вызова или текущего вызова sendEventToReactNative("OUTGOING_CALL", номер телефона); перерыв; случай TelephonyManager.CALL_STATE_IDLE: // Обработка завершения вызова sendEventToReactNative("CALL_ENDED", номер телефона); перерыв; } } } } Я подозреваю, что проблема связана с тем, что ReactApplicationContext имеет значение null во время изменения состояния вызова. Как я могу гарантировать действительный ReactApplicationContext при попытке показать плавающее окно?

Кроме того, существует ли лучший подход для обработки изменений состояния вызова и отображения плавающего окна в приложении Android, интегрированном с React Native?

Любая помощь или рекомендации приветствуются. Спасибо!
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»