我将已创建的 .db 文件复制/粘贴到我的 android studio 项目中,但它使我的应用程序崩溃。该数据库文件在另一个 android studio 项目上工作正常,但它给出了异常并导致应用程序在我当前的项目上崩溃。以下是logcat
2022-05-26 19:42:18.147 21758-21758/com.learning.kidslearningzone E/TAG: setAppAdId:BeforeChange::::: ca-app-pub-3940256099942544~3347511713
2022-05-26 19:42:18.147 21758-21758/com.learning.kidslearningzone E/TAG: setAppAdId:AfterChange:::: ca-app-pub-3940256099942544~3347511713
2022-05-26 19:42:30.180 21758-21758/com.learning.kidslearningzone E/SQLiteLog: (1) no such table: kids in "SELECT * FROM kids WHERE id=2"
2022-05-26 19:42:30.183 21758-21758/com.learning.kidslearningzone E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.learning.kidslearningzone, PID: 21758
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.learning.kidslearningzone/com.learning.kidslearningzone.Courses.ListVideoActivity}: android.database.sqlite.SQLiteException: no such table: kids (code 1 SQLITE_ERROR[1]): , while compiling: SELECT * FROM kids WHERE id=2
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3835)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4011)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2325)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8633)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Caused by: android.database.sqlite.SQLiteException: no such table: kids (code 1 SQLITE_ERROR[1]): , while compiling: SELECT * FROM kids WHERE id=2
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1463)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:901)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:590)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:62)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:2063)
at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:2002)
at com.learning.kidslearningzone.Databases.DatabaseHelper.getVideoDetails(DatabaseHelper.kt:20)
at com.learning.kidslearningzone.Courses.ListVideoActivity.setRvVideoListAdapter(ListVideoActivity.java:60)
at com.learning.kidslearningzone.Courses.ListVideoActivity.initDefine(ListVideoActivity.java:49)
at com.learning.kidslearningzone.Courses.ListVideoActivity.onCreate(ListVideoActivity.java:39)
at android.app.Activity.performCreate(Activity.java:8207)
at android.app.Activity.performCreate(Activity.java:8191)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3808)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4011)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2325)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8633)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
请有人告诉我问题是什么或者我做错了什么。谢谢
每个项目都有自己的数据库,可能是 Room 或 Sqlite,一旦您构建项目,数据库将在本地创建,因此它对于项目来说是唯一的,您需要手动添加元素。你所做的就是将该文件带到另一个项目中,并且你编写的查询非常SUS,因为你当前的项目数据库没有任何 id:2 条目,因此它失败了。
您不能只是将数据库剪切并粘贴到项目中。对于这样一个预先存在的数据库,您通常会将数据库复制并粘贴到资产文件夹中,然后使用扩展 SQLiteOpenHelper 的改编自定义类(来自堆栈跟踪
Databases.DatabaseHelper
)。
除了通常的实现之外,这个改编的自定义类还必须具有以下代码:-
如果数据库不存在(如果没有异常停止应用程序)或者数据库已损坏,则将创建数据库WITHOUT除了 sqlite_master 表和 android_metadata 表之外的任何内容,从用户/开发人员的角度来看,非常有效,一个空数据库,因此找不到表。
我怀疑这就是正在发生的事情。
但是,如果捕获/捕获异常并允许继续处理,则可能会发生这种情况。是当
SQLiteDatabase
的 getWritableDatabase
或 getReadableDatabase
用于更高版本的 Android 时,WAL(预写日志记录是默认值)。简而言之,这会创建一个 -wal 文件,该文件不属于方法创建的原始数据库文件所拥有,因为该数据库文件已被从资产复制的数据库文件覆盖。使用过于友好的 openOrCreate
方法会看到损坏的数据库,并为您提供一个没有任何表的新数据库。
建议您遇到的问题是以上之一。虽然有点过头了这可能有用。
am getting an error in this whole code can anyone please help me out with this
//bookappointment
package com.example.clinicalmanagement;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.Spinner;
import android.widget.TimePicker;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class BookAppointmentActivity extends AppCompatActivity {
Spinner spinnerDoctor;
DatePicker datePicker;
TimePicker timePicker;
Button bookAppointmentButton;
DatabaseHelper databaseHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book_appointment);
databaseHelper = new DatabaseHelper(this);
spinnerDoctor = findViewById(R.id.spinnerDoctor);
datePicker = findViewById(R.id.datePicker);
timePicker = findViewById(R.id.timePicker);
bookAppointmentButton = findViewById(R.id.buttonBookAppointment);
// Populate spinner with doctor names
List<String> doctorNames = new ArrayList<>();
doctorNames.add("Dr. John Doe");
doctorNames.add("Dr. Jane Smith");
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, doctorNames);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerDoctor.setAdapter(adapter);
spinnerDoctor.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
// Handle doctor selection
}
@Override
public void onNothingSelected(AdapterView<?> parentView) {
// Do nothing
}
});
bookAppointmentButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String doctorName = spinnerDoctor.getSelectedItem().toString();
// Get selected date and time
int day = datePicker.getDayOfMonth();
int month = datePicker.getMonth() + 1;
int year = datePicker.getYear();
int hour = timePicker.getCurrentHour();
int minute = timePicker.getCurrentMinute();
// Store appointment details in database
long result = databaseHelper.insertAppointment(doctorName, day, month, year, hour, minute);
String res = String.valueOf(result);
if (result != -1) {
Toast.makeText(BookAppointmentActivity.this, "Appointment booked successfully", Toast.LENGTH_SHORT).show();
finish();
} else {
Toast.makeText(BookAppointmentActivity.this, "Error number is "+res, Toast.LENGTH_SHORT).show();
}
}
});
}
}
//dbhelper
package com.example.clinicalmanagement;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "clinical_management.db";
private static final int DATABASE_VERSION = 1;
// Table names and columns
private static final String TABLE_USERS = "users";
private static final String COLUMN_USER_ID = "id";
private static final String COLUMN_USERNAME = "username";
private static final String COLUMN_PASSWORD = "password";
private static final String TABLE_APPOINTMENTS = "appointments";
private static final String COLUMN_APPOINTMENT_ID = "id";
private static final String COLUMN_DOCTOR_NAME = "doctor_name";
private static final String COLUMN_DAY = "day";
private static final String COLUMN_MONTH = "month";
private static final String COLUMN_YEAR = "year";
private static final String COLUMN_HOUR = "hour";
private static final String COLUMN_MINUTE = "minute";
// Create table statement for appointments
private static final String CREATE_TABLE_APPOINTMENTS = "CREATE TABLE " + TABLE_APPOINTMENTS + "("
+ COLUMN_APPOINTMENT_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_DOCTOR_NAME + " TEXT,"
+ COLUMN_DAY + " INTEGER,"
+ COLUMN_MONTH + " INTEGER,"
+ COLUMN_YEAR + " INTEGER,"
+ COLUMN_HOUR + " INTEGER,"
+ COLUMN_MINUTE + " INTEGER" + ")";
private static final String CREATE_TABLE_USERS = "CREATE TABLE " + TABLE_USERS + "("
+ COLUMN_USER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_USERNAME + " TEXT,"
+ COLUMN_PASSWORD + " TEXT" + ")";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// Create tables
db.execSQL(CREATE_TABLE_USERS);
db.execSQL(CREATE_TABLE_APPOINTMENTS);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Upgrade database (if needed)
}
// Insert user into the database
public long insertUser(String username, String password) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_USERNAME, username);
values.put(COLUMN_PASSWORD, password);
long id = db.insert(TABLE_USERS, null, values);
db.close();
return id;
}
// Check if user exists in the database
public boolean checkUser(String username, String password) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_USERS,
new String[]{COLUMN_USER_ID},
COLUMN_USERNAME + " = ? AND " + COLUMN_PASSWORD + " = ?",
new String[]{username, password},
null, null, null);
boolean exists = cursor.getCount() > 0;
cursor.close();
db.close();
return exists;
}
// Insert appointment into the database
public long insertAppointment(String doctorName, int day, int month, int year, int hour, int minute) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_DOCTOR_NAME, doctorName);
values.put(COLUMN_DAY, day);
values.put(COLUMN_MONTH, month);
values.put(COLUMN_YEAR, year);
values.put(COLUMN_HOUR, hour);
values.put(COLUMN_MINUTE, minute);
long id = db.insert(TABLE_APPOINTMENTS, null, values);
db.close();
return id;
}
}
//login
package com.example.clinicalmanagement;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class LoginActivity extends AppCompatActivity {
EditText usernameEditText, passwordEditText;
Button loginButton;
DatabaseHelper databaseHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
usernameEditText = findViewById(R.id.editTextUsername);
passwordEditText = findViewById(R.id.editTextPassword);
loginButton = findViewById(R.id.buttonLogin);
databaseHelper = new DatabaseHelper(this);
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = usernameEditText.getText().toString().trim();
String password = passwordEditText.getText().toString().trim();
if (databaseHelper.checkUser(username, password)) {
Toast.makeText(LoginActivity.this, "Login successful", Toast.LENGTH_SHORT).show();
// Redirect to main activity or dashboard
startActivity(new Intent(LoginActivity.this, BookAppointmentActivity.class));
finish();
} else {
Toast.makeText(LoginActivity.this, "Invalid username or password", Toast.LENGTH_SHORT).show();
}
}
});
}
}
//main
package com.example.clinicalmanagement;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
Button register;
Button login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
register = findViewById(R.id.register);
login = findViewById(R.id.login);
register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, RegisterActivity.class);
startActivity(intent);
}
});
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
}
});
}
}
//register
package com.example.clinicalmanagement;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import android.database.sqlite.SQLiteDatabase;
public class RegisterActivity extends AppCompatActivity {
EditText usernameEditText, passwordEditText;
Button registerButton;
DatabaseHelper databaseHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
usernameEditText = findViewById(R.id.editTextUsername);
passwordEditText = findViewById(R.id.editTextPassword);
registerButton = findViewById(R.id.buttonRegister);
databaseHelper = new DatabaseHelper(this);
registerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = usernameEditText.getText().toString().trim();
String password = passwordEditText.getText().toString().trim();
// Add validation logic here if needed
long result = databaseHelper.insertUser(username, password);
if (result != -1) {
Toast.makeText(RegisterActivity.this, "Registration successful", Toast.LENGTH_SHORT).show();
// Redirect to login activity
startActivity(new Intent(RegisterActivity.this, LoginActivity.class));
finish();
} else {
Toast.makeText(RegisterActivity.this, "Registration failed", Toast.LENGTH_SHORT).show();
}
}
});
}
}