Android的打开和保存文件到/从谷歌驱动器SDK [英] Android Open and Save files to/from Google Drive SDK

查看:213
本文介绍了Android的打开和保存文件到/从谷歌驱动器SDK的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了最近六小时浇筑了来自谷歌的文档,我仍然不知道如何开始与此有关。所有我想要做的就是让它所以我现有的Andr​​oid应用程序可以阅读从谷歌硬盘中的文件,上传新文件到谷歌驱动器,以及谷歌驱动器编辑现有的文件。

我读过驱动器SDK V2是只集中在使它容易为Android(和移动一般),开发人员可以使用它,但似乎有几乎没有在其关于它的文档。

在理想情况下,我想有人指出,在一些体面的文件,例如,或教程涵盖如何做到这一点(记住我使用Android系统。他们有很多东西在如何使用驱动器与谷歌应用程序发动机;我已经看了一下,我不知道如何从去Android应用程序)

我需要知道哪些库我需要下载并添加到我的项目,我需要添加到我的表现,我怎么能最终获得来自谷歌硬盘中的文件列表,下载一个,然后上传修改后的版本。

在理想情况下,我想它会自动处理帐户,该官方谷歌驱动器应用程序做的方式。

解决方案

编辑:克劳迪奥凯鲁比诺说,谷歌播放服务现已推出,将使得这一过程变得更加简单。然而,有没有样品code可用(然而,他说这是即将推出......他们说,谷歌播放服务是即将推出4个月前,所以这是一个很好的机会,这个答案将继续是唯一完全工作例如访问谷歌驱动器从你的Andr​​oid应用程序到2013年。)

编辑2X:貌似我被关了大约一个月的时候我说,谷歌不会有工作的例子到明年。从谷歌的官方指导价是在这里:

https://developers.google.com/drive/quickstart-android

我没有测试他们的方法还没有,所以它可能是我的解决方案,从2012年9月(下)仍然是最好的:

谷歌播放服务不需要这个。它在一个痛苦的对接,和我花了远远超过50小时(编辑:100个小时)搞清楚这一切了,但这里的很多东西,这将有助于了解:

有关谷歌在一般的网络服务,你需要这些库在您的项目:(说明和下载链接

  • 在谷歌的API客户端-1.11.0-beta.jar
  • 在谷歌的API客户端,Android为1.11.0-beta.jar
  • 在谷歌的HTTP客户端-1.11.0-beta.jar
  • 在谷歌的HTTP客户端,Android为1.11.0-beta.jar
  • 在谷歌的HTTP客户端 - 杰克逊-1.11.0-beta.jar
  • 在谷歌的OAuth客户端-1.11.0-beta.jar
  • 番石榴11.0.1.jar
  • 杰克逊核心ASL-1.9.9.jar
  • jsr305-1.3.9.jar

有关谷歌驱动器尤其是你还需要这样的:

  • 谷歌API的服务驱动-V2-rev9-1.8.0-beta.jar(<一href="http://mavenrepo.google-api-java-client.google$c$c.com/hg/com/google/apis/google-api-services-drive/v2-rev9-1.8.0-beta/"相对=nofollow>下载链接)

设置控制台

接下来,进入谷歌控制台。创建一个新的项目。在服务,你需要打开两件事情: DRIVE API DRIVE SDK !他们是独立的,一个不自动打开其他的,和你必须把二者都在!(搞清楚了这一点浪费了至少20个小时的单独我的时间。)

不过在控制台上,去API访问。创建一个客户端,使其成为一个Android应用程序。给它你的包ID。我不认为指纹东西其实很重要,因为我是pretty的肯定,我用错了,而是试图让这项权利反正(谷歌提供有关它。)

它会生成一个客户端ID 。你会需要的。抓住它。

编辑:有人告诉我,我是错误的,你只需要打开驱动器API,驱动器的SDK并不需要打开所有,而你只需要使用简单的API密钥,不设置一些为Android。我寻找到了现在,并可能会修改这个答案在几分钟内,如果我搞清楚了......

在Android code - 建立和上传

首先,获得身份验证令牌:

 的AccountManager AM = AccountManager.get(活动);
am.getAuthToken(am.getAccounts())[0],
    oauth2:+ DriveScopes.DRIVE,
    新包()
    真正,
    新OnTokenAcquired(),
    空值);
 

接下来,OnTokenAcquired()需要被设置是这样的:

 私有类OnTokenAcquired实现AccountManagerCallback&LT;包&GT; {
    @覆盖
    公共无效的run(AccountManagerFuture&LT;包&GT;的结果){
        尝试 {
            最终字符串标记= result.getResult()的getString(AccountManager.KEY_AUTHTOKEN)。
            HttpTransport httpTransport =新NetHttpTransport();
            JacksonFactory jsonFactory =新JacksonFactory();
            Drive.Builder B =新Drive.Builder(httpTransport,jsonFactory,NULL);
            b.setJsonHtt prequestInitializer(新JsonHtt prequestInitializer(){
                @覆盖
                公共无效初始化(JSonHtt prequest要求)抛出IOException异常{
                    DriveRequest driveRequest =(DriveRequest)请求;
                    driveRequest.set prettyPrint(真正的);
                    driveRequest.setKey(客户端ID你有在设置控制台之前,你开始编码)
                    driveRequest.setOauthToken(标记);
                }
            });

            最终的驱动器驱动器= b.build();

            最后com.google.api.services.drive.model.File体=新com.google.api.services.drive.model.File();
            body.setTitle(我的测试文件);
    body.setDescription(测试文件);
    body.setMimeType(text / plain的);

            最后FileContent mediaContent =新FileContent(它使用一个FileWriter什么text / plain的,一个普通的java.io.File你要上传,制作,这真是这个答案的范围之内。)
            新主题(新的Runnable(){
                公共无效的run(){
                    尝试 {
                        。com.google.api.services.drive.model.File文件= drive.files()插入(身体,mediaContent).execute();
                        alreadyTriedAgain = FALSE; //全球布尔,以确保您不要反复尝试过很多次,当服务器关闭或code出现故障......他们会阻止请求,直到第二天如果你让10错误的请求,我发现。
                    }赶上(IOException异常E){
                        如果(!alreadyTriedAgain){
                            alreadyTriedAgain = TRUE;
                            的AccountManager AM = AccountManager.get(活动);
                            am.invalidateAuthToken(am.getAccounts()[0] .TYPE,NULL); //需要的权限MANAGE_ACCOUNTS和放大器;在清单USE_CREDENTIALS
                            am.getAuthToken(和以前一样...)
                        } 其他 {
                            // 放弃。崩溃或登录错误或任何你想要的。
                        }
                    }
                }
            })。开始();
            意向推出=(意向)result.getResult()得到(AccountManager.KEY_INTENT)。
            如果(推出!= NULL){
                startActivityForResult(发射,3025);
                返回; //不知道为什么......我在这里写的出于某种原因。可能实际上并不需要。
            }
        }赶上(OperationCanceledException E){
            // 处理它...
        }赶上(AuthenticatorException E){
            // 处理它...
        }赶上(IOException异常E){
            // 处理它...
        }
    }
}
 

在Android code - 下载

 私人java.io.File中downloadGFileToJFolder(驱动器驱动器,串记号,文件GFILE,java.io.File中jFolder)抛出IOException异常{
    如果(gFile.getDownloadUrl()=空&安培;!&安培; gFile.getDownloadUrl()长度()大于0){
        如果(jFolder == NULL){
            jFolder = Environment.getExternalStorageDirectory();
            jFolder.mkdirs();
        }
        尝试 {

            HttpClient的客户端=新DefaultHttpClient();
            HTTPGET GET =新HTTPGET(gFile.getDownloadUrl());
            get.setHeader(授权,承载+令牌);
            HTT presponse响应= client.execute(获得);

            InputStream中的InputStream = response.getEntity()的getContent()。
            jFolder.mkdirs();
            java.io.File的jFile =新的java.io.File(jFolder.getAbsolutePath()+/+ getGFileName(GFILE)); // getGFileName()是我自己的方法......它只是抓住originalFilename如果存在或标题,如果它没有。
            FileOutputStream中FILESTREAM =新的FileOutputStream(jFile);
            字节的缓冲区[] =新的字节[1024];
            INT长;
            而((长度= inputStream.read(缓冲液))大于0){
                fileStream.write(缓冲液,0,长度);
            }
            fileStream.close();
            inputStream.close();
            返回jFile;
        }赶上(IOException异常E){
            //处理的IOExceptions这里...
            返回null;
        }
    } 其他 {
        //处理,其中对谷歌驱动器的文件没有长度这里的情况。
        返回null;
    }
}
 

最后一件事......如果这一意图被被罚下,你需要处理时,它的结果返回。

  @覆盖
保护无效onActivityResult(INT申请code,INT结果code,意图数据){
    如果(要求code == 3025){
        开关(结果code){
            案例RESULT_OK:
                的AccountManager AM = AccountManager.get(活动);
                am.getAuthToken(同其他两个时代......它应该工作这段时间,虽然,因为现在实际上是登录用户。)
                打破;
            案例RESULT_CANCELED:
                //这可能意味着用户拒绝登录。向他们解释为什么他们需要登录。
                打破;
            默认:
                //这不是预期的...也许只要登录返回任何code。
                打破;
        }
    } 其他 {
        //你的应用程序,它触发了除了一个用于驱动器的记录,如果它曾经达到这点在其他意图。它处理在这里,但是你会喜欢。
    }
}
 

在Android code - 更新

在更新的谷歌驱动器文件的最后修改日期的两个快速说明:

  1. 您必须提供一个完全初始化的日期时间。如果你不这样做,你会得到谷歌驱动器错误的请求的响应。
  2. 您必须使用从谷歌驱动器和setSetModifiedDate(真)上的更新请求本身的文件既setModifiedDate()。 (有趣的名字,是吧?setSet [...],没有办法的人可以输错一个......)

下面是一些简单的示例code,展示了如何做一个更新,包括更新文件时间:

 公共无效updateGFileFromJFile(驱动器的驱动器,文件GFILE,java.io.File中jFile)抛出IOException异常{
    FileContent gContent =新FileContent(文/ CSV,jFile);
    gFile.setModifiedDate(新的日期时间(假,jFile.lastModified(),0));
    GFILE = drive.files()更新(gFile.getId(),GFILE,gContent).setSetModifiedDate(真).execute()。
}
 

清单中

您将需要以下权限:GET_ACCOUNTS,USE_CREDENTIALS,MANAGE_ACCOUNTS,互联网和有你需要WRITE_EXTERNAL_STORAG​​E为好,这取决于你想存储文件的本地副本的好机会

您的构建目标

右键单击您的项目,进入它的属性,而Android在构建目标更改为谷歌的API,如果你一定要。如果它们不存在,从Android下载管理器进行下载。

如果您正在测试模拟器上,要确保它的目标是谷歌的API,而不是普通的Andr​​oid系统。

您将需要一个谷歌帐户设置测试设备上。书面会自动将其找到的第一个谷歌帐户的code(这是[0]是什么。)IDK如果需要下载了谷歌硬盘应用此发挥了作用。我用的是API等级15,我不知道这回code将在多大程度上工作。

其余

以上应该让你开始,希望你可以计算你的出路在那里......说实话,这只是就我到目前为止得到。我希望这有助于人们了很多,为他们节省了很多时间。我相当肯定我刚刚写过的最COM prehensive设置向导建立一个Android应用程序使用谷歌驱动器。可耻的是谷歌对于s preading必要的物质经过至少6个不同的页面不链接到对方都没有。

I've spent the last six hours pouring over documents from Google and I still don't know how to get started with this. All I want to do is make it so my existing Android app can read files from Google Drive, upload new files to Google Drive, and edit existing files on Google Drive.

I've read that Drive SDK v2 was focused solely on making it easy for Android (and mobile in general) developers to use it, and yet there seems to be virtually nothing in their documentation about it.

Ideally, I'd like someone to point at some decent documentation, example, or tutorial covering how to do this (keep in mind I'm using Android. They have plenty of stuff on how to use Drive with the Google App Engine; I have already looked at it and I have no idea how to go from that to an Android app.)

I need to know which libraries I need to download and add to my project, what I need to add to my manifest, and how I can ultimately get a list of files from Google Drive, download one, and then upload a modified version.

Ideally, I'd like it to handle accounts automatically, the way that the officially Google Drive app does.

解决方案

Edit: Claudio Cherubino says that Google Play Services is now available and will make this process a lot easier. However, there's no sample code available (yet, he says it's coming soon... they said Google Play Services was "coming soon" 4 months ago, so there's a good chance this answer will continue to be the only completely working example of accessing Google Drive from your Android application into 2013.)

Edit 2X: Looks like I was off by about a month when I said Google wouldn't have a working example until next year. The official guide from Google is over here:

https://developers.google.com/drive/quickstart-android

I haven't tested their methods yet, so it's possible that my solutions from September 2012 (below) are still the best:

Google Play Services is NOT REQUIRED for this. It's a pain in the butt, and I spent well over 50 hours (edit: 100+ hours) figuring it all out, but here's a lot of things that it'll help to know:

THE LIBRARIES

For Google's online services in general you'll need these libraries in your project: (Instructions and Download Link)

  • google-api-client-1.11.0-beta.jar
  • google-api-client-android-1.11.0-beta.jar
  • google-http-client-1.11.0-beta.jar
  • google-http-client-android-1.11.0-beta.jar
  • google-http-client-jackson-1.11.0-beta.jar
  • google-oauth-client-1.11.0-beta.jar
  • guava-11.0.1.jar
  • jackson-core-asl-1.9.9.jar
  • jsr305-1.3.9.jar

For Google Drive in particular you'll also need this:

  • google-api-services-drive-v2-rev9-1.8.0-beta.jar (Download Link)

SETTING UP THE CONSOLE

Next, go to Google Console. Make a new project. Under Services, you'll need to turn on two things: DRIVE API and DRIVE SDK! They are separate, one does not automatically turn the other on, and YOU MUST TURN BOTH ON! (Figuring this out wasted at least 20 hours of my time alone.)

Still on the console, go to API Access. Create a client, make it an Android app. Give it your bundle ID. I don't think the fingerprints thing is actually important, as I'm pretty sure I used the wrong one, but try to get that right anyways (Google provides instructions for it.)

It'll generate a Client ID. You're going to need that. Hold onto it.

Edit: I've been told that I'm mistaken and that you only need to turn on Drive API, Drive SDK doesn't need to be turned on at all, and that you just need to use the Simple API Key, not set up something for Android. I'm looking into that right now and will probably edit this answer in a few minutes if i figure it out...

THE ANDROID CODE - Set Up and Uploading

First, get an auth token:

AccountManager am = AccountManager.get(activity);
am.getAuthToken(am.getAccounts())[0],
    "oauth2:" + DriveScopes.DRIVE,
    new Bundle(),
    true,
    new OnTokenAcquired(),
    null);

Next, OnTokenAcquired() needs to be set up something like this:

private class OnTokenAcquired implements AccountManagerCallback<Bundle> {
    @Override
    public void run(AccountManagerFuture<Bundle> result) {
        try {
            final String token = result.getResult().getString(AccountManager.KEY_AUTHTOKEN);
            HttpTransport httpTransport = new NetHttpTransport();
            JacksonFactory jsonFactory = new JacksonFactory();
            Drive.Builder b = new Drive.Builder(httpTransport, jsonFactory, null);
            b.setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() {
                @Override
                public void initialize(JSonHttpRequest request) throws IOException {
                    DriveRequest driveRequest = (DriveRequest) request;
                    driveRequest.setPrettyPrint(true);
                    driveRequest.setKey(CLIENT ID YOU GOT WHEN SETTING UP THE CONSOLE BEFORE YOU STARTED CODING)
                    driveRequest.setOauthToken(token);
                }
            });

            final Drive drive = b.build();

            final com.google.api.services.drive.model.File body = new com.google.api.services.drive.model.File();
            body.setTitle("My Test File");
    body.setDescription("A Test File");
    body.setMimeType("text/plain");

            final FileContent mediaContent = new FileContent("text/plain", an ordinary java.io.File you'd like to upload. Make it using a FileWriter or something, that's really outside the scope of this answer.)
            new Thread(new Runnable() {
                public void run() {
                    try {
                        com.google.api.services.drive.model.File file = drive.files().insert(body, mediaContent).execute();
                        alreadyTriedAgain = false; // Global boolean to make sure you don't repeatedly try too many times when the server is down or your code is faulty... they'll block requests until the next day if you make 10 bad requests, I found.
                    } catch (IOException e) {
                        if (!alreadyTriedAgain) {
                            alreadyTriedAgain = true;
                            AccountManager am = AccountManager.get(activity);
                            am.invalidateAuthToken(am.getAccounts()[0].type, null); // Requires the permissions MANAGE_ACCOUNTS & USE_CREDENTIALS in the Manifest
                            am.getAuthToken (same as before...)
                        } else {
                            // Give up. Crash or log an error or whatever you want.
                        }
                    }
                }
            }).start();
            Intent launch = (Intent)result.getResult().get(AccountManager.KEY_INTENT);
            if (launch != null) {
                startActivityForResult(launch, 3025);
                return; // Not sure why... I wrote it here for some reason. Might not actually be necessary.
            }
        } catch (OperationCanceledException e) {
            // Handle it...
        } catch (AuthenticatorException e) {
            // Handle it...
        } catch (IOException e) {
            // Handle it...
        }
    }
}

THE ANDROID CODE - Downloading

private java.io.File downloadGFileToJFolder(Drive drive, String token, File gFile, java.io.File jFolder) throws IOException {
    if (gFile.getDownloadUrl() != null && gFile.getDownloadUrl().length() > 0 ) {
        if (jFolder == null) {
            jFolder = Environment.getExternalStorageDirectory();
            jFolder.mkdirs();
        }
        try {

            HttpClient client = new DefaultHttpClient();
            HttpGet get = new HttpGet(gFile.getDownloadUrl());
            get.setHeader("Authorization", "Bearer " + token);
            HttpResponse response = client.execute(get);

            InputStream inputStream = response.getEntity().getContent();
            jFolder.mkdirs();
            java.io.File jFile = new java.io.File(jFolder.getAbsolutePath() + "/" + getGFileName(gFile)); // getGFileName() is my own method... it just grabs originalFilename if it exists or title if it doesn't.
            FileOutputStream fileStream = new FileOutputStream(jFile);
            byte buffer[] = new byte[1024];
            int length;
            while ((length=inputStream.read(buffer))>0) {
                fileStream.write(buffer, 0, length);
            }
            fileStream.close();
            inputStream.close();
            return jFile;
        } catch (IOException e) {        
            // Handle IOExceptions here...
            return null;
        }
    } else {
        // Handle the case where the file on Google Drive has no length here.
        return null;
    }
}

One last thing... if that intent gets sent off, you'll need to handle when it returns with a result.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 3025) {
        switch (resultCode) {
            case RESULT_OK:
                AccountManager am = AccountManager.get(activity);
                am.getAuthToken(Same as the other two times... it should work this time though, because now the user is actually logged in.)
                break;
            case RESULT_CANCELED:
                // This probably means the user refused to log in. Explain to them why they need to log in.
                break;
            default:
                // This isn't expected... maybe just log whatever code was returned.
                break;
        }
    } else {
        // Your application has other intents that it fires off besides the one for Drive's log in if it ever reaches this spot. Handle it here however you'd like.
    }
}

THE ANDROID CODE - Updating

Two quick notes on updating the last modified date of a file on Google Drive:

  1. You must provide a fully initialized DateTime. If you do not, you'll get a response of "Bad Request" from Google Drive.
  2. You must use both setModifiedDate() on the File from Google Drive and setSetModifiedDate(true) on the update request itself. (Fun name, huh? "setSet[...]", there's no way people could mistype that one...)

Here's some brief sample code showing how to do an update, including updating the file time:

public void updateGFileFromJFile(Drive drive, File gFile, java.io.File jFile) throws IOException {
    FileContent gContent = new FileContent("text/csv", jFile);
    gFile.setModifiedDate(new DateTime(false, jFile.lastModified(), 0));
    gFile = drive.files().update(gFile.getId(), gFile, gContent).setSetModifiedDate(true).execute();
}

THE MANIFEST

You'll need the following permissions: GET_ACCOUNTS, USE_CREDENTIALS, MANAGE_ACCOUNTS, INTERNET, and there's a good chance you'll need WRITE_EXTERNAL_STORAGE as well, depending on where you'd like to store the local copies of your files.

YOUR BUILD TARGET

Right click your project, go into it's properties, and under Android change the build target to Google APIs if you must. If they aren't there, download them from the android download manager.

If you're testing on an emulator, make sure its target is Google APIs, not generic Android.

You'll need a Google Account set up on your test device. The code as written will automatically use the first Google Account it finds (that's what the [0] is.) IDK if you need to have downloaded the Google Drive app for this to have worked. I was using API Level 15, I don't know how far back this code will work.

THE REST

The above should get you started and hopefully you can figure your way out from there... honestly, this is just about as far as I've gotten so far. I hope this helps A LOT of people and saves them A LOT of time. I'm fairly certain I've just written the most comprehensive set up guide to setting up an Android app to use Google Drive. Shame on Google for spreading the necessary material across at least 6 different pages that don't link to each other at all.

这篇关于Android的打开和保存文件到/从谷歌驱动器SDK的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆