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

Android location tracker crashes after a long time

我创建了一个位置跟踪应用程序,每次位置更改时都会写入本地 SQLite 数据库。 不幸的是,该应用程序在跟踪时大约 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

我有一些东西可以帮助您捕获崩溃报告,即使您没有连接到调试器 - 从而帮助您找到问题的根源!我已将此作为答案发布,因此我可以很好地格式化它。

下面的 class 将处理未捕获的异常,将它们打包到电子邮件中并在您的 phone 上放置通知(您可以根据需要进行调整)

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);
    }
}

在您的应用程序 class 中这样设置:

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));

    }

}

我不建议在您的发布版本中包含此代码!届时,您可以使用 Developer Console 获取崩溃报告。