私は、組み込みのSMSアプリに似たアプリを作成しています。
必要なもの:
私が試したもの:
-Androidがサービスを強制終了するまで正常に機能する通常のサービスを実行する
-AlarmManagerを使用して5分を作成します。サービスへのインターバル呼び出し。しかし、私はこの作品を作ることができませんでした。
常にバックグラウンドで実行されているサービス
あなたが発見したように、これは 不可能 という用語の本当の意味です。また、 悪いデザイン です。
5分ごとサービスはデバイスの現在の場所を確認し、Webサービスを呼び出します
AlarmManager
を使用します。
alarmManagerを使用して5分間行います。サービスへのインターバル呼び出し。しかし、私はこの作品を作ることができませんでした。
ここに サンプルプロジェクト の使用方法と WakefulIntentService
の使用方法が示されているので、Webサービス全体を実行しようとしているときに目を覚ましておくことができます。
引き続き問題が発生する場合は、AlarmManager
であなたが悲しんでいる特定の事柄について、新しい質問を開いてください。
私のアプリの1つは非常に似たようなことをします。一定期間後にサービスを起動するには、postDelayed()
をお勧めします
ハンドラーフィールドがあります。
_private final Handler handler = new Handler();
_
そしてリフレッシャーRunnable
_private final Runnable refresher = new Runnable() {
public void run() {
// some action
}
};
_
実行可能ファイルで通知を起動できます。
サービス構築時、および各実行後に次のように開始します。
_handler.postDelayed(refresher, /* some delay in ms*/);
_
onDestroy()
で投稿を削除
_handler.removeCallbacks(refresher);
_
起動時にサービスを開始するには、自動スターターが必要です。これはマニフェストに入れます
_<receiver Android:name="com.example.ServiceAutoStarter">
<intent-filter>
<action Android:name="Android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
_
ServiceAutoStarter
は次のようになります。
_public class ServiceAutoStarter extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, UpdateService.class));
}
}
_
OSがサービスを強制終了しないようにするのは難しいです。また、アプリケーションでRuntimeException
が発生してクラッシュしたり、ロジックが停止したりする可能性があります。
私の場合、画面上のサービスを常にBroadcastReceiver
で更新すると役立つように思えました。そのため、更新のチェーンが停止した場合、ユーザーが携帯電話を使用すると復活します。
サービス内:
_private BroadcastReceiver screenOnReceiver;
_
サービスでonCreate()
_screenOnReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Some action
}
};
registerReceiver(screenOnReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
_
次に、onDestroy()
でサービスの登録を解除します
_unregisterReceiver(screenOnReceiver);
_
いくつかの簡単な実装でこれを行うことができます。
public class LocationTrace extends Service implements LocationListener{
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
private static final int TWO_MINUTES = 100 * 10;
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 10; // 30 seconds
private Context context;
double latitude;
double longitude;
Location location = null;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
protected LocationManager locationManager;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.context = this;
get_current_location();
// Toast.makeText(context, "Lat"+latitude+"long"+longitude,Toast.LENGTH_SHORT).show();
return START_STICKY;
}
@Override
public void onLocationChanged(Location location) {
if((location != null) && (location.getLatitude() != 0) && (location.getLongitude() != 0)){
latitude = location.getLatitude();
longitude = location.getLongitude();
if (!Utils.getuserid(context).equalsIgnoreCase("")) {
Double[] arr = { location.getLatitude(), location.getLongitude() };
// DO ASYNCTASK
}
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
/*
* Get Current Location
*/
public Location get_current_location(){
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if(!isGPSEnabled && !isNetworkEnabled){
}else{
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
// Toast.makeText(context, "Latgps"+latitude+"long"+longitude,Toast.LENGTH_SHORT).show();
}
}
}
}
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
// Toast.makeText(context, "Latgps1"+latitude+"long"+longitude,Toast.LENGTH_SHORT).show();
}
}
}
}
return location;
}
public double getLatitude() {
if(location != null){
latitude = location.getLatitude();
}
return latitude;
}
public double getLongitude() {
if(location != null){
longitude = location.getLongitude();
}
return longitude;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
if(locationManager != null){
locationManager.removeUpdates(this);
}
super.onDestroy();
}
}
これによりサービスを開始できます:
/*--Start Service--*/
startService(new Intent(Splash.this, LocationTrace.class));
マニフェスト内:
<service Android:name=".LocationTrace">
<intent-filter Android:priority="1000">
<action Android:name="Android.location.PROVIDERS_CHANGED"/>
<category Android:name="Android.intent.category.DEFAULT"/>
</intent-filter>
</service>
これら3つのステップにより、ほとんどのAndroidデバイス:
1。異なるAPIの代替AlarmManagerを設定します:
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(getApplicationContext(), OwnReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0, i, 0);
if (Build.VERSION.SDK_INT >= 23) {
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000 * 60 * 5), pi);
}
else if (Build.VERSION.SDK_INT >= 19) {
am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000 * 60 * 5), pi);
} else {
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000 * 60 * 5), pi);
}
2。独自の静的BroadcastReceiverを構築します:
public static class OwnReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//do all of your jobs here
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, OwnReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
if (Build.VERSION.SDK_INT >= 23) {
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000 * 60 * 5), pi);
}
else if (Build.VERSION.SDK_INT >= 19) {
am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000 * 60 * 5), pi);
} else {
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000 * 60 * 5), pi);
}
}
}
。<receiver>
をAndroidManifest.xml
に追加:
<receiver Android:name=".OwnReceiver" />