2013-05-01 10 views
2

Je reçois base de données est une erreur verrouillé dans SqlLite Android. Y a-t-il quelque chose qui ne va pas dans mon code? J'ai essayé divers trucs trouvés à partir d'ici, même essayé de mettre le fil de sommeil après l'appel de la requête, mais pas d'utilisation. Je reçois toujours une erreur de verrouillage de la base de données. Quelqu'un peut-il dire pourquoi je reçois cela? et que dois-je faire pour résoudre cette erreur?base de données SQLite Android

classe 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 feux trop rapidement bloquant toujours d'autres transactions à votre base de données – JRowan

+0

@JRowan, mon mauvais .. Je collais code erroné. Juste le code mis à jour à nouveau. J'utilise DELAY_UI pour un capteur qui est relativement lent. Mais encore je reçois problème de verrouillage de la base de données. –

+0

encore accéléromètre déclenche la foudre rapidement chaque fois qu'il utilise votre base de données – JRowan

Répondre

2

Essayez déclarant un ReentrantLock dans votre assistant de base de données et verrouiller et déverrouiller partout vous accédez à votre base de données. Cela devrait permettre aux threads d'attendre la disponibilité de la base de données et d'éviter une panne/erreur. par exemple. Dans Helper Base de données:

public static Lock l = new ReentrantLock(false); 

Partout où vous accédez à la base de données:

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

Cependant, comme mentionné précédemment, si vous essayez d'écrire dans la base de données plusieurs fois par seconde que votre édition de base de données peut réellement vous MANQUANT se retrouver avec un long retard dans les écritures de base de données. Ma suggestion serait d'utiliser une fonction d'horodatage à chaque fois que le déclencheur de l'écriture de votre base de données se produira et passera l'écriture dans la base de données sauf par exemple une demi-seconde depuis que vous avez écrit ces informations dans la base de données.

+0

quelqu'un at-il essayé cette solution et a travaillé avec lui? –

0

En supposant que vous recevez de nouveaux onSensorData plus souvent que le temps qu'il faut pour stocker des données dans la DB que vous aurez besoin soit d'accélérer db écrit d'une manière ou d'éviter des événements. Voici quelques pensées sur le dessus de ma tête. En ce qui concerne l'accélération des écritures db, vous pouvez probablement supposer que le fournisseur de localisation ne change pas entre chaque événement et si vous pensez à ce qui est susceptible de changer et à quelle fréquence vous pouvez stocker certaines choses comme variables membres plutôt que de les récupérer. temps.

Une façon de sauter des événements est une liste de rotation. onSensorData ajoute un nouvel événement à la liste de fin et s'il est au-dessus d'une certaine longueur, il supprime le premier élément (le plus ancien). L'éditeur db (éventuellement un thread) lit depuis le début de la liste et écrit l'élément le plus ancien. Si vous utilisez des threads pour cela, vous aurez besoin d'un peu de synchronisation, pour réduire la synchronisation, vous pouvez lire les événements par lots au lieu d'un seul à la fois.

Ou vous pouvez combiner les deux méthodes.

+0

je ne vous ai pas eu.Pourriez-vous s'il vous plaît me donner quelque chose avec un exemple ou me dire quelque chose dans mon code? –