2014-01-29 4 views
6

У меня есть служба, которая отправляет уведомление, когда пользователь меняет свое местоположение. Эта служба работает нормально, но проблема возникает, когда пользователь закрывает приложение, когда служба закрывается.Храните сервис определения местоположения живым, когда приложение закрыто.

Как я могу сделать сервис еще живым, даже если приложение было закрыто?

Мой Сервис:

public class LocationService extends Service implements LocationListener { 
    public final static int MINUTE = 1000 * 60; 


    boolean isGPSEnabled = false; 
    boolean isNetworkEnabled = false; 
    boolean canGetLocation = false; 

    Location location; // location 
    double latitude = 0; // latitude 
    double longitude = 0; // longitude 
    String provider; 

    // The minimum distance to change Updates in meters 
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; 

    // The minimum time between updates in milliseconds 
    private static final long MIN_TIME_BW_UPDATES = 1 * MINUTE; 

    // Declaring a Location Manager 
    protected LocationManager locationManager; 



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

    /** 
    * 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 LocalBinder extends Binder { 
     public LocationService getService() { 
      // Return this instance of LocalService so clients can call public 
      // methods 
      return LocationService.this; 
     } 
    } 

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

    public Location getLocation() { 
     try { 
      locationManager = (LocationManager) getBaseContext().getSystemService(LOCATION_SERVICE); 

      // getting GPS status 
      isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 

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

      if (!isGPSEnabled && !isNetworkEnabled) { 
       // no network provider is enabled. DEFAULT COORDINATES 


      } else { 
       this.canGetLocation = true; 
       if (isNetworkEnabled) { 
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, 
          this); 
        Log.d("Network", "Network Enabled"); 
        if (locationManager != null) { 
         location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
         if (location != null) { 
          latitude = location.getLatitude(); 
          longitude = location.getLongitude(); 
         } 
        } 
       } 
       // if GPS Enabled get lat/long using GPS Services 
       if (isGPSEnabled) { 
        if (location == null) { 
         locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, 
           this); 
         Log.d("GPS", "GPS Enabled"); 
         if (locationManager != null) { 
          location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
          if (location != null) { 
           latitude = location.getLatitude(); 
           longitude = location.getLongitude(); 
          } 
         } 
        } 
       } 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     Log.i("LOCATION", "Latitude: " + latitude + "- Longitude: " + longitude); 


     return location; 
    } 

    @Override 
    public void onLocationChanged(Location arg0) { 

     NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); 
     Intent intent = null; 

     intent = new Intent(this, CompleteSurveyActivity.class); 

     PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 

     NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_launcher).setAutoCancel(true) 
       .setContentIntent(contentIntent).setContentTitle(this.getString(R.string.app_name)).setContentText("text"); 

     // mBuilder.setContentIntent(contentIntent); 
     mNotificationManager.notify((int) System.currentTimeMillis() % Integer.MAX_VALUE, mBuilder.build()); 

     double longitude = location.getLongitude(); 
     double latitude = location.getLatitude(); 

     Log.i("LOCATION", "Latitude: " + latitude + "- Longitude: " + longitude); 

    } 

    @Override 
    public void onProviderDisabled(String arg0) { 
    } 

    @Override 
    public void onProviderEnabled(String arg0) { 
    } 

    @Override 
    public void onStatusChanged(String arg0, int arg1, Bundle arg2) { 
    } 

} 

я назвал здесь:

public class MyActivity extends Activity { 

    LocationService mService; 
    boolean mBound = false; 


    private ServiceConnection mConnection = new ServiceConnection() { 

     @Override 
     public void onServiceConnected(ComponentName className, IBinder service) { 
      // We've bound to LocalService, cast the IBinder and get 
      // LocalService instance 
      LocalBinder binder = (LocalBinder) service; 
      mService = binder.getService(); 
      mBound = true; 

     } 

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

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.my_activity); 

     exampleButton.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       initService(); 
      } 
     }); 

    } 

    public void initService() { 
     if (mBound) 
      mService.getLocation(); 
    } 

    @Override 
    protected void onStart() { 
     super.onStart(); 
     // Bind to LocalService 
     Intent intent = new Intent(this, LocationService.class); 
     bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 
     // Unbind from the service 
     if (mBound) { 
      unbindService(mConnection); 
      mBound = false; 
     } 
    } 
} 

Manifest.xml

<service android:name=".LocationService" android:enabled="true"></service> 
+0

Вы можете предоставить нам новый код неограниченного обслуживания? @sany –

ответ

8

Противно, что сказал @ Свен-menschner, я думаю, что несвязанные Service это именно то, что вам нужно, как и оценка сервисы подвержены связыванию/отмене механизмов, которые убьют вашу службу. Это то, что я хотел бы сделать:

В вашем файле манифеста, определите сервис:

<service 
    android:name=".YourService" 
    android:enabled="true" 
    android:exported="true" 
    android:description="@string/my_service_desc" 
    android:label="@string/my_infinite_service"> 
    <intent-filter> 
    <action android:name="com.yourproject.name.LONGRUNSERVICE" /> 
    </intent-filter> 
</service> 

Примечание: Там список уже реализованных действий, но вы можете определить свои собственные действия для намерения к запуску обслуживание. Просто создайте одноэлементный класс и определите строки, присваивающие им String, которые должны быть уникальными. «Включено», установленное в true, - это просто создать экземпляр службы, а экспортированный набор в true - только в том случае, если вам нужны другие приложения, отправляющие намерения на ваш Service. Если нет, вы можете безопасно установить для последнего значение false.

Следующий шаг должен начинаться с вашей деятельности. Это можно легко сделать с помощью:

public class MainActivity extends Activity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    Intent servIntent = new Intent("com.yourproject.name.LONGRUNSERVICE"); 
    startService(servIntent); 

    ... 
    } 
} 

Последним шагом является определение ваших Service инициализацию. Следите за методом onBind(). Поскольку вы не хотите, чтобы это было связано, просто верните null. Было бы что-то вроде этого:

public class MyService extends Service { 
    @Override 
    public IBinder onBind(Intent intent) { 
    // This won't be a bound service, so simply return null 
    return null; 
    } 

    @Override 
    public void onCreate() { 
    // This will be called when your Service is created for the first time 
    // Just do any operations you need in this method. 
    } 

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

Теперь ваша служба будет работать, даже если вы закроете ваш главный Activity. Осталось всего один шаг: чтобы ваша Service не закончилась, запустите ее как службу переднего плана (сделайте это в своей службе). В основном это создаст значок уведомления в строке состояния. Это не означает, что ваша основная активность тоже работает (поэтому вам не нужна связанная служба), так как «Деятельность и службы» имеют разные жизненные циклы.Чтобы помочь этой службе работать так долго, постарайтесь сохранить свою кучу как можно ниже, чтобы она избегала Android SO, убивающего ее.

Еще одно дополнение: вы не можете проверить, продолжает ли Служба продолжать убивать DVM. Если вы убьете DVM, вы будете убивать все, а тем самым и Службу.

+1

это сработало! спасибо :) – SolArabehety

+0

О нет! Я имел в виду право, но написал не так. Конечно, запущенная (или несвязанная) служба является правильной. Просто испортил приказ в первом предложении ... Однако можно было бы понять, что я намеревался из остальной части моего ответа;) –

2

Существует два вида Android-сервисов: начаты и связаны. Вы ищите последнего. The documentation показывает, как его использовать, приведенная ниже схема жизненного цикла.

Вместо того чтобы начать и привязать услугу за один шаг, используя bindService(), сначала необходимо позвонить startService(). Затем он запускается, пока вы не остановите его, даже если приложение закрыто. Но не забывайте, чтобы остановить службу в нужное время, чтобы избежать проблем с памятью и т.д.

HTH

Смежные вопросы