2014-07-02 5 views
0

Я программирую игру, в которой используется база данных SQLite для хранения целочисленных значений, представляющих ресурсы, которые пользователь приобрел. У меня есть кнопка изображения, которая при нажатии вызывает службу с использованием обработчика в качестве таймера. Этот таймер добавляет определенное количество ресурсов к общей сумме пользователя в течение установленного периода времени. Проблема в том, что когда я пытаюсь вставить новые данные в базу данных, она не вставлена ​​правильно. Странно то, что мой оригинальный тестовый телефон (работает froyo) отлично вставлял вставки. После переключения на телефон с kitkat он больше не вставляется. Я запустил инструмент sqlite3, и база данных создается правильно, все значения остаются на нуле. Чтение также работает с некоторыми тестами, которые я пробовал. Дайте мне знать, видите ли вы что-то, что мне здесь не хватает, потому что я был в тупике с этой проблемой в течение нескольких недель. Спасибо, парни.Данные не вставляются в базу данных SQLite

Вот код в базу данных, где создается таблица, содержащий одну строку данных:

public class Database 
{ 
public static final String KEY_ROWID = "_id"; 
public static final String KEY_ROCK = "amount_of_rock"; 
public static final String KEY_METEORROCK = "amount_of_meteor_rock"; 
public static final String KEY_WATER = "amount_of_water"; 
public static final String KEY_SHOVEL = "shovel_level"; 
public static final String KEY_SHOVELEXP = "shovel_experience"; 
public static final String KEY_BUCKET = "bucket_level"; 
public static final String KEY_BUCKETEXP = "bucket_experience"; 
public static final String KEY_PICKAXE = "pickaxe_level"; 
public static final String KEY_PICKAXEEXP = "pickaxe_experience"; 
public static final String KEY_POPULATION = "population"; 

private static final String DATABASE_NAME = "2023db"; 
private static final String DATABASE_TABLE = "maintable"; 
private static final int DATABASE_VERSION = 1; 

private DbHelper ourHelper; 
private final Context ourContext; 
private SQLiteDatabase ourDatabase; 

private static class DbHelper extends SQLiteOpenHelper 
{ 

    public DbHelper(Context context) 
    { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION);  
    }//end DbHelper constructor 

    @Override 
    public void onCreate(SQLiteDatabase db) 
    { 
     //create table 
     db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" + 
      KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + 
      KEY_ROCK + " INTEGER, " + 
      KEY_METEORROCK + " INTEGER, " + 
      KEY_WATER + " INTEGER, " + 
      KEY_POPULATION + " INTEGER, " + 
      KEY_SHOVEL + " INTEGER, " + 
      KEY_BUCKET + " INTEGER, " + 
      KEY_PICKAXE + " INTEGER, " + 
      KEY_SHOVELEXP + " INTEGER, " + 
      KEY_BUCKETEXP + " INTEGER, " + 
      KEY_PICKAXEEXP + " INTEGER);"); 
    }//end onCreate function 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    { 
     db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE); 
     onCreate(db); 
    }//end onUpgrade function 
}//end DbHelper class 

public Database(Context c) 
{ 
    ourContext = c; 
}//end Database constructor 

public Database open() { 
    ourHelper = new DbHelper(ourContext); 
    ourDatabase = ourHelper.getWritableDatabase(); 
    return this; 
}//end Database open function 

public void close() { 
    ourHelper.close(); 
}//end close function 

public long rockAmountEntry(int rockAmount) { 
    ContentValues cv = new ContentValues(); 
    cv.put(KEY_ROCK, rockAmount); 
    return ourDatabase.update(DATABASE_TABLE, cv, null, null); 
}//end rockAmountEntry function 

public int getRockAmount() { 
    int rockAmount = 0, iRockAmount = 0; 
    String[] columns = new String[] {KEY_ROWID, KEY_ROCK, KEY_METEORROCK, 
     KEY_WATER, KEY_POPULATION, KEY_SHOVEL, KEY_BUCKET, KEY_PICKAXE, 
     KEY_SHOVELEXP, KEY_BUCKETEXP, KEY_PICKAXEEXP 
    }; 
    Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null); 

    if (c != null && c.getCount() > 0) { 
     if (c.moveToFirst()) { 
      iRockAmount = c.getColumnIndex(KEY_ROCK); 
      rockAmount = c.getInt(iRockAmount); 
     }//end if 
     c.close(); 
     return rockAmount; 
    }//end if 
    return 0; 
}//end getRockAmount function 
}//end Database 

Пользователь дается ImageButton, которые они могут нажать, чтобы получить ресурсы. Когда он нажимается, он вызывает службу, которая запускает обработчик в качестве таймера и добавляет определенное количество камней в базу данных в зависимости от уровня пользователя.

Вот код ImageButton как упоминалось:

spaceRock1 = (ImageButton) findViewById(R.id.spaceRockButton1); 
spaceRock1.setOnClickListener(new OnClickListener() 
{ 
    @Override 
    public void onClick(View v) 
    { 
     Toast.makeText(getApplicationContext(), "Attempting to Gain Resources", Toast.LENGTH_SHORT).show(); 

     //button cannot be clicked 
     spaceRock1.setEnabled(false); 

     //start service for timer 
     startService(new Intent(runGraphics.this, SetupTimerSR1.class)); 

     //stop service for timer 
     stopService(new Intent(runGraphics.this, SetupTimerSR1.class)); 

     //button can be clicked again 
     mMessageReceiver3 = new BroadcastReceiver() 
     { 
      @Override 
      public void onReceive(Context context, Intent intent) 
      { 
       clickOnOff3 = intent.getBooleanExtra("spaceRock1Stat", false); 
       spaceRock1.setEnabled(clickOnOff3); 
       if (clickOnOff3) 
       { 
        updateScores(); 
       }//end if 
      }//end onReceive function 
     }; 
     LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(mMessageReceiver3, new IntentFilter("spaceRock1Status")); 

    }//end onClick function 
});//end setOnClickListener 

Вот код службы вызывается при ImageButton нажатии:

public class SetupTimerSR1 extends Service { 
Handler handler; 
Database data; 
Intent i; 
int pickLevel = 1, pickExpTotal = 0; 
int rockAmount = 0, pickExp = 0, totalRock = 0; 
int timerCount = 0; 
@Override 
public IBinder onBind(Intent intent) { 
    return null; 
}//end onBind function 

@Override 
public void onCreate() { 
    super.onCreate(); 

    //setup 24 hour timer 
    handler = new Handler(Looper.getMainLooper()); 
    handler.postDelayed(runnable, 5000); 
}//end onCreate function 

private Runnable runnable = new Runnable() { 
    public void run() { 
     //check experience for current level 
     if (pickExp < 3000) { 
      pickLevel = 1; 
     }//end if 
     else if (pickExp > 3000 && pickExp < 6000) { 
      pickLevel = 2; 
     }//end else if 
     else if (pickExp > 6000 && pickExp < 9000) { 
      pickLevel = 3; 
     }//end else if 
     else if (pickExp > 9000 && pickExp < 12000) { 
      pickLevel = 4; 
     }//end else if 
     else if (pickExp > 12000) { 
      pickLevel = 5; 
     }//end else if 

     //give resource based on level 
     if (pickLevel == 1) { 
      rockAmount += 1; 
      pickExp += 10; 
     }//end if 
     else if (pickLevel == 2) { 
      rockAmount += 3; 
      pickExp += 20; 
     }//end else if 
     else if (pickLevel == 3) { 
      rockAmount += 4; 
      pickExp += 30; 
     }//end else if 
     else if (pickLevel == 4) { 
      rockAmount += 5; 
      pickExp += 40; 
     }//end else if 
     else if (pickLevel == 5) { 
      rockAmount += 7; 
      pickExp += 50; 
     }//end else if 
     timerCount++; 
     if (timerCount < 3) { 
      handler.postDelayed(runnable, 5000); 
     }//end if 
     else { 
      //pull data 
      data = new Database(SetupTimerSR1.this); 
      data.open(); 
      pickExpTotal = data.getPickExp(); 
      totalRock = data.getRockAmount(); 
      data.close(); 

      //add new data to old 
      pickExpTotal += pickExp; 
      totalRock += rockAmount; 

      //push data 
      data.open(); 
      data.pickExpEntry(pickExpTotal); 
      data.rockAmountEntry(totalRock); 
      data.close(); 

      Toast.makeText(getApplicationContext(), "pickExp: " + pickExpTotal, Toast.LENGTH_SHORT).show(); 
      Toast.makeText(getApplicationContext(), "Total rock: " + totalRock, Toast.LENGTH_SHORT).show(); 
      i.putExtra("spaceRock1Stat", true); 

      LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(i); 
      handler.removeCallbacks(runnable); 
     }//end else 
    }//end run function 
};//end runnable  

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    i = new Intent("spaceRock1Status"); 
    i.putExtra("spaceRock1Stat", false); 

    LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(i); 
    return Service.START_NOT_STICKY; 
}//end onStartCommand function 
}//end SetupTimerSR1 class 
+0

Убедитесь, что rockAmountEntry() является одновременно получать аргумент, что вы ожидаете его получит, и что он возвращает правильное значение, которое можно было бы ожидать , – JDJ

+0

В вашем коде нет места, где он вставляет новые данные в базу данных. –

+0

@JDJ rockAmountEntry получает правильную сумму, но значение в возвращаемой базе данных равно нулю. – sboehnke

ответ

1

Метод update может изменить только те строки, которые уже существуют в таблице. Однако приложение never вставляет любую строку в таблицу.

Строка должна быть добавлена, когда база данных созданы:

public void onCreate(SQLiteDatabase db) 
{ 
    db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" + 
     ...); 
    db.execSQL("INSERT INTO " + DATABASE_TABLE + " DEFAULT VALUES"); 
} 
+0

Это сработало отлично. Большое спасибо. Интересно, почему он работал во Фройо без этого заявления. – sboehnke

Смежные вопросы