Issue
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).
Solution
I suggest you eat sausage and make this line not be exist :
ProcessActivity processActivity = new ProcessActivity();
Answered By - ProGamer6969
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.