I have an Activity and Service that work together in my application. I've configured the service as a remote service (implemented AIDL) so it will keep running even when the Activity isn't visible.
The service is responsible for polling a server for data and sending alert notifications when certain criteria are met. I do not want the Service to send these notifications when the Activity is visible.
Is there a way for the Service to know the status of any particular activity? Particularly an activity that is bound to it?
updated with manifest to troubleshoot permission problem:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.interact.listen.android.voicemail"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MyAppName"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MyObjectDetails"/>
<service android:enabled="true" android:name=".MyService" />
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="com.foo.bar.EVENT"/>
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>
The error I'm getting in Logcat:
09-17 15:33:17.881: WARN/ActivityManager(53): Permission Denial: receiving Intent { act=com.foo.bar.myobject.EVENT (has extras) } to ProcessRecord{43928b40 223:com.foo.bar.myobject/10022} (pid=223, uid=10022) requires com.foo.bar.myobject.EVENT due to sender com.foo.bar.myobject (uid 10022)
09-17 15:33:48.901: WARN/ActivityManager(53): Permission Denial: receiving Intent { act=com.foo.bar.myobject.EVENT (has extras) } to com.foo.bar.myobject requires com.foo.bar.myobject.EVENT due to sender com.foo.bar.myobject (uid 10022)
Task that sends the broadcast:
@Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
serviceHandler = new Handler();
serviceHandler.postDelayed(myTask, 100L);
Log.d(TAG, "onStart()");
}
class Task implements Runnable
{
public void run()
{
Log.i(TAG, "Getting myObjects...");
getMyObjects();
Bundle bundle = new Bundle();
bundle.putLongArray("ids", getIdsToUpdate());
Intent i = new Intent();
i.setAction(UPDATE_ACTION_STRING);
i.putExtras(bundle);
sendOrderedBroadcast(i, UPDATE_ACTION_STRING);
serviceHandler.postDelayed(this, 30000L);
}
}
}
You can implement some sort of callback system.
But there's a cleaner way to solve the problem.
Use an ordered broadcast. Have the activity have a high-priority receiver; have the raise-a-notification logic be in a low-priority receiver. Have the activity's receiver callUse an event bus: greenrobot's EventBus,abortBroadcast()
to prevent the notification. I have a blog post up about the technique.LocalBroadcastManager
, an Rx-based event bus, or even aMutableLiveData
. Have the service post a message to the bus. Have the UI layer register for events on the bus when the UI is in the foreground. Have the service raise aNotification
if nobody picks up the event placed onto the bus.