简体   繁体   English

在 Android 上卸载/重新安装应用程序后保留 SQFlite 数据的最佳方法?

[英]Best way to keep SQFlite data after app is uninstalled/reinstalled on Android?

I have a problem with SQFlite that the database is deleted after the app is uninstalled/reinstalled.我对 SQFlite 有疑问,即在卸载/重新安装应用程序后删除了数据库。 My client will have thousands of logs stored in the database and I can't risk the data being lost.我的客户将在数据库中存储数以千计的日志,我不能冒丢失数据的风险。

Some questions and ideas I have:我有一些问题和想法:

Can I create a SQFLite database file in the external file system and query directly from a db file there?我可以在外部文件系统中创建一个 SQFLite 数据库文件并直接从那里的 db 文件中查询吗?

Or is my only option to constantly write a copy of the db file as a backup to the external file system?还是我唯一的选择是不断将 db 文件的副本作为备份写入外部文件系统? Will this be a problem if the file reaches a size of 2-5mb?如果文件大小达到 2-5mb,这会是一个问题吗? Will that write be slow or could cause crashes?写入会很慢还是会导致崩溃?

Should I just skip using SQFlite altogether and use a remote SQL Server database instead for my purpose?我是否应该完全跳过使用 SQFlite 并使用远程 SQL 服务器数据库来代替我的目的?

I find it very annoying that there doesn't seem to be a good option to backup SQFLite.我觉得很烦人,似乎没有备份 SQFLite 的好选择。 Many apps need to keep the data I'm sure.我敢肯定,许多应用程序都需要保留数据。

Thanks!谢谢!

Just use something like Firebase from the get-go.从一开始就使用 Firebase 之类的东西。 Don't store it locally.不要将其存储在本地。

You can keep the data between installations of the app by storing the SQFLite database in external storage, since this is not deleted when uninstalling the app.您可以通过将 SQFLite 数据库存储在外部存储中来保留应用程序安装之间的数据,因为卸载应用程序时不会删除这些数据。 I have tested it myself and it works.我自己测试过它并且它有效。

Here is an example of how you can set up that database in external memory:以下是如何在外部 memory 中设置该数据库的示例:

import 'dart:io';
import 'package:SQFLite_test/helpers/ClientMocker.dart';
import 'package:SQFLite_test/models/ClientModel.dart';
import 'package:ext_storage/ext_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:sqflite/sqflite.dart';

class LogServiceTwo {
  LogServiceTwo._();

  static final LogServiceTwo logRepo = LogServiceTwo._();

  static Database _database;

  Future<Database> get database async {
    if (_database != null) {
      return _database;
    }

    await askForWritePermission();
    var db = await openDb();
    if (db == null) {
      _database = await initDB();
      return _database;
    }

    var hasClientTableB = await hasClientTable(db);
    if (hasClientTableB) {
      _database = db;
      return _database;
    }

    await createClientTable(db);
    _database = db;
    return _database;
  }

  Future createClientTable(Database db) async {
    await db.execute("CREATE TABLE Client ("
        "id INTEGER PRIMARY KEY,"
        "first_name TEXT,"
        "last_name TEXT,"
        "blocked BIT"
        ")");
  }

  Future<bool> hasClientTable(Database db) async {
    try {
      var table = await db.query("Client");
      return table != null;
    } catch (e) {
      return false;
    }
  }

  Future<Database> openDb() async {
    try {
      var path = await getPersistentDbPath();
      var db = await openDatabase(path, version: 1);
      return db;
    } catch (e) {
      return null;
    }
  }

  Future initDB() async {
    var path = await getPersistentDbPath();
    return await openDatabase(path, version: 1, onOpen: (db) {}, onCreate: (Database db, int version) async {
      await db.execute("CREATE TABLE Client ("
          "id INTEGER PRIMARY KEY,"
          "first_name TEXT,"
          "last_name TEXT,"
          "blocked BIT"
          ")");
    });
  }

  Future newClient(Client newClient) async {
    final db = await database;
    var res = await db.insert("Client", newClient.toMap());
    return res;
  }

  Future newClients(List<Client> clients) async {
    var clientMaps = clients.map((client) => client.toMap()).toList();
    final db = await database;
    var batch = db.batch();
    clientMaps.forEach((clientMap) async {
      batch.insert("Client", clientMap);
    });
    await batch.commit(noResult: true);
  }

  Future<Client> getClient(int id) async {
    final db = await database;
    var res = await db.query("Client", where: "id = ?", whereArgs: [id]);
    return res.isNotEmpty ? Client.fromMap(res.first) : Null;
  }

  Future<List<Client>> getAllClients() async {
    final db = await database;
    var res = await db.query("Client");
    List<Client> list = res.isNotEmpty ? res.map((c) => Client.fromMap(c)).toList() : [];
    return list;
  }

  Future<List<Client>> getBlockedClients() async {
    final db = await logRepo.database;
    var res = await db.rawQuery("SELECT * FROM Client WHERE blocked=1");
    List<Client> list = res.isNotEmpty ? res.toList().map((c) => Client.fromMap(c)) : null;
    return list;
  }

  Future<List<String>> getTables() async {
    var db = await logRepo.database;
    var tableNames = (await db.query('sqlite_master', where: 'type = ?', whereArgs: ['table'])).map((row) => row['name'] as String).toList(growable: false);
    return tableNames;
  }

  Future<String> getPersistentDbPath() async {
    return await createPersistentDbDirecotry();
  }

  Future<String> createPersistentDbDirecotry() async {
    var externalDirectoryPath = await ExtStorage.getExternalStorageDirectory();
    var persistentDirectory = "$externalDirectoryPath/db_persistent";
    var directory = await createDirectory(persistentDirectory);
    listFiles(directory);
    return "$persistentDirectory/persistent.db";
  }

  listFiles(Directory directory) {
    print("${directory.path} files:");
    directory.list().forEach((file) {
      print(file.path);
      print(file.statSync().size);
    });
  }

  Future<Directory> createDirectory(String path) async {
    return await (new Directory(path).create());
  }

  Future<bool> askForWritePermission() async {
    var status = await Permission.storage.status;
    if (!status.isGranted) {
      status = await Permission.storage.request();
      return status.isGranted;
    }
    return status.isGranted;
  }

  Future mockData() async {
    var clients = ClientMocker.createClients();
    await newClients(clients);
  }

  Future deleteAll() async {
    var db = await database;
    await db.rawDelete("DELETE FROM Client");
  }

  Future getClients() async {
    try {
      var db = await database;
      return await db.rawQuery("SELECT * FROM Client");
    } catch (e) {
      print(e);
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android 通过应用程序保存和共享数据的最佳方式 - Android Best way to keep and share data through the app 有没有办法检查应用程序是否已重新安装? - Is there a way to check if the app was reinstalled? Android 中有没有办法检测我的应用程序是否被卸载? - Is there a way in Android to detect that my App is getting uninstalled? 即使已卸载应用程序,WorkManager实例仍保持活动状态(?) - WorkManager instances keep alive even after the app is uninstalled (?) 重新安装应用程序后,为什么数据没有被删除。 在模拟器上? - Why is data not being wiped after I reinstalled app. on emulator? 如果该应用已卸载,如何将sqlite数据库保留在android设备上? - How to keep sqlite database on an android device if the app is uninstalled? 我在Android设备上卸载并安装了ionic v1应用后,已经有$ localStorage数据了 - $localStorage data already there after I uninstalled and installed the ionic v1 app in Android device Android卸载的应用程序记录 - Android uninstalled app records Android App突然卸载 - Android App uninstalled suddenly 在Android平台上保持活动(或应用)运行状态的最佳方法是什么? - What is the best way for keep running state of activity(or app) on android platform?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM