Android广播没有触发接收器
我一直在尝试几天来弄清楚这个错误...
问题:sendBroadcast(Intent)
没有触发broadcastreceiver
。
我的代码成功启动了一个前景服务 ...这应该在活动中广播给接收器,但是意图永远不会归于接收器。
我已经尝试按照文档中给出的示例完全编写代码,甚至从这里的较早帖子中复制了代码,但没有任何效果。
我的清单文件:
<?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()
来自活动到目前为止从未被调用,因为接收器从未触发过,所以我将其删除要使问题更简洁(如果很重要,我将其添加到问题中)。
I've been trying to figure out this bug for days...
Issue: sendBroadcast(intent)
isn't triggering BroadcastReceiver
.
My code successfully starts a foreground service... This is supposed to broadcast to a receiver in an activity, but the intent never makes it to the Receiver.
I've tried writing the code out exactly as the examples are given in the documentation, and even copied code from earlier posts here, but nothing has worked.
My manifest file:
<?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>
The service that's broadcasting:
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);
}
}
}
The activity with the receiver:
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();
}
}
}
The doProcess()
function from the activity has so far never been called because the reciever has never been triggered, so I removed it to make the question more concise (if it's important, I'll add it into the question).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,如果您在清单中声明接收器,则不需要创建一个实例并以编程方式进行注册,因为。
3)应该删除此行:
您不能仅仅创建活动对象,因为它是系统组件,并且正在创建活动实例。
修复后尝试检查日志。
First of all, if you declared receiver in manifest you don't need to create an instance and register it programmatically, because.
3)This line should be removed:
You can't just create an object of activity, because it's a system component and it's creating instance of the activity.
try to check logs after fixes.