0

After failing at creating a battery widget, I tried again using a different technique.

After browsing and researching, I decided to use a service and a broadcast receiever inside my AppWidgetProvider class.

My battery value is always null and never changes.

I registered the service in the manifest and see that the service is started.

I added logs and noticed the Start command is called before the onRecieve of the broadcast.

The value changes in the onReceieve but is never changed in the the onStartCommand where I update my view.

What am I doing wrong?

Also, where do I unregister the receiever?

My class is below

public class BatteryWidgetProvider extends AppWidgetProvider
{
    private RemoteViews views;
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) 
    {
        context.startService(new Intent(context, BatteryMonitorReceiver.class));
        /*context.getApplicationContext().registerReceiver(this, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
        ComponentName name = new ComponentName(context, BatteryWidgetProvider.class);
        appWidgetManager.updateAppWidget(name, this.views);

        super.onUpdate(context, appWidgetManager, appWidgetIds);*/

    }

    public static class BatteryMonitorReceiver extends Service
    {
        private RemoteViews views;
        private Integer level;
        private BroadcastReceiver batteryReceiver = new BroadcastReceiver(){
            @Override
            public void onReceive( Context context, Intent intent )
            {
                String action = intent.getAction();
                if(action.equals(Intent.ACTION_BATTERY_CHANGED))
                {
                    level = intent.getIntExtra( "level", 0 );
                    Log.d("BATTERY ON Receieve", "Battery Level is "+level);
views = new RemoteViews(getPackageName(), R.layout.battery100layout);

                }
ComponentName thisWidget = new ComponentName(context,BatteryWidgetProvider.class);
                    AppWidgetManager manager = AppWidgetManager.getInstance(context);
                    manager.updateAppWidget(thisWidget, views);

            }
        };

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) 
        {
            registerReceiver( this.batteryReceiver, new IntentFilter( Intent.ACTION_BATTERY_CHANGED ) );

            Log.d("BATTERY Service", "Battery Level is "+level);


            super.onStart(intent, startId);
            return super.onStartCommand(intent, flags, startId);
        }

        @Override
        public void onStart(Intent intent, int startId) 
        {


        }

        @Override
        public IBinder onBind(Intent intent) 
        {
            // TODO Auto-generated method stub
            return null;
        }

    }
}

Here is my stacktrace

java.lang.RuntimeException: Unable to start service com.mischel.batterywidget.BatteryWidgetProvider$BatteryMonitorReceiver@40522428 with null: java.lang.NullPointerException
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2473)
at android.app.ActivityThread.access$2800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1127)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:4385)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.test.batterywidget.BatteryWidgetProvider$BatteryMonitorReceiver.onStartCommand(BatteryWidgetProvider.java:102)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2456)
... 10 more
jimmym715
  • 1,512
  • 1
  • 16
  • 25
Mich
  • 105
  • 1
  • 2
  • 9

1 Answers1

0

What am I doing wrong?

You are attempting to update your app widget from onStartCommand(), instead of from onReceive().

Also where do I unregister the receiever?

onDestroy() of the Service would seem like a likely spot to do that.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • What would the onStartCommand() be used for if I moved all my code in the onReceieve()? – Mich Apr 21 '12 at 20:40
  • I am so confused.... onReceived doesnt allow me to do updates. this line doesnt work inside on Receieved ComponentName thisWidget = new ComponentName( this, BatteryWidgetProvider.class); – Mich Apr 21 '12 at 20:45
  • @user1155204: "What would the onStartCommand() be used for if I moved all my code in the onReceieve()?" -- nothing, but I never said for you to move all your code into `onReceive()`. "this line doesnt work" -- that is because `BroadcastReceiver` is not a `Context`. You need to use the `Context` supplied to `onReceive()` as the first parameter to your `ComponentName` constructor. – CommonsWare Apr 21 '12 at 20:51
  • Thanks, I still get a few crashes very rearly. You helped a lot. – Mich May 07 '12 at 17:52