0

I'm working on android widget that displays the level of battery left.

It seem to work on the emulator except that the emulator's battery level doesn't move, so I can't test further. On real device (ICS), it only displays the initial textview("TEST") and doesn't do anything else.

Manifest

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.battery"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="17" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <receiver android:name="main.MyBatteryWidget"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data android:name="android.appwidget.provider"
            android:resource="@xml/widget_info" />
    </receiver>
    <service android:name="main.MyBatteryWidget$BatteryUpdateService"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.example.battery.action.UPDATE" />
        </intent-filter>
    </service>
</application>

widget_info.xml

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:updatePeriodMillis="0"
    android:minWidth="40dip"
    android:minHeight="72dip"
    android:initialLayout="@layout/widget_layout" >

</appwidget-provider>

widget_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView android:id="@+id/textView"
        android:text="TEST"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />


</LinearLayout>

MyBatteryWidget.java

package main;

import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.IBinder;
import android.util.Log;
import android.widget.RemoteViews;

import com.example.battery.R;

public class MyBatteryWidget extends AppWidgetProvider {

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {
        Log.d("TEST", "onUpdate");
        context.getApplicationContext().startService(new Intent("com.example.battery.action.UPDATE"));
    }

    public static class BatteryUpdateService extends Service {
        private static int level = 0;
        private static int scale = 0;

        private BroadcastReceiver receiver = new BroadcastReceiver(){
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();

                if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                    level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
                    scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
                    Log.d("TEST", "receive");
                    updateViews(context);
                }
            }
        };

        private void updateViews(Context context) {
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
            views.setTextViewText(R.id.textView, String.valueOf(level / scale));
            ComponentName componentName = new ComponentName(context, MyBatteryWidget.class);
            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
            appWidgetManager.updateAppWidget(componentName, views);
        }

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // TODO Auto-generated method stub
            Log.d("TEST", "start");
            registerReceiver(receiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
            return super.onStartCommand(intent, flags, startId);
        }

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

    }

}

Logcat

03-27 19:51:34.963: D/dalvikvm(608): Not late-enabling CheckJNI (already on)
03-27 19:51:35.043: E/Trace(608): error opening trace file: No such file or directory (2)
03-27 19:51:35.083: D/TEST(608): onUpdate
03-27 19:51:35.103: D/TEST(608): start
03-27 19:51:35.133: D/TEST(608): receive
MrJre
  • 7,082
  • 7
  • 53
  • 66
awonderer
  • 665
  • 9
  • 26
  • You can change the battery level in the emulator using telnet: http://www.stealthcopter.com/blog/2010/07/changing-the-battery-percentage-in-an-avd-android-virtual-device-emulator/ – twaddington Mar 28 '13 at 01:00

2 Answers2

0
Intent.ACTION_BATTERY_CHANGED

You have to listen it in Android Manifest

<receiver android:name=".myReceiver" >
    <intent-filter>
        <action android:name="Intent.ACTION_BATTERY_CHANGED" />
    </intent-filter>
</receiver>
minhaz
  • 4,233
  • 3
  • 33
  • 49
  • You shouldn't need to register that there. According to official android tutorial, BatteryManager broadcasts them in a sticky intent. – awonderer Mar 28 '13 at 02:54
  • Sticky means after broadcast it stick around but if you want to receive regular broadcast then you have to register it in Manifest. – minhaz Mar 28 '13 at 03:09
  • I took `android.appwidget.action.APPWIDGET_UPDATE` out and tried above except I put `android:name="main.MyBatteryWidget"` for receiver. Do I need to modify something else in my code? It didn't do anything on emulator. – awonderer Mar 28 '13 at 03:20
  • As you are having trouble with this i recommend you try each module individually. And, FYI, i am not sure why you need service. – minhaz Mar 28 '13 at 03:29
  • I used service because of the tutorials and sample codes I saw around. Could you tell me what is wrong about using service here? – awonderer Mar 28 '13 at 05:34
0

For a working example have a look at my Mini Status Widget, see code

j.holetzeck
  • 4,048
  • 2
  • 21
  • 29