views:

148

answers:

1

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);
        }
    }
}
+3  A: 

Is there a way for the Service to know the status of any particular activity? Particularly an activity that is bound to it?

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 call abortBroadcast() to prevent the notification. I have a blog post up about the technique.

CommonsWare
This is perfect for what I'm trying to do, as you referenced in your blog post.I've run into one issue before I think this will all work. I'm getting told that a permission denial is basically preventing my activity and my broadcast receiver from receiving the intent. I only use one permission (INTERNET) in my manifest (updated the question with it). Why am I getting this?
twilbrand
@twilbrand: I have no idea. How are you sending the broadcast?
CommonsWare
From my remote service. I have a task that gets run every 30 seconds. I've added the code to the question.
twilbrand
One things that could be an issue is that you mentioned in your blog post to "Define an action string you will use when the event occurs that you want to go to the activity or notification"I'm simply using a String I made up that is the same in my manifest file, the intent-filter I create in my activity, and in the intent my service fires the broadcast with. Should I have made it some other way?
twilbrand
Nevermind, I figured it out. The second parameter of my call to sendOrderedBroadcast() was trying to set a permission. I set that to null and everything is fine.
twilbrand
I should say that using CommonsWare's blog post along with this stackoverflow question is how I was able to implement this: http://stackoverflow.com/questions/3447594/android-alarm-manager-with-broadcast-receiver-registered-in-code-rather-than-mani
twilbrand