SQliteデータベースを使用してAndroidアプリを作成しようとしていますが、テーブル「clientes」にクエリを実行しようとすると、RuntimeExceptionが表示されます。私は多くのことを試みました、私は多くの解決策を見つけました、しかしどれもうまくいきません。
メインクラス:
public class AndroidBaseDatos extends Activity {
private TextView texto;
private String nombre;
private DBHelper BD;
/**Array donde guardamos los nuevos dispositivos encontrados**/
private ArrayAdapter<String> query;
private ListView queryResult;
UsuariosSQLiteHelper usdbh =
new UsuariosSQLiteHelper(this, "DBUsuarios", null, 1);
SQLiteDatabase db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_android_base_datos);
texto = (TextView) findViewById(R.id.textView1);
queryResult = (ListView) findViewById(R.id.listView1);
BD=new DBHelper(this);
BD.open();
}
public void onStart() {
super.onStart();
//Base de datos database
String[] campos = new String[] {"nombre", "apellidos", "edad"};
String[] args = new String[] {"2"};
db=usdbh.getReadableDatabase();
Cursor c = db.query("clientes", campos, "_id=?", args, null, null, null);
//Cursor c = db.query("Usuarios", campos, null, null, null, null, null);
// Inicializa el array
query = new ArrayAdapter<String>(this, R.layout.nombre_dispositivo);
// Establece el Listview para los dispositivos nuevos
//Nos aseguramos de que existe al menos un registro
if (c.moveToFirst()) {
//Recorremos el cursor hasta que no haya más registros
do {
nombre = c.getString(0);
String apellidos = c.getString(1);
int edad = Integer.parseInt(c.getString(2));
Log.d("obteniendo datos", nombre);
query.add(nombre);
query.add(apellidos);
query.add(String.valueOf(edad));
//String email = c.getString(1);
} while(c.moveToNext());
}
texto.setText(nombre);
queryResult.setAdapter(query);
db.close();
}
およびSQLiteOpenHelperを拡張するクラス
public class DBHelper extends SQLiteOpenHelper {
// Ruta por defecto de las bases de datos en el sistema Android
private static String DB_PATH = "/data/data/com.example.bbdd/databases/";
private static String DB_NAME = "database.db";
private SQLiteDatabase myDataBase;
private final Context myContext;
// Array de strings para su uso en los diferentes métodos
/**
* Constructor Toma referencia hacia el contexto de la aplicación que lo
* invoca para poder acceder a los 'assets' y 'resources' de la aplicación.
* Crea un objeto DBOpenHelper que nos permitirá controlar la apertura de la
* base de datos.
*
* @param context
*/
public DBHelper(Context context) {
super(context, DB_NAME, null, 1);
myContext = context;
myDataBase = this.getReadableDatabase();
}
/**
* Crea una base de datos vacía en el sistema y la reescribe con nuestro
* fichero de base de datos.
* */
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
SQLiteDatabase db_Read = null;
if (dbExist) {
// la base de datos existe y no hacemos nada.
Log.i("creando base de datos", "Ya existe");
//copyDataBase();
} else {
// Llamando a este método se crea la base de datos vacía en la ruta
// por defecto del sistema
// de nuestra aplicación por lo que podremos sobreescribirla con
// nuestra base de datos.
db_Read = this.getReadableDatabase();
db_Read.close();
Log.i("creando base de datos", "Creando la base de datos");
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copiando Base de Datos");
}
}
}
/**
* Comprueba si la base de datos existe para evitar copiar siempre el
* fichero cada vez que se abra la aplicación.
*
* @return true si existe, false si no existe
*/
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
// si llegamos aqui es porque la base de datos no existe todavía.
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Copia nuestra base de datos desde la carpeta assets a la recién creada
* base de datos en la carpeta de sistema, desde dónde podremos acceder a
* ella. Esto se hace con bytestream.
* */
private void copyDataBase() throws IOException {
Log.i("copiando base de datos", "Copiando...");
// Abrimos el fichero de base de datos como entrada
InputStream myInput = myContext.getAssets().open(DB_NAME);
Log.i("copiando base de datos", myContext.getAssets().open(DB_NAME).toString());
// Ruta a la base de datos vacía recién creada
String outFileName = DB_PATH + DB_NAME;
Log.i("copiando base de datos", DB_PATH + DB_NAME);
// Abrimos la base de datos vacía como salida
OutputStream myOutput = new FileOutputStream(outFileName);
// Transferimos los bytes desde el fichero de entrada al de salida
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
// Liberamos los streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public void open() throws SQLException {
// Abre la base de datos
try {
createDataBase();
} catch (IOException e) {
throw new Error("Ha sido imposible crear la Base de Datos");
}
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
}
@Override
public synchronized void close() {
if (myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
}
public void crearTabla(){
String sqlCreate = "CREATE TABLE clientes (_id INTEGER, nombre TEXT, apellidos TEXT, edad INTEGER)";
myDataBase.execSQL(sqlCreate);
myDataBase.execSQL("INSERT INTO clientes (_id, nombre, apellidos, edad) " +
"VALUES (2, 'Alberto', 'Redondo', 27)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
これがデバッグ情報です。
> 02-23 02:18:25.072: E/Trace(4081): error opening trace file: No such file or directory (2)
02-23 02:18:26.370: I/creando base de datos(4081): Ya existe
02-23 02:18:26.410: E/SQLiteLog(4081): (1) no such table: clientes
02-23 02:18:26.410: D/AndroidRuntime(4081): Shutting down VM
02-23 02:18:26.421: W/dalvikvm(4081): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
02-23 02:18:26.450: E/AndroidRuntime(4081): FATAL EXCEPTION: main
02-23 02:18:26.450: E/AndroidRuntime(4081): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.bbdd/com.example.bbdd.AndroidBaseDatos}: android.database.sqlite.SQLiteException: no such table: clientes (code 1): , while compiling: SELECT nombre, apellidos, edad FROM clientes WHERE _id=?
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.app.ActivityThread.access$600(ActivityThread.java:130)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.os.Handler.dispatchMessage(Handler.java:99)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.os.Looper.loop(Looper.java:137)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.app.ActivityThread.main(ActivityThread.java:4745)
02-23 02:18:26.450: E/AndroidRuntime(4081): at java.lang.reflect.Method.invokeNative(Native Method)
02-23 02:18:26.450: E/AndroidRuntime(4081): at java.lang.reflect.Method.invoke(Method.java:511)
02-23 02:18:26.450: E/AndroidRuntime(4081): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
02-23 02:18:26.450: E/AndroidRuntime(4081): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
02-23 02:18:26.450: E/AndroidRuntime(4081): at dalvik.system.NativeStart.main(Native Method)
02-23 02:18:26.450: E/AndroidRuntime(4081): Caused by: android.database.sqlite.SQLiteException: no such table: clientes (code 1): , while compiling: SELECT nombre, apellidos, edad FROM clientes WHERE _id=?
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:882)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:493)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1161)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1032)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1200)
02-23 02:18:26.450: E/AndroidRuntime(4081): at com.example.bbdd.AndroidBaseDatos.onStart(AndroidBaseDatos.java:90)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1163)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.app.Activity.performStart(Activity.java:5018)
02-23 02:18:26.450: E/AndroidRuntime(4081): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2032)
02-23 02:18:26.450: E/AndroidRuntime(4081): ... 11 more
02-23 02:23:26.573: I/Process(4081): Sending signal. PID: 4081 SIG: 9
テーブルはdbファイル名データベースにあり、シェルで開くと、テーブルクライアントが作成されます。もう一度作成しようとすると、前に確認したように、テーブルがすでに存在することを示すSQLExceptionが表示されますが、できません。任意のデータベースの任意のテーブルに対して行われたクエリを表示します。
ありがとうございました。