tumblthree tialausad escritorio blog android api encoding tumblr

android - tialausad - tumblr settings



Cargar imágenes a tumblr API desde Android (5)

Un supuesto uso de la API de Tumblr para cargar imágenes sería fácil. No lo es ( EDITAR Es ahora, vea Edición 2 al final de esta entrada)

Se supone que mi aplicación sube una imagen a tumblr . Preferiría hacerlo desde un servicio, pero por ahora utilizo una actividad que se cierra tan pronto como se realiza la carga. En OnCreate() el usuario es autenticado:

consumer = new CommonsHttpOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET); // It uses this signature by default // consumer.setMessageSigner(new HmacSha1MessageSigner()); provider = new CommonsHttpOAuthProvider(REQUEST_TOKEN_URL,ACCESS_TOKEN_URL,AUTH_URL); String authUrl; try { authUrl = provider.retrieveRequestToken(consumer, CALLBACK_URL); Log.d(TAG, "Auth url:" + authUrl); startActivity(new Intent("android.intent.action.VIEW", Uri.parse(authUrl))); }

Esto abre una actividad del navegador donde el usuario puede agregar un nombre de usuario y contraseña y luego la aplicación vuelve a la actividad (también es por eso que tengo que usar una actividad, no sé cómo hacerlo desde un servicio)

Al regresar del navegador se extraen los datos:

Uri uri = context.getIntent().getData(); if (uri != null && uri.toString().startsWith(CALLBACK_URL)) { Log.d(TAG, "uri!=null"); String verifier = uri.getQueryParameter("oauth_verifier"); Log.d(TAG, "verifier"+verifier); try { provider.setOAuth10a(true); provider.retrieveAccessToken(consumer, verifier); Log.d(TAG, "try"); } catch (Exception e) { Log.e(TAG, e.toString()); e.printStackTrace(); } OAUTH_TOKEN = consumer.getToken(); OAUTH_SECRET = consumer.getTokenSecret();

La mayoría de estos dos fragmentos que obtuve de aquí y funcionan bien.

Con estos tokens ahora puedo intentar poner datos en tumblr. Cuando intento agregar texto, esto funciona bien usando este método:

private void createText() { if(!OAUTH_TOKEN.equals("")) { HttpContext context = new BasicHttpContext(); HttpPost request = new HttpPost("http://api.tumblr.com/v2/blog/" + blogname + ".tumblr.com/post"); List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); nameValuePairs.add(new BasicNameValuePair("type", "text")); nameValuePairs.add(new BasicNameValuePair("body", "this is just a test")); try { request.setEntity(new UrlEncodedFormEntity(nameValuePairs)); } catch (UnsupportedEncodingException e1) { Log.e(TAG, e1.toString()); e1.printStackTrace(); } if (consumer == null) { consumer = new CommonsHttpOAuthConsumer(OAuthConstants.TUMBR_CONSUMERKEY, OAuthConstants.TUMBR_SECRETKEY); } if (OAUTH_TOKEN == null || OAUTH_SECRET == null) { Log.e(TAG, "Not logged in error"); } consumer.setTokenWithSecret(OAUTH_TOKEN, OAUTH_SECRET); try { consumer.sign(request); } catch (OAuthMessageSignerException e) { } catch (OAuthExpectationFailedException e) { } catch (OAuthCommunicationException e) { } HttpClient client = new DefaultHttpClient(); //finally execute this request try { HttpResponse response = client.execute(request, context); HttpEntity responseEntity = response.getEntity(); if (responseEntity != null) { Log.d(TAG, "responseEntety!=null"); try { Log.d(TAG, EntityUtils.toString(responseEntity)); } catch (ParseException e) { e.printStackTrace(); Log.e(TAG, e.toString()); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, e.toString()); } // gives me {"meta":{"status":401,"msg":"Not Authorized"},"response":[]} when I try to upload a photo } else { Log.d(TAG, "responseEntety==null"); } } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } PostToTumblr.this.finish(); }

Como puede ver aquí, http://www.tumblr.com/blog/snapnowandroid (al menos hasta este momento) se publica el texto "esto es solo una prueba".

Sin embargo, cuando intento publicar imágenes, se pone extraño. Ahora he comprobado y aparentemente este es un problema bien conocido con la API de tumblr, que se ha discutido en exceso here y algunos lo han resuelto en otros lenguajes de programación (por ejemplo here ) pero no he podido repetir esos éxitos.

El método (en su totalidad a continuación) tiene exactamente la misma estructura que el método anterior (que funciona), los nameValuePairs son diferentes

Al método se le da una variable de mapa de bits llamada foto:

private void uploadToTumblr(Bitmap photo)

Este mapa de bits se convierte en una matriz:

ByteArrayOutputStream stream = new ByteArrayOutputStream(); photo.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] bytes = stream.toByteArray();

Los nameValuePairs se llenan de la siguiente manera:

nameValuePairs.add(new BasicNameValuePair(URLEncoder.encode("type", enc), URLEncoder.encode("photo", enc))); nameValuePairs.add(new BasicNameValuePair(URLEncoder.encode("caption", enc), URLEncoder.encode(text, enc))); nameValuePairs.add(new BasicNameValuePair("data", Base64.encodeToString(bytes, Base64.URL_SAFE)));

El resultado es un {"meta":{"status":400,"msg":"Bad Request"},"response":{"errors":["Error uploading photo."]}} Del archivo tumblr api.

Intenté codificar la imagen de forma diferente a como se describe en here pero sin ningún cambio.

//http://www.coderanch.com/t/526487/java/java/Java-Byte-Hex-String final char[] hexArray = {''0'',''1'',''2'',''3'',''4'',''5'',''6'',''7'',''8'',''9'',''A'',''B'',''C'',''D'',''E'',''F''}; char[] hexChars = new char[bytes.length * 3]; int v; for ( int j = 0; j < bytes.length; j++ ) { v = bytes[j] & 0xFF; hexChars[j * 3] = ''%''; hexChars[j * 3 + 1] = hexArray[v >>> 4]; hexChars[j * 3 + 2] = hexArray[v & 0x0F]; } String s = new String(hexChars); s = URLEncoder.encode(s, enc); nameValuePairs.add(new BasicNameValuePair(URLEncoder.encode("data", enc), s));

Aquí el método completo (sin la codificación hexadecimal):

private void uploadToTumblr(Bitmap photo) { if(!OAUTH_TOKEN.equals("")) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); photo.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] bytes = stream.toByteArray(); String text ="SNAP"; HttpContext context = new BasicHttpContext(); HttpPost request = new HttpPost("http://api.tumblr.com/v2/blog/" + blogname + ".tumblr.com/post"); List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); String enc = "UTF-8"; try { nameValuePairs.add(new BasicNameValuePair(URLEncoder.encode("type", enc), URLEncoder.encode("photo", enc))); nameValuePairs.add(new BasicNameValuePair(URLEncoder.encode("caption", enc), URLEncoder.encode(text, enc))); nameValuePairs.add(new BasicNameValuePair("data", Base64.encodeToString(bytes, Base64.URL_SAFE))); } catch (UnsupportedEncodingException e2) { Log.e(TAG, e2.toString()); e2.printStackTrace(); } try { request.setEntity(new UrlEncodedFormEntity(nameValuePairs)); } catch (UnsupportedEncodingException e1) { Log.e(TAG, e1.toString()); e1.printStackTrace(); } if (consumer == null) { consumer = new CommonsHttpOAuthConsumer(OAuthConstants.TUMBR_CONSUMERKEY, OAuthConstants.TUMBR_SECRETKEY); } if (OAUTH_TOKEN == null || OAUTH_SECRET == null) { //throw new LoginErrorException(LoginErrorException.NOT_LOGGED_IN); Log.e(TAG, "Not logged in error"); } consumer.setTokenWithSecret(OAUTH_TOKEN, OAUTH_SECRET); try { consumer.sign(request); } catch (OAuthMessageSignerException e) { } catch (OAuthExpectationFailedException e) { } catch (OAuthCommunicationException e) { } HttpClient client = new DefaultHttpClient(); //finally execute this request try { HttpResponse response = client.execute(request, context); HttpEntity responseEntity = response.getEntity(); if (responseEntity != null) { Log.d(TAG, "responseEntety!=null"); try { Log.d(TAG, EntityUtils.toString(responseEntity)); } catch (ParseException e) { e.printStackTrace(); Log.e(TAG, e.toString()); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, e.toString()); } } else { Log.d(TAG, "responseEntety==null"); } } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { Log.d(TAG, "upload imposble... Toklen not set"); } PostToTumblr.this.finish(); }

Ahora, aunque hay varias cosas con las que no estoy contento (por ejemplo, que esto se haga mediante una actividad en lugar de un servicio), el gran problema aquí es claramente el problema de cargar imágenes. No soy de ninguna manera el primero en tener este problema, entonces, ¿alguien ha podido hacer esto en java?

Editar 1

No he hecho ningún progreso con el problema actual, pero creó una solución que podría ser agradable para las personas que tienen el mismo problema. Tumblr ofrece publicaciones por correo y puede programar Android para enviar correos electrónicos en el fondo como se muestra aquí . Esto funciona muy bien, pero debe pedir a los usuarios que proporcionen los datos de su cuenta de correo y la dirección de correo de Tumblr para publicar.

Editar 2

Los años han pasado y el uso del correo electrónico ya no es la forma más fácil de hacerlo. Con jumblr finalmente hay una buena API para Java que funcionará en Android. La autenticación OAuth no es divertida (nunca lo es) pero una vez que superas esto, es fantástico.

Ahora, técnicamente, la pregunta sobre cómo realizar la autenticación no pertenece aquí, pero es una pregunta demasiado larga, así que solo pegaré un código aquí y, si no le interesa, simplemente omítalo.

Esto usa un jar llamado jumblr-0.0.10-jar-with-dependencies.jar

import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.util.Log; import com.tumblr.jumblr.JumblrClient; import com.tumblr.jumblr.request.RequestBuilder; import com.tumblr.jumblr.types.Blog; import com.tumblr.jumblr.types.User; import org.scribe.builder.ServiceBuilder; import org.scribe.builder.api.TumblrApi; import org.scribe.model.Token; import org.scribe.model.Verifier; import org.scribe.oauth.OAuthService; import java.io.File; public class Tumblr { private static final String PROTECTED_RESOURCE_URL = "http://api.tumblr.com/v2/user/info"; static OAuthService service; static Token requestToken=null; public static void share(final Activity ctx, File file) { Thread tt = new Thread(new Runnable() { @Override public void run() { JumblrClient client = new JumblrClient(Tumblr_Constants.CONSUMER_KEY, Tumblr_Constants.CONSUMER_SECRET); RequestBuilder requestBuilder = client.getRequestBuilder(); requestBuilder.setConsumer(Tumblr_Constants.CONSUMER_KEY, Tumblr_Constants.CONSUMER_SECRET); SharedPreferences settings = ctx.getSharedPreferences("TumblrData", 0); String oauthToken=settings.getString("OauthToken", ""); String oauthTokenSecret=settings.getString("OauthSecret", ""); if(oauthToken.equals("") || oauthTokenSecret.equals("")) { authenticate(ctx); while(WebViewFragment.verifier.equals("")) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } String v = WebViewFragment.verifier; Token accessToken = authenticatefurther(v); SharedPreferences.Editor edit = settings.edit(); edit.putString("OauthToken", accessToken.getToken()); edit.putString("OauthSecret", accessToken.getSecret()); edit.commit(); oauthToken=settings.getString("OauthToken", ""); oauthTokenSecret=settings.getString("OauthSecret", ""); } if(!oauthToken.equals("") && !oauthTokenSecret.equals("")) { client.setToken(oauthToken, oauthTokenSecret); User user = client.user(); System.out.println(user.getName()); for (Blog blog : user.getBlogs()) { Log.d("TUMBLR", blog.getTitle()); } } } }); tt.start(); } private static void authenticate(Context ctx) { service = new ServiceBuilder() .provider( TumblrApi.class ) .apiKey(Tumblr_Constants.CONSUMER_KEY) .apiSecret(Tumblr_Constants.CONSUMER_SECRET) .callback("snapnao://snapnao.de/ok") // OOB forbidden. We need an url and the better is on the tumblr website ! .build(); Log.d("TUMBLR", "=== Tumblr''s OAuth Workflow ===" ); System.out.println(); // Obtain the Request Token Log.d("TUMBLR", "Fetching the Request Token..."); requestToken = service.getRequestToken(); Log.d("TUMBLR", "Got the Request Token!"); Log.d("TUMBLR", ""); Log.d("TUMBLR", "Now go and authorize Scribe here:" ); Log.d("TUMBLR", service.getAuthorizationUrl( requestToken ) ); String url = service.getAuthorizationUrl(requestToken); Intent i = new Intent(ctx, WebViewFragment.class); i.putExtra("url", url); ctx.startActivity(i); } private static Token authenticatefurther(String v) { Token accessToken = null; Log.d("TUMBLR", "And paste the verifier here"); Log.d("TUMBLR", ">>"); Verifier verifier = new Verifier( v); Log.d("TUMBLR", ""); // Trade the Request Token and Verfier for the Access Token Log.d("TUMBLR", "Trading the Request Token for an Access Token..."); accessToken = service.getAccessToken( requestToken , verifier ); Log.d("TUMBLR", "Got the Access Token!"); Log.d("TUMBLR", "(if your curious it looks like this: " + accessToken + " )"); Log.d("TUMBLR", ""); return accessToken; } }

El WebViewFragement se ve así:

import android.app.Activity; import android.graphics.Bitmap; import android.net.http.SslError; import android.os.Bundle; import android.util.Log; import android.webkit.SslErrorHandler; import android.webkit.WebView; import android.webkit.WebViewClient; public class WebViewFragment extends Activity { public static String verifier=""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.webviewfragment); String url = getIntent().getStringExtra("url"); Log.d("TUMBLR", "webview-> "+url); WebView view = (WebView) findViewById(R.id.webView); view.setWebViewClient( new SSLTolerentWebViewClient() ); view.getSettings().setJavaScriptEnabled(true); view.loadUrl(url); } // SSL Error Tolerant Web View Client private class SSLTolerentWebViewClient extends WebViewClient { @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); // Ignore SSL certificate errors } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); Log.d("TUMBLR", "+++++"+url); if(url.contains("oauth_verifier=")) { String[] x = url.split("oauth_verifier="); verifier=x[1].replace("#_=_", ""); WebViewFragment.this.finish(); } } } }


¿Por qué no usas jumblr el cliente oficial de Java para Tumblr?

Saludos.


Esto me funcionó ...

nameValuePairs.add(new BasicNameValuePair(URLEncoder .encode("type", "UTF-8"), URLEncoder.encode("photo", "UTF-8"))); Log.e("Tumblr", "Image shareing file path" + filePath); nameValuePairs.add(new BasicNameValuePair("caption", caption)); nameValuePairs.add(new BasicNameValuePair("source", filePath));`

donde filePath es http url.


He terminado de usar el siguiente método. puedes probar esto

// paramString = "texto que quieres poner en el título"

private void postPhotoTumblr(String uploadedImagePhotoUrl, String paramString) { CommonsHttpOAuthConsumer localCommonsHttpOAuthConsumer = getTumblrConsumer(); String str1 = "logged in username"; String encodedImage = uploadedImagePhotoUrl; DefaultHttpClient localDefaultHttpClient = new DefaultHttpClient(); HttpPost localHttpPost = new HttpPost("http://api.tumblr.com/v2/blog/" + str1 + ".tumblr.com/post"); try { ArrayList localArrayList = new ArrayList(); localArrayList.add(new BasicNameValuePair("type", "photo")); BasicNameValuePair localBasicNameValuePair = new BasicNameValuePair("caption", paramString); localArrayList.add(localBasicNameValuePair); localArrayList.add(new BasicNameValuePair("data",encodedImage)); UrlEncodedFormEntity localUrlEncodedFormEntity = new UrlEncodedFormEntity(localArrayList); localHttpPost.setEntity(localUrlEncodedFormEntity); localCommonsHttpOAuthConsumer.sign(localHttpPost); InputStream localInputStream = localDefaultHttpClient.execute(localHttpPost).getEntity().getContent(); InputStreamReader localInputStreamReader = new InputStreamReader(localInputStream); BufferedReader localBufferedReader = new BufferedReader(localInputStreamReader); StringBuilder localStringBuilder = new StringBuilder(); while (true) { String str2 = localBufferedReader.readLine(); if (str2 == null) { Log.i("DATA post resp", localStringBuilder.toString()); break; } localStringBuilder.append(str2); } } catch (ClientProtocolException localClientProtocolException) { localClientProtocolException.printStackTrace(); } catch (IOException localIOException) { localIOException.printStackTrace(); } catch (OAuthMessageSignerException localOAuthMessageSignerException) { localOAuthMessageSignerException.printStackTrace(); } catch (OAuthExpectationFailedException localOAuthExpectationFailedException) { localOAuthExpectationFailedException.printStackTrace(); } catch (OAuthCommunicationException localOAuthCommunicationException) { localOAuthCommunicationException.printStackTrace(); } }

EDITAR: Primero cargue la imagen en el servidor web, luego obtenga la URL e intente publicar con la URL cargada o la ruta del archivo. funcionará bien seguro ... :)


Puede hacer esto fácilmente usando jumblr - Tumblr java client

JumblrClient client = new JumblrClient(Constant.CONSUMER_KEY,Constant.CONSUMER_SECRET); client.setToken(preferences.getString("token",null), preferences.getString("token_secret", null)); PhotoPost pp = client.newPost(client.user().getBlogs().get(0).getName(),PhotoPost.class); pp.setCaption(caption); // pp.setLinkUrl(link); // pp.setSource(mImage); // String URL pp.setPhoto(new Photo(imgFile)); pp.save();


Tengo uso multiparte clase pública VideoUploader extiende AsyncTask {

ProgressDialog progressDialog; @Override protected void onPreExecute() { // TODO Auto-generated method stub progressDialog = ProgressDialog.show(RecordingActivity.this, "", "Uploading video.. "); super.onPreExecute(); } @Override protected JSONObject doInBackground(String... params) { JSONObject jsonObject = null; StringBuilder builder = new StringBuilder(); try { String url = UrlConst.VIDEO_URL; HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(url); FileBody filebodyVideo = new FileBody(new File(params[0])); StringBody title = new StringBody("uploadedfile: " + params[0]); StringBody description = new StringBody( "This is a video of the agent"); // StringBody code = new StringBody(realtorCodeStr); MultipartEntity reqEntity = new MultipartEntity(); reqEntity.addPart("uploadedfile", filebodyVideo); reqEntity.addPart("title", title); reqEntity.addPart("description", description); // reqEntity.adddPart("code", code); httppost.setEntity(reqEntity); // DEBUG System.out.println("executing request " + httppost.getRequestLine()); HttpResponse response = httpclient.execute(httppost); HttpEntity resEntity = response.getEntity(); // DEBUG StatusLine status = response.getStatusLine(); int statusCode = status.getStatusCode(); System.out.println(response.getStatusLine()); if (resEntity != null) { System.out.println(EntityUtils.toString(resEntity)); } // end if if (resEntity != null) { resEntity.consumeContent(); } // end if if (statusCode == 200) { InputStream content = resEntity.getContent(); BufferedReader reader = new BufferedReader( new InputStreamReader(content)); String line; while ((line = reader.readLine()) != null) { builder.append(line); } jsonObject = new JSONObject(builder.toString()); return jsonObject; } else { Log.e(LoginActivity.class.toString(), "Failed to download file"); } httpclient.getConnectionManager().shutdown(); } catch (Exception e) { // TODO: handle exception } return null; } @Override protected void onPostExecute(JSONObject result) { // TODO Auto-generated method stub super.onPostExecute(result); progressDialog.dismiss(); if (result != null) { try { JSONObject jsonObject = result .getJSONObject(ParsingTagConst.COMMANDRESULT); String strSuccess = jsonObject .getString(ParsingTagConst.SUCCESS); String responseString = jsonObject .getString(ParsingTagConst.RESPONSE_STRING); Toast.makeText(RecordingActivity.this, "" + responseString, Toast.LENGTH_LONG).show(); if (strSuccess.equals("1")) { // get here your response } } catch (Exception e) { // TODO: handle exception } } } } enter code here