在Android屏幕上方向更改SQL中重绘折线

时间:2015-12-30 19:40:34

标签: java android sql android-studio orientation

我不确定这里有什么问题,但是当你通过位置数据移动时,这个应用程序会跟踪你的路线。我想弄清楚的是为什么当我的屏幕方向改变而跟踪线条消失并停止跟踪时。我的想法是,我可以将我的路由存储在onSavedInstanceState中的SQL中,并在屏幕方向更改时将其恢复到onRestoreInstanceState中。它出于某种原因无法正常工作。

变量和onCreate(MainActivity)

private static final long INTERVAL = 1000;
private static final long FASTEST_INTERVAL = 1000;
private static final long SMALLEST_DISPLACEMENT = 1;
private LocationRequest mLocationRequest;
private Location mCurrentLocation;
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
public GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
public static final String TAG = MapsActivity.class.getSimpleName();
public Polyline line;
public static ArrayList<LatLng> Points;
public DatabaseHelper database = new DatabaseHelper(this);

protected void createLocationRequest(){
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(INTERVAL);
    mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
    mLocationRequest.setSmallestDisplacement(SMALLEST_DISPLACEMENT);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
    createLocationRequest();

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

在跟踪和绘制线条时存储LatLng点。

public Boolean isTracking = false;

public void startNewRoute(View view) {
    Points = new ArrayList<>();
    isTracking = true;
}

@Override
public void onLocationChanged(Location location) {
    mCurrentLocation = location;
    double lat = location.getLatitude();
    double lng = location.getLongitude();
    LatLng latLng = new LatLng(lat, lng);

    if (isTracking){
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 18));
        Points.add(latLng);
        drawLine();
    }
}
public void drawLine(){
    PolylineOptions options = new PolylineOptions()
            .width(5)
            .color(Color.BLUE)
            .geodesic(true);

    for(int a = 0; a < Points.size(); a++){
        LatLng point = Points.get(a);
        double lat = point.latitude;
        double lng = point.longitude;
        Log.d(TAG, "Drawline point got: Lat: "+lat+", Lng: "+lng);
        options.add(point);
        line = mMap.addPolyline(options);
    }
}

在onSaveInstanceState中将ArrayList中的点保存到数据库中。

    protected void onSaveInstanceState(Bundle savedInstanceState){
    String routeID = "SavedInstance";
    for (int a = 0; a < Points.size(); a++) {
        LatLng point = Points.get(a);
        double lat = point.latitude;
        double lng = point.longitude;
        database.insertSaveInstancePoints(routeID, lat, lng);
        Log.d(TAG, "Point inserted, RID: " + routeID + ", Lat: " + lat + " Lng: " + lng);
    }
    super.onSaveInstanceState(savedInstanceState);
}

这是来自SQL数据库的insertSavedInstancePoints()。 (DatabaseHelper)

    public void insertSaveInstancePoints(String routeID, double lat, double lng){
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues cv = new ContentValues();
    cv.put(colSavedID, routeID);
    cv.put(colSavedLat, lat);
    cv.put(colSavedLng, lng);
    db.insert(savedInstanceTable, null, cv);
    db.close();
}

然后最后恢复实例状态。 (MainActivity)

 protected void onRestoreInstanceState(Bundle savedInstanceState){
    super.onRestoreInstanceState(savedInstanceState);
    Points = new ArrayList<>();
    database.getSavedPoints();
    drawLine();
}

getSavedPoints()(DatabaseHelper)

 public void getSavedPoints(){
    map = new MapsActivity();
    Log.d(TAG, "getSavedPoints called!");
    String query = "SELECT "+colSavedID+", "+colSavedLat+", "+colSavedLng+" FROM "+savedInstanceTable;
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor c = db.rawQuery(query, null);
    c.moveToFirst();
    for(int a = 0; a < c.getCount(); a++) {
        double lat = c.getDouble(c.getColumnIndex(colSavedLat));
        double lng = c.getDouble(c.getColumnIndex(colSavedLng));
        LatLng latLng = new LatLng(lat, lng);
        map.addToPointsArray(latLng);
        c.moveToNext();
    }
    deleteSavedTableData();
    c.close();
    db.close();
}

向数组添加点(MainActivity)

 public void addToPointsArray(LatLng latLng){
    Points.add(latLng);
    Log.d(TAG, "Point Added to Array from DB! " + latLng);
}

现在,当跟踪时屏幕方向发生变化时,它会崩溃并且logcat会说:

 12-30 11:29:18.035 29721-29721/com.example.jared.backtrack D/MapsActivity:      Drawline point got: Lat: 47.510955, Lng: -122.1862465
 12-30 11:29:18.045 29721-29721/com.example.jared.backtrack D/MapsActivity: Drawline point got: Lat: 47.5108991, Lng: -122.186089
 12-30 11:29:18.045 29721-29721/com.example.jared.backtrack D/MapsActivity: Drawline point got: Lat: 47.5109001, Lng: -122.1861128
 12-30 11:29:18.055 29721-29721/com.example.jared.backtrack D/MapsActivity: Drawline point got: Lat: 47.5109044, Lng: -122.1861483
 12-30 11:29:20.085 29721-29721/com.example.jared.backtrack D/MapsActivity: Drawline point got: Lat: 47.510955, Lng: -122.1862465
 12-30 11:29:20.085 29721-29721/com.example.jared.backtrack D/MapsActivity: Drawline point got: Lat: 47.5108991, Lng: -122.186089
 12-30 11:29:20.085 29721-29721/com.example.jared.backtrack D/MapsActivity: Drawline point got: Lat: 47.5109001, Lng: -122.1861128
 12-30 11:29:20.085 29721-29721/com.example.jared.backtrack D/MapsActivity: Drawline point got: Lat: 47.5109044, Lng: -122.1861483
 12-30 11:29:20.095 29721-29721/com.example.jared.backtrack D/MapsActivity: Drawline point got: Lat: 47.5109081, Lng: -122.1861328
 12-30 11:29:22.225 29721-29721/com.example.jared.backtrack D/MapsActivity: Point inserted, RID: SavedInstance, Lat: 47.510955 Lng: -122.1862465
 12-30 11:29:22.235 29721-29721/com.example.jared.backtrack D/MapsActivity: Point inserted, RID: SavedInstance, Lat: 47.5108991 Lng: -122.186089
 12-30 11:29:22.265 29721-29721/com.example.jared.backtrack D/MapsActivity: Point inserted, RID: SavedInstance, Lat: 47.5109001 Lng: -122.1861128
 12-30 11:29:22.295 29721-29721/com.example.jared.backtrack D/MapsActivity: Point inserted, RID: SavedInstance, Lat: 47.5109044 Lng: -122.1861483
 12-30 11:29:22.305 29721-29721/com.example.jared.backtrack D/MapsActivity: Point inserted, RID: SavedInstance, Lat: 47.5109081 Lng: -122.1861328
 12-30 11:29:22.405 29721-29721/com.example.jared.backtrack I/Google Maps Android API: Google Play services package version: 8489038
 12-30 11:29:22.455 29721-29721/com.example.jared.backtrack D/DatabaseHelper: getSavedPoints called!
 12-30 11:29:22.465 29721-29721/com.example.jared.backtrack D/MapsActivity: Point Added to Array from DB! lat/lng: (47.510955,-122.1862465)
 12-30 11:29:22.465 29721-29721/com.example.jared.backtrack D/MapsActivity: Point Added to Array from DB! lat/lng: (47.5108991,-122.186089)
 12-30 11:29:22.475 29721-29721/com.example.jared.backtrack D/MapsActivity: Point Added to Array from DB! lat/lng: (47.5109001,-122.1861128)
 12-30 11:29:22.475 29721-29721/com.example.jared.backtrack D/MapsActivity: Point Added to Array from DB! lat/lng: (47.5109044,-122.1861483)
 12-30 11:29:22.475 29721-29721/com.example.jared.backtrack D/MapsActivity: Point Added to Array from DB! lat/lng: (47.5109081,-122.1861328)
 12-30 11:29:22.505 29721-29721/com.example.jared.backtrack D/MapsActivity: Drawline point got: Lat: 47.510955, Lng: -122.1862465
 12-30 11:29:22.505 29721-29721/com.example.jared.backtrack D/AndroidRuntime: Shutting down VM
 12-30 11:29:22.505 29721-29721/com.example.jared.backtrack W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x41e92d88)
 12-30 11:29:22.515 29721-29721/com.example.jared.backtrack E/AndroidRuntime: FATAL EXCEPTION: main

因此,您可以从我的调试日志中看到它正在跟踪路线,正在绘制线条。当屏幕旋转时,点成功加载到SQl然后检索。一旦它启动drawline方法,它会尝试绘制第一个点,崩溃并且它表示nullpointer异常。

任何想法?

2 个答案:

答案 0 :(得分:2)

您正在#getSavedPoints中实例化一个新的MapsActivity(这是您在我的问题中调用MainActivity的原因吗?)并在该实例上设置数据。该实例不是系统在轮换时重新创建后在屏幕上显示的内容。

相反,make #getSavedPoints返回点的ArrayList,并将其设置为活动中的Points字段。

public List<LatLng> getSavedPoints(){
  List<LatLng> points = new ArrayList();
  Log.d(TAG, "getSavedPoints called!");
  String query = "SELECT "+colSavedID+", "+colSavedLat+", "+colSavedLng+" FROM "+savedInstanceTable;
  SQLiteDatabase db = this.getReadableDatabase();
  Cursor c = db.rawQuery(query, null);
  c.moveToFirst();
  for(int a = 0; a < c.getCount(); a++) {
    double lat = c.getDouble(c.getColumnIndex(colSavedLat));
    double lng = c.getDouble(c.getColumnIndex(colSavedLng));
    LatLng latLng = new LatLng(lat, lng);
    points.add(latLng);
    c.moveToNext();
  }
  deleteSavedTableData();
  c.close();
  db.close();
  return points;
}

在onRestoreInstanceState

protected void onRestoreInstanceState(Bundle savedInstanceState){
  super.onRestoreInstanceState(savedInstanceState);
  Points = database.getSavedPoints();
  drawLine();
}

此外,您无需使用数据库即可完成此操作。如果你的LatLng类只是两个双精度类,那么让它实现Parcelable然后你就可以在onSaveInstanceState / onRestoreInstanceState中放入/检索bundle中的Points对象。有一些实现Parcelable的设置,但它应该很容易理解。

以上只是一个建议,如果你没有注意到使用数据库的性能瓶颈,那么只需坚持工作。

答案 1 :(得分:0)

感谢@BG_NE,我们发现问题是我的mMap GoogleMap对象在onRestoreInstanceState()期间没有被初始化,所以drawLine()方法指向null,因为没有地图。

因此,解决方案是将drawRine()从onRestoreInstanceState()移动到onMapReady()并传递一个布尔值来检查是否正在恢复某些内容。

以下是代码:

protected void onRestoreInstanceState(Bundle savedInstanceState){
    super.onRestoreInstanceState(savedInstanceState);

/////Set restorePoints to true.
    restorePoints = true;           
    Points = database.getSavedPoints();
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    mMap.setMyLocationEnabled(true);
    mMap.getUiSettings().setZoomControlsEnabled(true);
    mMap.getUiSettings().setAllGesturesEnabled(true);

///// Here I draw the line during onMapReady();
    if(restorePoints){
        drawLine();
        restorePoints = false;
    }
}