How to get facebook profile picture of user in facebook SDK Android - android

I used facebook 3.6 sdk . i want to get profile picture from graph user , last time i got image but now it returns null Bitmap.
I used following code
private void onSessionStateChange(Session session, SessionState state,
Exception exception) {
if (session.isOpened()) {
Request.newMeRequest(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
try {
URL imgUrl = new URL("http://graph.facebook.com/"
+ user.getId() + "/picture?type=large");
InputStream in = (InputStream) imgUrl.getContent();
Bitmap bitmap = BitmapFactory.decodeStream(in);
//Bitmap bitmap = BitmapFactory.decodeStream(imgUrl // tried this also
//.openConnection().getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).executeAsync();
}
}
When i use direct link then it works.
imgUrl = new URL("https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-ash3/t39.2365-6/851558_160351450817973_1678868765_n.png");
i refered this also Graph API Reference

Auto redirection works automatically when original and redirected protocols are same.
So, try to load images from https instead of http : "https://graph.facebook.com/USER_ID/picture"; since image's url is "https://fbcdn-profile-a.akamaihd.net/...."
Then BitmapFactory.decodeStream shall work again.

Try this code,
try {
URL image_value = new URL("http://graph.facebook.com/"+ user.getId()+ "/picture?type=large");
Bitmap bmp = null;
try {
bmp = BitmapFactory.decodeStream(image_value.openConnection().getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
profile_pic.setImageBitmap(bmp);
} catch (MalformedURLException e) {
e.printStackTrace();
}
here profile_pic is your ImageView replace it with your ImageView Name.
Edit
Session.openActiveSession(this, true, new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state,
Exception exception) {
if (session.isOpened()) {
// make request to the /me API
Request.executeMeRequestAsync(session,
new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user,
Response response) {
if (user != null) {
try {
URL image_value = new URL("http://graph.facebook.com/"+ user.getId()+ "/picture?type=large");
Bitmap bmp = null;
try {
bmp = BitmapFactory.decodeStream(image_value.openConnection().getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
profile_pic.setImageBitmap(bmp);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
});
} else {
Toast.makeText(getApplicationContext(), "Error...",
Toast.LENGTH_LONG);
}
}
});

Try this code
public static String getProfilePicture() {
String stringURL = null;
try {
stringURL = "http://graph.facebook.com/" + URLEncoder.encode(DataStorage.getFB_USER_ID(), "UTF-8") + "?fields=" + URLEncoder.encode("picture", "UTF-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
LogUtil.log(TAG, "getProfilePicture final url is : "+stringURL);
JSONObject jsonObject = null;
String response = "";
try {
HttpGet get = new HttpGet(stringURL);
get.setHeader("Content-Type", "text/plain; charset=utf-8");
get.setHeader("Expect", "100-continue");
HttpResponse resp = null;
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
resp = httpClient.execute(get);
} catch (Exception e) {
e.printStackTrace();
}
// get the response from the server and store it in result
DataInputStream dataIn = null;
try {
// dataIn = new DataInputStream(connection.getInputStream());
if (resp != null) {
dataIn = new DataInputStream((resp.getEntity().getContent()));
}
}catch (Exception e) {
e.printStackTrace();
}
if(dataIn != null){
String inputLine;
while ((inputLine = dataIn.readLine()) != null) {
response += inputLine;
}
if(Constant.DEBUG) Log.d(TAG,"final response is : "+response);
if(response != null && !(response.trim().equals(""))) {
jsonObject = new JSONObject(response);
}
dataIn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
String profilePicture = "";
try{
if(jsonObject != null){
JSONObject jsonPicture = jsonObject.getJSONObject("picture");
if(jsonPicture != null){
JSONObject jsonData = jsonPicture.getJSONObject("data");
if(jsonData != null){
profilePicture = jsonData.getString("url");
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
LogUtil.log(TAG, "user fb profile picture url is : "+profilePicture);
return profilePicture;
}

I tried to use redirect page "https://fbcdn-profile-a.akamaihd.net/" + USERID + "/picture?type=large" but it didn't work.
It seems that now facebook redirect you to a different page that we cannot guess. Kind of random variables in URL.
So try below method to get the new redirect page provided by facebook.
private String getProfileGif(String userId) throws IOException {
HttpParams httpParams = new BasicHttpParams();
httpParams.setParameter("http.protocol.handle-redirects", false);
HttpGet pageToRequest = new HttpGet("http://graph.facebook.com/" + userId + "/picture?type=large");
pageToRequest.setParams(httpParams);
AndroidHttpClient httpClient = AndroidHttpClient
.newInstance("Android");
HttpMessage httpResponse = httpClient.execute(pageToRequest);
Header header = httpResponse.getFirstHeader("location");
if(header != null){
return(header.getValue());
}
return "";
}
This is gonna return you the real gif URL (final URL).
After that, use this new URL to parse your bitmap.
Change from:
URL image_value = new URL("http://graph.facebook.com/"+ user.getId()+ "/picture?type=large");
to
URL image_value = new URL(getProfileGif(user.getId());
Bitmap bmp = BitmapFactory.decodeStream(image_value.openConnection().getInputStream());
PS: Dont execute getProfileGif or any URL request in main thread.
Let me know your results.

Related

Android automatic webview login

I am trying to get my webview to show a page that is only accesible after i am logged in. but whatever i try i cant get past the login url.
How can i open/show the SEND_VISUM_URL after i login.
this is what i have so far:
String LOGIN_URL = "http://10.35.50.125/BCS/index.php?module=";
String SEND_VISUM_URL = "http://10.35.50.1/BCS/index.php?module=ScanVisa&Action=save";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView)findViewById(R.id.webviewer);
webView.loadUrl(LOGIN_URL);
cookieManager = new CookieManager();
Button login = (Button) findViewById(R.id.PostData);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
new loginTask().execute(getLoginData());
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
public class loginTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
String loginData = params[0];
String text = "";
BufferedReader reader = null;
// Send data
try {
// Defined URL where to send data
URL login_url = new URL(LOGIN_URL);
// getting cookies:
URLConnection conn = login_url.openConnection();
conn.connect();
// setting cookies
cookieManager.storeCookies(conn);
cookieManager.setCookies(login_url.openConnection());
cookiestring = cookieManager.toString();
Log.d("Cookie in logintask:", cookiestring);
conn.getContent();
conn.setDoOutput(true);
conn.setConnectTimeout(3000);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
try {
wr.write(loginData); //post
wr.flush();
} catch (Exception e) {
e.printStackTrace();
}
// Get the server response
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
if (line.length() > 0) {
sb.append(line + "\n");
if (line == null) {
continue;
}
}
}
text = sb.toString();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
if (reader != null) reader.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
return text;
}
protected void onPostExecute(String line) {
if (!line.contains("I107")) { //I107 is an error code that is returend when a login failed
Toast.makeText(getBaseContext(), "Login succesfull", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getBaseContext(), "Login failed", Toast.LENGTH_LONG).show();
}
}
}
public void setCookies(URLConnection conn) throws IOException {
// let's determine the domain and path to retrieve the appropriate cookies
URL url = conn.getURL();
String domain = getDomainFromHost(url.getHost());
String path = url.getPath();
Map domainStore = (Map)store.get(domain);
if (domainStore == null) return;
StringBuffer cookieStringBuffer = new StringBuffer();
Iterator cookieNames = domainStore.keySet().iterator();
while(cookieNames.hasNext()) {
String cookieName = (String)cookieNames.next();
Map cookie = (Map)domainStore.get(cookieName);
// check cookie to ensure path matches and cookie is not expired
// if all is cool, add cookie to header string
if (comparePaths((String)cookie.get(PATH), path) && isNotExpired((String)cookie.get(EXPIRES))) {
cookieStringBuffer.append(cookieName);
cookieStringBuffer.append("=");
cookieStringBuffer.append((String)cookie.get(cookieName));
if (cookieNames.hasNext()) cookieStringBuffer.append(SET_COOKIE_SEPARATOR);
}
}
try {
conn.setRequestProperty(COOKIE, cookieStringBuffer.toString());
} catch (java.lang.IllegalStateException ise) {
IOException ioe = new IOException("Illegal State! Cookies cannot be set on a URLConnection that is already connected. "
+ "Only call setCookies(java.net.URLConnection) AFTER calling java.net.URLConnection.connect().");
throw ioe;
}
}
any help would be greatly appreciated!

HttpUrlConnection does not work on mobile device but on emulator

all of a sudden my mobile device can't connect to the local server anymore. async tasks are not executed and i just can't figure out why. slowly i'm getting really desperate because in my opinion i didn't change anything to cause this.
as an example, this is a background task which is not working
public class Login extends AsyncTask<String, Void, String>{
private String loginUrl = "http://...";
private int loginSuccess = 0;
public String getToken(String fromJson) throws JSONException {
JSONObject json = new JSONObject(fromJson);
if(json.has("api_authtoken")) {
loginSuccess = 1;
String appToken = json.getString("api_authtoken");
return appToken;
}
else {
return json.toString();
}
}
public String doInBackground(String... arg0) {
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String authToken;
try {
// get logged in to get the api_authtoken
String email = (String) arg0[0];
String password = (String) arg0[1];
URL url = new URL(loginUrl);
// Create the request and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "application/json");
//put values of edittexts into json-Object
JSONObject data = new JSONObject();
try {
data.put("email", email);
data.put("password", password);
} catch(JSONException e) {
Log.e("EXCEPTION", "unexpected JSON exception", e);
e.printStackTrace();
}
urlConnection.connect();
OutputStreamWriter wr = new OutputStreamWriter(urlConnection.getOutputStream());
wr.write(data.toString());
wr.flush();
reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
//read server response
while((line = reader.readLine()) != null) {
sb.append(line);
}
//receive server "answer"
try {
return getToken(sb.toString());
}catch(JSONException e) {
Log.e("LOG", "unexpected JSON exception", e);
e.printStackTrace();
} finally{
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("MainActivity", "Error closing stream", e);
}
}
}
//return sb.toString();
return null;
}
catch(IOException e) {
Log.e("LoginTask", "Error ", e);
// If the code didn't successfully get the data, there's no point in attempting
// to parse it.
//forecastJsonStr = null;
return null;
}
}
public void onPostExecute(String result) {
super.onPostExecute(result);
//Log.v("RESULT", result);
if(result == null) {
CharSequence text = "no internet connection";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(MainActivity.this, text, duration);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
if(loginSuccess == 0) {
// if the request wasn't successful
// give user a message via toast
CharSequence text = "wrong password or user. please try again";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(MainActivity.this, text, duration);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
else {
// save token in shared preferences
SharedPreferences tokenPref = getSharedPreferences(getString(R.string.preference_token), Context.MODE_PRIVATE);
SharedPreferences.Editor editorToken = tokenPref.edit();
editorToken.putString(getString(R.string.saved_auth_token), result);
editorToken.commit();
//save login status = 1 in shared preferences
SharedPreferences loginPref = getSharedPreferences(getString(R.string.preference_logged_in), Context.MODE_PRIVATE);
SharedPreferences.Editor editorLogin = loginPref.edit();
editorLogin.putString(getString(R.string.saved_login), "1");
editorLogin.commit();
Intent mapsIntent = new Intent(getApplicationContext(), MapsActivity.class);
startActivity(mapsIntent);
}
}
}
HttpClient is not supported any more in sdk 23. You have to use URLConnection or downgrade to sdk 22 (compile 'com.android.support:appcompat-v7:22.2.0')
If you need sdk 23, add this to your gradle:
android {
useLibrary 'org.apache.http.legacy'
}
HttpClient won't import in Android Studio
You should think about using a HTTP library, there is a bunch of them on internet, some are really easy to use, optimize and errorless.
For example, Volley (made by Google, I really like this one), okHttp or Picasso (for image).
You should take a look at this.
If you want to send (output), for example with POST or PUT requests you need to use this :-
urlConnection.setDoOutput(true);
In your code :-
public class Login extends AsyncTask<String, Void, String>{
private String loginUrl = "http://...";
private int loginSuccess = 0;
public String getToken(String fromJson) throws JSONException {
JSONObject json = new JSONObject(fromJson);
if(json.has("api_authtoken")) {
loginSuccess = 1;
String appToken = json.getString("api_authtoken");
return appToken;
}
else {
return json.toString();
}
}
public String doInBackground(String... arg0) {
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String authToken;
try {
// get logged in to get the api_authtoken
String email = (String) arg0[0];
String password = (String) arg0[1];
URL url = new URL(loginUrl);
// Create the request and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setDoOutput(true); // HERE
//put values of edittexts into json-Object
JSONObject data = new JSONObject();
try {
data.put("email", email);
data.put("password", password);
} catch(JSONException e) {
Log.e("EXCEPTION", "unexpected JSON exception", e);
e.printStackTrace();
}
OutputStreamWriter wr = new OutputStreamWriter(urlConnection.getOutputStream());
wr.write(data.toString());
wr.flush();
urlConnection.connect();
reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
//read server response
while((line = reader.readLine()) != null) {
sb.append(line);
}
//receive server "answer"
try {
return getToken(sb.toString());
}catch(JSONException e) {
Log.e("LOG", "unexpected JSON exception", e);
e.printStackTrace();
} finally{
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("MainActivity", "Error closing stream", e);
}
}
}
//return sb.toString();
return null;
}
catch(IOException e) {
Log.e("LoginTask", "Error ", e);
// If the code didn't successfully get the data, there's no point in attempting
// to parse it.
//forecastJsonStr = null;
return null;
}
}
public void onPostExecute(String result) {
super.onPostExecute(result);
//Log.v("RESULT", result);
if(result == null) {
CharSequence text = "no internet connection";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(MainActivity.this, text, duration);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
if(loginSuccess == 0) {
// if the request wasn't successful
// give user a message via toast
CharSequence text = "wrong password or user. please try again";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(MainActivity.this, text, duration);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
else {
// save token in shared preferences
SharedPreferences tokenPref = getSharedPreferences(getString(R.string.preference_token), Context.MODE_PRIVATE);
SharedPreferences.Editor editorToken = tokenPref.edit();
editorToken.putString(getString(R.string.saved_auth_token), result);
editorToken.commit();
//save login status = 1 in shared preferences
SharedPreferences loginPref = getSharedPreferences(getString(R.string.preference_logged_in), Context.MODE_PRIVATE);
SharedPreferences.Editor editorLogin = loginPref.edit();
editorLogin.putString(getString(R.string.saved_login), "1");
editorLogin.commit();
Intent mapsIntent = new Intent(getApplicationContext(), MapsActivity.class);
startActivity(mapsIntent);
}
}
}

Why am I getting null pointer in the getGraphObject when trying to post a image to facebook from android?

I am trying to post a photo from an url to the facebook. So, I have a method that converts the image located in the provided url to a bitmap, after that I want to publish the image to the facebook photos of the user. This is my code:
Method that converts image located in a URL to a Bitmap image:
public Bitmap downloadImage(String url) {
Bitmap bm = null;
try {
URL aURL = new URL(url);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
} catch (IOException e) {
Log.e("Hub","Error getting the image from server : " + e.getMessage().toString());
}
return bm;
}
This is where I try to post the image in the facebook:
private void postToFacebook(byte[] data) {
Session session = Session.getActiveSession();
if (session != null) {
Bundle postParams = new Bundle();
postParams.putString("caption", "Teste caption");
postParams.putByteArray("picture", data);
Request.Callback callback = new Request.Callback() {
public void onCompleted(Response response) {
JSONObject graphResponse = response.getGraphObject().getInnerJSONObject();
String postId = null;
try {
postId = graphResponse.getString("id");
} catch (JSONException e) {
Log.i("", "JSON error "+ e.getMessage());
}
FacebookRequestError error = response.getError();
if (error != null) {
Toast.makeText(getContext(), error.getErrorMessage(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), postId, Toast.LENGTH_LONG).show();
}
}
};
Request request = new Request(session, "me/photos", postParams, HttpMethod.POST, callback);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
} else {
Toast.makeText(getContext(), "Not logged", Toast.LENGTH_SHORT).show();
}
But at this line: response.getGraphObject(), I am getting the null pointer exception. I've tried to execute in a background thread, like this:
class ConvertImageTask extends AsyncTask<URL, Integer, byte[]> {
AsyncTask<Params,Progress,Result>
#Override
protected void onPreExecute() {
super.onPreExecute(); // do nothing here
}
#Override
protected byte[] doInBackground(URL... params) {
byte[] data;
Bitmap bi = downloadImage(getPhotoUrl());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bi.compress(Bitmap.CompressFormat.PNG, 100, baos);
data = baos.toByteArray();
return data;
}
#Override
protected void onPostExecute(byte[] result) {
postToFacebook(result);
}
But the error continues.
How can I fix this?
Thank you!
The pages I've gone through show the "picture" parameter is a URL, not data you can upload from your computer.
To upload a photo I am using:
Request request = Request.newUploadPhotoRequest(Session.getActiveSession(),
BitmapFactory.decodeStream(this.getAssets().open("YourFile.png")),
new Request.Callback(){
#Override
public void onCompleted(Response response) {
FacebookRequestError error = response.getError();
if(error != null){
Log.i(this.getClass().getName(),"Error publishing.");
}else{
JSONObject graphResponse = response.getGraphObject().getInnerJSONObject();
String postId = null;
try {
postId = graphResponse.getString("id");
} catch (JSONException e) {
Log.i("Facebook error", "JSON error " + e.getMessage());
}
//Logged in Succesfully!
}
}
});
Bundle params = request.getParameters();
params.putString("name", "The title for the photo.");
request.setParameters(params);
request.executeAsync();
I am passing a png I have in my assets folder, but you can adapt that part to what you need. Looking at your code it should be straight forward.

Uploading Images to tumblr API from Android

One assumed using the Tumblr API to upload images would be easy. It isn't. (EDIT It is now, see Edit 2 at the end of this entry)
My app is supposed to upload an image to tumblr. I would prefer doing that from a service but for now I use an activity that closes itself as soon as its done uploading. In OnCreate() the user is authenticated:
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)));
}
This opens a browser activity where the user can add username and passoword and then the app returns to the activity (this is also why I have to use an activity, I don't know how to do this from a service)
Returning from the browser the data is extracted:
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();
Most of these two snippets I got from here and they work well.
With these tokens I can now try putting data on tumblr. When I try to add Text this works fine using this method:
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();
}
As you can see here http://www.tumblr.com/blog/snapnowandroid (at least as of this time) the text "this is just a test" is posted.
However, when I try to post images, it gets strange. Now I have checked around and apparently this is a well known issue with the tumblr API, which has excessively been discussed here and some have solved it in other programming languages (for example here) but I have been unable to repeat those successes.
The method (in its entirety below) has the exact same structure to the above method (that works), the nameValuePairs are just different
The method is given a Bitmap variable called photo:
private void uploadToTumblr(Bitmap photo)
This bitmap is converted into an array:
ByteArrayOutputStream stream = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] bytes = stream.toByteArray();
The nameValuePairs are filled as follows:
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)));
The result is a {"meta":{"status":400,"msg":"Bad Request"},"response":{"errors":["Error uploading photo."]}} from the tumblr api.
I have tries encoding the picture differently as discribed in this article but without any changes.
//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));
Here the entire method (without the hex encoding):
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();
}
Now, while there are several things I am unhappy with (for example that this is done using an activity instead of a service) the big issue here is clearly the problem of uploading images. I am by no means the first to have this problem, so has anyone been able to get this done in java?
Edit 1
Have not made any progress with the problem at hand but created a workaround that might be nice for people who have the same issue. Tumblr offers posting via mail and you can programm android to send emails in the background as shown here. This works very well but you need to ask users to provide their mail account data and the Tumblr-mail Adress to post.
Edit 2
Years have pased and using email is no longer the easy way to do it. With jumblr there is finally a good API for Java that will work on android. OAuth-Authentication is no fun (it never is) but once you get past this, its fantastic.
Now, technically the question of how to do the authentication does not belong here but It's my overly long question, so I'll just paste some code here and if it's not interesting to you just skip it.
This uses a jar called 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;
}
}
The WebViewFragement looks like this:
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();
}
}
}
}
Why don't you use Jumblr the official Java client for Tumblr.
Regards.
You can easily do this using 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();
This worked for me...
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));`
where filePath is http url.
I have use multipart
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
I have done using following method. you can try this.
//paramString="text you want to put in caption"
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 : First Upload image to Web Server then get Url and try to Post with uploaded Url or File path. it will work fine sure... :)

Http delete gets bad request in Android

I am working with Android http stuff to register/unregister to the server. I have a DELETE request to use HttpDelete. I am getting Http401 'Bad request' error when I try to call it. I cannot why it is happening. Please help me.
Here is my code:
HttpUtils.java
private BasicHttpParams mParams;
private UsernamePasswordCredentials mCredentials = null;
private ResponseHandler mResponseHandler = null;
public void setUserCredentials(String userName, String password) {
this.mCredentials = new UsernamePasswordCredentials(userName, password);
}
public void setResponseHandler(ResponseHandler responseHandler){
this.mResponseHandler = responseHandler;
}
public Result<String> delete(String url){
Result<String> result = new Result<T>();
result.setStatus(Result.FAIL);
try {
DefaultHttpClient httpClient = new DefaultHttpClient(mParams);
httpClient.setParams(mParams);
httpClient.getCredentialsProvider().setCredentials(new AuthScope(null, -1), mCredentials);
HttpResponse response = httpClient.execute(new HttpDelete(url));
result.setResult(mResponseHandler.handleResponse(response));
result.setStatus(Result.SUCCESS);
} catch (IllegalArgumentException e) {
e.printStackTrace();
result.setMessage(e.getMessage());
} catch (ClientProtocolException e) {
e.printStackTrace();
result.setMessage(e.getMessage());
} catch (ConnectTimeoutException e) {
result.setMessage("Connection timed out.");
} catch (IOException e) {
e.printStackTrace();
result.setMessage(e.getMessage());
}
return result;
}
UnregisterTask.java
#Override
protected Void doInBackground(String... urls) {
if (urls==null || urls.length!=1)
return null;
String url = urls[0];
HttpUtils httpUtils = new HttpUtils();
httpUtils.setUserCredentials("userid", "password");
httpUtils.setResponseHandler(new UnrgisterHandler());
httpUtils.delete(url);
Result<String> result = aClient.delete(url);
if (result!=null || result.result != null){
//Do Something
}
}
//UnrgisterActivity.java
public void onUnregisterButtonClick(View view){
UnregisterTask task = new UnregisterTask(this);
task.execute(ServerConfig.getIdmServer() + ServerConfig.DELETE_DEVICE + "myid");
}
Error recevied:
Apache Tomcat/7.0.26 - Error report HTTP Status 400 - type Status reportmessage description The request sent by the client was syntactically incorrect ().Apache Tomcat/7.0.26
Thanks in Advance.
I fixed it by myself but I do not understand clearly why the error happened. I changed my code after searching how to set basic authentication.
public Result<T> delete(String url)
Result<T> result = new Result<T>();
result.setStatus(Status.FAIL);
try {
DefaultHttpClient http = new DefaultHttpClient();
if (this.mCredentials!=null){
CredentialsProvider credProvider = new BasicCredentialsProvider();
credProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), this.mCredentials);
http.setCredentialsProvider(credProvider);
}
HttpDelete delete = new HttpDelete(url);
//delete.setEntity(new StringEntity(data, "UTF8"));
delete.addHeader("Content-type", JSON_TYPE);
HttpResponse response = http.execute(delete);
result.setResult(mResponseHandler.handleResponse(response));
result.setStatus(Result.Status.SUCCESS);
} catch (IllegalArgumentException e) {
e.printStackTrace();
result.setMessage(e.getMessage());
} catch (ClientProtocolException e) {
e.printStackTrace();
result.setMessage(e.getMessage());
} catch (ConnectTimeoutException e) {
result.setMessage("Connection timed out.");
} catch (IOException e) {
e.printStackTrace();
result.setMessage(e.getMessage());
}
return result;
}
A bit still confusing. Anyway, now it works charm.

Categories

Resources