如何从外部文件替换(覆盖)数据库
How to replace(overwrite) DB from external file
我想从特定路径将旧基地替换为新基地。我应该删除旧版本只复制新文件吗?它可以工作,但应用程序会在我清除现金或重新启动设备后立即应用新的基础。为什么这样?或者我应该使用 dbHelper.onUpgrade()
?可能它更好。但是我不能将参数设置为 onUpgrade()
因为它需要 SQLiteDatabase
作为参数,我有数据库的文件路径所以我如何设置必要的参数?它应该看起来像这样:
downloadDbPath = file.getPath();
sql = new SQLiteDatabase().getPath(downloadDbPath);
dbHelper.onUpgrade(sql, 1, 2);
第二行我有一个错误Error: SQLiteDatabase() is not public in SQLiteDatabase; cannot be accessed from outside package
所以我不能创建一个新对象
好的,如果有人感兴趣我接下来会做:
主要方法:
public void downloadDb() {
new FileChooser(this).setFileListener(new FileChooser.FileSelectedListener() {
@Override public void fileSelected(final File file) {
downloadDbPath = file.getPath();
try {
InputStream in = new FileInputStream(downloadDbPath);
OutputStream out = new FileOutputStream(uploadDbPath);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
deleteCache(context);
restartApp();
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).showDialog();
}
配件:
清理缓存:
<uses-permission android:name="android.permission.CLEAR_APP_CACHE"/>
public static void deleteCache(Context context) {
try {
File dir = context.getCacheDir();
deleteDir(dir);
} catch (Exception e) {}
}
public static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
return dir.delete();
} else if(dir!= null && dir.isFile()) {
return dir.delete();
} else {
return false;
}
}
重启应用:
public void restartApp(){
Intent mStartActivity = new Intent(context, MainActivity.class);
int mPendingIntentId = 123456;
PendingIntent mPendingIntent = PendingIntent.getActivity(context, mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
System.exit(0);
}
文件选择器:
https://rogerkeays.com/simple-android-file-chooser
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
class FileChooser {
private static final String PARENT_DIR = "..";
private final Activity activity;
private ListView list;
private Dialog dialog;
private File currentPath;
// filter on file extension
private String extension = null;
public void setExtension(String extension) {
this.extension = (extension == null) ? null :
extension.toLowerCase();
}
// file selection event handling
public interface FileSelectedListener {
void fileSelected(File file);
}
public FileChooser setFileListener(FileSelectedListener fileListener) {
this.fileListener = fileListener;
return this;
}
private FileSelectedListener fileListener;
public FileChooser(Activity activity) {
this.activity = activity;
dialog = new Dialog(activity);
list = new ListView(activity);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override public void onItemClick(AdapterView<?> parent, View view, int which, long id) {
String fileChosen = (String) list.getItemAtPosition(which);
File chosenFile = getChosenFile(fileChosen);
if (chosenFile.isDirectory()) {
refresh(chosenFile);
} else {
if (fileListener != null) {
fileListener.fileSelected(chosenFile);
}
dialog.dismiss();
}
}
});
dialog.setContentView(list);
dialog.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
refresh(Environment.getExternalStorageDirectory());
}
public void showDialog() {
dialog.show();
}
/**
* Sort, filter and display the files for the given path.
*/
private void refresh(File path) {
this.currentPath = path;
if (path.exists()) {
File[] dirs = path.listFiles(new FileFilter() {
@Override public boolean accept(File file) {
return (file.isDirectory() && file.canRead());
}
});
File[] files = path.listFiles(new FileFilter() {
@Override public boolean accept(File file) {
if (!file.isDirectory()) {
if (!file.canRead()) {
return false;
} else if (extension == null) {
return true;
} else {
return file.getName().toLowerCase().endsWith(extension);
}
} else {
return false;
}
}
});
// convert to an array
int i = 0;
String[] fileList;
if (path.getParentFile() == null) {
fileList = new String[dirs.length + files.length];
} else {
fileList = new String[dirs.length + files.length + 1];
fileList[i++] = PARENT_DIR;
}
Arrays.sort(dirs);
Arrays.sort(files);
for (File dir : dirs) { fileList[i++] = dir.getName(); }
for (File file : files ) { fileList[i++] = file.getName(); }
// refresh the user interface
dialog.setTitle(currentPath.getPath());
list.setAdapter(new ArrayAdapter(activity,
android.R.layout.simple_list_item_1, fileList) {
@Override public View getView(int pos, View view, ViewGroup parent) {
view = super.getView(pos, view, parent);
((TextView) view).setSingleLine(true);
return view;
}
});
}
}
/**
* Convert a relative filename into an actual File object.
*/
private File getChosenFile(String fileChosen) {
if (fileChosen.equals(PARENT_DIR)) {
return currentPath.getParentFile();
} else {
return new File(currentPath, fileChosen);
}
}
}
我想从特定路径将旧基地替换为新基地。我应该删除旧版本只复制新文件吗?它可以工作,但应用程序会在我清除现金或重新启动设备后立即应用新的基础。为什么这样?或者我应该使用 dbHelper.onUpgrade()
?可能它更好。但是我不能将参数设置为 onUpgrade()
因为它需要 SQLiteDatabase
作为参数,我有数据库的文件路径所以我如何设置必要的参数?它应该看起来像这样:
downloadDbPath = file.getPath();
sql = new SQLiteDatabase().getPath(downloadDbPath);
dbHelper.onUpgrade(sql, 1, 2);
第二行我有一个错误Error: SQLiteDatabase() is not public in SQLiteDatabase; cannot be accessed from outside package
所以我不能创建一个新对象
好的,如果有人感兴趣我接下来会做: 主要方法:
public void downloadDb() {
new FileChooser(this).setFileListener(new FileChooser.FileSelectedListener() {
@Override public void fileSelected(final File file) {
downloadDbPath = file.getPath();
try {
InputStream in = new FileInputStream(downloadDbPath);
OutputStream out = new FileOutputStream(uploadDbPath);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
deleteCache(context);
restartApp();
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).showDialog();
}
配件:
清理缓存:
<uses-permission android:name="android.permission.CLEAR_APP_CACHE"/>
public static void deleteCache(Context context) {
try {
File dir = context.getCacheDir();
deleteDir(dir);
} catch (Exception e) {}
}
public static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
return dir.delete();
} else if(dir!= null && dir.isFile()) {
return dir.delete();
} else {
return false;
}
}
重启应用:
public void restartApp(){
Intent mStartActivity = new Intent(context, MainActivity.class);
int mPendingIntentId = 123456;
PendingIntent mPendingIntent = PendingIntent.getActivity(context, mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
System.exit(0);
}
文件选择器: https://rogerkeays.com/simple-android-file-chooser
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
class FileChooser {
private static final String PARENT_DIR = "..";
private final Activity activity;
private ListView list;
private Dialog dialog;
private File currentPath;
// filter on file extension
private String extension = null;
public void setExtension(String extension) {
this.extension = (extension == null) ? null :
extension.toLowerCase();
}
// file selection event handling
public interface FileSelectedListener {
void fileSelected(File file);
}
public FileChooser setFileListener(FileSelectedListener fileListener) {
this.fileListener = fileListener;
return this;
}
private FileSelectedListener fileListener;
public FileChooser(Activity activity) {
this.activity = activity;
dialog = new Dialog(activity);
list = new ListView(activity);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override public void onItemClick(AdapterView<?> parent, View view, int which, long id) {
String fileChosen = (String) list.getItemAtPosition(which);
File chosenFile = getChosenFile(fileChosen);
if (chosenFile.isDirectory()) {
refresh(chosenFile);
} else {
if (fileListener != null) {
fileListener.fileSelected(chosenFile);
}
dialog.dismiss();
}
}
});
dialog.setContentView(list);
dialog.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
refresh(Environment.getExternalStorageDirectory());
}
public void showDialog() {
dialog.show();
}
/**
* Sort, filter and display the files for the given path.
*/
private void refresh(File path) {
this.currentPath = path;
if (path.exists()) {
File[] dirs = path.listFiles(new FileFilter() {
@Override public boolean accept(File file) {
return (file.isDirectory() && file.canRead());
}
});
File[] files = path.listFiles(new FileFilter() {
@Override public boolean accept(File file) {
if (!file.isDirectory()) {
if (!file.canRead()) {
return false;
} else if (extension == null) {
return true;
} else {
return file.getName().toLowerCase().endsWith(extension);
}
} else {
return false;
}
}
});
// convert to an array
int i = 0;
String[] fileList;
if (path.getParentFile() == null) {
fileList = new String[dirs.length + files.length];
} else {
fileList = new String[dirs.length + files.length + 1];
fileList[i++] = PARENT_DIR;
}
Arrays.sort(dirs);
Arrays.sort(files);
for (File dir : dirs) { fileList[i++] = dir.getName(); }
for (File file : files ) { fileList[i++] = file.getName(); }
// refresh the user interface
dialog.setTitle(currentPath.getPath());
list.setAdapter(new ArrayAdapter(activity,
android.R.layout.simple_list_item_1, fileList) {
@Override public View getView(int pos, View view, ViewGroup parent) {
view = super.getView(pos, view, parent);
((TextView) view).setSingleLine(true);
return view;
}
});
}
}
/**
* Convert a relative filename into an actual File object.
*/
private File getChosenFile(String fileChosen) {
if (fileChosen.equals(PARENT_DIR)) {
return currentPath.getParentFile();
} else {
return new File(currentPath, fileChosen);
}
}
}