11

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.

wescpy
  • 8,970
  • 2
  • 46
  • 43
user1680435
  • 169
  • 1
  • 2
  • 10
  • This error is because its not getting the SpreadsheetService class. Which jar files you have added? http://code.google.com/p/google-api-java-client/downloads/detail?name=google-api-java-client-1.11.0-beta.zip&can=2&q= Have you used this library? – Scorpion Oct 16 '12 at 16:41
  • Have you set the build path of the project or not? If not i recommend please do that thing first and then try again. – Scorpion Oct 16 '12 at 16:46
  • 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 Oct 16 '12 at 18:28
  • 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 Oct 16 '12 at 18:37
  • 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 Oct 16 '12 at 20:04

4 Answers4

5

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();
}
Scorpion
  • 6,447
  • 14
  • 72
  • 114
  • 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. – user1680435 Oct 16 '12 at 21:59
  • 1
    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 Oct 17 '12 at 03:44
  • 1
    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 Oct 17 '12 at 03:53
  • service.getFeed gives me a ParseException, saying "Unrecognized content type:application/binary" – Nels Beckman Jul 28 '13 at 22:31
4

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. :)

user1680435
  • 169
  • 1
  • 2
  • 10
  • Fo Oauth 2.0 please go through this http://blog.doityourselfandroid.com/2011/08/06/oauth-2-0-flow-android/ – Scorpion Oct 18 '12 at 05:09
  • I am so sorry I put my answer because it's exactly what I did and worked for me that doesn`t mean that you didn`t 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. – user1680435 Oct 18 '12 at 11:07
3

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.
  }

}
Nels Beckman
  • 20,402
  • 3
  • 21
  • 28
  • I tried @2 nov 2015 downloading your app but it did not work – Milon Nov 02 '15 at 11:03
  • 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 – Nels Beckman Nov 03 '15 at 13:05
  • Its like a charm. today I have downloaded again your app from play store and now it's working great. Thanks. – Milon Nov 03 '15 at 13:35
3

(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!

Inzimam Tariq IT
  • 5,936
  • 8
  • 32
  • 61
wescpy
  • 8,970
  • 2
  • 46
  • 43
  • 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. – YBDevi Sep 20 '17 at 07:19
  • I don't have any personally, but in addition to the Quickstart I linked to above, check out this other SO Q&A: http://stackoverflow.com/questions/40781620 – wescpy Sep 21 '17 at 01:58
  • Thanks for the link i will try to get information from it. – YBDevi Sep 21 '17 at 05:42