1

私はLocationAfterサービスを持っていたいので、MainActivityから照会する必要があります。私は、サーバーに場所を送信し、それに基づいて通知を送信するために、アプリケーションが閉じられたときにバックグラウンドで実行する必要があるサービス理由が必要です。また、私はバインドされたサービスがサーバーのような振る舞いをし、クライアントのような活動をすることを読んだことがあります。このサービスが必要とするタスクに最適なサービスを開始する必要はありません。どのタイプのサービスが私のニーズを満たすことができますか?Android:アプリケーションが終了しても実行できるAndroidサービスはありますか?また、バインドされたサービス(一定の相互作用)のようにも動作しますか?

答えて

1

START_STICKYは、メモリに十分なメモリがある場合にOSにサービスを再作成し、ヌルインテントでもう一度onStartCommand()を呼び出すように指示します。 START_NOT_STICKYは、OSにサービスの再作成を邪魔しないように指示します。

あなたはアプリを閉じたときに発射へのサービスを使用するか、タスクから殺すことができます。

public class App_killed extends Service { 

@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    Log.d("ClearFromRecentService", "Service Started"); 
    return START_STICKY; 
} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    Log.d("ClearFromRecentService", "Service Destroyed"); 
} 

public void onTaskRemoved(Intent rootIntent) { 
    Log.e("ClearFromRecentService", "END"); 
    //here you can call a background network request to post you location to server when app is killed 
    Toast.makeText(getApplicationContext(), "Warning: App killed", Toast.LENGTH_LONG).show(); 
    stopSelf(); //call this method to stop the service 
} 
} 

はmenifest

<service 
     android:name="com.empiregroup.amarridebiker.App_killed" 
     android:stopWithTask="false" /> 

にこのサービスをあなたのサービスをdelcareアプリはなっても実行し続けますまた、バインダークラスを使用して、任意のアクティビティでサービスクラスのインスタンスを取得することもできます。

完全なソースコード:

public class GPSTracker extends Service { 

private static Context mContext; 
// flag for GPS status 
boolean isGPSEnabled = false; 
// flag for network status 
boolean isNetworkEnabled = false; 
// flag for GPS status 
boolean canGetLocation = false; 
protected LocationManager locationManager; 
static String latitude_s, longitude_s; 
Thread triggerService; 
private final IBinder mBinder = new MyBinder(); 

public GPSTracker() { 
    super(); 
} 


public GPSTracker(Context context) { 
    mContext = context; 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    //Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); 
    Log.i(LOG, "Service started"); 
    if (intent != null) { 
     addLocationListener(); 
    } 
    return START_STICKY; 
} 

private void addLocationListener() { 
    triggerService = new Thread(new Runnable() { 
     public void run() { 
      try { 
       Looper.prepare();//Initialise the current thread as a looper. 
       locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); 

       //Criteria c = new Criteria(); 
       //c.setAccuracy(Criteria.ACCURACY_COARSE); 

       //final String PROVIDER = locationManager.getBestProvider(c, true); 

       MyLocationListener myLocationListener = new MyLocationListener(); 
       if (checkLocationPermission()) { 
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 0, myLocationListener); 
       } 
       Log.d("LOC_SERVICE", "Service RUNNING!"); 
       Looper.loop(); 
      } catch (Exception ex) { 
       ex.printStackTrace(); 
      } 
     } 
    }, "LocationThread"); 
    triggerService.start(); 
} 

public static void updateLocation(Location location) { 
    Context appCtx = Global_variable.getAppContext(); 

    double latitude, longitude; 

    latitude = location.getLatitude(); 
    longitude = location.getLongitude(); 
    try { 
     latitude_s = Double.toString(latitude); 
     longitude_s = Double.toString(longitude); 
    } catch (Exception e) { 

    } 
    Intent filterRes = new Intent(); 
    filterRes.setAction("mypackage.action.LOCATION"); 
    filterRes.putExtra("latitude", latitude); 
    filterRes.putExtra("longitude", longitude); 
    filterRes.putExtra("id", id); 
    appCtx.sendBroadcast(filterRes); 
} 


class MyLocationListener implements LocationListener { 

    @Override 
    public void onLocationChanged(Location location) { 
     updateLocation(location); 
    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 

    } 

    @Override 
    public void onProviderEnabled(String provider) { 

    } 

    @Override 
    public void onProviderDisabled(String provider) { 

    } 
} 


public boolean checkLocationPermission() { 
    String permission = "android.permission.ACCESS_FINE_LOCATION"; 
    int res = mContext.checkCallingOrSelfPermission(permission); 
    return (res == PackageManager.PERMISSION_GRANTED); 
} 


@Override 
public void onCreate() { 
    super.onCreate(); 
    Log.d(LOG, "Service created"); 
} 


@Override 
public void onDestroy() { 
    super.onDestroy(); 
    Log.d(LOG, "Service destroyed"); 
} 


/** 
* Function to check GPS/wifi enabled 
* 
* @return boolean 
*/ 
public boolean canGetLocation() { 
    locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); 
    // getting GPS status 
    isGPSEnabled = locationManager 
      .isProviderEnabled(LocationManager.GPS_PROVIDER); 

    // getting network status 
    isNetworkEnabled = locationManager 
      .isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

    if (!isGPSEnabled && !isNetworkEnabled) { 
     // location service disabled 
     canGetLocation = false; 
    } else { 
     canGetLocation = true; 
    } 
    return canGetLocation; 
} 

/** 
* Function to show settings alert dialog 
* On pressing Settings button will lauch Settings Options 
*/ 
public void showSettingsAlert() { 
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext); 
    // Setting Dialog Title 
    alertDialog.setTitle("GPS is settings"); 
    // Setting Dialog Message 
    alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?"); 
    // On pressing Settings button 
    alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int which) { 
      Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
      mContext.startActivity(intent); 
     } 
    }); 

    // on pressing cancel button 
    alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int which) { 
      dialog.cancel(); 
     } 
    }); 

    // Showing Alert Message 
    alertDialog.show(); 
} 

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

public class MyBinder extends Binder { 
    GPSTracker getService() { 
     return GPSTracker.this; 
    } 
} 

public String getLatitude_s() { 
    return latitude_s; 
} 

public String getLongitude_s() { 
    return longitude_s; 
} 

}

サービスから位置を取得し、それをサーバーに送るための放送受信機クラス。マニフェストファイル内

public class LocationReceiver extends BroadcastReceiver { 

double latitude, longitude; 

@Override 
public void onReceive(final Context context, final Intent calledIntent) 
{ 
    Log.d("LOC_RECEIVER", "Location RECEIVED!"); 

    latitude = calledIntent.getDoubleExtra("latitude", -1); 
    longitude = calledIntent.getDoubleExtra("longitude", -1); 

    updateRemote(latitude, longitude,biker_id); 

} 

private void updateRemote(final double latitude, final double longitude ,final String id) 
{ 
    //HERE YOU CAN PUT YOUR ASYNCTASK TO UPDATE THE LOCATION ON YOUR SERVER 
    String latitude_s=Double.toString(latitude); 
    String longitude_s=Double.toString(longitude); 
    new SendToServer().execute(longitude_s, latitude_s,id); 
} 

サービスと受信機

<service 
     android:name="com.yourpackage.GPSTracker" 
     android:enabled="true" 
     android:label="GPS Data"></service> 

    <service 
     android:name="com.yourpackage.App_killed" 
     android:stopWithTask="false" /> 

    <receiver 
     android:name="com.yourpackage.LocationReceiver" 
     android:enabled="true"> 
     <intent-filter> 
      <action android:name="mypackage.action.LOCATION" /> 
     </intent-filter> 
    </receiver> 
を追加する活動にサービスを開始

GPSTracker gps; 
    gps = new GPSTracker(this); 
     // check if GPS enabled 
     if (gps.canGetLocation()) { 
      startService(new Intent(getApplicationContext(), GPSTracker.class)); 
      } else { 
      gps.showSettingsAlert(); 
     } 
+0

が、これは容易なオプションです?。それはバインドされたサービスでなければならないのですか、それとも開始されたサービスですか?場所を取得するコードはどこに置くのですか?他のクラスからそれを消費する方法を知るための完全な例がありますか? – Juan

+0

Ok ....私はあなたがonBindを実装する必要があることを読んでいます。これは、開始されたサービスとして使用されることを意図しています。いいですか...それでも、私はこのサービスを別のクラスからどのように消費しますか? – Juan

+0

この場合、START_NOT_STICKYではなくSTART_STICKYにする必要がありますか?ああ、私はそれがないので、アプリが殺されたときにSOがプロセスを殺すべきではないと言っているからxmlでそれのための必要はない粘着性のないだと思うが、実際にその仕事ですか?メモリがなくなり、プロセスが終了するとどうなりますか?not_stickyで再作成されません – Juan

関連する問題