2017-08-10 106 views
2

我正在編寫一個應用程序來跟蹤Google地圖上的路線歷史記錄。它將每5分鐘獲取設備的當前位置並通過web服務將數據發送到服務器。設備睡眠時BroacastReceiver不工作?

此代碼從MainActivity

manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 

Intent intent = new Intent(getApplicationContext(), AlarmReceiver.class); 
intent.putExtra("USERNAME", mUsername); 
intent.putExtra("DB_NAME", mDBName); 
intent.putExtra("DB_IP", mDBIP); 
intent.putExtra("DB_USER", mDBUsername); 
intent.putExtra("DB_PASS", mDBPassword); 
intent.putExtra("SERVER_IP", mServerIP); 

mAlarmIntent = PendingIntent.getActivity(getApplicationContext(), REQUEST_CODE, intent, 0); 
int mTimeRepeat = 300 * 1000; // repeat every 5 minutes 
int mTimeStart = 5 * 1000; 

manager.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + mTimeStart, mTimeRepeat, mAlarmIntent); 

調用廣播接收器在廣播接收器,我得到的LAT-長,並調用Web服務。

public class AlarmReceiver extends BroadcastReceiver { 
private static final String TAG = "Alarm Receiver"; 

private String mUsername = ""; 
private String mDBName = ""; 
private String mDBIP = ""; 
private String mDBUsername = ""; 
private String mDBPassword = ""; 
private String mServerIP = ""; 

private Context context; 
private static AsyncHttpClient sClient = new AsyncHttpClient(); 

@Override 
public void onReceive(final Context context, Intent intent) { 
    this.context = context; 

    mUsername = intent.getStringExtra("USERNAME"); 
    mDBIP = intent.getStringExtra("DB_IP"); 
    mDBName = intent.getStringExtra("DB_NAME"); 
    mDBUsername = intent.getStringExtra("DB_USER"); 
    mDBPassword = intent.getStringExtra("DB_PASS"); 
    mServerIP = intent.getStringExtra("SERVER_IP"); 

    if (Utility.checkLocationPermission(context)) { 
     try { 
      GPSTracker mGPS = new GPSTracker(context); 
      // check if GPS enabled 
      if (mGPS.canGetLocation()) { 
      double latitude = mGPS.getLatitude(); 
      double longitude = mGPS.getLongitude(); 

      // more code here 

問題是應用程序工作正常,當我讓我的手機保持清醒,如果手機睡覺,它沒有工作。即使手機在睡眠,我也希望發送數據,我該怎麼做?

+0

嘗試使用標誌'AlarmManager.ELAPSED_REALTIME_WAKEUP' –

+0

由於棉花糖,你應該實現你的應用程序,它可以兼容打盹模式。 https://developer.android.com/training/monitoring-device-state/doze-standby.html檢查也https://stackoverflow.com/a/35657522/1196752 – Vektor88

+0

AlarmManager已過時,並不適用於高於21的設備 使用Job scheduler而不是 –

回答

1

爲了實現這個需求更好地使用JobScheduler API。

AlarmManager已過時。

優點使用的jobscheduler的:

  1. 在設備重新啓動你不需要接收OnBootComplete行動,以重新啓動該服務
  2. 暫時當設備電池​​電量低,以避免不良U可以停止服務用戶體驗。
  3. 在後臺同步從設備到服務器的數據的最佳方法。

我測試它工作正常。欲瞭解更多信息,請查看下面的鏈接。

僅供參考,請經過下面的鏈接:

http://www.vogella.com/tutorials/AndroidTaskScheduling/article.html#schedulingtasks

https://developer.android.com/reference/android/app/job/JobScheduler.html

如果有不清楚的地方,請讓我知道將共享工作樣本,讓我知道,如果有幫助。

工作示例如下用途:

public class PollingService extends JobService { 

    @Override 
    public boolean onStartJob(JobParameters params) { 
     Log.d("PollingService", "onStartJob in PollingService is called"); 
     jobFinished(params, false); 
     return false; 
    } 

    @Override 
    public boolean onStopJob(JobParameters params) { 
     Log.d("PollingService", "onStopJob in PollingService is called"); 
     return false; 
    } 
} 

註冊在清單:

<service 
      android:name=".Services.PollingService" 
      android:exported="true" 
      android:permission="android.permission.BIND_JOB_SERVICE" /> 

使用下面的代碼在活動啓動服務:

//put this in oncreate of Activity or from where u want to start 
     JobScheduler mJobScheduler = JobScheduler.getInstance(getApplicationContext()); 

    buidJob(); //Method call 

    //Method 
    private void buidJob() { 
      JobInfo.Builder jobinfo = new JobInfo.Builder(100,new ComponentName(this,PollingService.class)); 
      jobinfo.setPeriodic(50*1000). 
        setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED). 
        setPersisted(true); 
      //build(); 

      mJobScheduler.schedule(jobinfo.build()); 
      Log.d(TAG,"buidJob()"); 
     } 

依賴關係:

compile 'me.tatarka.support:jobscheduler:0.1.1' 

爲了支持上述AAR使用下端版本。如果我們遵循上面提到的鏈接,您可以使用上面的aar來完成。

+0

感謝您的參考鏈接,但它在我的手機睡眠時仍然無法運行。不知道是因爲服務沒有被調用或者我的params數據有什麼問題,我生成了.apk並在我的手機上運行它,所以我無法跟蹤日誌。 – Jacky

+0

使用以上發佈的代碼。經過測試,當設備處於睡眠模式時,它正在工作,它也可以在設備重新啓動時工作。提及的時間是(50 * 1000)在這裏,可以減少測試時間。注意:更好地測試它在未啓動設備becoz我注意到Rooted設備的一些問題。 – Jeelan

+0

我試過你的上面的代碼,但它沒有跳轉到onStartJob。 – Jacky

0

有很多在Android的8.0(O)行爲的變化, 我們都應該承認,關於這裏這些問題>>What's new in Android 8.0 ?

檢查,如果你的目標API等級26或沒有(我想你)
app > build.gradle > targetSdkVersion

如果當時,我認爲你應該檢查此鏈接>>Background location limits

+0

感謝您的回覆,我的targetSdkVersion是25 – Jacky

0

使用WakeLock,A激活鎖定是一種機制,指示您的應用程需要使設備保持開啓狀態。

<uses-permission android:name="android.permission.WAKE_LOCK"/> 

注意:wakelock將只保留onRecieve方法的持續時間。如果你想保持設備的一個長時段中的該library可以幫助

0

使用AlarmManager.ELAPSED_REALTIME_WAKEUP,並利用這些條件設定的報警

if(Build.VERSION.SDK_INT < 23){ 
    if(Build.VERSION.SDK_INT >= 19){ 
     setExact(...); 
    } 
    else{ 
     set(...); 
    } 
} 
else{ 
    setExactAndAllowWhileIdle(...); 
} 

,並在廣播接收器設置一個報警火