Существует множество потенциальных проблем. Вот немного контрольного списка, с которого нужно начать: -
- Существует ли файл mydatabase2.db в ???? / App / Main / assets папка?
- Это действительная база данных SQLite (откройте ее в SQlite Tool и проверьте).
- Таблица fradeu должнаиметь столбец с именем _id, который должен быть псевдонимом rowid (например, он определен как
_id INTEGER PRIMARY KEY
или _id INTEGER PRIMARY AUTOINCREMENT
, , последний не рекомендуется из-за ненужных издержек ) - Примечание: обратитесь к коду, который устанавливает allColumns (и как вы можете обойтись без столбца _id ).
Исправление
Чтобы преодолеть проблему, код был довольно сильно изменен, включая код для выявления потенциальных проблем, поэтому он немного раздутый и вместо того, чтобы распространять исключения, требующие предложений try / catch на более высоких уровнях, для которых они тестируются, изахвачено на нижнем уровне (для моего удобства).
из рабочего кода (как показано ниже) в качестве mydatabase3.db используется следующее: -
, которое было скопировано в папку ресурсов.
Результирующее приложение изначально выглядит так: -
А затем: -
Код
- Примечание. См. Комментарии для исправлений, рекомендации и причины изменений
DatabaseHelper.java : -
public class DatabaseHelper extends SQLiteOpenHelper {
private String DB_PATH = null;
private static String DB_NAME = "mydatabase3.db";
private SQLiteDatabase database;
private final Context myContext;
public static final String TABLE_NAME = "fradeu";
public static final String COL1 = "fra";
public static final String COL2 = "deu";
public DatabaseHelper(Context context) {
super (context, DB_NAME, null, 10);
this.myContext = context;
this.DB_PATH = "/data/data/" + context.getPackageName () + "/" + "databases/";
String altdbpath = (context.getDatabasePath("anything")).getParent() + "/"; //<<<< gets path without hardcoding recommended
//<<<< Added for info re paths
Log.d("DBPATHINFO","Hardcoded DB path is >>>>" + DB_PATH + "<<<<");
Log.d("DBPATHINFO","Derived DB path is >>>>" + altdbpath + "<<<<");
Log.e ("Path 1", DB_PATH);
}
public void createDataBase() {
boolean dbExist = checkDataBase ();
if (!dbExist) {
this.getReadableDatabase ();
copyDataBase();
}
}
// Note can check file which won't issue stacktrace which may be confusing
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase (myPath, null, SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
}
if (checkDB != null) {
checkDB.close ();
}
return checkDB != null;
}
private void copyDataBase() {
InputStream myInput;
OutputStream myOutput;
final String TAG = "COPYDATABASE";
Log.d(TAG,"Attempt to copy database initiated.");
Log.d(TAG,"Attempting to open Asset " + DB_NAME);
try {
myInput = myContext.getAssets().open(DB_NAME);
} catch (IOException e) {
Log.d(TAG,"Error attempting to open Asset " +DB_NAME);
throw new RuntimeException(e);
}
//InputStream myInput = myContext.getAssets ().open (DB_NAME);
String outFileName = DB_PATH + DB_NAME;
Log.d(TAG,"Attempting to open the Database file :- " + outFileName);
try {
myOutput = new FileOutputStream(outFileName);
} catch (IOException e) {
Log.d(TAG,"Error attempting to open the Database file :-" + outFileName);
throw new RuntimeException(e);
}
byte[] buffer = new byte[4096];
long bytescopied = 0;
int length;
Log.d(TAG,"Attempting to copy from the asset file to the Database file");
try {
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
bytescopied = bytescopied + length;
}
} catch (IOException e) {
Log.d(TAG,"Error while copying from the asset file to the Database file - " +
String.valueOf(bytescopied) +
" bytes copied, so far.");
}
Log.d(TAG,"File has been copied from the assets file to the Database file." +
String.valueOf(bytescopied) +
" bytes were copied."
);
Log.d(TAG, "Attempting to flush and close files.");
try {
myOutput.flush();
myOutput.close();
myInput.close();
} catch (IOException e) {
Log.d(TAG,"Error flusing or closing files.");
}
}
public void openDataBase() {
String myPath = DB_PATH + DB_NAME;
database = SQLiteDatabase.openDatabase (myPath, null, SQLiteDatabase.OPEN_READONLY);
}
public Cursor readData(){
// String[] allColumns = new String[] {DatabaseHelper.COL1,DatabaseHelper.COL2};
//<<<<< for a CursorAdapater _id column MUST be included
// Assuming you have an _id column then allColumns replaced with null (all columns)
// Alternaelty if the table doesn have _id column then you could use :-
//String[] allColumns = new String[] {DatabaseHelper.COL1,DatabaseHelper.COL2,"rowid AS _id"};
Cursor c =database.query (DatabaseHelper.TABLE_NAME,null,null,null,null,null,null);
//<<<< useless code cursor WILL NOT be null
// (very rarely would a cursor be null and
// probably only if trapped by try/catch
// which will tend to obfuscate matters/issues
// )
/*
if(c != null) {
c.moveToFirst ();
}
*/
return c;
}
@Override
public synchronized void close() {
if (database != null)
database.close ();
super.close ();
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion > oldVersion)
copyDataBase();
}
public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {
return database.query ("fradeu", null, null, null, null, null,null);
}
}
Метод onCreateView для фрагмента : -
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//<<<< Obviously change to use your layout (this is stock layout)
View rootView = inflater.inflate(R.layout.fragment_so50804849, container, false);
listView = (ListView) rootView.findViewById(R.id.list); //<<<< ADDED NOTE use your id
buttondisplay = (Button) rootView.findViewById(R.id.showlist); //<<<< ADDED NOTE use your id
DatabaseHelper myDbHelper = new DatabaseHelper (getActivity ());
myDbHelper.createDataBase();
myDbHelper.openDataBase();
/*
c = myDbHelper.query(DatabaseHelper.TABLE_NAME,null,null,null,null,null,null);
Cursor c = myDbHelper.readData(); //???? two cursors called c c will now refer to this one
*/
c = myDbHelper.readData(); //<<<< Just the one cursor
String[] from = new String []{DatabaseHelper.COL1,DatabaseHelper.COL2};
int[] to = new int[] {R.id.fra, R.id.deu};
adapter = new SimpleCursorAdapter(getActivity(),R.layout.list_view_adapter,c,from,to,0);
//listView.setAdapter(adapter);
//<<<< No need for a button see commented out line above where setAdapter is used this works
buttondisplay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (buttondisplay.getText().toString().contains("SHOW")) {
listView.setAdapter(adapter);
buttondisplay.setText("HIDE LIST");
} else {
listView.setAdapter(null);
buttondisplay.setText("SHOW LIST");
}
}
});
return rootView;
}