嗨,我正在为Android使用picasa示例并对其进行修改,但我没有得到任何文档列表,请发布我的修改后的类其余内容与在picasa示例中相同吗?
获取400 bad request in executeRefreshAlbums()方法
400 bad request in executeRefreshAlbums()
FetchGooleDocsActivity(这是主要活动)
package com.fetchgoogledocs; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import android.accounts.Account; import android.accounts.AccountManager; import android.app.AlertDialog; import android.app.Dialog; import android.app.ListActivity; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore.Images; import android.util.Log; import android.widget.ArrayAdapter; import android.widget.Toast; import com.google.api.client.googleapis.GoogleHeaders; import com.google.api.client.googleapis.GoogleTransport; import com.google.api.client.http.HttpRequest; import com.google.api.client.http.HttpResponse; import com.google.api.client.http.HttpResponseException; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.InputStreamContent; import com.google.api.client.xml.atom.AtomParser; public class FetchGooleDocsActivity extends ListActivity { private static final String AUTH_TOKEN_TYPE = "writely"; private static final String TAG = "PrinterAppGDOCS"; private static final int REQUEST_AUTHENTICATE = 0; private static final String PREF = "MyPrefs"; private static final int DIALOG_ACCOUNTS = 0; private static HttpTransport transport; private String authToken; private static Context context; private String postLink; private final List<AlbumEntry> albums = new ArrayList<AlbumEntry>(); //private final List<AlbumEntry> albums = new ArrayList<AlbumEntry>(); public FetchGooleDocsActivity() { transport = GoogleTransport.create(); GoogleHeaders headers = (GoogleHeaders) transport.defaultHeaders; headers.setApplicationName("PrinterApp/1.0"); headers.gdataVersion = "2"; AtomParser parser = new AtomParser(); parser.namespaceDictionary = Util.NAMESPACE_DICTIONARY; transport.addParser(parser); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); context=this; SharedPreferences settings = getSharedPreferences(PREF, 0); setLogging(settings.getBoolean("logging", false)); getListView().setTextFilterEnabled(true); registerForContextMenu(getListView()); Intent intent = getIntent(); if (Intent.ACTION_SEND.equals(intent.getAction())) { sendData = new SendData(intent, getContentResolver()); Toast.makeText(context, "Send data initilize", Toast.LENGTH_SHORT).show(); } else if (Intent.ACTION_MAIN.equals(getIntent().getAction())) { sendData = null; } gotAccount(false); } @Override protected Dialog onCreateDialog(int id) { switch (id) { case DIALOG_ACCOUNTS: AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Select a Google account"); final AccountManager manager = AccountManager.get(this); final Account[] accounts = manager.getAccountsByType("com.google"); final int size = accounts.length; String[] names = new String[size]; for (int i = 0; i < size; i++) { names[i] = accounts[i].name; } builder.setItems(names, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { gotAccount(manager, accounts[which]); } }); return builder.create(); } return null; } private void gotAccount(boolean tokenExpired) { SharedPreferences settings = getSharedPreferences(PREF, 0); String accountName = settings.getString("accountName", null); if (accountName != null) { AccountManager manager = AccountManager.get(this); Account[] accounts = manager.getAccountsByType("com.google"); int size = accounts.length; for (int i = 0; i < size; i++) { Account account = accounts[i]; if (accountName.equals(account.name)) { if (tokenExpired) { manager.invalidateAuthToken("com.google", this.authToken); } gotAccount(manager, account); return; } } } showDialog(DIALOG_ACCOUNTS); } private void gotAccount(final AccountManager manager, final Account account) { SharedPreferences settings = getSharedPreferences(PREF, 0); SharedPreferences.Editor editor = settings.edit(); editor.putString("accountName", account.name); editor.commit(); new Thread() { @Override public void run() { try { final Bundle bundle = manager.getAuthToken(account, AUTH_TOKEN_TYPE, true, null, null) .getResult(); runOnUiThread(new Runnable() { public void run() { try { if (bundle.containsKey(AccountManager.KEY_INTENT)) { Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT); int flags = intent.getFlags(); flags &= ~Intent.FLAG_ACTIVITY_NEW_TASK; intent.setFlags(flags); startActivityForResult(intent, REQUEST_AUTHENTICATE); } else if (bundle.containsKey(AccountManager.KEY_AUTHTOKEN)) { authenticatedClientLogin( bundle.getString(AccountManager.KEY_AUTHTOKEN)); } } catch (Exception e) { handleException(e); } } }); } catch (Exception e) { handleException(e); } } }.start(); } @Override protected void onActivityResult( int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQUEST_AUTHENTICATE: if (resultCode == RESULT_OK) { gotAccount(false); } else { showDialog(DIALOG_ACCOUNTS); } break; } } private void authenticatedClientLogin(String authToken) { this.authToken = authToken; ((GoogleHeaders) transport.defaultHeaders).setGoogleLogin(authToken); authenticated(); } static class SendData { String fileName; Uri uri; String contentType; long contentLength; SendData(Intent intent, ContentResolver contentResolver) { Toast.makeText(context, "Send data", Toast.LENGTH_SHORT).show(); Bundle extras = intent.getExtras(); if (extras.containsKey(Intent.EXTRA_STREAM)) { Uri uri = this.uri = (Uri) extras.getParcelable(Intent.EXTRA_STREAM); String scheme = uri.getScheme(); Toast.makeText(context, scheme, Toast.LENGTH_LONG).show(); if (scheme.equals("content")) { Cursor cursor = contentResolver.query(uri, null, null, null, null); cursor.moveToFirst(); this.fileName = cursor.getString( cursor.getColumnIndexOrThrow(Images.Media.DISPLAY_NAME)); this.contentType = intent.getType(); this.contentLength = cursor.getLong(cursor.getColumnIndexOrThrow(Images.Media.SIZE)); } } } } static SendData sendData; private void authenticated() { if (sendData != null) { try { if (sendData.fileName != null) { boolean success = false; try { HttpRequest request = transport.buildPostRequest(); request.url = GdocUrl.relativeToRoot( "default/private/full"); Toast.makeText(context, request.url.toString(), Toast.LENGTH_LONG).show(); ((GoogleHeaders) request.headers).setSlugFromFileName( sendData.fileName); InputStreamContent content = new InputStreamContent(); content.inputStream = getContentResolver().openInputStream(sendData.uri); content.type = sendData.contentType; content.length = sendData.contentLength; request.content = content; request.execute().ignore(); success = true; } catch (IOException e) { handleException(e); } setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new String[] {success ? "OK" : "ERROR"})); } } finally { sendData = null; } } else { executeRefreshAlbums(); } } private void executeRefreshAlbums() { String[] albumNames; List<AlbumEntry> albums = this.albums; albums.clear(); try { GdocUrl url = GdocUrl.relativeToRoot("default/private/full"); // page through results while (true) { UserFeed userFeed = UserFeed.executeGet(transport, url); this.postLink = userFeed.getPostLink(); if (userFeed.albums != null) { albums.addAll(userFeed.albums); } String nextLink = userFeed.getNextLink(); if (nextLink == null) { break; } } int numAlbums = albums.size(); albumNames = new String[numAlbums]; for (int i = 0; i < numAlbums; i++) { albumNames[i] = albums.get(i).title; } } catch (IOException e) { Toast.makeText(context, e.getMessage(), Toast.LENGTH_LONG).show(); handleException(e); albumNames = new String[] {e.getMessage()}; albums.clear(); } setListAdapter(new ArrayAdapter<String>( this, android.R.layout.simple_list_item_1, albumNames)); Toast.makeText(context, albumNames.toString(), Toast.LENGTH_LONG).show(); } private void setLogging(boolean logging) { Logger.getLogger("com.google.api.client").setLevel( logging ? Level.CONFIG : Level.OFF); SharedPreferences settings = getSharedPreferences(PREF, 0); boolean currentSetting = settings.getBoolean("logging", false); if (currentSetting != logging) { SharedPreferences.Editor editor = settings.edit(); editor.putBoolean("logging", logging); editor.commit(); } } private void handleException(Exception e) { e.printStackTrace(); SharedPreferences settings = getSharedPreferences(PREF, 0); boolean log = settings.getBoolean("logging", false); if (e instanceof HttpResponseException) { HttpResponse response = ((HttpResponseException) e).response; int statusCode = response.statusCode; try { response.ignore(); } catch (IOException e1) { e1.printStackTrace(); } if (statusCode == 401 || statusCode == 403) { gotAccount(true); return; } if (log) { try { Log.e(TAG, response.parseAsString()); } catch (IOException parseException) { parseException.printStackTrace(); } } } if (log) { Log.e(TAG, e.getMessage(), e); } } }
GdocUrl
package com.fetchgoogledocs; import com.google.api.client.googleapis.GoogleUrl; import com.google.api.client.util.Key; /** * @author Yaniv Inbar */ public class GdocUrl extends GoogleUrl { public static final String ROOT_URL = "https://docs.google.com/feeds/"; @Key public String kinds; public GdocUrl(String encodedUrl) { super(encodedUrl); } /** * Constructs a new URL based on the given relative path. * * @param relativePath encoded path relative to the {@link #ROOT_URL} * @return new URL */ public static GdocUrl relativeToRoot(String relativePath) { return new GdocUrl(ROOT_URL + relativePath); } }
维护节
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.api.client.sample.picasa" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="7" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" /> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true"> <activity android:name=".PicasaDemoActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEND"></action> <category android:name="android.intent.category.DEFAULT"></category> <data android:mimeType="image/*"></data> </intent-filter> </activity> </application> </manifest>
UserFeed
import com.google.api.client.http.HttpTransport; import com.google.api.client.util.Key; import java.io.IOException; import java.util.List; public class UserFeed extends Feed { @Key("entry") public List<AlbumEntry> albums; public static UserFeed executeGet(HttpTransport transport, GdocUrl url) throws IOException { url.kinds = "album"; return (UserFeed) Feed.executeGet(transport, url, UserFeed.class); } }
饲料
import com.google.api.client.googleapis.xml.atom.GData; import com.google.api.client.http.HttpRequest; import com.google.api.client.http.HttpTransport; import com.google.api.client.util.Key; import java.io.IOException; import java.util.List; /** * @author Yaniv Inbar */ public class Feed { @Key("link") public List<Link> links; public String getPostLink() { return Link.find(links, "http://schemas.google.com/g/2005#post"); } public String getNextLink() { return Link.find(links, "next"); } static Feed executeGet(HttpTransport transport, GdocUrl url, Class<? extends Feed> feedClass) throws IOException { url.fields = GData.getFieldsFor(feedClass); HttpRequest request = transport.buildGetRequest(); request.url = url; return request.execute().parseAs(feedClass); } }
我认为我的问题出在Feed或Userfeed类原因中,我不知道接下来在URL中输入什么
Feed
Userfeed
您需要设置版本。从API文档部分中的“ 指定版本” …
如果您请求使用仅版本3中提供的功能的API的请求,但忘记设置版本,则您很可能会收到400错误的请求响应。由于版本2和版本3之间的URL结构不同,因此这是API的新用户常犯的错误。 要指定版本号,请使用GData-Version HTTP标头。此标头的值必须为3.0。十进制和零是必需的。
如果您请求使用仅版本3中提供的功能的API的请求,但忘记设置版本,则您很可能会收到400错误的请求响应。由于版本2和版本3之间的URL结构不同,因此这是API的新用户常犯的错误。
要指定版本号,请使用GData-Version HTTP标头。此标头的值必须为3.0。十进制和零是必需的。
GData-Version: 3.0
或者,您可以在URL中将v = 3指定为查询参数。在剥离HTTP标头或来自某些JavaScript请求的防火墙后工作时,通常需要这样做。建议尽可能使用HTTP标头。
https://docs.google.com/feeds/default/private/full?v=3