アプリがオンになっていない場合でも、バッテリー情報 (充電中かどうか、レベルなど) を追跡したいと考えています。多分サービスはそれでいいと思いますか?それとも、他の解決策がありますか?私はすべての耳を上げています。
2 に答える
サービスは AndroidManifest.xml で宣言する必要があり、実装クラスは Service クラスまたはそのサブクラスの 1 つを拡張する必要があります。次のコードは、サービス宣言とその実装の例を示しています。
<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;
}
}
これは実際には非常に古い投稿ですが、受け入れられた回答はスタブ サービスのように見えるため、さらに深く掘り下げる必要があると思います。
Android マニフェストでサービスを宣言する必要があります。特定のパッケージに含まれている場合、宣言は次のようになります。
<service android:name="packagename.servicename" />
次に、サービス クラスを実装する必要があります。アプリケーションの 1 つを作成しました。これがお役に立てば幸いです。
私はこれをセンサーの文脈で持っています。センサーは監視したいものなので、次のようなインターフェイスを作成しました。
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;
}