2015-09-22 146 views
1

我創建了一個位置跟蹤應用程序,每次更改位置時都會寫入本地SQLite數據庫。 該應用不幸在跟蹤時約7-8小時後崩潰,不幸的是,當我將設備連接到調試器時不會發生這種情況,所以沒有我可以附加的日誌。 一些更多的可能有用的信息:Android位置跟蹤器在很長一段時間後崩潰

  • 該應用程序將其從後臺喚醒之前崩潰(可以看出,顯然是在跟蹤的數據),所以我可以從其他應用程序
  • 試圖寫入排除這個bug到TEXTFILES,而不是沒有任何成功的數據庫(剛跑崩潰前約3小時)
  • 更改追蹤間隔(5S正常最快1秒間隔):同樣的結果的應用程序崩潰也7-8小時

這裏有後一些代碼片段:

位置變化事件

@Override 
public void onLocationChanged(Location location) { 
    if(location == null){ 
     location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
     if(location == null) { 
      return; 
     } 
    } 
    Log.d(TAG, location.toString()); 
    double currentLatitude = location.getLatitude(); 
    double currentLongitude = location.getLongitude(); 
    ActivitylogRepo activityRepo = new ActivitylogRepo(this); 
    Activitylog activity = new Activitylog(); 
    activity.activity = "Position"; 
    activity.timestamp = getDateTime(); 
    activity.value2 = String.valueOf(currentLatitude); 
    activity.value3 = String.valueOf(currentLongitude); 
    activityRepo.insert(activity); 
} 

數據庫插入命令

public int insert(Activitylog activitylog) { 

    //Open connection to write data 
    SQLiteDatabase db = dbHelper.getWritableDatabase(); 
    ContentValues values = new ContentValues(); 
    values.put(Activitylog.KEY_activity, activitylog.activity); 
    values.put(Activitylog.KEY_timestamp, activitylog.timestamp); 
    values.put(Activitylog.KEY_value1, activitylog.value1); 
    values.put(Activitylog.KEY_value2, activitylog.value2); 
    values.put(Activitylog.KEY_value3, activitylog.value3); 
    values.put(Activitylog.KEY_value4, activitylog.value4); 


    // Inserting Row 
    long activitylog_id = db.insert(Activitylog.TABLE, null, values); 
    db.close(); // Closing database connection 
    return (int) activitylog_id; 
} 

初始化服務

mGoogleApiClient = new GoogleApiClient.Builder(this) 
      .addConnectionCallbacks(this) 
      .addOnConnectionFailedListener(this) 
      .addApi(LocationServices.API) 
      .build(); 
    mGoogleApiClient.connect(); 

    mLocationRequest = LocationRequest.create() 
      .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) 
      .setInterval(20 * 1000)  // 20s in ms 
      .setFastestInterval(5 * 1000); // 5s in ms 
+0

可以請您發佈崩潰日誌? –

+0

正如我上面提到的那樣,在使用調試器時從未出現錯誤,我忘了補充說,連接到Android Studio時也不會發生。 –

回答

1

我含有S即使你沒有連接到調試器,它也能幫助你捕捉崩潰報告 - 從而幫助你找到問題的根源!我已經發布了這個答案,所以我可以很好地格式化它。

類下面將處理捕獲的異常,它們包裝成一個電子郵件,將通知您的手機上(你可以調整這個爲任何你需要的)

public class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { 

    private Context mContext; 

    private java.lang.Thread.UncaughtExceptionHandler mDefaultUEH; 

    public UncaughtExceptionHandler(Context context, java.lang.Thread.UncaughtExceptionHandler defaultUEH) { 
     mContext = context; 
     mDefaultUEH = defaultUEH; 
    } 

    @Override 
    public void uncaughtException(Thread thread, Throwable ex) { 

     // Make error into something more readable 
     String timestamp = android.text.format.DateFormat.getLongDateFormat(mContext).format(
       new Date(System.currentTimeMillis())); 
     final Writer result = new StringWriter(); 
     final PrintWriter printWriter = new PrintWriter(result); 
     ex.printStackTrace(printWriter); 
     String stacktrace = result.toString(); 
     printWriter.close(); 

     // Create email intent for error 
     Intent emailIntent = new Intent(Intent.ACTION_SEND); 
     emailIntent.setType("text/html"); 
     emailIntent.putExtra(Intent.EXTRA_EMAIL, "email address"); 
     emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Crash Report " + timestamp); 
     emailIntent.putExtra(Intent.EXTRA_TEXT, stacktrace); 

     // Make into pending intent for notifcation 

     PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, 
       Intent.createChooser(emailIntent, "Send report with.."), 
       Intent.FLAG_ACTIVITY_NEW_TASK); 

     // here create a notification for the user 
     NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext); 
     builder.setContentTitle("Crash Caught"); 
     builder.setContentText("Send to Developer"); 
     builder.setContentIntent(pendingIntent); 
     builder.setAutoCancel(true); 
     builder.setSmallIcon(R.drawable.ic_notification); 

     // Finally display the notification! 
     NotificationManager mNotificationManager = (NotificationManager) mContext 
       .getSystemService(Context.NOTIFICATION_SERVICE); 
     mNotificationManager.notify(1337, builder.build()); 

     // re-throw critical exception further to the os (important) 
     mDefaultUEH.uncaughtException(thread, ex); 
    } 
} 

在喜歡你的應用程序類此設置這個:

public class App extends Application { 

    @Override 
    public void onCreate() { 
    super.onCreate(); 

    /* 
    * Set up uncaught exception handler 
    */ 

    java.lang.Thread.UncaughtExceptionHandler defaultUEH = 
    Thread.getDefaultUncaughtExceptionHandler(); 
    Thread.setDefaultUncaughtExceptionHandler(new 
    UncaughtExceptionHandler(this, defaultUEH)); 

    } 

} 

我不建議在你的發佈版本中包含這段代碼!此時,您可以使用開發者控制檯獲取崩潰報告。

+0

感謝那至今我會嘗試一下,不幸的是它會花費大約8小時才能獲得新的結果。 –

+0

我知道這很令人沮喪,但是如果沒有撞機報告,你就會盲目失明!我們明天會在這裏;-) – JoeyJubb

+1

對不起,我沒有更新任何信息,但我真的想在我再次發佈之前測試所有內容。您的解決方案幫助我找到解決問題的方案。這只是一個簡單的NullPointerException,它拋出了我在後臺線程中創建的JSONObject。目前該應用程序幾乎24小時運行,沒有任何問題。非常感謝你的解決方案,它絕對有幫助,並且也將幫助我未來的發展。 –