我已经通过数据库浏览器为sqlite 创建了一个数据库表,并在Assets文件夹中添加了该文件。 我想从表中获取数据并在我单击按钮时在TextView中显示它们,但每次运行时都没有出现,编译器说它们不是名为Account的表。我看过很多教程,每次出现同样的错误 这是代码。
帐户
public class Account {
private String UserName;
private String Email;
public Account() {
}
public Account(String userName, String email) {
UserName = userName;
Email = email;
}
public String getUserName() {
return UserName;
}
public void setUserName(String userName) {
UserName = userName;
}
public String getEmail() {
return Email;
}
public void setEmail(String email) {
Email = email;
}
}
DataBaseHelper
public class DbHelper extends SQLiteOpenHelper {
private static String DB_PATH="";
private static String DB_NAME="MyDB.db";
private SQLiteDatabase mDataBase;
private Context mContext;
public DbHelper(Context context) {
super(context, DB_NAME, null, 1);
if (Build.VERSION.SDK_INT >= 17){
DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
} else {
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
}
mContext = context;
}
@Override
public synchronized void close() {
if (mDataBase != null){
mDataBase.close();
}
super.close();
}
private boolean checkDataBase(){
SQLiteDatabase tempDB = null;
try {
String path = DB_PATH + DB_NAME;
tempDB = SQLiteDatabase.openDatabase(path,null, SQLiteDatabase.OPEN_READWRITE);
}
catch (Exception ex){
if (tempDB != null)
tempDB.close();
}
return tempDB != null ? true:false;
}
public void copyDataBase(){
try {
InputStream myInput = mContext.getAssets().open(DB_NAME);
String outputFileNme = DB_PATH + DB_NAME;
OutputStream myOutput = new FileOutputStream(outputFileNme);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer,0,length);
}
myOutput.flush();
myOutput.close();
myInput.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void openDataBase(){
String path = DB_PATH + DB_NAME;
mDataBase = SQLiteDatabase.openDatabase(path,null,SQLiteDatabase.OPEN_READWRITE);
}
public void createDataBase(){
boolean isDBExist = checkDataBase();
if (isDBExist){
} else {
this.getReadableDatabase();
try {
copyDataBase();
}catch (Exception ex){
}
}
}
public List<Account> getAllUsers(){
List<Account> temp = new ArrayList<Account>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor c;
try {
c = db.rawQuery("SELECT * FROM Account",null);
if (c == null) return null;
c.moveToFirst();
do {
Account account = new Account(c.getString(c.getColumnIndex("UserName")),c.getString(c.getColumnIndex("Email")));
temp.add(account);
} while (c.moveToNext());
c.close();
} catch (Exception e){
}
db.close();
return temp;
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
List<Account> lstUser = new ArrayList<Account>();
DbHelper dbHelper;
Button btnGetData;
LinearLayout container;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnGetData = findViewById(R.id.btnGetData);
container = findViewById(R.id.container);
dbHelper = new DbHelper(getApplicationContext());
dbHelper.createDataBase();
btnGetData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
lstUser = dbHelper.getAllUsers();
for (Account account:lstUser){
LayoutInflater inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View addView = inflater.inflate(R.layout.row,null);
TextView txtUser = addView.findViewById(R.id.txtUser);
TextView txtEmail = addView.findViewById(R.id.txtEmail);
txtUser.setText(account.getUserName());
txtEmail.setText(account.getEmail());
container.addView(addView);
}
}
});
}
}
答案 0 :(得分:0)
在测试代码之后,一切都在寻找。因此看起来问题是数据库是空的(可能没有使用DBBrowser为SQlite正确保存,这看起来很古怪)。
我建议,如果使用DB Browser for SQlite,要始终保存数据库(写入更改),关闭数据库,然后打开数据库并检查它是否符合预期。重复直到它,然后将文件复制到assets文件夹。
但是,这里是CopyDatabase方法的修改版本,可以帮助检测复制数据库的任何问题: -
public boolean copyDataBase() {
InputStream myInput;
OutputStream myOutput;
try {
myInput = mContext.getAssets().open(DB_NAME);
} catch (IOException ex) {
Log.d("COPYDB-OPN ASSET","IoException opening Asset file " + DB_NAME);
ex.printStackTrace();
return false;
}
String outputFileNme = DB_PATH + DB_NAME;
try {
myOutput = new FileOutputStream(outputFileNme);
} catch (IOException ex) {
Log.d("COPYDB-OPN OUT","IOException opening Output file " + outputFileNme);
ex.printStackTrace();
return false;
}
long bytes_read = 0;
long bytes_written = 0;
try {
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
bytes_read = bytes_read + length;
myOutput.write(buffer, 0, length);
bytes_written = bytes_written + length;
}
} catch (IOException ex) {
Log.d("COPYDB-CPY DATA",
"IOException Copying Data. " +
" Bytes Read=" + String.valueOf(bytes_read) +
" Bytes Written=" + String.valueOf(bytes_written));
ex.printStackTrace();
return false;
}
try {
myOutput.flush();
myOutput.close();
myInput.close();
} catch (IOException e) {
Log.d("COPYDB-FINALISE","IOException Flushing/Closing Files");
e.printStackTrace();
return false;
}
Log.d("COPYDB-COMPLETED",
"The copy of " + DB_NAME + " has completed. " +
String.valueOf(bytes_written) + " bytes were copied to " + outputFileNme);
return true;
}
也可以使用稍微不同的CreateDatabase方法: -
public void createDataBase() {
boolean isDBExist = checkDataBase();
if (isDBExist) {
} else {
this.getReadableDatabase();
if (!copyDataBase()) {
throw new RuntimeException("Failed to Copy Database " + DB_NAME + " from the Asset file");
}
}
}
例如,如果缺少资产文件,则日志中会出现以下内容: -
6-15 04:42:49.633 2252-2252/? E/SQLiteLog: (14) cannot open file at line 35652 of [8201f4e1c5]
(14) os_unix.c:35652: (2) open(/data/user/0/soanswers.soanswers/databases/MyDB.db) -
06-15 04:42:49.641 2252-2252/? E/SQLiteDatabase: Failed to open database '/data/user/0/soanswers.soanswers/databases/MyDB.db'.
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:808)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:793)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:696)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:671)
at soanswers.soanswers.DbHelperSO50867547.checkDataBase(DbHelperSO50867547.java:49)
at soanswers.soanswers.DbHelperSO50867547.createDataBase(DbHelperSO50867547.java:115)
at soanswers.soanswers.MainActivity.SO50867547(MainActivity.java:635)
at soanswers.soanswers.MainActivity.onCreate(MainActivity.java:140)
at android.app.Activity.performCreate(Activity.java:6975)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
06-15 04:42:49.645 2252-2252/? I/swers.soanswers: type=1400 audit(0.0:2324): avc: denied { read } for name="databases" dev="sdb3" ino=81932 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:system_data_file:s0:c512,c768 tclass=dir permissive=1
06-15 04:42:49.657 2252-2252/? I/swers.soanswers: type=1400 audit(0.0:2326): avc: denied { setattr } for name="MyDB.db" dev="sdb3" ino=81933 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:system_data_file:s0:c512,c768 tclass=file permissive=1
06-15 04:42:49.666 2252-2252/? D/COPYDB-OPN ASSET: IoException opening Asset file MyDB.db
06-15 04:42:49.666 2252-2252/? W/System.err: java.io.FileNotFoundException: MyDB.db
at android.content.res.AssetManager.openAsset(Native Method)
at android.content.res.AssetManager.open(AssetManager.java:374)
at android.content.res.AssetManager.open(AssetManager.java:348)
at soanswers.soanswers.DbHelperSO50867547.copyDataBase(DbHelperSO50867547.java:61)
at soanswers.soanswers.DbHelperSO50867547.createDataBase(DbHelperSO50867547.java:119)
at soanswers.soanswers.MainActivity.SO50867547(MainActivity.java:635)
06-15 04:42:49.667 2252-2252/? W/System.err: at soanswers.soanswers.MainActivity.onCreate(MainActivity.java:140)
at android.app.Activity.performCreate(Activity.java:6975)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
06-15 04:42:49.668 2252-2252/? W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
注意无法打开数据库是由于checkDatabase方法检查数据库是否存在。
由于无法打开资产文件而导致的实际错误是: -
06-15 04:42:49.666 2252-2252/? D/COPYDB-OPN ASSET: IoException opening Asset file MyDB.db
06-15 04:42:49.666 2252-2252/? W/System.err: java.io.FileNotFoundException: MyDB.db
at android.content.res.AssetManager.openAsset(Native Method)
at android.content.res.AssetManager.open(AssetManager.java:374)
at android.content.res.AssetManager.open(AssetManager.java:348)
at soanswers.soanswers.DbHelperSO50867547.copyDataBase(DbHelperSO50867547.java:61)
如果没有错误,那么日志将包含类似于: -
的内容06-15 04:57:57.337 2384-2384/soanswers.soanswers D/COPYDB-COMPLETED: The copy of MyDB.db has completed. 8192 bytes were copied to /data/user/0/soanswers.soanswers/databases/MyDB.db
E/SQLiteLog: (14) cannot open file at line ....
的堆栈跟踪。