How do I connect Android apps with Google Sheets spreadsheets?

27,662

Solution 1

Thank you so so much Scorpion! It works!! I've been trying this for too long. Ok here is my solution: I started a new project and included these jars:

gdata-client-1.0
gdata-client-meta-1.0
gdata-core-1.0
gdata-spreadsheet-3.0
gdata-spreadsheet-meta-3.0
guava-13.0.1  

and my code:

    SpreadsheetService spreadsheet= new SpreadsheetService("v1");
    spreadsheet.setProtocolVersion(SpreadsheetService.Versions.V3);

    try {
        spreadsheet.setUserCredentials("username", "password");
        URL metafeedUrl = new URL("https://spreadsheets.google.com/feeds/spreadsheets/private/full");
        SpreadsheetFeed feed = spreadsheet.getFeed(metafeedUrl, SpreadsheetFeed.class);

        List<SpreadsheetEntry> spreadsheets = feed.getEntries();
        for (SpreadsheetEntry service : spreadsheets) {             
            System.out.println(service.getTitle().getPlainText());
       }
    } catch (AuthenticationException e) {           
        e.printStackTrace();
    }

of course this is executed in a different thread not in the main thread. There is no java documentation for OAuth 2.0 but I will try and if I can't do it I'll ask here. Again, thank you very much and I hope to help you when I work on this time enough. :)

Solution 2

(Feb 2017) The question (and most answers) are now out-of-date as:

  1. GData APIs are the previous generation of Google APIs. While not all GData APIs have been deprecated, all modern Google APIs do not use the Google Data protocol
  2. Google released a new Google Sheets API (v4; not GData) in 2016, and
  3. Android Studio is now the preferred IDE over Eclipse. In order to use Google APIs, you need to get the Google APIs Client Library for Android (or for more general Java, the Google APIs Client Library for Java). Now you're set.

To start, the latest Sheets API is much more powerful than all older versions. The latest API provides features not available in older releases, namely giving developers programmatic access to a Sheet as if you were using the user interface (create frozen rows, perform cell formatting, resize rows/columns, add pivot tables, create charts, etc.).

That said, yeah, it's tough when there aren't enough good (working) examples floating around, right? In the official docs, we try to put "quickstart" examples in as many languages as possible to help get you going. In that spirit, here are the Android quickstart code sample as well as the more general Java Quickstart code sample. For convenience, here's the Sheets API JavaDocs reference.

Another answer suggested using OAuth2 for data authorization, which you can do with this auth snippet from the quickstart above, plus the right scope:

// Sheets RO scope
private static final String[] SCOPES = {SheetsScopes.SPREADSHEETS_READONLY};
    :

// Initialize credentials and service object
mCredential = GoogleAccountCredential.usingOAuth2(
        getApplicationContext(), Arrays.asList(SCOPES))
        .setBackOff(new ExponentialBackOff());

If you're not "allergic" to Python, I've made several videos with more "real-world" examples using the Sheets API (non-mobile though):

Finally, note that the Sheets API performs document-oriented functionality as described above. For file-level access, i.e. import, export etc. you'd use the Google Drive API instead; specifically for mobile, use the Google Drive Android API. Hope this helps!

Solution 3

Sample code for you without OAuth 2.0. But its recommended to perform OAuth as its good for the security purpose. You also have to add below permissions.

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCOUNT_MANAGER"/>
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

Sample Code:-

try {
    SpreadsheetEntry spreadsheet;
    service = new SpreadsheetService("Spreadsheet");
    service.setProtocolVersion(SpreadsheetService.Versions.V3);
    service.setUserCredentials("username", "password");//permission required to add in Manifest
    URL metafeedUrl = new URL("https://spreadsheets.google.com/feeds/spreadsheets/private/full");
    feed = service.getFeed(metafeedUrl, SpreadsheetFeed.class);

    List<SpreadsheetEntry> spreadsheets = feed.getEntries();
    if (spreadsheets.size() > 0) {
        spreadsheet = spreadsheets.get(i);//Get your Spreadsheet
   }
} catch (Exception e) {
    e.printStackTrace();
}

Solution 4

It's a complex process, but it can be done! I wrote a blog post on getting the basics up and running. And I've also published an open-source project that is actually useful, but still quite minimal. It uses OAuth, and therefore can pull the permission directly from Android's permission model (no hardcoded email/password!).

You need something to start the "Choose account intent":

    View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
         Intent intent = AccountPicker.newChooseAccountIntent(null, null, new String[]{"com.google"},
                 false, null, null, null, null);
         startActivityForResult(intent, 1);

        if (AUTO_HIDE) {
            delayedHide(AUTO_HIDE_DELAY_MILLIS);
        }
        return false;
    }
};

And then when that intent returns, you can try to use the token that was returned (although note, if it's the first time the user may have to explicitly authorize your program; that's the UserRecoverableAuthException):

    protected void onActivityResult(final int requestCode, final int resultCode,
        final Intent data) {
    if (requestCode == 1 && resultCode == RESULT_OK) {
        final String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
        System.err.println(accountName);

        (new AsyncTask<String, String,String>(){
            @Override
            protected String doInBackground(String... arg0) {
                try {
                    // Turn account name into a token, which must
                    // be done in a background task, as it contacts
                    // the network.
                    String token = 
                            GoogleAuthUtil.getToken(
                                    FullscreenActivity.this, 
                                    accountName, 
                                    "oauth2:https://spreadsheets.google.com/feeds https://docs.google.com/feeds");
                    System.err.println("Token: " + token);

                    // Now that we have the token, can we actually list
                    // the spreadsheets or anything...
                    SpreadsheetService s =
                            new SpreadsheetService("Megabudget");
                    s.setAuthSubToken(token);

                    // Define the URL to request.  This should never change.
                    // (Magic URL good for all users.)
                    URL SPREADSHEET_FEED_URL = new URL(
                        "https://spreadsheets.google.com/feeds/spreadsheets/private/full");

                    // Make a request to the API and get all spreadsheets.
                    SpreadsheetFeed feed;
                    try {
                        feed = s.getFeed(SPREADSHEET_FEED_URL, SpreadsheetFeed.class);
                        List<SpreadsheetEntry> spreadsheets = feed.getEntries();

                        // Iterate through all of the spreadsheets returned
                        for (SpreadsheetEntry spreadsheet : spreadsheets) {
                          // Print the title of this spreadsheet to the screen
                          System.err.println(spreadsheet.getTitle().getPlainText());
                        }
                    } catch (ServiceException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } catch (UserRecoverableAuthException e) {
                    // This is NECESSARY so the user can say, "yeah I want
                    // this app to have permission to read my spreadsheet."
                    Intent recoveryIntent = e.getIntent();
                    startActivityForResult(recoveryIntent, 2);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (GoogleAuthException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return null;
            }}).execute();
  } else if (requestCode == 2 && resultCode == RESULT_OK) {
      // After the user YAYs or NAYs our permission request, we are
      // taken here, so if we wanted to grab the token now we could.
  }

}
Share:
27,662
user1680435
Author by

user1680435

Updated on July 09, 2022

Comments

  • user1680435
    user1680435 almost 2 years

    I'm trying to do an Android app that needs to work with Google spreadsheet API. I'm new in this, so I'm starting with the version 3 of the api: https://developers.google.com/google-apps/spreadsheets/

    I followed all the steps, downloaded all the jar files to lib subfolder in my project folder and then I added to the build path in Eclipse as usual. So although there is no Java example to perform Oauth 2.0, I just tried to declare:

    SpreadsheetService service = new SpreadsheetService("v1");
    

    but when I emulate this simple line it gives me an error:

    java.lang.NoClassDefFoundError: com.google.gdata.client.spreadsheet.SpreadsheetService
    

    I'm using all the jars included in the documentation and I have the import:

    import com.google.gdata.client.spreadsheet.SpreadsheetService;
    

    but I am totally lost. I dont know what else to do just to start, connect to Google APIs and work with the spreadsheets.

    • Scorpion
      Scorpion over 11 years
      This error is because its not getting the SpreadsheetService class. Which jar files you have added? code.google.com/p/google-api-java-client/downloads/… Have you used this library?
    • Scorpion
      Scorpion over 11 years
      Have you set the build path of the project or not? If not i recommend please do that thing first and then try again.
    • user1680435
      user1680435 over 11 years
      I've followed all the steps from the documentation and I've build the path in Eclipse with all the libraries included that. But still get the same error.
    • user1680435
      user1680435 over 11 years
      Libraries: gdata, javamail, google-api-java-client: all of them in the path of the app (lib subfolder) It compiles great but once I run it, Eclipse throws me that error.
    • user1680435
      user1680435 over 11 years
      I've been working on this for hours and I only know that the required libraries for SpreadsheetService are the jars: gdata-spreadsheet-meta-3.0 and gdata-spreadsheet-3.0 It only compiles with these 2 libraries but yet getting the same error. :(
  • user1680435
    user1680435 over 11 years
    I think I dont have the indicated Jars because Im not able to create an Spreadsheet class as in the first line you put there. I dont know what else to do. The only option is to start all over again and do it step by step.
  • Scorpion
    Scorpion over 11 years
    Just calm down and don't get frustrated. Answer some of my question that have you included gdata-core-1.0.jar & guava-11.0.1.jar in your project or not?
  • Scorpion
    Scorpion over 11 years
    Its my mistake actually its a SpreadsheetEntry not Spreadsheet. Just add the 2jars which i said above if you don't added because its needed and then try again. I think it will work for you.
  • Scorpion
    Scorpion over 11 years
  • user1680435
    user1680435 over 11 years
    I am so sorry I put my answer because it's exactly what I did and worked for me that doesnt mean that you didnt help It`s just a way to say to other people that is the way to do and help them. Thanks and sorry for my mistakes here. And also thanks for the Oauth 2.0 link I will try it.
  • Nels Beckman
    Nels Beckman over 10 years
    service.getFeed gives me a ParseException, saying "Unrecognized content type:application/binary"
  • Milon
    Milon over 8 years
    I tried @2 nov 2015 downloading your app but it did not work
  • Nels Beckman
    Nels Beckman over 8 years
    You downloaded the app or you tried building from source? The app seems to be working for me on Android M. What didn't work? @DinIslamMilon
  • Milon
    Milon over 8 years
    Its like a charm. today I have downloaded again your app from play store and now it's working great. Thanks.
  • YBDevi
    YBDevi over 6 years
    do you have any example android app which will save data in Google Sheet and get from Sheet to visible.I have check google sample code still i am getting confusion regarding this.If you know any example plz post link it will help me a lot.
  • wescpy
    wescpy over 6 years
    I don't have any personally, but in addition to the Quickstart I linked to above, check out this other SO Q&A: stackoverflow.com/questions/40781620
  • YBDevi
    YBDevi over 6 years
    Thanks for the link i will try to get information from it.