android-fragments Android广播未触发接收器

kh212irz  于 2022-11-14  发布在  Android
关注(0)|答案(1)|浏览(162)

我已经想了好几天了。

问题:sendBroadcast(intent)未触发BroadcastReceiver

我的代码成功地启动了前台服务...这应该是广播到一个活动中的接收者,但是Intent从未到达接收者。
我试着完全按照文档中给出的示例编写代码,甚至从前面的文章中复制代码,但没有任何效果。

  • 我的清单文件:*
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.julescarboni.speedcamerawarning">

    <!-- Request permissions  -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.SpeedCameraWarning"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:theme="@style/Theme.SpeedCameraWarning.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Mention the Location Service here -->
        <service android:name=".LocationService"
            android:foregroundServiceType="location"
            android:enabled="true" />
        <receiver android:name=".ProcessActivity$LocationReceiver"
            android:exported="true">
            <intent-filter>
                <!-- Sample filter to listen when device boot is completed -->
                <!-- This type of receiver cant be declared in codes -->
                <action android:name="com.julescarboni.speedcamerawarning.LocationService" />
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </receiver>

    </application>

</manifest>
  • 正在广播的**服务 *
public class LocationService extends Service {

    public static final String INTENT_ID = "com.julescarboni.speedcamerawarning.LocationService";
    private static final int ONGOING_NOTIFICATION_ID = 1;
    public static final String CHANNEL_ID = "ForegroundServiceChannel";
    //private final Context context = getApplicationContext();
    private Timer timer = new Timer(); // Timer for the service to use
    public static final int SERVICE_INTERVAL = 1000; // TODO: Set to 10 seconds

    /*@Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        startService();
    }*/

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

    // Execution of service will start on calling this method
    public int onStartCommand(Intent intent, int flags, int startId) {

        // Create foreground service notification
        // TODO: Add icon to notification

        String input = intent.getStringExtra("inputExtra");
        createNotificationChannel();
        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,
                0, notificationIntent, 0);
        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("Foreground Service")
                .setContentText(input)
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .setContentIntent(pendingIntent)
                .build();
        startForeground(1, notification);

        // Activate timer with location getting task
        timer.scheduleAtFixedRate(new ProcessTrigger(), 0, SERVICE_INTERVAL);

        // Return status of the service
        return START_NOT_STICKY;
    }

    @Override
    // Execution of the service will stop on calling this method
    public void onDestroy() {
        super.onDestroy();

        // Stop the timer and task
        timer.cancel();
        timer = null;

        // Stop the process
        stopForeground(true);
    }

    // This is what the service actually runs
    // It simply sends a signal that it is time to run the process code

    private class ProcessTrigger extends TimerTask {
        @Override
        public void run() {
            // This is the process we do every time the timer triggers
            Log.d("LocationService", "Timer triggered");
            Intent intent = new Intent();
            intent.setAction(INTENT_ID);
            //intent.putExtra("data", "null");
            sendBroadcast(intent);
        }
    }

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

    private void createNotificationChannel() {
        // Create notification channel for foreground service notifications
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library

        // Build API level must be 26 or greater (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O).
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel serviceChannel = new NotificationChannel(
                    CHANNEL_ID,
                    "Foreground Service Channel",
                    NotificationManager.IMPORTANCE_DEFAULT
            );
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(serviceChannel);
        }
    }
}
    • 活动**与接收方:*
public class ProcessActivity extends AppCompatActivity {

    LocationReceiver locationReceiver = null;
    Boolean myReceiverIsRegistered = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        locationReceiver = new LocationReceiver();
        // Register receiver
        registerReceiver(locationReceiver, new IntentFilter(LocationService.INTENT_ID));
        myReceiverIsRegistered = true;
    }
    @Override
    protected void onResume() {
        super.onResume();
        /*if (!myReceiverIsRegistered) {
            registerReceiver(locationReceiver, new IntentFilter(LocationService.INTENT_ID));
            myReceiverIsRegistered = true;
        }*/
    }
    @Override
    protected void onPause() {
        super.onPause();
        /*if (myReceiverIsRegistered) {
            unregisterReceiver(locationReceiver);
            myReceiverIsRegistered = false;
        }*/
    }

    private void doProcess() {

        // THIS CODE HERE HAS BEEN REMOVED TO KEEP THIS SECTION CONCISE.
        // SEE BELOW FOR THIS doProcess() FUNCTION.
        // Its main purpose is to get the last known location from a fused location manager.

    }

    public static class LocationReceiver extends BroadcastReceiver {
        // RECEIVES TIMER TRIGGERS FROM LOCATION SERVICE

        // Create new instance of the process activity
        // This instance contains all the code that we need to run each time the timer is triggered
        // I.e. it is the foreground process code
        ProcessActivity processActivity = new ProcessActivity();

        @Override
        public void onReceive(Context context, Intent intent ) {
            Log.d("LocationReceiver", "Trigger received, calling process now");
            processActivity.doProcess();
        }
    }

}
    • 活动**中的doProcess()函数到目前为止从未被调用过,因为接收器从未被触发过,因此我将其删除以使问题更简洁 (如果它很重要,我会将其添加到问题中)。*
8hhllhi2

8hhllhi21#

首先,如果您在清单中声明了receiver,则不需要创建示例并以编程方式注册它,因为。
安装应用程序时,系统软件包管理器会注册接收器。然后,接收器将成为您的应用程序的单独入口点,这意味着如果应用程序当前未运行,系统可以启动应用程序并传送广播。
系统创建一个新的BroadcastReceiver组件对象来处理它接收的每个广播。此对象仅在调用onReceive(Context,Intent)期间有效。一旦代码从此方法返回,系统将认为该组件不再活动。https://developer.android.com/guide/components/broadcasts#manifest-declared-receivers 2)在IntentFilter标记内使用此行的目的是什么:
3)应删除以下行:

ProcessActivity processActivity = new ProcessActivity();

你不能只创建一个活动对象,因为它是一个系统组件,它正在创建活动的示例。
请尝试在修复后检查日志。

相关问题