gpt4 book ai didi

java - 导出和导入 SQLite 数据库

转载 作者:搜寻专家 更新时间:2023-11-01 09:20:07 26 4
gpt4 key购买 nike

晚上好,我正在开发一个 android 应用程序,它有 SQLite 数据库,我需要一种方法将数据库复制到设备的外部存储,在那里我可以复制到另一个设备,这样我就可以将数据库导入另一台设备。

例如:

假设应用程序调用“example”,数据库在“/data/data/com.gnd.example/databases”文件夹中,名为data.db,需要将其复制到“example/backup”文件夹”,例如“/storage/emulated/0/Example/Backup”。这是第一部分。

第二部分是导入,应用程序应将文件从“example/import”文件夹复制到文件夹“/data/data/com.gnd.example/databases”

为此,我有两个按钮 Activity ,btn_export 和 btn_import。

我已经依赖于以下解决方案:

导入/导出到android sqlite数据库Android上SQLite数据库的简单导出导入

我已经把它插入到 AndroidManifest 中了

如何请求用户许可?

我尝试使用我在其中一个示例中采用的这段代码进行复制

private void backupDatabase () throws IOException {
   String inFileName = "/data/data/com.gnd.example/databases/dados.db";
   File dbFile = new File (inFileName);
   FileInputStream fis = new FileInputStream (dbFile);

   String outFileName = Environment.getExternalStorageDirectory () + "/ example / backup / data.db";
   OutputStream output = new FileOutputStream (outFileName);
   byte [] buffer = new byte [1024];
   int length;
   while ((length = fis.read (buffer))> 0) {
       output.write (buffer, 0, length);
   }
   output.flush ();
   output.close ();
   fis.close ();

}

按钮看起来像这样:

   @Override
   public void onClick (View view) {
       try {
           backupDatabase ();
       } catch (IOException e1) {
           e1.printStackTrace ();
       }
   
});

当我按下按钮时记录:

07/01 19:35:39: Launching app
$ adb shell am start -n "com.gnd.keepkey / com.gnd.keepkey.Telephone" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Client not ready yet..Waiting for process to come online
Waiting for process to come online
Connected to process 27724 on device motorola-moto_z2_play-0039635857
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
I / zygote: Do partial code cache collection, code = 20KB, data = 29KB
I / zygote: After code cache collection, code = 20KB, data = 29KB
    Increasing code cache capacity to 128KB
I / zygote: Do partial code cache collection, code = 20KB, data = 47KB
I / zygote: After code cache collection, code = 20KB, data = 47KB
    Increasing code cache capacity to 256KB
I / zygote: Compiler allocated 4MB to compile void android.widget.TextView. <Init> (android.content.Context, android.util.AttributeSet, int, int)
I / zygote: Full code cache collection, code = 120KB, data = 82KB
I / zygote: After code cache collection, code = 117KB, data = 62KB
I / zygote: Do partial code cache collection, code = 125KB, date = 79KB
I / zygote: After code cache collection, code = 125KB, data = 79KB
    Increasing code cache capacity to 512KB
W / System.err: java.io.FileNotFoundException: /storage/emulated/0/teste/dados.db (No such file or directory)
        at java.io.FileOutputStream.open0 (Native Method)
W / System.err: at java.io.FileOutputStream.open (FileOutputStream.java:287)
        at java.io.FileOutputStream. <init> (FileOutputStream.java:223)
        at java.io.FileOutputStream. <init> (FileOutputStream.java:110)
        at com.gnd.keepkey.funcoes.Exportar_Importar.backupDatabase (Export_Importar.java:87)
        at com.gnd.keepkey.funcoes.Exportar_Importar.access $ 000 (Export_Importar.java:42)
        at com.gnd.keepkey.funcoes.Export_Import $ 1.onClick (Export_Import.java:69)
W / System.err: at android.view.View.performClick (View.java:6259)
        at android.view.View $ PerformClick.run (View.java:24732)
        at android.os.Handler.handleCallback (Handler.java:789)
        at android.os.Handler.dispatchMessage (Handler.java:98)
        at android.os.Looper.loop (Looper.java:164)
        at android.app.ActivityThread.main (ActivityThread.java:6592)
        at java.lang.reflect.Method.invoke (Native Method)
W / System.err: at com.android.internal.os.Zygote $ MethodAndArgsCaller.run (Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:769)

最佳答案

FileNotFoundException 可能是由于目录 teste 不存在,可能是由于权限问题。

使用:-

private void backupDatabase () throws IOException {
String inFileName = "/data/data/com.gnd.example/databases/dados.db";
File dbFile = new File (inFileName);
FileInputStream fis = new FileInputStream (dbFile);

String outFileName = Environment.getExternalStorageDirectory () + "/ example / backup / data.db";
//<<<<<<<<<<< CODE ADDED >>>>>>>>>>
File os = new File(outFileName);
if (!os.getParentFile().exists()) {
os.getParentFile().mkdirs();
}
//<<<<<<<<<< END Of ADDED CODE >>>>>>>>>>
OutputStream output = new FileOutputStream(os); //<<<<<<<<<< CHANGED
byte [] buffer = new byte [1024];
int length;
while ((length = fis.read (buffer))> 0) {
output.write (buffer, 0, length);
}
output.flush ();
output.close ();
fis.close ();
}

如果目录不存在将创建目录(假设权限正确)

工作示例:-

下面是一个可以运行的应用

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="aso.so56843045backup">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
  • 注意 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> (对于早期设备)

外部存储权限.java

class ExternalStoragePermissions {

public int API_VERSION = Build.VERSION.SDK_INT;
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {

//Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
public static final String THISCLASS = ExternalStoragePermissions.class.getSimpleName();
private static final String LOGTAG = "SW_ESP";

public ExternalStoragePermissions() {}
// Note call this method
public static void verifyStoragePermissions(Activity activity) {
int permission = ActivityCompat.checkSelfPermission(
activity,
Manifest.permission.WRITE_EXTERNAL_STORAGE);

if(permission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
}
  • 如果未授予权限,则无法创建目录,从而导致 FileNotFoundException。

DBHelper.java

public class DBHelper extends SQLiteOpenHelper {

public static final String DBNAME = "dados.db";
public static final int DBVERSION = 1;

public DBHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
this.getWritableDatabase();
}

@Override
public void onCreate(SQLiteDatabase db) {

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}
}
  • 一个非常基本的空数据库(android_metadata 表除外),足以检查备份。

主 Activity .java

public class MainActivity extends AppCompatActivity {

DBHelper mDBHlpr;
Button mBackup;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBackup = this.findViewById(R.id.backup);
mBackup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mDBHlpr.close();
try {
backupDatabase();
} catch (IOException e) {
e.printStackTrace();
}
}
});
ExternalStoragePermissions.verifyStoragePermissions(this);
mDBHlpr = new DBHelper(this);
}

private void backupDatabase () throws IOException {
FileInputStream fis = new FileInputStream (this.getDatabasePath("dados.db").getPath());
String outFileName = Environment.getExternalStorageDirectory () + "/example/backup/" + String.valueOf(System.currentTimeMillis()) + "data.db";
Log.d("OSFILEPATH",outFileName);
File os = new File(outFileName);
if (!os.getParentFile().exists()) {
os.getParentFile().mkdirs();
}
OutputStream output = new FileOutputStream(os);
byte [] buffer = new byte [1024];
int length;
while ((length = fis.read (buffer))> 0) {
output.write (buffer, 0, length);
}
output.flush ();
output.close ();
fis.close ();
}
}

注意事项

  • 安装后首次运行时,将请求以后的设备获得许可(点击允许)。

  • 备份已使用时间戳命名,因此可以存在多个备份。

  • 数据库已关闭,(这应该可以应对 Android Pie+,这里默认是 WAL 模式,关闭应该清空(提交更改)-wal 和 -shm 文件,从而不需要备份额外的文件) .

结果

enter image description here

关于java - 导出和导入 SQLite 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56843045/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com