2013-05-11 193 views
0

我正在尋找使AppWidget檢查電池狀態(級別,充電/不充電)。Android AppWidget電池狀態

我寫了很多代碼行,但即使它完美地工作,我也發現將它放在屏幕上會使電話變慢,有時甚至崩潰。

我認爲這是因爲我犯了錯誤。有人能幫我嗎?感謝的

這裏我的清單:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="it.bisneff.widgetone" 
    android:versionCode="1" 
    android:versionName="1.0" > 

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

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 


     <receiver android:name="MyWidgetProvider" > 
      <intent-filter > 
       <action 
        android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 

       <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/> 
       <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/> 

      </intent-filter> 

      <meta-data 
       android:name="android.appwidget.provider" 
       android:resource="@xml/widget_info" /> 
      </receiver> 


    </application> 

</manifest> 

在這裏,我的主類:

package it.bisneff.widgetone; 


import it.bisneff.widgetone.R; 
import android.app.PendingIntent; 
import android.appwidget.AppWidgetManager; 
import android.appwidget.AppWidgetProvider; 
import android.content.ComponentName; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.os.BatteryManager; 
import android.os.Bundle; 
import android.util.Log; 
import android.widget.RemoteViews; 

public class MyWidgetProvider extends AppWidgetProvider { 

    //Unused String 
    private static final String ACTION_CLICK = "ACTION_CLICK"; 


     @Override 
     public void onUpdate(Context context, AppWidgetManager appWidgetManager, 
      int[] appWidgetIds) { 

     ComponentName thisWidget = new ComponentName(context, 
      MyWidgetProvider.class); 
     int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget); 

     for (int widgetId : allWidgetIds) { 


       Intent batteryStatus =context.getApplicationContext().registerReceiver(this, 
         new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 

        //Battery Level 
       int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); 

       //Max Battery Level 
       int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1); 

       // % 
       float batteryPct = level/(float)scale; 
       batteryPct=batteryPct*100; 



      RemoteViews remoteViews = new RemoteViews(context.getPackageName(), 
       R.layout.widget_layout); 

      //Charging or not 
      int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1); 


      boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || 
        status == BatteryManager.BATTERY_STATUS_FULL; 

      //integer convertion 
      int batteryPctz=(int)batteryPct; 
      Log.w("WidgetExample", String.valueOf(batteryPctz)+"%"); 


      //USB or AC charge 
      int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); 
      boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB; 
      boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC; 

      //update view 
      remoteViews.setTextViewText(R.id.update, String.valueOf(batteryPctz)+"%"); 

      //select the image for the battery level 
      String res=new String(); 
      res="it.bisneff.widgetone:drawable/battery"; 



        if (batteryPct >= 90) 
      {  res+="6"; 
      } 
      if (batteryPct >= 75 && batteryPct < 90) 
      { 
       res+="5"; 
      } 
      if (batteryPct >= 60 && batteryPct < 75) 
      { 
      res+="4"; 
      } 
      if (batteryPct >= 35 && batteryPct < 60) 
      { 
      res+="3"; 
      } 
      if (batteryPct >= 15 && batteryPct < 35) 
      { 
      res+="2"; 
      } 
      if (batteryPct < 15) 
      { 
      res+="1"; 
      } 


      if(isCharging){ 


      if(acCharge) 
      { 

       res+="cha"; 

      } 


      if(usbCharge) 
      { 
      res+="usb"; 
      } 


      if (batteryPctz==100){res="it.bisneff.widgetone:drawable/battery6full";} 
      } 

      //check the resource 
      int reso= context.getResources().getIdentifier(res, null, null);  

      //put the right image 
      remoteViews.setImageViewResource(R.id.imageView1, reso); 



      //Set Click Listener 

      Intent intent = new Intent(context, MyWidgetProvider.class); 

      intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); 
      intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); 

      PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 
       0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
      remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent); 
      appWidgetManager.updateAppWidget(widgetId, remoteViews); 
     } 

     } 


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

     //check received intent action 
     if( ((intent.getAction()).equals(Intent.ACTION_BATTERY_CHANGED)) || ((intent.getAction()).equals(Intent.ACTION_POWER_CONNECTED)) || ((intent.getAction()).equals(Intent.ACTION_POWER_DISCONNECTED))){ 

      //get Bundle 
      Bundle extras = intent.getExtras(); 

      //if extras 
      if(extras!=null) { 


       AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);   
       ComponentName thisAppWidget = new ComponentName(context.getPackageName(), MyWidgetProvider.class.getName()); 
       int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget); 

      //call the onUpdate 
      onUpdate(context, appWidgetManager, appWidgetIds); 

     } 

     } 
     } 

     } 

編輯:

我看到哪裏出了問題。

如果我有

.... 
     Intent batteryStatus =context.getApplicationContext().registerReceiver(this, 
         new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 
      context.getApplicationContext().unregisterReceiver(this);//this line 
    .... 

小部件停止循環。但是,停止對電池電量的變化更新...

我加

@Override 
public void onEnabled(Context context){ 

    context.getApplicationContext().registerReceiver(this, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 

} 

就一定要登記我的接收器,但它不會工作,我不能從XML文檔的原因說其註冊它不能在那裏註冊。

我該怎麼辦?

+1

你需要調查墜機尋找在logcat的跟蹤消息的原因。我也可以建議使用try-catch結構來避免崩潰,並管理異常情況。 – GVillani82 2013-05-11 13:42:49

+0

好的。我這樣做,並在第一次看,我看到,當放在屏幕上的小部件開始運行此行Log.w(「WidgetExample」,String.valueOf(batteryPctz)+「%」);連續(它繼續記錄84%) 它爲什麼這樣做? – 2013-05-11 13:59:20

+0

顯然這意味着它會繼續調用onUpdate()。 – 2013-05-11 14:00:31

回答

0

你好瓦萊里奧Bisneff蓬扎,

你必須面對這個異常:

android.content.ReceiverCallNotAllowedException: BroadcastReceiver components are not allowed to register to receive intents 

原因:這是因爲,你(的Widget /廣播接收器),不能與其他Intent_Filter註冊本身或者登錄其它接收器,從(空間/廣播接收器)內...

如果添加在清單中,而登記的widget:

  • 行動機器人:名字= 「android.intent.action.BATTERY_CHANGED」 OR
  • 行動機器人:名字= 「android.intent.action.ACTION_POWER_CONNECTED」 OR
  • 行動機器人:名字=「android.intent.action。 ACTION_POWER_DISCONNECTED「等

...大部分時間您的Widget不會迴應。

原因:Widget與進程(pid)或服務相關聯,如果獨立運行(活動/服務)未運行,則不應接收Intents。

該做什麼?

In On啓用後,啓動一個服務,顯式地更新您的小部件,在服務的onStart()中註冊您的BroadCast接收器,並從Service中更新Widget。

注意:請記住在服務的onStop()中取消註冊接收方,否則會出現另一個異常......並顯式調用Widget的onDisabled()的stopService()。如果需要在這裏輸入代碼`d,請將您的服務保留爲清單中的exports =「false」。

親愛的Ponza,我曾經遇到過,有時候,你的服務被Android殺死,基於一些基於使用的GC。但是在這種情況下,我們總是可以在Widget的每個動作中使用一些共享的Pref布爾值進行智能檢查。

希望我的回答是不夠詳細;)