Google drive api 如何在Google Drive中查看隐藏的应用程序数据?
我有一个Android应用程序,可以在其中存储我的笔记。我想导出我的笔记,因此问题很简单:Google drive api 如何在Google Drive中查看隐藏的应用程序数据?,google-drive-api,Google Drive Api,我有一个Android应用程序,可以在其中存储我的笔记。我想导出我的笔记,因此问题很简单: 如何访问特定应用程序的Google Drive中隐藏的应用程序数据 用户无法直接访问隐藏应用程序文件夹中的数据,只有应用程序可以访问这些文件夹。这是为用户不应直接操作的配置或其他隐藏数据而设计的。(用户可以选择删除数据以释放数据使用的空间。) 用户访问它的唯一方式是通过特定应用程序公开的某些功能。事实上,谷歌不允许您直接访问这个隐藏的应用程序数据文件夹 但是,如果你可以获得应用程序的客户端ID/客户端机密
如何访问特定应用程序的Google Drive中隐藏的应用程序数据 用户无法直接访问隐藏应用程序文件夹中的数据,只有应用程序可以访问这些文件夹。这是为用户不应直接操作的配置或其他隐藏数据而设计的。(用户可以选择删除数据以释放数据使用的空间。)
用户访问它的唯一方式是通过特定应用程序公开的某些功能。事实上,谷歌不允许您直接访问这个隐藏的应用程序数据文件夹 但是,如果你可以获得应用程序的客户端ID/客户端机密/数字签名,用于对谷歌服务器进行身份验证,那么是的,你基本上可以模拟应用程序,并使用驱动器API访问谷歌驱动器中的隐藏数据 它在Android中的工作原理 通常,当安卓应用程序想要访问谷歌API(例如,游戏或谷歌登录-并非所有都受支持)时,它会与进行通信,然后谷歌会代表应用程序从谷歌获得访问令牌。该访问令牌随后随每个请求一起发送到API,以便Google知道谁在使用它以及允许他对您的帐户做什么()。为了第一次获得此访问令牌,Google Play服务向
android.clients.Google.com/auth
发送一个HTTPS POST请求,其中包含以下字段(以及其他详细信息):
-一种“主令牌”,用于标识Google帐户,基本上允许对其进行完全访问Token
-应用程序包名称,如app
com.whatsapp
-应用程序的数字签名(作为SHA1发送)client\u sig
-设备的设备
-应用程序希望拥有的(权限)服务
.apk
文件中提取签名:
shell> unzip whatsapp.apk META-INF/*
Archive: whatsapp.apk
inflating: META-INF/MANIFEST.MF
inflating: META-INF/WHATSAPP.SF
inflating: META-INF/WHATSAPP.DSA
shell> cd META-INF
shell> keytool -printcert -file WHATSAPP.DSA # can be CERT.RSA or similar
.....
Certificate fingerprints:
SHA1: 38:A0:F7:D5:05:FE:18:FE:C6:4F:BF:34:3E:CA:AA:F3:10:DB:D7:99
Signature algorithm name: SHA1withDSA
Version: 3
接下来我们需要的是主代币。当添加新的google帐户时(例如,首次设置手机时),通过向同一URL发出类似请求,通常会接收并存储此特殊令牌。不同之处在于,现在请求权限的应用程序是Play services应用程序本身(com.google.android.gms
),谷歌还获得了额外的Email
和Passwd
参数来登录。如果请求成功,我们将取回主令牌,然后将其添加到用户的应用程序请求中
有关身份验证过程的更多详细信息,请参阅
把它们放在一起
现在,我们可以直接使用这两个HTTP请求编写身份验证代码——一个可以使用任何Google帐户浏览任何应用程序文件的代码。只需选择您最喜欢的编程语言和。我发现使用以下方法更容易:
require\uuuuuu DIR\uuuuuuuuu.'/供应商/autoload.php';//谷歌硬盘API
//HTTPS身份验证
$masterToken=getMasterTokenForAccount(“您的_username@gmail.com“,“您的密码”);
$appSignature='38A0F7D505FE18FEC64FBF343ECAAF310DBD799';
$appID='com.whatsapp';
$accessToken=getGoogleDriveAccessToken($masterToken、$appID、$appSignature);
如果($accessToken==false)返回;
//初始化Google驱动器客户端
$client=新的Google_客户端();
$client->setAccessToken($accessToken);
$client->addScope(Google\u Service\u Drive::Drive\u APPDATA);
$client->addScope(谷歌服务驱动::驱动文件);
$client->setClientId(“”;//客户端id和客户端机密可以留空
$client->setClientSecret(“”;//因为我们假装是安卓客户端
$service=新的谷歌服务驱动器($client);
//打印最多10个文件的名称和ID。
$optParams=阵列(
“空格”=>“appDataFolder”,
'字段'=>'下一个GetOken,文件(id,名称)',
“页面大小”=>10
);
$results=$service->files->listFiles($optrams);
如果(计数($results->getFiles())==0)
{
打印“找不到文件。\n”;
}
其他的
{
打印“文件:\n”;
foreach($results->getFiles()作为$file)
{
打印$file->getName()。“(“$file->getId()。”)\n”;
}
}
/*
$fileId='1KTFG5TMGIGTPJUVYNWHKXXLPGZ32QNPJCE5JXL8DTN0';
$content=$service->files->get($fileId,array('alt'=>'media'));
echo var_dump($content);
*/
函数getGoogleDriveAccessToken($masterToken、$appIdentifier、$appSignature)
{
如果($masterToken==false),则返回false;
$url='1https://android.clients.google.com/auth';
$deviceID='0000000000000000';
$requestedService='oauth2:https://www.googleapis.com/auth/drive.appdata https://www.googleapis.com/auth/drive.file';
$data=array('Token'=>$masterToken',app'=>$appIdentifier',client\u sig'=>$appSignature',device'=>$deviceID',google\u play\u services\u version'=>'8703000',service'=>$requestedService',has\u permission'=>'1');
$options=array(
“http'=>数组(
“标题”=>“内容类型:应用程序/x-www-form-urlencoded\r\n连接:关闭”,
'方法'=>'发布',
'content'=>http\u build\u query($data),
“忽略错误”=>TRUE,
“协议_版本”=>“1.1”,
//'代理'=>'tcp://127.0.0.1:8080“,//用于调试的可选代理
//'request_fulluri'=>true
)
);
$context=stream\u context\u create($options);
$result=file\u get\u contents($url,false,$context);
if(strpos($http\u response\u头[0],'200ok')==false)
{
/*处理错误*/
打印“请求访问令牌时出错:”。$result。“\r\n”;
返回false;
}
$startsAt=strpos($result,“Auth=”)+strlen(“Auth=”);
$endsAt
Files:
gdrive_file_map (1d9QxgC3p4PTXRm_fkAY0OOuTGAckykmDfFls5bAyE1rp)
Databases/msgstore.db.crypt9 (1kTFG5TmgIGTPJuVynWfhkXxLPgz32QnPJCe5jxL8dTn0)
16467702039-invisible (1yHFaxfmuB5xRQHLyRfKlUCVZDkgT1zkcbNWoOuyv1WAR)
Done.
private void listFiles() {
Query query =
new Query.Builder()
.addFilter(Filters.or(Filters.eq(SearchableField.MIME_TYPE, "text/html"),
Filters.eq(SearchableField.MIME_TYPE, "text/plain")))
.build();
getDriveResourceClient()
.query(query)
.addOnSuccessListener(this,
new OnSuccessListener<MetadataBuffer>() {
@Override
public void onSuccess(MetadataBuffer metadataBuffer) {
//mResultsAdapter.append(metadataBuffer);
for (int i = 0; i <metadataBuffer.getCount() ; i++) {
retrieveContents(metadataBuffer.get(i).getDriveId().asDriveFile());
}
}
}
)
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.e(TAG, "Error retrieving files", e);
MainActivity.this.finish();
}
});
}
public void retrieveContents(DriveFile file) {
Task<DriveContents> openFileTask =
getDriveResourceClient().openFile(file, DriveFile.MODE_READ_ONLY);
openFileTask.continueWithTask(new Continuation<DriveContents, Task<Void>>() {
@Override
public Task<Void> then(@NonNull Task<DriveContents> task) throws Exception {
DriveContents contents = task.getResult();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(contents.getInputStream()))) {
StringBuilder builder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
builder.append(line).append("\n");
}
Log.e("result ", builder.toString());
}
Task<Void> discardTask = MainActivity.this.getDriveResourceClient().discardContents(contents);
// [END drive_android_discard_contents]
return discardTask;
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
}
});
}