से tumblr एपीआई में छवियां अपलोड करना एक छवियों को अपलोड करने के लिए Tumblr API का उपयोग करना आसान होगा। यह नहीं है (संपादित अब यह इस प्रविष्टि के अंत में संपादित 2 देखना है)एंड्रॉइड
मेरा ऐप tumblr
के लिए एक छवि अपलोड करने के लिए माना जाता है। मैं इसे सेवा से करना पसंद करूंगा लेकिन अभी के लिए मैं एक ऐसी गतिविधि का उपयोग करता हूं जो इसे अपलोड होने के तुरंत बाद बंद कर देता है। OnCreate()
में उपयोगकर्ता को प्रमाणीकृत किया जाता है:
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)));
}
यह एक ब्राउज़र गतिविधि जहां उपयोगकर्ता गतिविधि के लिए उपयोगकर्ता नाम और passoword और फिर ऐप्स रिटर्न जोड़ सकते हैं (यह भी कारण है कि मैं एक गतिविधि का उपयोग करने के, मैं 'को खोलता है पता नहीं कैसे एक सेवा से यह करने के लिए)
ब्राउज़र डेटा निकाला जाता है से लौटते:
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();
इन दो स्निपेट मैं from here मिला है और वे अच्छी तरह से काम के अधिकांश।
इन टोकन के साथ अब मैं tumblr पर डेटा डालने का प्रयास कर सकता हूं। जब मैं पाठ जोड़ने की कोशिश यह इस पद्धति का उपयोग ठीक काम करता है:
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();
}
आप यहाँ http://www.tumblr.com/blog/snapnowandroid देख सकते हैं (कम से कम इस बार के रूप में) पाठ पोस्ट किया जाता है "यह सिर्फ एक परीक्षण है।"
हालांकि, जब मैं छवियों को पोस्ट करने का प्रयास करता हूं, तो यह अजीब हो जाता है। अब मैंने चारों ओर जांच की है और स्पष्ट रूप से यह टंबल एपीआई के साथ एक प्रसिद्ध मुद्दा है, जिस पर अत्यधिक चर्चा की गई है here और कुछ ने इसे अन्य प्रोग्रामिंग भाषाओं में हल किया है (उदाहरण के लिए here) लेकिन मैं उन सफलताओं को दोहराने में असमर्थ हूं।
विधि (नीचे अपनी संपूर्णता में) उपरोक्त विधि करने के लिए ठीक उसी संरचना (कि काम करता है), nameValuePairs सिर्फ अलग हैं है
विधि एक बिटमैप चर कहा तस्वीर दी गई है:
private void uploadToTumblr(Bitmap photo)
इस प्रकार
ByteArrayOutputStream stream = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] bytes = stream.toByteArray();
nameValuePairs भर रहे हैं:
यह बिटमैप एक सरणी में बदल जाती है
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)));
परिणाम टंबल एपीआई से {"meta":{"status":400,"msg":"Bad Request"},"response":{"errors":["Error uploading photo."]}}
है।
मैंने this article में वर्णित तस्वीर को अलग-अलग एन्कोड करने का प्रयास किया है लेकिन बिना किसी बदलाव के।
//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));
यहाँ पूरे विधि (हेक्स एन्कोडिंग के बिना):
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();
}
अब, जबकि वहाँ कई चीजें मैं नाखुश हूँ कर रहे हैं (उदाहरण के लिए यह एक सेवा के बजाय एक गतिविधि का उपयोग किया जाता है कि) यहां बड़ी समस्या स्पष्ट रूप से छवियों को अपलोड करने की समस्या है। मैं इस समस्या का पहला कारण नहीं हूं, इसलिए क्या कोई जावा में ऐसा करने में सक्षम है?
संपादित करें 1
हाथ में समस्या के साथ किसी भी प्रगति नहीं बनाया है, लेकिन कोई समाधान है कि जो लोग एक ही मुद्दा है के लिए अच्छा हो सकता है बनाया। Tumblr posting via mail प्रदान करता है और आप पृष्ठभूमि में ईमेल भेजने के लिए एंड्रॉइड प्रोग्राम कर सकते हैं shown here। यह बहुत अच्छी तरह से काम करता है लेकिन आपको उपयोगकर्ताओं को अपने मेल खाता डेटा और टंबल-मेल एड्रेस पोस्ट करने के लिए कहने की आवश्यकता है।
संपादित 2
साल पारित कर दिया है और ईमेल का उपयोग कर नहीं रह गया है यह करने के लिए आसान तरीका है। jumblr के साथ अंततः जावा के लिए एक अच्छा एपीआई है जो एंड्रॉइड पर काम करेगा। OAuth- प्रमाणीकरण कोई मजेदार नहीं है (यह कभी नहीं है) लेकिन एक बार जब आप इसे पार कर लेंगे, तो यह शानदार होगा।
अब तकनीकी रूप से प्रमाणीकरण करने का सवाल यहां से संबंधित नहीं है, लेकिन यह मेरा अत्यधिक लंबा सवाल है, इसलिए मैं यहां कुछ कोड पेस्ट कर दूंगा और यदि यह आपके लिए दिलचस्प नहीं है तो बस इसे छोड़ दें।
यह एक जार बुलाया का उपयोग करता jumblr-0.0.10-जार-साथ-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;
}
}
WebViewFragement इस तरह दिखता है:
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();
}
}
}
}
क्यों क्या आप नाम-मूल्य जोड़े में 'डेटा' इनपुट नाम एन्कोड नहीं कर रहे हैं जैसे कि आप 'टाइप' और' कैप्शन 'हैं? – Madbreaks
असल में इनपुट नाम एन्कोडिंग अनिवार्य नहीं है (जैसा कि कोई पोस्ट की शुरुआत में टेक्स्ट पोस्ट के लिए वर्किंग कोड से देख सकता है) यह केवल उन चीज़ों में से एक है जिन्हें मैंने इसे काम करने के लिए प्रयास किया था। उदाहरण कोड में स्पष्टता के लिए इसे फिर से ले जाना चाहिए था। –
पहली बात यह है कि मुझे नोटिस है कि आप 'डेटा'' स्रोत का उपयोग नहीं कर रहे हैं, लेकिन आप इसे एक स्ट्रिंग नहीं भेज रहे हैं। यदि आप केवल एक फोटो अपलोड कर रहे हैं तो एक एन्कोडेड स्ट्रिंग तत्व के साथ एक एन्कोडेड स्ट्रिंग या 'डेटा' के साथ' स्रोत 'का उपयोग करने का प्रयास करें। – Ally