Téléchargement d'images sur tumblr API depuis Android

On a supposé que l'utilisation de l' API Tumblr pour télécharger des images serait facile. Ce n'est pas le cas. ( EDIT C'est maintenant, voir Edit 2 à la fin de cette entrée)

Mon application est censée télécharger une image sur tumblr . Je préférerais le faire à partir d'un service mais, pour l'instant, j'utilise une activité qui se ferme dès que le chargement est terminé. Dans OnCreate() l'utilisateur est authentifié:

  • Quelle est la meilleure façon d'itérer un curseur Android?
  • Choisissez entre ArrayAdapter et SimpleAdapter
  • Comment inclure un booléen dans une clause sql lite où
  • Envoyer automatiquement un courrier électronique par programme
  • Quelle API Android utiliser?
  • Comment intégrer l'activité recherchée avec la recherche vocale Ok Google?
  •  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))); } 

    Cela ouvre une activité de navigateur où l'utilisateur peut ajouter le nom d'utilisateur et le passoword, puis l'application revient à l'activité (c'est aussi pour cette raison que je dois utiliser une activité, je ne sais pas comment procéder à partir d'un service)

    En revenant du navigateur, les données sont extraites:

     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 plupart de ces deux extraits que j'ai obtenus d'ici et ils fonctionnent bien.

    Avec ces jetons, je peux maintenant essayer de mettre des données sur tumblr. Lorsque j'essaie d'ajouter un texte, cela fonctionne bien en utilisant cette méthode:

     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(); } 

    Comme vous pouvez le voir ici http://www.tumblr.com/blog/snapnowandroid (au moins à partir de ce moment), le texte "c'est juste un test" est publié.

    Cependant, lorsque j'essaie de publier des images, cela devient étrange. Maintenant, j'ai vérifié et apparemment il s'agit d'un problème bien connu avec l'API tumblr, qui a été trop discutée ici et certains l'ont résolu dans d'autres langages de programmation (par exemple ici ), mais j'ai été incapable de répéter ces succès.

    La méthode (dans son intégralité ci-dessous) a exactement la même structure que la méthode ci-dessus (cela fonctionne), le nomValuePairs est juste différent

    La méthode reçoit une variable Bitmap appelée photo:

      private void uploadToTumblr(Bitmap photo) 

    Ce bitmap est converti en un tableau:

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

    Le nomValuePairs est rempli comme suit:

     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))); 

    Le résultat est un {"meta":{"status":400,"msg":"Bad Request"},"response":{"errors":["Error uploading photo."]}} partir du tumblr api.

    J'ai essayé de coder l'image différemment comme décrit dans cet article mais sans aucune modification.

     //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)); 

    Ici la méthode entière (sans encodage hexadécimal):

     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(); } 

    Maintenant, bien qu'il y ait plusieurs choses avec lesquelles je suis mécontent (par exemple, cela se fait en utilisant une activité au lieu d'un service), le problème majeur ici est clairement le problème du téléchargement d'images. Je ne suis en aucun cas le premier à avoir ce problème, donc quelqu'un a-t-il pu faire cela dans java?

    Modifier 1

    N'a pas fait de progrès avec le problème à l'origine, mais a créé une solution de rechange qui pourrait être agréable pour les personnes ayant le même problème. Tumblr offre une publication par courrier électronique et vous pouvez programmer Android pour envoyer des courriels en arrière-plan comme indiqué ici . Cela fonctionne très bien, mais vous devez demander aux utilisateurs de fournir leurs données de compte de messagerie et l'adresse de messagerie de Tumblr pour publier.

    Modifier 2

    Les années ont passé et l'utilisation du courrier électronique n'est plus le moyen simple de le faire. Avec jumblr, il existe enfin une bonne API pour Java qui fonctionnera sur Android. OAuth-Authentication n'est pas amusant (ce n'est jamais le cas) mais une fois que vous avez dépassé cela, c'est fantastique.

    Maintenant, techniquement, la question de savoir comment faire l'authentification n'appartient pas ici, mais c'est une question trop longue, alors je vais juste coller un code ici et s'il n'est pas intéressant que vous l'ignorez.

    Cela utilise un jar appelé 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; } } 

    Le WebViewFragement ressemble à ceci:

     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(); } } } } 

  • Meilleures pratiques d'Android pour le problème de la structure des paquets
  • Intérêt électronique du courrier électronique et corps du message
  • Outil de conception UI Android
  • Android Studio 2.1 Erreur lors de la conversion de bytecode en dex
  • Pont indigène entre Python et Dalvik ou AAF
  • File Chooser ne fonctionne pas dans Samsung Tab 3 Android 4.4
  • 5 Solutions collect form web for “Téléchargement d'images sur tumblr API depuis Android”

    Pourquoi n'utilisez-vous pas Jumblr le client Java officiel pour Tumblr.

    Cordialement.

    Vous pouvez facilement le faire en utilisant 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(); 

    Cela a fonctionné pour moi …

     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));` 

    Où filePath est http url.

    J'ai utilisé multipartenus public class VideoUploader extends 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 

    J'ai fait en utilisant la méthode suivante. Vous pouvez essayer cela.

    // paramString = "texte que vous voulez mettre en légende"

     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(); } } 

    EDIT: Téléchargez d'abord l'image sur le serveur Web, puis cliquez sur Url et essayez de publier avec Url ou le chemin de fichier téléchargé. Ça va bien sûr … 🙂

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.