WakefulBroadcastReceiver startWakefulService fails to proceed

2.7k views Asked by At

My app will not invoke the intentservice request from the wakefulbroadcastreceiver

Manifest:

        <service
        android:name=".MyWearableListenerService">
        <intent-filter>
            <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
            <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED"/>
            <data android:scheme="wear" android:host="*"/>
        </intent-filter>
    </service>

    <service
        android:name=".CounterActivity$WearableReceiverService"
        android:exported="false">
    </service>

    <receiver
        android:name=".CounterActivity$WearableReceiver"
        android:enabled="true">
    </receiver>

So i register all receivers and services.

inside my main activity i have these as sub-classes within the main class so i can call the method in the main class msgReqAction()

public class WearableReceiver extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent service = new Intent(context, WearableReceiverService.class);
        startWakefulService(context, service);
    }
}

public class WearableReceiverService extends IntentService {

    public WearableReceiverService(){
        super("WearableReceiverService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        msgReqAction(intent.getIntExtra(MyConstants.BROADCAST_DATA_REQ, 0));
        WearableReceiver.completeWakefulIntent(intent);
    }
}

I don't think having these as subclasses should hinder the situation but it may. if i must have these outside the main class for operation let me know.

finally i begin the whole process from a listener outside the main activity that listens for a message from the wearable

@Override
public void onMessageReceived(final MessageEvent messageEvent) {
    nodeId = messageEvent.getSourceNodeId();
    String incomingPath = messageEvent.getPath();
    int incomingReq = Integer.parseInt(new String(messageEvent.getData()));

    if(incomingPath.equalsIgnoreCase(MyConstants.MSG_COUNTER_REQ_PATH)) {
        Intent broadcastIntent = new Intent();
        broadcastIntent.setAction(MyConstants.BROADCAST_ACTION_RESP);
        broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
        broadcastIntent.putExtra(MyConstants.BROADCAST_DATA_REQ, incomingReq);
        sendBroadcast(broadcastIntent);

    }else if(incomingPath.equalsIgnoreCase(MyConstants.MSG_DEFAULT_PATH)){

    }
}

public static final String BROADCAST_ACTION_RESP = "com.example.johnbravado.zionwork.MESSAGE_PROCESSED";

my project is com.example.johnbravado.zionwork - also on a side note is there a way to change and refactor that in android studio easily so i can get rid of example or change it completely?

when i run the debugger the system gets all the way to

startWakefulService(context, service);

then it crashes without entering the intent service. is there somethig simple i am missing amongst all this which is preventing it from going into the service and doing work. best i can tell is it does not go into the service at all. i added some intro lines of the service

@Override
protected void onHandleIntent(Intent intent) {
    int data;
    data = 0;
    data++;
    msgReqAction(intent.getIntExtra(MyConstants.BROADCAST_DATA_REQ, 0));
    WearableReceiver.completeWakefulIntent(intent);
}

and tried to run debug points on these lines and it didnt get there.

2

There are 2 answers

0
John Bravado On

The solution was to eliminate the WakefulfulBroadcastReceiver and secondary IntentService. Instead, I used a BroadcastReceiever and sent a broadcast directly from the Wearable listener function and used that to process data directly within the activity.

public class WearableReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        //Intent service = new Intent(context, WearableReceiverService.class);
        //startWakefulService(context, service);
        PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                "com.example.johnbravado.zionwork");
        wakeLock.acquire();
        // Do Work
        msgReqAction(intent.getIntExtra(MyConstants.BROADCAST_DATA_REQ, 0));

        wakeLock.release();
    }
}

Even though i do not do much that would necessarily require a wakelock. if i decide later to do more work i have it ready to go. i am not sure if this is best place for the wakelock either never really used them but that is another topic.

I removed reference to the extra service and receiver in the manifest file also. works good now

12
David Wasser On

You cannot have a Service defined as a non-static inner class.

A non-static inner class contains a reference to its outer class. This means that in order to create a new instance of the inner class, you need to have an instance of the outer class.

When Android tries to start your Service, it tries to create a new instance of the inner class. This fails, because Android does not have an instance of the outer class to use in the creation.

The same rule applies to the BroadcastReceiver.

Solution: Move all your inner classes to full-fledged classes (in their own source files).