2013-02-28 100 views
0

即使當我的應用程序未打開時,我想追蹤電池信息(是充電,電平等)。我想服務可能會對它有好處?或者也許還有其他解決方案?我全身心地投入。電池信息服務。要監控電池狀態等

+0

您可以使用服務定期觸發ACTION_BATTERY_CHANGED意圖,並按照我的[answer here](http:// stackoverflow)中所示讀取數據。com/questions/14805318/android-batterymanager-returns-only-1/14805410#14805410) – 2013-02-28 19:40:39

+0

@robin太棒了,你能告訴我應該多久開一次這個意圖,也許你有一些代碼示例的服務?會非常有幫助:) – whiteLT 2013-02-28 19:50:05

回答

1

這其實是一個很老的文章,但因爲公認的答案似乎是一個存根服務,我認爲有必要深究下去。

您需要在android清單中聲明服務。如果你在一個特定的包中,它的聲明是:

<service android:name="packagename.servicename" /> 

然後你需要實現服務類。我爲我的一個應用程序創建了一個。希望這可以幫助你。

我在傳感器的背景下有這個。傳感器是我想做的監測,所以我創建了類似的界面如下:

public interface Sensor { 

    SensorType getSensorType(); 

    SensorName getSensorName(); 

} 

我必須ENUM類,代表各類型和傳感器的名字,我有:

public enum SensorName { 
    ENVIRONMENTAL_SENSOR, AUDIO_SENSOR, SOUND_SENSOR, SOCIAL_SENSOR, 
    LOCATION_SENSOR, PHOTO_SENSOR, ACCELEROMETER_SENSOR, BATTERY_SENSOR; 
} 

public enum SensorType { 
    HARDWARE_SENSOR, SOFTWARE_SENSOR, HYBRID_SENSOR; 
} 

,因爲我有幾個傳感器,我可能想要列出所有需要實現此接口的傳感器。接下來,我創建了一個抽象類來實現類似於我所有傳感器的行爲。

public abstract class SensorElement extends Service implements Sensor{ 

    protected SensorType type; 
    protected SensorName name; 

    @Override 
    public abstract IBinder onBind(Intent arg0); 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId){ 
     return super.onStartCommand(intent, flags, startId); 
    } 

    @Override 
    public abstract void onCreate(); 

    @Override 
    public void onDestroy(){ 
     super.onDestroy(); 
    } 
} 

我的傳感器需要這種方法才能正常工作。在我的情況下,我只需要綁定器就可以將服務綁定到我的活動上。

現在,你想要什麼,電池傳感器本身:

public class BatterySensor extends SensorElement { 

    // Binder given to clients 
    private final IBinder mBinder = new BatteryLocalBinder(); 

    /** 
    * Class used for the client Binder. Because we know this service always 
    * runs in the same process as its clients, we don't need to deal with IPC. 
    */ 
    public class BatteryLocalBinder extends Binder { 
     public BatterySensor getService() { 
      // Return this instance of MotionLightOrientationSensor so clients 
      // can call 
      // public 
      // methods 
      return BatterySensor.this; 
     } 
    } 

    private static final String TAG = "BatterySensor"; 
    public static final SensorType type = SensorType.SOFTWARE_SENSOR; 
    public static final SensorName name = SensorName.BATTERY_SENSOR; 

    private int status; 
    private boolean isCharging; 
    private int chargePlug; 
    private boolean usbCharge; 
    private boolean acCharge; 
    private int level; 
    private int scale; 
    private double batteryPct; 
    private Battery battery; 

    @Override 
    public SensorType getSensorType() { 
     return type; 
    } 

    @Override 
    public SensorName getSensorName() { 
     return name; 
    } 

    @Override 
    public IBinder onBind(Intent arg0) { 
     return mBinder; 
    } 

    @Override 
    public void onCreate() { 
     Log.e(TAG, "onCreate"); 
     IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); 
     registerReceiver(powerconnectionreceiver, ifilter); 
     battery = new Battery(); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Log.e(TAG, "onStartCommand"); 
     super.onStartCommand(intent, flags, startId); 
     return START_STICKY; 
    } 

    @Override 
    public void onDestroy() { 
     Log.e(TAG, "onDestroy"); 
     super.onDestroy(); 
     unregisterReceiver(powerconnectionreceiver); 
    } 

    private BroadcastReceiver powerconnectionreceiver = new BroadcastReceiver() { 

     @Override 
     public void onReceive(Context context, Intent intent) { 
      // Retrieves a map of extended data from the intent. 
      status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1); 
      isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING 
        || status == BatteryManager.BATTERY_STATUS_FULL; 

      chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); 
      usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB; 
      acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC; 
      level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); 
      scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); 
      batteryPct = level/(float) scale; 
      battery.setStatus(status); 
      battery.setCharging(isCharging); 
      battery.setChargePlug(chargePlug); 
      battery.setUsbCharge(usbCharge); 
      battery.setAcCharge(acCharge); 
      battery.setLevel(level); 
      battery.setScale(scale); 
      battery.setBatteryPct(batteryPct); 

     } 

    }; 

    public Battery getBatteryReading() { 
     return this.battery; 
    } 

    public int getStatus() { 
     return status; 
    } 

    public boolean isCharging() { 
     return isCharging; 
    } 

    public int getChargePlug() { 
     return chargePlug; 
    } 

    public boolean isUsbCharge() { 
     return usbCharge; 
    } 

    public boolean isAcCharge() { 
     return acCharge; 
    } 

    public int getLevel() { 
     return level; 
    } 

    public int getScale() { 
     return scale; 
    } 


} 

從該傳感器獲取的數據,你只需要啓動它在你的活動是這樣的:

private BatterySensor batterySensor; 
private boolean mBatteryBound = false; 
private Intent intentBattery; 

intentBattery = new Intent(this.context, BatterySensor.class); 

然後我開始服務:

context.startService(intentBattery); 

,並將其綁定:

if(this.context.bindService(intentBattery, mBatteryConnection, Context.BIND_AUTO_CREATE)){ 
      this.numBoundedSensors++; 
     } 

綁定它,你需要有這個類在你的活動:

/** Defines callbacks for service binding, passed to bindService() */ 
    private ServiceConnection mBatteryConnection = new ServiceConnection() { 

     @Override 
     public void onServiceConnected(ComponentName className, 
       IBinder service) { 
      // We've bound to LocalService, cast the IBinder and get LocalService instance 
      BatteryLocalBinder BatteryBinder = (BatteryLocalBinder) service; 
      batterySensor = BatteryBinder.getService(); 
      mBatteryBound = true; 
     } 

     @Override 
     public void onServiceDisconnected(ComponentName arg0) { 
      mBatteryBound = false; 
     } 
    }; 

然後,如果它成功了,你可以調用所有來自傳感器的方法,像這樣綁定:

public Battery getBatteryData(){ 
     return mBatteryBound ? batterySensor.getBatteryReading() : null; 
} 
1

服務需要在AndroidManifest.xml中聲明,實現類必須擴展Service類或其中的一個子類。以下代碼顯示了服務聲明及其實現的示例。

<service 
    android:name="MyService" 
    android:icon="@drawable/icon" 
    android:label="@string/service_name" 
    > 
</service> 

public class MyService extends Service { 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
    //TODO do something useful 
    return Service.START_NOT_STICKY; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
    //TODO for communication return IBinder implementation 
    return null; 
    } 
}