2013-05-01 128 views
2

我正在接收數據庫鎖定sqllite android中的錯誤。我的代碼中有什麼問題嗎?我嘗試了從這裏找到的各種東西,甚至在我打電話查詢後試圖把線程睡眠,但沒有用。我仍然收到數據庫鎖定錯誤。任何人都可以告訴我爲什麼得到那個?我該怎麼做才能解決這個錯誤?數據庫鎖定錯誤sqlite android

MainActivity類別:

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.GooglePlayServicesUtil; 
import com.google.android.gms.maps.CameraUpdateFactory; 
import com.google.android.gms.maps.GoogleMap; 

import com.google.android.gms.maps.model.BitmapDescriptorFactory; 
import com.google.android.gms.maps.model.LatLng; 
import com.google.android.gms.maps.model.MarkerOptions; 
import com.google.gson.Gson; 

public class MapViewActivity extends Activity implements LocationListener, 
     SensorEventListener, OnClickListener { 

    GoogleMap googleMap; 

    private boolean started = false; 
    private ArrayList<AccelLocData> sensorData; 
    private SensorManager sensorManager; 
    private Button btnStart, btnStop; 
    private String provider; 

    // File root, dir, sensorFile; 
    FileOutputStream fOut; 
    private Sensor mAccelerometer; 
    private FileWriter writer; 
    private DatabaseHelper databaseHelper; 
    private BroadcastReceiver alarmReceiver; 
    private PendingIntent pendingIntentSender, pendingIntentReceiver; 

    private AlarmManager alarmManager; 
    private Intent alarmIntent,alarmIntent2; 

    // private Button btnUpload; 

    @SuppressLint("NewApi") 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     try { 

      databaseHelper = new DatabaseHelper(this); 
      databaseHelper.removeAll(); 


      Log.v("datacount", 
        Integer.toString(databaseHelper.getLocDataCount())); 

      sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 
      mAccelerometer = sensorManager 
        .getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 

      btnStart = (Button) findViewById(R.id.btnStart); 
      btnStop = (Button) findViewById(R.id.btnStop); 
      btnStart.setOnClickListener(this); 
      btnStop.setOnClickListener(this); 
      btnStart.setEnabled(true); 
      btnStop.setEnabled(false); 

      alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); 

      int status = GooglePlayServicesUtil 
        .isGooglePlayServicesAvailable(getBaseContext()); 
      if (status != ConnectionResult.SUCCESS) { // Google Play Services 
                 // are 
                 // not available 

       int requestCode = 10; 
       Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, 
         this, requestCode); 
       dialog.show(); 

      } else { // Google Play Services are available 

       // Getting reference to the SupportMapFragment of 
       // activity_main.xml 
       // SupportMapFragment supportMapFragment = (MapFragment) 
       // getFragmentManager().findFragmentById(R.id.map); 

       // Getting GoogleMap object from the fragment 
       googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap(); 


       // can use for overlay on the map 
       List<Double> latList = new ArrayList<Double>(); 
       latList.add(145.7309593); 
       latList.add(146.34); 
       latList.add(147.34); 

       List<Double> lonList = new ArrayList<Double>(); 
       lonList.add(-122.6365384); 
       lonList.add(-123.6365384); 
       lonList.add(-124.6365384); 

       for (int i = 0; i < 3; i++) { 
        // LatLng latLng = new LatLng(45.7309593, -122.6365384); 
        LatLng latLng = new LatLng(latList.get(i).doubleValue(), 
          lonList.get(i).doubleValue()); 
        googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 
        googleMap 
          .addMarker(new MarkerOptions() 
            .position(latLng) 
            .title("My Spot") 
            .snippet("This is my spot!") 
            .icon(BitmapDescriptorFactory 
              .defaultMarker(BitmapDescriptorFactory.HUE_AZURE))); 
       } 

       // Enabling MyLocation Layer of Google Map 
       googleMap.setMyLocationEnabled(true); 

       LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); 

       Criteria criteria = new Criteria(); 
       provider = locationManager.getBestProvider(criteria, true); 
       Location location = locationManager 
         .getLastKnownLocation(provider); 

       if (location != null) { 
        onLocationChanged(location); 
       } 

       locationManager 
         .requestLocationUpdates(provider, 20000, 0, this); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 

    public void onSensorChanged(SensorEvent event) { 

     if (started) { 

      double x = event.values[0]; 
      double y = event.values[1]; 
      double z = event.values[2]; 

      long timestamp = System.currentTimeMillis(); 

      LocationManager locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
      Criteria criteria = new Criteria(); 
      criteria.setPowerRequirement(Criteria.POWER_MEDIUM); 
      criteria.setAccuracy(Criteria.ACCURACY_FINE); 

      provider = locManager.getBestProvider(criteria, true); 
      Location location = locManager.getLastKnownLocation(provider); 

      double latitude = 0; 
      double longitude = 0; 
      if (location != null) { 
       latitude = location.getLatitude(); 
       longitude = location.getLongitude(); 
      } 
      AccelLocData accelLocData = new AccelLocData(timestamp, x, y, z, 
        latitude, longitude); 

      // Log.d("X data","data x:" + data.getX()); 

      try { 
       // writer.write(data.toString()); 
       if (databaseHelper != null) 
       databaseHelper.insertLocData(accelLocData); 
      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

     } 
    } 

    @Override 
    public void onLocationChanged(Location location) { 

     TextView tvLocation = (TextView) findViewById(R.id.tv_location); 

     // Getting latitude of the current location 
     double latitude = location.getLatitude(); 

     // Getting longitude of the current location 
     double longitude = location.getLongitude(); 

     // Creating a LatLng object for the current location 
     LatLng latLng = new LatLng(latitude, longitude); 

     // Showing the current location in Google Map 
     googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); 

     // Zoom in the Google Map 
     googleMap.animateCamera(CameraUpdateFactory.zoomTo(15)); 






    } 

    @Override 
    public void onClick(View v) { 
     switch (v.getId()) { 
     case R.id.btnStart: 

      Context context = getApplicationContext(); 
      alarmIntent = new Intent(context, AccelLocSender.class); 

      AlarmManager alarmManager = (AlarmManager) context 
        .getSystemService(Context.ALARM_SERVICE); 
      pendingIntentSender = PendingIntent.getBroadcast(context, 0, 
        alarmIntent, 0); 

      alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 
        System.currentTimeMillis(), 60000, pendingIntentSender); 

      alarmIntent2 = new Intent(context, AccelLocReceiver.class); 
      pendingIntentReceiver = PendingIntent.getBroadcast(context, 0, 
        alarmIntent2, 0); 
      alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 
        System.currentTimeMillis(), 30000, pendingIntentReceiver); 

      btnStart.setEnabled(false); 
      btnStop.setEnabled(true); 
      Log.d("startbutton", "cam on click of start"); 
      started = true; 

      // delete all files.. 
      // start thread to send data 

      sensorManager.registerListener(this, mAccelerometer, 
        SensorManager.SENSOR_DELAY_UI); 
      break; 
     case R.id.btnStop: 
      try { 
       btnStart.setEnabled(true); 
       btnStop.setEnabled(false); 
       // btnUpload.setEnabled(true); 
       started = false; 

       sensorManager.unregisterListener(this); 

       Context context1 = getApplicationContext(); 
       AlarmManager alarmManager1 = (AlarmManager) context1 
         .getSystemService(Context.ALARM_SERVICE); 
       alarmManager1.cancel(pendingIntentSender); 
       alarmManager1.cancel(pendingIntentReceiver); 

      // System.exit(0); 

       } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      break; 
     default: 
      break; 
     } 

    } 

    protected void onPause() { 
     super.onPause(); 

     /* 
     * if (writer != null) { try { writer.close(); } catch (IOException e) { 
     * // TODO Auto-generated catch block e.printStackTrace(); } } 
     */ 
    } 

    protected void onResume() { 
     super.onResume(); 
     /* 
     * try { Log.d("onresume","called onresume"); writer = new 
     * FileWriter(sensorFile, true); } catch (IOException e) { // TODO 
     * Auto-generated catch block e.printStackTrace(); } 
     */ 
    } 

    @Override 
    public void onProviderDisabled(String arg0) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onProviderEnabled(String provider) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onAccuracyChanged(Sensor arg0, int arg1) { 
     // TODO Auto-generated method stub 

    } 

} 

AccelLocSender.java

public class AccelLocSender extends BroadcastReceiver { 

    private DatabaseHelper databaseHelper; 
    private static int indexValue=1; 

    @Override 
    public void onReceive(Context context, Intent arg1) { 
     // TODO Auto-generated method stub 

     System.out.println("cmg in AccelLocsender"); 
     Log.i("Alarm sender", "Came in alarm sender"); 

     databaseHelper = new DatabaseHelper(context); 

     sendDataToServer(); 

    } 

    private void sendDataToServer() { 

     try { 


      int locDataCount = databaseHelper.getLocDataCount(); 

      List<AccelLocData> accelLocDataList = databaseHelper.getAllDataById(indexValue); 
      Thread.sleep(3000); 
      databaseHelper.deleteLocDataById(indexValue); 
      Thread.sleep(3000); 
      indexValue += 50; 

      HttpClient httpClient = new DefaultHttpClient(); 
      HttpPost httpPost = new HttpPost("*****"); 

      List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); 
      Log.d("datacount", Integer.toString(locDataCount)); 
      nameValuePairs.add(new BasicNameValuePair("datacount", Integer 
        .toString(locDataCount))); 
      for (int i = 0; i < accelLocDataList.size(); i++) { 

       nameValuePairs 
         .add(new BasicNameValuePair("latitude" + i, 
           Double.toString(accelLocDataList.get(i) 
             .getLatitude()))); 
       nameValuePairs 
         .add(new BasicNameValuePair("longitude" + i, Double 
           .toString(accelLocDataList.get(i) 
             .getLongitude()))); 
       nameValuePairs.add(new BasicNameValuePair("accelX" + i, Double 
         .toString(accelLocDataList.get(i).getX()))); 
       nameValuePairs.add(new BasicNameValuePair("accelY" + i, Double 
         .toString(accelLocDataList.get(i).getY()))); 
       nameValuePairs.add(new BasicNameValuePair("accelZ" + i, Double 
         .toString(accelLocDataList.get(i).getZ()))); 
       nameValuePairs 
         .add(new BasicNameValuePair("timeStamp" + i, Double 
           .toString(accelLocDataList.get(i) 
             .getTimeStamp()))); 

      } 

      httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 
      httpClient.execute(httpPost); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 

} 

DatabaseHelper.java

public class DatabaseHelper extends SQLiteOpenHelper { 

    private static final String DB_NAME = "myapp.db"; 
    static String TABLE_NAME = "AccelLocation"; 

    private static final String KEY_ID = "id"; 
    private static final String LATITUDE_VAL = "latitude"; 
    private static final String LONGITUDE_VAL = "longitude"; 
    private static final String ACCEL_X = "accelX"; 
    private static final String ACCEL_Y = "accelY"; 
    private static final String ACCEL_Z = "accelZ"; 
    private static final String CUR_TIME = "dataTime"; 

    public DatabaseHelper(Context context) { 
     super(context, DB_NAME, null, 3); 
    } 

    SQLiteDatabase db; 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     System.out.println("cmg in database helper"); 
     String CREATE_TABLE_SQL = "create table if not exists " + TABLE_NAME 
       + " (" + KEY_ID + " integer primary key autoincrement," 
       + LATITUDE_VAL + " TEXT," + LONGITUDE_VAL + " TEXT," + ACCEL_X 
       + " TEXT," + ACCEL_Y + " TEXT," + ACCEL_Z + " TEXT," + CUR_TIME 
       + " TEXT" + ")"; 
     Log.d("createquery", CREATE_TABLE_SQL); 
     System.out.println("Create query :" + CREATE_TABLE_SQL); 
     // db.execSQL("DROP TABLE IF EXISTS"+TABLE_NAME); 

     db.execSQL(CREATE_TABLE_SQL); 
    // db.close(); 
    } 

    public void insertLocData(AccelLocData accelLocData) { 

     if(db == null) 
     { 
      db = this.getWritableDatabase(); 
     } 

     ContentValues values = new ContentValues(); 
     values.put(LATITUDE_VAL, accelLocData.getLatitude()); 
     values.put(LONGITUDE_VAL, accelLocData.getLongitude()); 
     values.put(ACCEL_X, accelLocData.getX()); 
     values.put(ACCEL_Y, accelLocData.getY()); 
     values.put(ACCEL_Z, accelLocData.getZ()); 
     values.put(CUR_TIME, accelLocData.getTimeStamp()); 

     // Inserting Row 
     db.insert(TABLE_NAME, null, values); 
    // db.close(); // Closing database connection 

    } 

    public void dropTable(){ 
     if(db == null){ 
      db = this.getWritableDatabase(); 
     } 

     db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); 
    } 
    public List<AccelLocData> getAllData() { 

     Cursor cursor = null; 

     List<AccelLocData> accelLocDataList = new ArrayList<AccelLocData>(); 
     //SQLiteDatabase db = null; 
     // Select All Query 
     try { 

      String selectQuery = "SELECT * FROM " + TABLE_NAME; 
      if(db == null){ 
       db = this.getWritableDatabase(); 
      } 

      cursor = db.rawQuery(selectQuery, null); 

      // looping through all rows and adding to list 
      if (cursor.moveToFirst()) { 
       do { 
        AccelLocData accelLocData = new AccelLocData(
          Integer.parseInt(cursor.getString(0)), 
          Long.parseLong(cursor.getString(6)), 
          Double.parseDouble(cursor.getString(3)), 
          Double.parseDouble(cursor.getString(4)), 
          Double.parseDouble(cursor.getString(5)), 
          Double.parseDouble(cursor.getString(1)), 
          Double.parseDouble(cursor.getString(2))); 
        accelLocDataList.add(accelLocData); 
       } while (cursor.moveToNext()); 
      } 

     } catch (Exception e) { 
      Log.e("DatabasegetallData", e.toString()); 
     } finally { 
      if(cursor!= null) 
      cursor.close(); 

    //  if(db!=null) 
    //  db.close(); 


     } 

     // return accelLocData list 
     return accelLocDataList; 

    } 

    public List<AccelLocData> getAllDataById(int indexValue) { 

     Cursor cursor = null; 

     List<AccelLocData> accelLocDataList = new ArrayList<AccelLocData>(); 
    // SQLiteDatabase db = null; 
     // Select All Query 
     try { 
      String selectQuery = "SELECT * FROM " + TABLE_NAME + " where "+ KEY_ID + " < "+ indexValue; 

      if(db == null){ 
       db = this.getWritableDatabase(); 
      } 
      cursor = db.rawQuery(selectQuery, null); 

      // looping through all rows and adding to list 
      if (cursor.moveToFirst()) { 
       do { 
        AccelLocData accelLocData = new AccelLocData(
          Integer.parseInt(cursor.getString(0)), 
          Long.parseLong(cursor.getString(6)), 
          Double.parseDouble(cursor.getString(3)), 
          Double.parseDouble(cursor.getString(4)), 
          Double.parseDouble(cursor.getString(5)), 
          Double.parseDouble(cursor.getString(1)), 
          Double.parseDouble(cursor.getString(2))); 
        accelLocDataList.add(accelLocData); 
       } while (cursor.moveToNext()); 
      } 

     } catch (Exception e) { 
      Log.e("DatabasegetallData", e.toString()); 
     } finally { 
      if(cursor!= null) 
      cursor.close(); 

     // if(db!=null) 
     // db.close(); 


     } 

     // return accelLocData list 
     return accelLocDataList; 

    } 

    // Deleting single accelLocData 
    public void deleteLocData(AccelLocData accelLocData) { 
     if(db == null){ 
      db = this.getWritableDatabase(); 
     } 

     db.delete(TABLE_NAME, KEY_ID + " = ?", 
       new String[] { String.valueOf(accelLocData.getId()) }); 
    // db.close(); 
    } 

    public void deleteLocDataById(int indexValue) { 
     if(db == null){ 
      db = this.getWritableDatabase(); 
     } 
     db.delete(TABLE_NAME, KEY_ID + " < ?", 
       new String[] { String.valueOf(indexValue) }); 

    // if(db != null) 
    // db.close(); 
    } 

    // Getting contacts Count 
    public int getLocDataCount() { 
     String countQuery = "SELECT * FROM " + TABLE_NAME; 
     if (db == null){ 
      db = this.getReadableDatabase(); 
     } 
     Cursor cursor = db.rawQuery(countQuery, null); 
     int noOfRows = cursor.getCount(); 
     cursor.close(); 
    // db.close(); 
     return noOfRows; 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) { 
     // TODO Auto-generated method stub 

    } 

    public void removeAll() { 

     if(db == null) 
     db = this.getWritableDatabase(); // helper is object 
                 // extends 
                 // SQLiteOpenHelper 
     db.delete(DatabaseHelper.TABLE_NAME, null, null); 
    // db.close(); 

    } 

} 
+0

onSensorChanged的方式太快,總是阻止其他交易到您的數據庫 – JRowan 2013-05-01 09:41:40

+0

@JRowan,我的壞..我粘貼錯誤的代碼。只是再次更新代碼。我使用的DELAY_UI傳感器相對較慢。但仍然有數據庫鎖定問題。 – 2013-05-01 09:47:47

+0

仍然accellerometer閃電每次使用您的數據庫閃電 – JRowan 2013-05-01 09:52:40

回答

2

嘗試在數據庫幫助程序中聲明一個reentrantlock,並在您訪問數據庫的任何地方鎖定和解鎖。這應該允許線程等待數據庫可用性並避免崩潰/錯誤。 例如在數據庫助手:

public static Lock l = new ReentrantLock(false); 

舉目訪問數據庫:

l.lock(); 
    try 
    { 
      //do database editing 
    } 
    finally 
    { 
      l.unlock(); 
    } 

但是如前面提到的,如果你試圖寫入數據庫每秒更多的時間比你的數據庫編輯實際上可以完成你會結束了數據庫寫入的長時間積壓。我的建議是在每次觸發數據庫寫入操作時使用時間戳比較,並跳過寫入數據庫的操作,除非自上次將該信息寫入數據庫以來,例如半秒。

+0

做過任何一個嘗試此解決方案並與他一起工作? – 2015-10-11 11:25:06

0

假設你收到新onSensorData往往需要將數據存儲在時間你需要以某種方式加速數據庫寫入或跳過事件。這是我頭頂的一些想法。

關於加快數據庫寫入,您可能可以假設位置提供程序在每個事件之間不會發生變化,並且您可能會考慮可能會發生什麼變化以及將某些內容作爲成員變量存儲的頻率,而不是每次都檢索它們時間。

跳過事件的一種方式是旋轉列表。 onSensorData將新事件添加到結束列表中,並且如果它超過特定長度,它將刪除第一個(最早的)元素。數據庫寫入器(可能是一個線程)從列表的開頭讀取並寫入當前最早的元素。如果你爲此使用線程,它需要一點同步,爲了減少同步,你可以批量讀取事件,而不是一次一個。

或者你可以結合這兩種方法。

+0

我沒有得到你。你能否給我一些例子或告訴我一些我的代碼? – 2013-05-01 10:14:04