2014-01-29 173 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的「enabled」僅用於實例化服務,導出設置爲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顯示如何使用它,下面有一個很好的生命週期圖。

您需要先撥打startService(),而不是使用bindService()在一個步驟中啓動和綁定服務。然後運行,直到你停止它,即使應用程序關閉。但不要忘了在正確的時間以停止該服務,以避免出現內存問題等

HTH

相關問題