Android位置跟踪器在很长一段时间后崩溃

问题描述:

我创建了一个位置跟踪应用程序,每次更改位置时都会写入本地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时也不会发生。 –

我含有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小时运行,没有任何问题。非常感谢你的解决方案,它绝对有帮助,并且也将帮助我未来的发展。 –