フランの羽型Widgetのソースコード
前回 の記事はペーパーロンチで全然コード書いて無かったので、コードを記載していく。
Widget部とAcitivity部の2つの主要コードが織り交ざって書かれている。そしてJavaのくせにオブジェクト指向ガン無視である。VBの構造体とモジュール的なものが使えれば・・・。
構造体は全部パブリックのフィールドのみでクラス作ればいいのは知っている。問題は、どっからでも呼べる便利コード的な、VBで言う所のモジュールが欲しい。そうすると、javaのカプセル化の意味なくなっちゃうけどね。
では、マニフェスト。
<receiver android:name=".Denti" 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/appwidget" /> </receiver> <activity android:name=".Battery" android:label="@string/app_name" /> <service android:name=".WidgetService" /> <receiver android:name=".BatReceiver"> <intent-filter> <action android:name="jp.mydns.nekomimimaiden.kikurami.battery.CLICK" /> </intent-filter> </receiver>
レシーバー部分があればいいよね。次widgetの定義XML
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="144dp" android:minHeight="144dp" android:initialLayout = "@layout/widget" android:updatePeriodMillis = "600000"> </appwidget-provider>
144dp×144dpから縦2、横2の4セル使うことがわかるね。強制アップデートを30分に一度入れている。10分にしても30分になるからね。次、レイアウト。
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ImageView android:id="@+id/imgView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:src="@drawable/ic_launcher" android:contentDescription="@string/img_desc" /> <TextView android:id="@+id/textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" android:textAppearance="?android:attr/textAppearanceLarge" android:textColor="#ff000000" android:layout_gravity="top|center_horizontal" /> </FrameLayout>
ウイジェットは使えるUIウイジェット(←画面コントロールもウイジェットっていうからややこしい)が限られる。全部使える奴。フランの羽の画像と、バッテリー残量のテキストと配置のコントロールだけあればいい。次は、Widget自体のコード。
package jp.mydns.nekomimimaiden.kikurami.battery; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.content.Intent; import android.util.Log; import android.widget.RemoteViews; public class Denti extends AppWidgetProvider { public static final String firuta="jp.mydns.nekomimimaiden.kikurami.battery.CLICK"; @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // TODO 自動生成されたメソッド・スタブ super.onUpdate(context, appWidgetManager, appWidgetIds); Log.v("onUpdate", "onUpdate_called!"); //リモートビューを作る(←よく分かってない。多分リモコン。) RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget); //タップされたらActivityを立てるための設定をする。 for (int i = 0; i < appWidgetIds.length; i++) { Intent setting = new Intent(context, Battery.class);//立てるアクティビティークラスを指定 setting.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); PendingIntent pi=PendingIntent.getActivity(context, appWidgetIds[i], setting, 0); remoteViews.setOnClickPendingIntent(R.id.textview, pi);//テキストを押しても remoteViews.setOnClickPendingIntent(R.id.imgView, pi);//画像を押しても、Activityを起動 } //バッテリーを取得し続けるサービスを起動 Intent it = new Intent(context,WidgetService.class); context.startService(it); //ウイジェットの更新 appWidgetManager.updateAppWidget(appWidgetIds, remoteViews); } //ウィジェットが全部消される時に呼ばれる @Override public void onDeleted(Context context, int[] appWidgetIds) { // TODO 自動生成されたメソッド・スタブ super.onDeleted(context, appWidgetIds); Log.v("END:", "ウイジェットを終了。"); //作ったサービスを停止させる。 Intent it = new Intent(context, WidgetService.class); context.stopService(it); } }
onUpdateとonDeletedだけ書いとけば・・・、と言うよりここぐらいしか書くことが無い。次、サービス。
package jp.mydns.nekomimimaiden.kikurami.battery; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.appwidget.AppWidgetManager; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.IBinder; import android.util.Log; public class WidgetService extends Service { NotificationManager nm;//通知トレイを使う BatReceiver batteryReceiver = new BatReceiver(); @Override public void onCreate() { // TODO 自動生成されたメソッド・スタブ super.onCreate(); Log.v("service:", "onCreate"); //通知システムを準備する。 nm=(NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE); } //ぜったに復活するコマンドー(ホマンドー)を作る。 @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO 自動生成されたメソッド・スタブ //return super.onStartCommand(intent, flags, startId); Log.v("新スタート:", "新しいスタートが呼ばれた#"); onStart(intent, startId);//スタートを呼ぶ Log.v("指示:", "粘るように指示"); return Service.START_REDELIVER_INTENT;//メモリ不足で消されても復活する? } @Override public void onStart(Intent intent, int startId) { // TODO 自動生成されたメソッド・スタブ super.onStart(intent, startId); Log.v("旧スタート→", "旧スタートが呼ばれた。"); //通知を作る Notification nf = new Notification(R.drawable.nf_icon,"バッテリー情報取得サービス",System.currentTimeMillis()); nf.flags = Notification.FLAG_ONGOING_EVENT;//通知じゃなくて、実行中のカテゴリーに入れる //インテントを作る Intent it = new Intent(this, Battery.class); it.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0); PendingIntent pi = PendingIntent.getActivity(this, 0, it, 0); nf.setLatestEventInfo(getApplicationContext(), "バッテリーの詳細", "バッテリーの詳細を表示します",pi); //バッテリーの変化をキャッチさせる IntentFilter filter=new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); //レジスターに登録 getBaseContext().registerReceiver(batteryReceiver, filter); //通知領域に表示 nm.notify(0, nf); startForeground(0, nf);//サービスが出来るだけ居続けるようにする } //停止処理 @Override public void onDestroy() { // TODO 自動生成されたメソッド・スタブ super.onDestroy(); //レジスターに登録した情報を消す。 getBaseContext().unregisterReceiver(batteryReceiver); //通知を消す stopForeground(false); nm.cancel(0); } @Override public IBinder onBind(Intent intent) { // TODO 自動生成されたメソッド・スタブ return null; } }
頑張っても、頑張っても停まる我がウイジェット。訳分からない。メモリがやっぱり足りないのか?次、レシーバー。
package jp.mydns.nekomimimaiden.kikurami.battery; import android.appwidget.AppWidgetManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.os.BatteryManager; import android.util.Log; import android.widget.RemoteViews; public class BatReceiver extends BroadcastReceiver { int scale;//最大値 int level;//現在地 int health;//健康状態 String shealth;//バッテリーの健康状態を格納 int plugged;//電源接続 String splugged;//電源接続状態を格納 int status;//充電状況 String sstatus;//充電状況を格納 boolean isBattery;//バッテリーの有無 String sisBattery;//バッテリーの有無を格納 String tec;//バッテリー製造技術 int temperature;//バッテリー温度 int volt;//バッテリーの電圧 Resources res;//リソースを保持する String result_Battery_status;//バッテリーの情報すべてを持つ Bitmap result_Battery_bitmap;//フランの羽+バッテリーの画像 String result_Battery_little;//バッテリーのパーセントだけを持つ @Override public void onReceive(Context context, Intent intent) { // TODO 自動生成されたメソッド・スタブ Log.v("レシーバー:", "バッテリーレシーバー"); if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) { //電池の最大 scale = intent.getIntExtra("scale", 0); //電池の残量 level = intent.getIntExtra("level", 0); //バッテリーの健康状態を取得 health = intent.getIntExtra("health", 0); switch (health) { case BatteryManager.BATTERY_HEALTH_DEAD: shealth="バッテリーは寿命"; break; case BatteryManager.BATTERY_HEALTH_GOOD: shealth="バッテリーは良好"; break; case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE: shealth="バッテリーは過電圧"; break; case BatteryManager.BATTERY_HEALTH_OVERHEAT: shealth="バッテリーは過加熱"; break; case BatteryManager.BATTERY_HEALTH_UNKNOWN: shealth="バッテリーの状態は不明"; break; case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE: shealth="バッテリーの健康状態の取得に失敗"; break; default: shealth="バッテリーは≡⑨≡冷たすぎ。";//冷たすぎはAPI21~ break; } //バッテリーの電源接続状態 plugged = intent.getIntExtra("plugged", 0); switch (plugged) { case BatteryManager.BATTERY_PLUGGED_AC: splugged="AC電源に接続"; break; case BatteryManager.BATTERY_PLUGGED_USB: splugged="USB電源に接続"; break; default: splugged="電源接続無し"; break; } //充電の状況 status=intent.getIntExtra("status", 0); switch (status) { case BatteryManager.BATTERY_STATUS_CHARGING: sstatus="充電中"; break; case BatteryManager.BATTERY_STATUS_DISCHARGING: sstatus="放電中"; break; case BatteryManager.BATTERY_STATUS_FULL: sstatus="満充電"; break; case BatteryManager.BATTERY_STATUS_NOT_CHARGING: sstatus="充電してない"; break; case BatteryManager.BATTERY_STATUS_UNKNOWN: sstatus="充電状況不明"; break; default: sstatus="充電状況は謎"; break; } //バッテリーの有無 isBattery=intent.getBooleanExtra("present", false); if (isBattery){ sisBattery="有"; }else { sisBattery="無"; } //バッテリー製造技術 tec=intent.getStringExtra("technology"); //バッテリーの温度 temperature = intent.getIntExtra("temperature", 0); //バッテリーの電圧 volt = intent.getIntExtra("voltage", 0); //結果のプリント StringBuilder sb= new StringBuilder(""); //textView.setText(""); sb.append("充電池の有無:"+sisBattery + "\n"); sb.append("健康状態:"+shealth + "\n"); sb.append("電圧:"+ String.valueOf((float)volt/1000)+"[V]=" +volt +"[mV]" + "\n"); sb.append("充電池の種類:"+ tec + "\n"); sb.append("温度:"+ String.valueOf((float)temperature/10) + "[度]\n"); sb.append("充電状態:"+ sstatus + " \n"); sb.append("電源:" + splugged + "\n"); sb.append("残量:"+ String.valueOf(level*100/scale) +"[%](実値:"+level +")\n"); sb.append("最大値:"+ scale + "\n"); result_Battery_status=sb.toString(); result_Battery_little = "残量:" + level + "%"; //画像のビューにビットマップを指定 res=context.getResources(); result_Battery_bitmap =gazou_seisei(level,scale,plugged); //ウイジェットのテキストに反映。 RemoteViews rv=new RemoteViews(context.getPackageName(), R.layout.widget);//リモートビューを作る rv.setTextViewText(R.id.textview, "残量:" + level + "%");//ウイジェットに残量を文字で設定 rv.setImageViewBitmap(R.id.imgView, result_Battery_bitmap); //アクティビティーに反映 /* Battery bat = new Battery(); bat.setText(result_Battery_status); bat.setImage(result_Battery_bitmap); */ //ウイジェットを更新 AppWidgetManager am = AppWidgetManager.getInstance(context); am.updateAppWidget(new ComponentName(context, Denti. class ), rv);//ウイジェットを更新する。 } } //バッテリーの残量と電源の接続から画像を生成する関数(Denti.javaと同じ) public Bitmap gazou_seisei(int now_leve,int max_level,int puragu) { Bitmap bitmap=null; Bitmap bitmap2=null; int zanryou = now_leve*100/max_level; //Log.v("parsent:", "zanryou:" + String.valueOf(zanryou) + " nv:" + String.valueOf(now_leve) + " max:" + String.valueOf(max_level)); //バッテリーの残量を格納 if (zanryou >= 95) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_100); }else if (zanryou >= 80 && zanryou < 95) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_90); }else if (zanryou >= 60 && zanryou < 80) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_70); }else if (zanryou >= 40 && zanryou < 60) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_50); }else if (zanryou >= 30 && zanryou < 40) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_35); }else if (zanryou >= 20 && zanryou < 30) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_25); }else if (zanryou >= 10 && zanryou < 20) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_15); }else if(zanryou > 0 && zanryou < 10) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_05); }else { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_batu); } //フランドールの羽の状態を格納 if (zanryou >= 95) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_120_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_120_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_100); } }else if (zanryou >= 90 && zanryou < 95) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_90_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_90_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_90); } }else if (zanryou >= 80 && zanryou < 90) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_80_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_80_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_80); } }else if (zanryou >= 70 && zanryou < 80){ if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_70_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_70_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_70); } }else if (zanryou >= 60 && zanryou < 70){ if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_60_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_60_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_60); } }else if (zanryou >= 50 && zanryou < 60) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_50_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_50_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_50); } }else if (zanryou >= 40 && zanryou < 50) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_40_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_40_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_40); } }else if (zanryou >= 35 && zanryou < 40) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_35_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_35_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_35); } }else if (zanryou >= 30 && zanryou < 35) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_30_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_30_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_30); } }else if (zanryou >= 25 && zanryou < 30) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_25_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_25_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_25); } }else if (zanryou >= 20 && zanryou < 25) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_20_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_20_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_20); } }else if (zanryou >= 15 && zanryou < 20) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_15_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_15_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_15); } }else if (zanryou >= 10 && zanryou < 15) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_10_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_10_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_10); } }else if (zanryou > 5 && zanryou < 10) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_05_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_05_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_05); } }else if (zanryou >= 0 && zanryou <=5) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_00_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_00_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_00); } }else { //0未満は無いはず } //充電状態ならバッテリーの画像を差し替える。 if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap=BitmapFactory.decodeResource(res, R.drawable.charge); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_ch); }else { //放電中は何もしない。 } //bitmapを合成する Bitmap haikei = bitmap2.copy(Bitmap.Config.ARGB_8888, true); Canvas c = new Canvas(haikei);//まずはフランの羽を設置 c.drawBitmap(bitmap, bitmap2.getWidth()/2-bitmap.getWidth()/2, 10, null);//電池を描画 return haikei; } //画像を返す public Bitmap getBitmap() { return result_Battery_bitmap; } //テキストデータを返す public String getBattery_Full_String() { return result_Battery_status; } public String getBattery_String() { return result_Battery_little; } }
このウィジェットの最大の肝。バッテリー残量を取得して、ウィジェットに表示する。画像生成は別関数で行っている。アクティビティーをここから操作する方法が分かればなぁー。次、Activity。
package jp.mydns.nekomimimaiden.kikurami.battery; import java.util.List; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningServiceInfo; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.os.BatteryManager; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.RemoteViews; import android.widget.TextView; //タップされて起動するアクティビティー public class Battery extends Activity { ImageView iv;//フランのバッテリーステータス画像を放り込む TextView textView;//バッテリー状況の表示場所 Button cbutton;//閉じるボタン int ident;//IDを拾う //アクティビテーを作る @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);//xmlのレイアウトを指定 Log.v("アクティビティー:", "アクティビティー起動"); //activity_main.xmlから画面情報を拾う iv = (ImageView)findViewById(R.id.imageView1); textView = (TextView)findViewById(R.id.textView1); cbutton = (Button)findViewById(R.id.button1); //インテントのIDを拾う Intent it =getIntent(); Bundle ex = it.getExtras(); ident=ex.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID); cbutton.requestFocus();//ボタンにフォーカスを当てる。効いて無い? } //xmlで定義された、閉じるボタンを押したときに呼ばれる public void onCloseButton(View view){ //アクティビティー終了 Log.v("Activity:", "アクティビティー終了"); finish(); //finish()やっても次が呼ばれるので、この辺にサービスが生きてるか確認するコード入れる? /* if (!isServiceRunning(WidgetService.class.getCanonicalName())) { //バッテリー情報を取得するサービスが落ちている場合は、 //バッテリーを取得し続けるサービスを起動 Log.v("Service停止?", "サービスが止まっている模様。"); Intent it = new Intent(getApplicationContext(),WidgetService.class); getApplicationContext().startService(it); } */ //ウィジェットにクリック設定 RemoteViews rv=new RemoteViews(getPackageName(), R.layout.widget); Intent it = new Intent(getBaseContext(), Battery.class); it.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0); PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, it, 0); rv.setOnClickPendingIntent(R.id.textview, pi); rv.setOnClickPendingIntent(R.id.imgView, pi); //ウイジェットを更新 /* Intent widgetUpdate = new Intent(); widgetUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); sendBroadcast(widgetUpdate); */ AppWidgetManager manager = AppWidgetManager.getInstance(this); manager.updateAppWidget(new ComponentName(getBaseContext(), Denti. class ), rv); } //再開 @Override protected void onResume() { // TODO 自動生成されたメソッド・スタブ super.onResume(); //バッテリー状態を拾うフィルターを設置し登録 IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); getApplicationContext().registerReceiver(batteryReceiver, filter); } //一時停止 @Override protected void onPause() { // TODO 自動生成されたメソッド・スタブ super.onPause(); //登録されたフィルターを消去 getApplicationContext().unregisterReceiver(batteryReceiver); //ウイジェットを更新 /* Intent widgetUpdate = new Intent(); widgetUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); sendBroadcast(widgetUpdate); */ RemoteViews rv=new RemoteViews(getPackageName(), R.layout.widget); AppWidgetManager manager = AppWidgetManager.getInstance(this); manager.updateAppWidget(new ComponentName(getBaseContext(), Denti. class ), rv); } //サービスの存在確認 boolean isServiceRunning(String classname){ ActivityManager am = (ActivityManager)getSystemService(ACTIVITY_SERVICE); List<ActivityManager.RunningServiceInfo> serviceInfos = am.getRunningServices(Integer.MAX_VALUE); for (RunningServiceInfo Info : serviceInfos) { if (classname.equals(Info.service.getClassName())) { return true; } } return false; } //テキストを設置 public void setText(String str_battery) { if (textView !=null) { textView.setText(str_battery); } } //画像を設置 public void setImage(Bitmap bmp_battery) { if(iv !=null){ iv.setImageBitmap(bmp_battery); } } //やっていることは、BatReceiver.javaと同じ。 //何でオブジェクト指向なのに、同じコードを何度も書かなければならないのか BroadcastReceiver batteryReceiver = new BroadcastReceiver() { int scale;//最大値 int level;//現在地 int health;//健康状態 String shealth;//バッテリーの健康状態を格納 int plugged;//電源接続 String splugged;//電源接続状態を格納 int status;//充電状況 String sstatus;//充電状況を格納 boolean isBattery;//バッテリーの有無 String sisBattery;//バッテリーの有無を格納 String tec;//バッテリー製造技術 int temperature;//バッテリー温度 int volt;//バッテリーの電圧 Resources res;//リソースを保持する String result_Battery_status;//バッテリーの情報すべてを持つ Bitmap result_Battery_bitmap;//フランの羽+バッテリーの画像 @Override public void onReceive(Context context, Intent intent) { // TODO 自動生成されたメソッド・スタブ Log.v("actレシーバー:", "アクティビティーのバッテリーレシーバー"); if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) { //電池の最大 scale = intent.getIntExtra("scale", 0); //電池の残量 level = intent.getIntExtra("level", 0); //バッテリーの健康状態を取得 health = intent.getIntExtra("health", 0); switch (health) { case BatteryManager.BATTERY_HEALTH_DEAD: shealth="バッテリーは寿命"; break; case BatteryManager.BATTERY_HEALTH_GOOD: shealth="バッテリーは良好"; break; case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE: shealth="バッテリーは過電圧"; break; case BatteryManager.BATTERY_HEALTH_OVERHEAT: shealth="バッテリーは過加熱"; break; case BatteryManager.BATTERY_HEALTH_UNKNOWN: shealth="バッテリーの状態は不明"; break; case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE: shealth="バッテリーの健康状態の取得に失敗"; break; default: shealth="バッテリーは≡⑨≡冷たすぎ。";//冷たすぎはAPI21~ break; } //バッテリーの電源接続状態 plugged = intent.getIntExtra("plugged", 0); switch (plugged) { case BatteryManager.BATTERY_PLUGGED_AC: splugged="AC電源に接続"; break; case BatteryManager.BATTERY_PLUGGED_USB: splugged="USB電源に接続"; break; default: splugged="電源接続無し"; break; } //充電の状況 status=intent.getIntExtra("status", 0); switch (status) { case BatteryManager.BATTERY_STATUS_CHARGING: sstatus="充電中"; break; case BatteryManager.BATTERY_STATUS_DISCHARGING: sstatus="放電中"; break; case BatteryManager.BATTERY_STATUS_FULL: sstatus="満充電"; break; case BatteryManager.BATTERY_STATUS_NOT_CHARGING: sstatus="充電してない"; break; case BatteryManager.BATTERY_STATUS_UNKNOWN: sstatus="充電状況不明"; break; default: sstatus="充電状況は謎"; break; } //バッテリーの有無 isBattery=intent.getBooleanExtra("present", false); if (isBattery){ sisBattery="有"; }else { sisBattery="無"; } //バッテリー製造技術 tec=intent.getStringExtra("technology"); //バッテリーの温度 temperature = intent.getIntExtra("temperature", 0); //バッテリーの電圧 volt = intent.getIntExtra("voltage", 0); //結果のプリント StringBuilder sb= new StringBuilder(""); //textView.setText(""); sb.append("充電池の有無:"+sisBattery + "\n"); sb.append("健康状態:"+shealth + "\n"); sb.append("電圧:"+ String.valueOf((float)volt/1000)+"[V]=" +volt +"[mV]" + "\n"); sb.append("充電池の種類:"+ tec + "\n"); sb.append("温度:"+ String.valueOf((float)temperature/10) + "[度]\n"); sb.append("充電状態:"+ sstatus + " \n"); sb.append("電源:" + splugged + "\n"); sb.append("残量:"+ String.valueOf(level*100/scale) +"[%](実値:"+level +")\n"); sb.append("最大値:"+ scale + "\n"); result_Battery_status=sb.toString(); //画像のビューにビットマップを指定 res=context.getResources(); result_Battery_bitmap =gazou_seisei(level,scale,plugged); //ウイジェットのテキストに反映。 RemoteViews rv=new RemoteViews(context.getPackageName(), R.layout.widget);//リモートビューを作る rv.setTextViewText(R.id.textview, "残量:" + level + "%");//ウイジェットに残量を文字で設定 rv.setImageViewBitmap(R.id.imgView, result_Battery_bitmap); //アクティビティーに反映 textView.setText(result_Battery_status); iv.setImageBitmap(result_Battery_bitmap); //ウイジェットを更新 AppWidgetManager am = AppWidgetManager.getInstance(context); am.updateAppWidget(new ComponentName(context, Denti. class ), rv);//ウイジェットを更新する。 } } //バッテリーの残量と電源の接続から画像を生成する関数(Denti.javaと同じ) public Bitmap gazou_seisei(int now_leve,int max_level,int puragu) { Bitmap bitmap=null; Bitmap bitmap2=null; int zanryou = now_leve*100/max_level; //Log.v("parsent:", "zanryou:" + String.valueOf(zanryou) + " nv:" + String.valueOf(now_leve) + " max:" + String.valueOf(max_level)); //バッテリーの残量を格納 if (zanryou >= 95) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_100); }else if (zanryou >= 80 && zanryou < 95) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_90); }else if (zanryou >= 60 && zanryou < 80) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_70); }else if (zanryou >= 40 && zanryou < 60) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_50); }else if (zanryou >= 30 && zanryou < 40) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_35); }else if (zanryou >= 20 && zanryou < 30) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_25); }else if (zanryou >= 10 && zanryou < 20) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_15); }else if(zanryou > 0 && zanryou < 10) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_05); }else { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_batu); } //フランドールの羽の状態を格納 if (zanryou >= 95) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_120_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_120_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_100); } }else if (zanryou >= 90 && zanryou < 95) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_90_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_90_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_90); } }else if (zanryou >= 80 && zanryou < 90) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_80_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_80_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_80); } }else if (zanryou >= 70 && zanryou < 80){ if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_70_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_70_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_70); } }else if (zanryou >= 60 && zanryou < 70){ if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_60_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_60_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_60); } }else if (zanryou >= 50 && zanryou < 60) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_50_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_50_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_50); } }else if (zanryou >= 40 && zanryou < 50) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_40_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_40_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_40); } }else if (zanryou >= 35 && zanryou < 40) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_35_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_35_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_35); } }else if (zanryou >= 30 && zanryou < 35) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_30_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_30_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_30); } }else if (zanryou >= 25 && zanryou < 30) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_25_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_25_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_25); } }else if (zanryou >= 20 && zanryou < 25) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_20_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_20_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_20); } }else if (zanryou >= 15 && zanryou < 20) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_15_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_15_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_15); } }else if (zanryou >= 10 && zanryou < 15) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_10_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_10_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_10); } }else if (zanryou > 5 && zanryou < 10) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_05_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_05_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_05); } }else if (zanryou >= 0 && zanryou <=5) { if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_00_ac); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_00_usb); }else { bitmap2=BitmapFactory.decodeResource(res, R.drawable.fra_00); } }else { //0未満は無いはず } //充電状態ならバッテリーの画像を差し替える。 if (puragu == BatteryManager.BATTERY_PLUGGED_AC) { bitmap=BitmapFactory.decodeResource(res, R.drawable.charge); }else if (puragu == BatteryManager.BATTERY_PLUGGED_USB) { bitmap=BitmapFactory.decodeResource(res, R.drawable.batteri_ch); }else { //放電中は何もしない。 } //bitmapを合成する Bitmap haikei = bitmap2.copy(Bitmap.Config.ARGB_8888, true); Canvas c = new Canvas(haikei);//まずはフランの羽を設置 c.drawBitmap(bitmap, bitmap2.getWidth()/2-bitmap.getWidth()/2, 10, null);//電池を描画 return haikei; } }; //↓メニュー周り。今作は使わない。 @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. return false; } }
ブロードキャストレシーバーはbatReciveと共通なんだよね。Activityのコードが冗長すぎる。そして、端末使いまくってると、setOnClickPendingIntentが仕事しなくなる。ん~分からない。
Widgetはいろいろとデバッグ情報が取れないらしく、開発難易度は高いとの事。
参考サイト:
バッテリー残量ウィジェットの作り方 (1/4)、
android widgetで電池アプリを開発してみよう1、
android widgetで電池アプリを開発してみよう2
役に立たなかった:
高橋麻奈のやさしいAndroidプログラミング
やっぱりググって、海外フォーラムが最強よ。(アメ語読めないとだめだが。)
しかし、蒼穹工房のチルノ に出来て、私のフランドールに出来ないというのは、なんか癪だな。人のコードが動いている以上、自分のところのAPIでもできるはずだ。アプリの有料・無料、プロ・素人問わずAPIは共通のはずだ。2ボスがExボスにコードコーティング力に敗北するなんてな。
« フランの羽型バッテリー残量ウイジェット | トップページ | 681系・683系SRE »
「プログラミング」カテゴリの記事
- Intel oneAPI をインストールした(2021.07.17)
- 電車でD ShiningStage の MOD 作りは可能かの調査(2020.08.16)
- unityの変数にアタックする(2016.11.03)
- はじめてのVisual C++(2016.07.20)
- androidのwidgetを作る(2016.05.04)
コメント