首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Android:如何在同一用户的设备之间同步存储在Room数据库中的应用程序数据?

Android:如何在同一用户的设备之间同步存储在Room数据库中的应用程序数据?
EN

Stack Overflow用户
提问于 2020-04-11 10:06:52
回答 2查看 4.2K关注 0票数 8

我正在开发一个本地存储用户数据的应用程序。我使用Room数据库将用户创建的数据存储在Android设备中。现在,如果用户有一个以上的设备,那么数据应该可以在他们的所有(Android)设备上使用,而不需要任何中央数据库或web服务。

注意:在iOS端,我使用CloudKit在iOS设备之间同步数据。有没有办法让Android设备也这么做呢?请注意,我不想将数据存储在任何中央数据库或don服务器或任何中央云存储。它只应由用户拥有。(也就是说,它应该通过用户的Google帐户同步)。注意:我想要一个本地的android解决方案,并且不需要跨平台(Android )同步。

更新:直到现在,我发现了一些选项,如萤火虫实时数据库,以及一些AWS服务也提供了同步功能,但问题是它们都将用户数据存储在一个中心云位置。

所以我的问题仍然是一样的--是否有一种方法可以在使用Google Drive的安卓设备之间同步数据,或者类似的东西:我们可以利用用户自己的云存储,而不是将用户数据存储在中央数据库中。

EN

回答 2

Stack Overflow用户

发布于 2020-04-14 13:09:52

编辑

没有本机/默认/开箱即用的机制来实时同步Android上的数据

不过也有代孕者。

在Android的背景下,出现了两个主要选项:

  • 带有一些持久存储的套接字--您可以使用套接字实现后端服务器,并为android(ios/web/桌面)应用程序添加这种支持。这是实现设备间实时同步的最常见和最低级的机制。优点:跨平台通用,行业标准,在线大量信息。缺点:由于这是一个相对较低的级别,需要大量的代码,如果存在大量的同步事件,需要后端,需要单独的持久性,则可能非常复杂和复杂。主要实现:Socket.io
  • Firebase 实时数据库/ 云雾恢复 -基本上是将套接字与某些数据库结合在一起包装。"Pros":既不需要后端也不需要数据库,对原型/低负载应用程序免费,非常直接的实现,跨平台,运行良好。缺点:很多样板--如果你想走“干净的道路”,你无法控制内部流程,在高负载下不太明显的付费计算,你把自己和第三方后端与特定的API连接起来--如果你想在没有完全的应用程序重做的情况下从其他地方移动,就需要定义得很好的架构。比较:防火墙云防火墙与实时数据库

我将不详细介绍实现,因为在这种情况下,正式文档非常简单(与google驱动器不同)。

Cloud Firestore文档

Realtime Database文档

编辑端

是。可以使用Google Drive私下存储数据。它将只能通过您的应用程序访问。此外,它不会占用用户的任何空间Google Drive,这是相当方便。在这种情况下,跨平台是可能的,但它需要单独为iOs和Android实现(SDK不支持开箱即用)。

因此,该解决方案基于Google,更具体地说是基于它的存储特定于应用程序的数据部分。

这方面的用户操作唯一可见的是google登录提示。

这里是Java的一个详细的快速启动。

因此,为了做到这一点,您需要:

  • 增加依赖关系;
  • 像描述的这里这里那样实现google
  • 非常重要,使用drive.appdatadrive.file作用域对用户进行身份验证。另外,Google控制台中的启用 Google。所有这些都被描述为这里
  • 找出Room SQLite文件的位置,如下所示:String currentDBPath = context.getDatabasePath("your_database_name.db").getAbsolutePath();
  • 将文件上传到Google文件夹,就像这里描述的那样

基本上它看起来是这样的

  • 控制台中的启用 Google潜水API
  • 添加依赖项(可能需要更新到相关版本)
代码语言:javascript
运行
复制
implementation 'com.google.android.gms:play-services-auth:17.0.0'// for google sign in

// for drive integration
implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation 'com.google.http-client:google-http-client-gson:1.26.0'
implementation('com.google.api-client:google-api-client-android:1.26.0') {
exclude group: 'org.apache.httpcomponents'
}
implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0') 
{
exclude group: 'org.apache.httpcomponents'
} 
  • android级标签中
代码语言:javascript
运行
复制
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/ASL2.0'
}
  • 清单
代码语言:javascript
运行
复制
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  • Google使用所需的作用域
代码语言:javascript
运行
复制
       val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestScopes(
                 Scope(Scopes.DRIVE_FILE),
                 Scope(Scopes.DRIVE_APPFOLDER)
            )
            .requestEmail()
            .build()
        googleSingInClient = GoogleSignIn.getClient(this, gso)
        val signInIntent = googleSingInClient.signInIntent
        startActivityForResult(signInIntent, RC_SIGN_IN)
        ... // handle sign in result
  • 设置服务(上下文在其中)
代码语言:javascript
运行
复制
        val mAccount = GoogleSignIn.getLastSignedInAccount(this)

        val credential =
            GoogleAccountCredential.usingOAuth2(
                applicationContext, Collections.singleton(Scopes.DRIVE_FILE)
            )
        credential.setSelectedAccount(mAccount.getAccount())
        val googleDriveService =
            Drive.Builder(
                AndroidHttp.newCompatibleTransport(),
                GsonFactory(),
                credential
            )
                .setApplicationName("Your app name")
                .build()
  • 创建和发送文件
代码语言:javascript
运行
复制
        val fileMetadata = File()
        fileMetadata.setName("your_database_name.db")
        fileMetadata.setParents(Collections.singletonList("appDataFolder"))
        val databasePath = context.getDatabasePath("your_database_name.db").absolutePath
        val filePath = File(databasePath)
        val mediaContent = FileContent("application/sqlite", filePath)
        val file = driveService.files().create(fileMetadata, mediaContent)
            .setFields("id")
            .execute()
  • 在其他设备上搜索文件
代码语言:javascript
运行
复制
        val files = driveService.files().list()
            .setSpaces("appDataFolder")
            .setFields("nextPageToken, files(id, name)")
            .setPageSize(10)
            .execute()
        for (file in files.getFiles()) {
            // get file here 
        }

更多的信息,你可能会得到这里

希望能帮上忙。

票数 9
EN

Stack Overflow用户

发布于 2020-04-20 12:08:41

您可以使用Firebase中的云FireStore来实现这个https://firebase.google.com/docs/firestore

这是scalabe,Google已被废弃。我个人已经在其中一个应用程序中使用了FireStore,它运行得很好。巴拉特

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61155034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档