- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
谷歌正在搁置其用于访问谷歌服务(即Google云端硬盘)的Android API,并将其替换为REST。
尽管有“迁移指南”,但由于“重复类定义”之类的原因,它无法构建可供安装的APK软件包。
由于某种原因,要找到关于如何通过Android使用REST(最好使用OS固有的方法)访问Google服务的全面信息非常困难。
最佳答案
经过大量的搜索,困惑,挠头,偶尔的咒骂以及对我真正不想关心的事情的大量学习之后,我想分享一些实际上对我有用的代码。
免责声明:我是一名菜鸟Android程序员(他的确不怎么挑衅),因此,如果这里有真正的Android向导摇头的事情,希望您能原谅我。
所有代码示例均使用Kotlin和Android Studio编写。
值得注意的是:在本小教程中仅查询“应用程序数据文件夹”,如果要执行其他操作,则需要调整请求的scopes
。
必要的准备工作
按照here所述为您的应用程序创建一个项目和一个OAuth密钥。我收集的许多授权信息都来自那个地方,因此希望能找到一些相似之处。
您的项目的仪表板可以在https://console.developers.google.com/apis/dashboard中找到
将implementation "com.google.android.gms:play-services-auth:16.0.1"
添加到您的应用程序gradle文件中。此依赖关系将用于身份验证目的。
为您的应用程序 list 添加“互联网”支持
<uses-permission android:name="android.permission.INTERNET"/>
GoogleSignIn
框架。
if (requestCode == RC_SIGN_IN) {
GoogleSignIn.getSignedInAccountFromIntent(data)
.addOnSuccessListener(::evaluateResponse)
.addOnFailureListener { e ->
Log.w(RecipeList.TAG, "signInResult:failed =" + e.toString())
evaluateResponse(null)
}
}
RC_REQUEST_CODE
是在随播对象中定义为常量的任意选择的ID值。
GoogleSignIn.getClient(this, GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken("YourClientIDGoesHere.apps.googleusercontent.com")
.requestScopes(Scope(Scopes.DRIVE_APPFOLDER))
.build())
startActivityForResult(client.signInIntent, RC_SIGN_IN)
onActivityResult
GoogleSignIn.getLastSignedInAccount(this);
方法。
null
,因此请准备好进行处理。
GoogleAuthUtil.getToken(this, account.account, "oauth2:https://www.googleapis.com/auth/drive.appdata")
调用。
private fun performNet(url: String, method: String, onSuccess: (JSONObject) -> Unit)
{
ThreadedTask<String>()
.addOnSuccess { onSuccess(JSONObject(it)) }
.addOnFailure { Log.w("DriveSync", "Sync failure $it") }
.execute(executor) {
val url = URL(url)
with (url.openConnection() as HttpURLConnection)
{
requestMethod = method
useCaches = false
doInput = true
doOutput = false
setRequestProperty("Authorization", "Bearer $authToken")
processNetResponse(responseCode, this)
}
}
}
private fun processNetResponse(responseCode: Int, connection: HttpURLConnection) : String
{
var responseData = "No Data"
val requestOK = (responseCode == HttpURLConnection.HTTP_OK)
BufferedReader(InputStreamReader(if (requestOK) connection.inputStream else connection.errorStream))
.use {
val response = StringBuffer()
var inputLine = it.readLine()
while (inputLine != null) {
response.append(inputLine)
inputLine = it.readLine()
}
responseData = response.toString()
}
if (!requestOK)
throw Exception("Bad request: $responseCode ($responseData)")
return responseData
}
GET
,
POST
,
PATCH
,
DELETE
)并从中构造HTTP请求。
onSuccess
,它将JSON回复转换为JSONObject,然后将其传递给我们之前注册的评估函数。
performNet("https://www.googleapis.com/drive/v3/files?spaces=appDataFolder", "GET")
spaces
参数用于告知Google,我们不想看到根文件夹,而是看到应用程序数据文件夹。没有此参数,请求将失败,因为我们仅请求访问appDataFolder。
JSONArray
键下包含一个
files
,然后您可以解析并绘制所需的任何信息。
import android.os.Handler
import android.os.Looper
import android.os.Message
import java.lang.Exception
import java.util.concurrent.Executor
class ThreadedTask<T> {
private val onSuccess = mutableListOf<(T) -> Unit>()
private val onFailure = mutableListOf<(String) -> Unit>()
private val onComplete = mutableListOf<() -> Unit>()
fun addOnSuccess(handler: (T) -> Unit) : ThreadedTask<T> { onSuccess.add(handler); return this; }
fun addOnFailure(handler: (String) -> Unit) : ThreadedTask<T> { onFailure.add(handler); return this; }
fun addOnComplete(handler: () -> Unit) : ThreadedTask<T> { onComplete.add(handler);return this; }
/**
* Performs the passed code in a threaded context and executes Success/Failure/Complete handler respectively on the calling thread.
* If any (uncaught) exception is triggered, the task is considered 'failed'.
* Call this method last in the chain to avoid race conditions while adding the handlers.
*
*/
fun execute(executor: Executor, code: () -> T)
{
val handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
publishResult(msg.what, msg.obj)
}
}
executor.execute {
try {
handler.obtainMessage(TASK_SUCCESS, code()).sendToTarget()
} catch (exception: Exception) {
handler.obtainMessage(TASK_FAILED, exception.toString()).sendToTarget()
}
}
}
private fun publishResult(returnCode: Int, returnValue: Any)
{
if (returnCode == TASK_FAILED)
onFailure.forEach { it(returnValue as String) }
else
onSuccess.forEach { it(returnValue as T) }
onComplete.forEach { it() }
// Removes all handlers, cleaning up potential retain cycles.
onFailure.clear()
onSuccess.clear()
onComplete.clear()
}
companion object {
private const val TASK_SUCCESS = 0
private const val TASK_FAILED = 1
}
}
execute
,并为其提供要使用其运行线程的执行器,当然还要提供要执行的代码。
关于android - 如何使用其REST API在Android上的Google云端硬盘上访问应用程序数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54052220/
我创建了一个具有高级非托管磁盘配置的 Azure RM VM。我有 1 个 127GB 的操作系统磁盘和一个大小为 56GB 的临时磁盘。我的操作系统磁盘还包含 SQL Server 和 ShareP
我正在开发一个目录树比较工具,它可以跨多台计算机工作,通过 TCP 与其他实例通信。 该工具运行良好,但到目前为止一直依赖于可由用户更改的驱动器号和标签。可移动驱动器是另一个问题。 我想通过某种唯一的
我正在使用硬盘 ID 为我的软件生成许可证 key 。在我的机器中,我得到 15 个字符长度的 ID。所有制造商的硬盘 ID 的这个长度是恒定的还是在它们之间变化? 是否有任何公认的方法来解释硬盘 I
本文实例讲述了java实现获取cpu、内存、硬盘、网络等信息的方法。分享给大家供大家参考,具体如下: 1. 下载安装sigar-1.6.4.zip 使用java自带的包获取系统数据,容易找不到包
我正在探索将 Aerospike 作为键值数据库,并将数据存储在磁盘上以确保安全。请确认,我理解正确: 如果在命名空间配置中我设置: 存储引擎设备 内存大小4G 文件/opt/aerospike/da
看着海藻,想换minio。主要原因 - 海藻可以很容易地用任意数量的节点/磁盘扩大。 但是对我的基础设施有几个问题。现在我有 2 个节点,每个节点有 100 个硬盘(HPE CL5800),它们被包含
我目前正在编写一个 CUDA 应用程序,并且遇到了一些“喂养野兽”的 IO 问题。 我想知道是否有任何方法可以直接从 RAID Controller 或 NIC 读取数据并将该数据直接发送到 GPU。
如何衡量文件(硬盘)I/O 的特性?例如,在具有硬盘(速度 X)和 cpu i7(或任何数量的内核)和 Y 数量的 ram(使用 Z Hz BIOS)的机器上(在 Windows 操作系统上): 可以
就像标题一样,我在裸机主机上安装了 RancherOS 并且想要 动态处理外部 USB 硬盘的添加/移除。它应该可以作为其他容器的绑定(bind)挂载访问。 最佳答案 你可以这样做: # udev_c
我想实现以下目标。 这样做的目的是让用户能够从他/她的硬盘驱动器中选择一个文件。 而没有上传的原因当然是传输成本和存储配额。没有理由保存文件。 这可能吗? 最佳答案 可以播放本地视频文件。 当
我想实现以下目标。 这样做的目的是让用户能够从他/她的硬盘驱动器中选择一个文件。 而没有上传的原因当然是传输成本和存储配额。没有理由保存文件。 这可能吗? 最佳答案 可以播放本地视频文件。 当
对于这些实例,在 C++ 运行时,有人可以大致说明什么是什么(硬盘、RAM、堆栈或堆): 局部/全局变量 类、方法和函数 指针 对象 堆栈/堆是否都位于物理 RAM 中? 如果有人可以在答案中包含硬件
我是 Synology 的新手。我想要访问我的 Synology NAS 驱动器。我遵循 Synology_Download_Station_Official_API。 我阅读了基本工作示例以获取 A
我想知道Linux(特别是树莓派)是否可以实现将我的有线电视接收器连接到我的树莓派(主/从?)有线电视接收器认为树莓派是硬盘但同时允许网络中的客户端获取录制的电影(当然不是正在录制的电影) 我猜 WD
由于我在本地主机上构建了许多虚拟网络,并且 htdocs 文件夹中的数据每天都在增加。 我想将 htdocs 文件夹移动到外部硬盘,可以这样做吗? 我尝试编辑 httpd.conf 文件。但是当我打开
我是一名优秀的程序员,十分优秀!