Warning: include(/home/users/2/lolipop.jp-a-virtual/web/dhmo/dhmo/wp-content/advanced-cache.php): failed to open stream: No such file or directory in /home/users/2/lolipop.jp-a-virtual/web/dhmo/dhmo/wp-settings.php on line 74

Warning: include(/home/users/2/lolipop.jp-a-virtual/web/dhmo/dhmo/wp-content/advanced-cache.php): failed to open stream: No such file or directory in /home/users/2/lolipop.jp-a-virtual/web/dhmo/dhmo/wp-settings.php on line 74

Warning: include(): Failed opening '/home/users/2/lolipop.jp-a-virtual/web/dhmo/dhmo/wp-content/advanced-cache.php' for inclusion (include_path='.:/usr/local/php/5.4/lib/php') in /home/users/2/lolipop.jp-a-virtual/web/dhmo/dhmo/wp-settings.php on line 74
Android widgetで電池アプリを開発してみよう-② – Androidアプリつくったった

Android widgetで電池アプリを開発してみよう-②

android widget battery

前回に引き続き
今回で電池アプリに仕上げようと思います。
汎用性とシンプルな実装を目指して作成されています。
状況に合わせ改編して頂ければと思います。

前回の部分まで作っていれば
以下たった2ステップで
電池アプリが完成してしまいます。

①インテントからバッテリー残量の情報を引き出します。
②ウィジェットに表示します。

完成したアプリ(ウィジェット)の見た目はこんな感じになります。
android widget battery

取得値を組み合わせることで応用が利くので
BatteryManagerについては公式ページで確認すると良いでしょう。

代表的なものを列挙しましたが、*が付いている値を今回は利用します。

*level 電池の残量
*scale 電池の最大値
*temperature 電池の温度

status 電池の状態
*plugged    端末の接続状態
technology 充電池の種類
present バッテリの有無
voltage 電池の電圧
icon-small バッテリ状態のアイコンのリソースID

◇電池残量(%)の取得方法

まず、電池残量(%)の取得方法です
以下の値を用います。
*level 電池の残量
*scale 電池の最大値
この2つの値を組み合わせます。

電池残量(%) = level / scale *100

ですから、ソースは以下のようになります。


/////// add1 //////
        public int getBatteryLevel() {
            Intent battery = getApplicationContext().registerReceiver(null,
                    new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
            int level = battery.getIntExtra("level", 0);
            int scale = battery.getIntExtra("scale", 100);
            return level * 100 / scale;
        }
/////// add1  /////

電池温度の取得方法

次は電池の温度の取得です。
以下の値を用います。
*temperature 電池の温度

0.1℃単位になっているので℃数表示したい場合は
10で割ってあげる必要があります。

ソースは以下のようになります。

/////// add2 //////
        public int getBatteryTemperature() {
            Intent battery = getApplicationContext().registerReceiver(null,
                    new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
            int temperature = battery.getIntExtra("temperature", 0);
            //温度は0.1度単位なので10で割る
            return temperature/10;
        }
/////// add2  /////

端末の接続状態の取得方法

最後に端末のUSBケーブルなどの接続状況の取得に付いてです。
statusを利用した方がより細かい状態の取得ができますが
簡単に接続の有無と種類を知りたいならpluggedでいいでしょう。

以下の値を用います。
*plugged    端末の接続状態

BatteryManager.BATTERY_PLUGGED_AC ACアダプタ
BatteryManager.BATTERY_PLUGGED_USB USB

となります。

ソースは以下のようになります。

/////// add3 //////
        public String getBatteryPlugged() {
            Intent battery = getApplicationContext().registerReceiver(null,
                    new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
            int plugged = battery.getIntExtra("plugged", 0);
            String pluggedStr = "";

            switch (plugged) {
            case BatteryManager.BATTERY_PLUGGED_AC:
            	pluggedStr = "plugged ac";
                break;
            case BatteryManager.BATTERY_PLUGGED_USB:
            	pluggedStr = "plugged usb";
                break;
            }
            return pluggedStr;
        }
/////// add3  /////

画面の表示・更新部分

workerLoop()の部分ですが、
前回と順番を多少入れ替えていますがほぼ内容は変わりません。
表示部分で今回の各値を取得しています。

ソースは以下のようになります。

        private void workerLoop() {

            int cnt=0;
            // Main worker loop for the service
            while (keepRunning) {

                try {
                        Thread.sleep(10000);
                        cnt++;

                } catch (Exception e) {
                }
                RemoteViews remoteViews = new RemoteViews(getPackageName(),
                        R.layout.main);
                remoteViews.setTextViewText(R.id.textView1,getBatteryLevel()+ "%\t"+getBatteryTemperature()+"℃\n"+getBatteryPlugged());
                ComponentName thisWidget = new ComponentName(this, Widget.class);
                AppWidgetManager manager = AppWidgetManager.getInstance(this);
                manager.updateAppWidget(thisWidget, remoteViews);
            }
        }

以上できちんと、電池残量、電池温度、接続状態が表示されるはずです。
 
最後に、全体のソースです。
 
XML/Manifestファイルは変更ありませんので
省略させて頂きます。

public class Widget extends AppWidgetProvider {

    private final long interval = 1 * 1 * 1000; // 更新間隔
    private static final String ACTION_START_MY_ALARM = "jp.gr.java_conf..test_widget.ACTION_START_MY_ALARM";

    /** アラームマネージャをで更新間隔を設定する。 */
    private void setAlarm(Context context) {
        Intent alarmIntent = new Intent(context, Widget.class);
        alarmIntent.setAction(ACTION_START_MY_ALARM);
        PendingIntent operation = PendingIntent.getBroadcast(context, 0,
                alarmIntent, 0);
        AlarmManager am = (AlarmManager) context
                .getSystemService(Context.ALARM_SERVICE);
        long now = System.currentTimeMillis() + 1; // + 1 は確実に未来時刻になるようにする保険
        long oneHourAfter = now + interval - now % (interval);
        am.set(AlarmManager.RTC, oneHourAfter, operation);
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {
        super.onUpdate(context, appWidgetManager, appWidgetIds);
        /*
         * ホームボタンを押したら、receiveを呼び出す タスクキラーなどで、アプリを強制終了された際、 Widgetも終了してしまうため。
         */
        context.getApplicationContext().registerReceiver(
                new BroadcastReceiver() {
                    @SuppressWarnings("unused")
                    public void onUpdate(Context context,
                            AppWidgetManager appWidgetManager,
                            int[] appWidgetIds) {
                        setAlarm(context);
                    }

                    @Override
                    public void onReceive(Context context, Intent intent) {
                        Widget.this.onReceive(context, intent);
                    }
                }, new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));

        setAlarm(context);

        /** Click時のActivity */
        for (int i : appWidgetIds) {
            RemoteViews views = new RemoteViews(context.getPackageName(),
                    R.layout.main);
            // Textをセットする。
            views.setTextViewText(R.id.textView1, "measuring");
            appWidgetManager.updateAppWidget(i, views);
        }

    }

    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
        if (intent.getAction().equals(ACTION_START_MY_ALARM)) {

            if (ACTION_START_MY_ALARM.equals(intent.getAction())) {
                Intent serviceIntent = new Intent(context, MyService.class);
                context.startService(serviceIntent);
            }
            setAlarm(context);
        }
    }

    // 起動したServiceを停止する(1)
    @Override
    public void onDisabled(Context context) {
        super.onDisabled(context);
        Intent in = new Intent(context, MyService.class);
        context.stopService(in);
    }

    static int itemcount = 0;
    // サービスの内容
    public static class MyService extends Service implements LocationListener {
        private Thread runner;
        private volatile boolean keepRunning;

        @Override
        public void onCreate() {
            keepRunning = true;
            runner = new Thread(null, new Runnable() {
                public void run() {
                    workerLoop();
                }
            });
            runner.start();
        }
/////// add1 //////
        public int getBatteryLevel() {
            Intent battery = getApplicationContext().registerReceiver(null,
                    new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
            int level = battery.getIntExtra("level", 0);
            int scale = battery.getIntExtra("scale", 100);
            return level * 100 / scale;
        }
/////// add1  /////

/////// add2 //////
        public int getBatteryTemperature() {
            Intent battery = getApplicationContext().registerReceiver(null,
                    new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
            int temperature = battery.getIntExtra("temperature", 0);
            //温度は0.1度単位なので10で割る
            return temperature/10;
        }
/////// add2  /////

/////// add3 //////
        public String getBatteryPlugged() {
            Intent battery = getApplicationContext().registerReceiver(null,
                    new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
            int plugged = battery.getIntExtra("plugged", 0);
            String pluggedStr = "";

            switch (plugged) {
            case BatteryManager.BATTERY_PLUGGED_AC:
            	pluggedStr = "plugged ac";
                break;
            case BatteryManager.BATTERY_PLUGGED_USB:
            	pluggedStr = "plugged usb";
                break;
            }
            return pluggedStr;
        }
/////// add3  /////
        private void workerLoop() {

            int cnt=0;
            // Main worker loop for the service
            while (keepRunning) {

                try {
                        Thread.sleep(10000);
                        cnt++;

                } catch (Exception e) {
                }
                RemoteViews remoteViews = new RemoteViews(getPackageName(),
                        R.layout.main);
                remoteViews.setTextViewText(R.id.textView1,getBatteryLevel()+ "%\t"+getBatteryTemperature()+"℃\n"+getBatteryPlugged());
                ComponentName thisWidget = new ComponentName(this, Widget.class);
                AppWidgetManager manager = AppWidgetManager.getInstance(this);
                manager.updateAppWidget(thisWidget, remoteViews);
            }
        }

        @Override
        public void onDestroy() {
            keepRunning = false;
            runner.interrupt();
        }

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.v("TEST", "OK onStartCommand");;
            return super.onStartCommand(intent, flags, startId);
        }
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
        @Override
        public void onProviderDisabled(String arg0) {
        }
        @Override
        public void onProviderEnabled(String arg0) {
        }
        @Override
        public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
        }

        @Override
        public void onLocationChanged(Location location) {
        }
    }
    @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
        super.onDeleted(context, appWidgetIds);

    }
}

以上です。

参考になれば幸いです。


About the Author

dhmo
Author:DHMO(ディベロッパー名) 仕事では自社サービス・メディアの開発を行ってます。 趣味でAndroidアプリ製作を行っています。 カラオケではランキングバトルにはまっております。 Mail: dihydromooxide7@gmail.com 

Be the first to comment on "Android widgetで電池アプリを開発してみよう-②"

Leave a comment

Your email address will not be published.


*