【发布时间】:2018-05-16 13:24:49
【问题描述】:
我在将 SQLite 数据库从我的应用程序导出到本地文件时遇到问题。 我花了很多时间使用来自现有主题的代码,例如: is it possible backup and RESTORE a database file in android? non root devices 或Backup and restore SQLite database to sdcard。
在我的情况下,按下导出按钮后,应用程序停止工作。
我的活动:
NaprawyDB.java (DBHelper)
public class NaprawyDB extends SQLiteOpenHelper {
//Database Version
private static final int DATABASE_VERSION = 1;
private static String dbName = "NaprawyDB";
private static String tableName = "naprawy";
private static String idColumn = "id";
private static String pojazdColumn = "pojazd";
private static String periodColumn = "period";
private static String przebiegColumn = "przebieg";
private static String kwotaColumn = "kwota";
private static String warsztatColumn = "warsztat";
private static String opisColumn = "opis";
private Context context;
public NaprawyDB(Context context) {
super(context, dbName, null, DATABASE_VERSION);
}
private static final String CREATE_TABLE_NAPRAWY = "create table " + tableName + "(" +
idColumn + " integer primary key autoincrement, " +
pojazdColumn + " text, " +
periodColumn + " text, " +
przebiegColumn + " text, " +
kwotaColumn + " text, " +
warsztatColumn + " text, " +
opisColumn + " text " +
")";
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL(CREATE_TABLE_NAPRAWY);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("drop table if exists " + tableName);
onCreate(sqLiteDatabase);
}
public List<Naprawy> findAll() {
try {
List<Naprawy> naprawies = new ArrayList<Naprawy>();
SQLiteDatabase sqLiteDatabase = getWritableDatabase();
Cursor cursor = sqLiteDatabase.rawQuery("select * from " + tableName, null);
if (cursor.moveToFirst()) {
do {
Naprawy naprawy = new Naprawy();
naprawy.setId(cursor.getInt(0));
naprawy.setPojazd(cursor.getString(1));
naprawy.setPeriod(cursor.getString(2));
naprawy.setPrzebieg(cursor.getString(3));
naprawy.setKwota(cursor.getString(4));
naprawy.setWarsztat(cursor.getString(5));
naprawy.setOpis(cursor.getString(6));
naprawies.add(naprawy);
} while (cursor.moveToNext());
}
sqLiteDatabase.close();
return naprawies;
} catch (Exception e) {
return null;
}
}
public boolean create(Naprawy naprawy){
try {
SQLiteDatabase sqLiteDatabase = getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(pojazdColumn, naprawy.getPojazd());
contentValues.put(periodColumn, naprawy.getPeriod());
contentValues.put(przebiegColumn, naprawy.getPrzebieg());
contentValues.put(kwotaColumn, naprawy.getKwota());
contentValues.put(warsztatColumn, naprawy.getWarsztat());
contentValues.put(opisColumn, naprawy.getOpis());
long rows = sqLiteDatabase.insert(tableName, null, contentValues);
sqLiteDatabase.close();
return rows > 0;
}catch (Exception e) {
return false;
}
}
public boolean delete(int id) {
try {
SQLiteDatabase sqLiteDatabase = getWritableDatabase();
int rows = sqLiteDatabase.delete(tableName,idColumn + " = ?", new String[] {String.valueOf(id)});
sqLiteDatabase.close();
return rows > 0;
}catch (Exception e) {
return false;
}
}
public void backup(String outFileName) {
//database path
final String inFileName = context.getDatabasePath(dbName).toString();
try {
File dbFile = new File(inFileName);
FileInputStream fis = new FileInputStream(dbFile);
// Open the empty db as the output stream
OutputStream output = new FileOutputStream(outFileName);
// Transfer bytes from the input file to the output file
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
// Close the streams
output.flush();
output.close();
fis.close();
Toast.makeText(context, "Backup Completed", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(context, "Unable to backup database. Retry", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
Dziennik napraw.java(类似于主要活动)
public class Dziennik_napraw extends AppCompatActivity {
private ListView listViewNaprawy;
FloatingActionButton fab_add;
private Button buttonimport;
private Button buttonexport;
private Button buttonGexport;
private Button buttonGimport;
@Override
protected void onCreate (Bundle saveInstanceState) {
super.onCreate(saveInstanceState);
setContentView(R.layout.activity_dziennik_napraw);
this.fab_add = (FloatingActionButton) findViewById(R.id.fab_dodaj);
this.fab_add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent1 = new Intent(Dziennik_napraw.this, AddNaprawyActivity.class);
startActivity(intent1);
}
});
final NaprawyDB naprawyDB = new NaprawyDB(getApplicationContext());
this.listViewNaprawy = (ListView) findViewById(R.id.listViewNaprawy);
this.listViewNaprawy.setAdapter(new NaprawyListAdapter(this, naprawyDB.findAll()));
this.listViewNaprawy.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int i, long l) {
Naprawy naprawy = naprawyDB.findAll().get(i);
Intent intent1 = new Intent(Dziennik_napraw.this, NaprawyDetailActivity.class);
intent1.putExtra("naprawy", naprawy);
startActivity(intent1);
}
});
this.buttonexport = (Button) findViewById(R.id.button_export);
this.buttonexport.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String outFileName = Environment.getExternalStorageDirectory() + File.separator + getResources().getString(R.string.app_name) + File.separator;
performBackup(naprawyDB, outFileName);
}
});
}
private void performBackup(final NaprawyDB naprawyDB, final String outFileName) {
verifyStoragePermissions(this);
File folder = new File(Environment.getExternalStorageDirectory() + File.separator + getResources().getString(R.string.app_name));
boolean success = true;
if (!folder.exists())
success = folder.mkdirs();
if (success) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Backup Name");
final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_TEXT);
builder.setView(input);
builder.setPositiveButton("Save", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String m_Text = input.getText().toString();
String out = outFileName + m_Text + ".db";
naprawyDB.backup(out);
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
} else
Toast.makeText(this, "Unable to create directory. Retry", Toast.LENGTH_SHORT).show();
}
// Storage Permissions variables
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
android.Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
public static void verifyStoragePermissions(Activity activity) {
// Check if we have read or write permission
int writePermission = ActivityCompat.checkSelfPermission(activity, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
int readPermission = ActivityCompat.checkSelfPermission(activity, android.Manifest.permission.READ_EXTERNAL_STORAGE);
if (writePermission != PackageManager.PERMISSION_GRANTED || readPermission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
}
你知道我会在哪里犯错吗? 所有数据库工作都很好。我可以创建新项目/编辑/删除,结果以列表视图的形式显示。 感谢您的任何回复:)
Logcat:
05-16 15:48:30.341 27280-27280/com.example.jacek.hondadiagnostic E/AndroidRuntime: 致命异常: main 进程:com.example.jacek.hondadiagnostic,PID:27280 java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“java.io.File android.content.Context.getDatabasePath(java.lang.String)” 在 database.NaprawyDB.backup(NaprawyDB.java:166) 在 com.example.jacek.hondadiagnostic.Dziennik_napraw$4.onClick(Dziennik_napraw.java:109) 在 android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:166) 在 android.os.Handler.dispatchMessage(Handler.java) 在 android.os.Looper.loop(Looper.java) 在 android.app.ActivityThread.main(ActivityThread.java) 在 java.lang.reflect.Method.invoke(本机方法) 在 java.lang.reflect.Method.invoke(Method.java:372) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
从 Logcat 我有信息要从空对象引用进行备份。
【问题讨论】:
-
是否有logcat报错?
-
就像一个小提示:如果您编写代码,请使用一种语言(显然是英语)而不是混合使用。这样,世界各地的开发人员将能够轻松阅读并理解您的代码。这将帮助您在这种情况下获得更多帮助。
-
我知道。这是我的第一个应用程序中的一个。多语言代码也让我很恼火。我不会再犯这个错误了。我在上面添加了 logcat :)
标签: android database android-sqlite database-backups android-database