How do you do write an HttpPut request with authentication on Android?
(I'm trying to work around using HttpURLConnection, which seems to serious have bugs (at least in Android 2.2) but GET works fine. I'd like to send a JSON representation of an array, and I have correct credentials already set using PasswordAuthentication.)
First you need to have an authentication token. And then just add this line.
httpGet.setHeader("Authorization", "Bearer " + yourToken);
Here's one general solution.
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, this.CONNECT_TIMEOUT);
HttpConnectionParams.setSoTimeout(httpParameters, this.CONNECT_TIMEOUT);
DefaultHttpClient client = new DefaultHttpClient(httpParameters);
// Retrieve user credentials.
SharedPreferences settings = context.getSharedPreferences("LOGIN", 0);
String loginNameString = settings.getString("login_name", null);
String passwordString = settings.getString("password", null);
UsernamePasswordCredentials credentials =
new UsernamePasswordCredentials(loginNameString, passwordString);
AuthScope authScope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT);
client.getCredentialsProvider().setCredentials(authScope,
credentials);
HttpPut put = new HttpPut(UPLOAD_URL);
try
{
put.setEntity(new StringEntity(responseJSONArray.toString(),
SERVER_PREFERRED_ENCODING));
put.addHeader("Content-Type", "application/json");
put.addHeader("Accept", "application/json");
HttpResponse response = client.execute(put);
// 200 type response.
if (response.getStatusLine().getStatusCode() >= HttpStatus.SC_OK &&
response.getStatusLine().getStatusCode() < HttpStatus.SC_MULTIPLE_CHOICES)
{
// Handle OK response etc........
}
}
catch (Exception e)
{
}
Related
When I use Follow/Unfollow API in instagram. I give me error like that.
Error:
{"meta":{"error_type":"OAuthPermissionsException","code":400,"error_message":"This client has not been approved to access this resource."}}
My Post method Call is here.
public static AllMessage postAction(String action, String UserID, String mAccessToken, DefaultHttpClient httpClient) {
AllMessage ReturnMessage = new AllMessage();
String url = String.format(RELATIONSHIP_URL, new Object[]{UserID, mAccessToken});
Log.v("log_tag", "FolURL " + url);
try {
HttpParams params = new BasicHttpParams();
params.setParameter("http.protocol.version", HttpVersion.HTTP_1_1);
params.setParameter("action=", action);
if (httpClient == null) {
httpClient = OpenHttpClientConnection();
}
HttpPost httpPost = new HttpPost(url);
List<NameValuePair> arrayList = new ArrayList(2);
arrayList.add(new BasicNameValuePair("action", action));
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", String.valueOf(arrayList));
UrlEncodedFormEntity ent = new UrlEncodedFormEntity(arrayList, "UTF-8");
httpPost.setEntity(ent);
String mHttpReturnedData = readInputStreamToString(httpClient.execute(httpPost).getEntity().getContent());
Log.v("log_tag", "Return " + mHttpReturnedData);
} catch (Exception e4) {
ReturnMessage.MessageType = "Unsupported Format";
ReturnMessage.MessageError = "Unsupported data format Error -1000";
ReturnMessage.ActionSucess = false;
ReturnMessage.ActionID = 0;
ReturnMessage.PrvAction = action;
}
return ReturnMessage;
}
Please help me for this code.
You need to first register your app to use the Instagram API
The link is here https://www.instagram.com/developer/endpoints/
Then you comunicate with the endpoint https://api.instagram.com/v1/tags/nofilter/media/recent?access_token=ACCESS_TOKEN
and make the proper calls.
Currently there is not an Android SDK made by them that I have heard of, but I'm pretty sure there has to be a 3rd party out there.
Hope it helps.
I am trying to make a login and register for an android app.
I have been having problems adjusting the code to API 22.
Although I know I have to use HttpURLConnection instead of HttpRequestParams etc., and have done that, I can't figure out how to adjust the code to incorporate the database server and my PHP files stored on there.
It's mostly this bit below that I can't figure out.
HttpClient client = new DefaultHttpClient(httpRequestParams);
HttpPost post = new HttpPost(SERVER_ADDRESS + "FetchUserData.php");
Can anyone help? Thanks in advance.
Here's the full code:
#Override
protected User doInBackground(Void... params) {
ContentValues contentValues = new ContentValues();
contentValues.put("username", user.username);
contentValues.put("password", user.password);
URL url = new URL(SERVER_ADDRESS);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setReadTimeout(CONNECTION_TIMEOUT);
HttpClient client = new DefaultHttpClient(httpRequestParams);
HttpPost post = new HttpPost(SERVER_ADDRESS + "FetchUserData.php");
User returnedUser = null;
try {
post.setEntity(new UrlEncodedFormEntity(dataToSend));
HttpResponse httpResponse = client.execute(post);
HttpEntity entity = httpResponse.getEntity();
String result = EntityUtils.toString(entity);
JSONObject jObject = new JSONObject(result);
if(jObject.length() == 0) {
returnedUser = null;
} else {
String mobile = jObject.getString("mobile");
String email = jObject.getString("email");
returnedUser = new User(mobile, email, user.mobile, user.email);
}
} catch(Exception e) {
e.printStackTrace();
}
return returnedUser;
}
first: It's already been answered
Sending Http request for Android 22+
second: I've made a class that meets your needs, which allow you to send request and receive response with one line of code (It's also explained in post above)
Here is the link for the my class:
HttpRequest
I used httppost to login a bbs.
The httpclient can save cookie and other information automatically.
I want to get cookie for httpclient and save it.
So next time I can give the cookie to httpclient and I can visit the bbs again.
So my question is how to get cookie from httpclient.
and how to save the cookie.
and how to set httpclient used the cookie.
Thank you.
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpClientContext context = HttpClientContext.create();
BasicCookieStore cookieStore = new BasicCookieStore();
context.setCookieStore(cookieStore);
HttpGet httpget = new HttpGet("https://host/stuff");
CloseableHttpResponse response = httpclient.execute(httpget);
try {
List<Cookie> cookies = cookieStore.getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.size(); i++) {
System.out.println("- " + cookies.get(i).toString());
}
}
EntityUtils.consume(response.getEntity());
} finally {
response.close();
}
Please note you will need to use the official Apache HttpClient port to Android
Do it like this:
Header[] headers = null;
HttpResponse response = null;
HttpClient httpclient = new DefaultHttpClient(params);
HttpPost post = new HttpPost(URI.create(this._strBaseUrl));
response = httpclient.execute(post);
After request returned, extract cookie via:
headers = response.getHeaders("Set-Cookie");
Then You can iterate through cookie values ( if necessary).
I am sending some information to a sever for a university project of mine. The problem i am having is that the sever will only acpect POST request, it will not parse GET requests which is fair enough.
The issue i am having is that i am sending a httpPost request i check this using the built in Android method (see below) but when it arrives at the server it sees it as a GET request.
Post code:
JSONObject auth = new JSONObject();
auth.put("TEST", "TESTING");
HttpClient httpclient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://xxxxxxxxxxxxx/upload.php");
String meth = httpPost.getMethod();
Toast checker = Toast.makeText(this, meth, Toast.LENGTH_LONG);
checker.show();
String json = "";
json = auth.toString();
StringEntity se = new StringEntity(json);
httpPost.setHeader("User-Agent", "android app");
httpPost.setEntity(se);
httpclient.execute(httpPost);
The check Toast, displays the value POST, which is correct.
The sever log shows this as a GET request.
xxxxxxxxxxx MY IP - - [09/Dec/2013:00:20:57 +0000] "GET /upload.php HTTP/1.1" 405 352 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0"
Edited severname / Ip's out of the log and code.
ANy ideas?
Use this method my friend for posting data to server
public Boolean postDataWithURL(String url, String fileUrl,
ArrayList<NameValuePair> listParamsWithValues) {
boolean result = false;
try {
int TIMEOUT_MILLISEC = 100000; // = 10 seconds
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams,
TIMEOUT_MILLISEC);
HttpConnectionParams.setSoTimeout(httpParams, TIMEOUT_MILLISEC);
HttpClient client = new DefaultHttpClient(httpParams);
HttpPost request = new HttpPost(url);
if (fileUrl.equalsIgnoreCase("")) {
request.setEntity(new UrlEncodedFormEntity(listParamsWithValues));
} else {
// System.out.println("file path "+fileUrl+" with actual path "+file);
}
// request.setEntity(new
// ByteArrayEntity(listParamsWithValues.toString().getBytes("UTF8")));
HttpResponse response = client.execute(request);
String responseString = request(response);
// System.out.println(responseString);
if (responseString.toLowerCase().contains("1")) {
result = true;
} else {
result = false;
}
} catch (Exception e) {
// Some things goes Wrong
e.printStackTrace();
}
return result;
}
I'm trying to upload an image file from an android device to my drupal website using services module
I can log-in succesfully:
HttpParams connectionParameters = new BasicHttpParams();
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(connectionParameters, timeoutConnection);
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(connectionParameters, timeoutSocket);
httpClient = new DefaultHttpClient(connectionParameters);
HttpPost httpPost = new HttpPost(serverUrl+"user/login");
JSONObject json = new JSONObject();
try{
json.put("password", editText_Password.getText().toString());
json.put("username", editText_UserName.getText().toString());
StringEntity se = new StringEntity(json.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
httpPost.setEntity(se);
//Execute HTTP post request
HttpResponse response = httpClient.execute(httpPost);
int status_code = response.getStatusLine().getStatusCode();
...
...
}
catch(Exception ex)
{
}
via response object I can get session name session id , user id and many other info.
after the login , I set no session info by myself through my HttpGet object , but use the same DefaultHttpClient, I can magically retrieve a node using the following code:
HttpGet httpPost2 = new HttpGet(serverUrl+"node/537.json");
HttpResponse response2 = httpClient.execute(httpPost2);
this made me think that, httpClient object stored the session info for me automatically.
because if I dont login first or use a new HttpClient object and try to retrieve the node, I get a 401 error.
However when I try to upload an image file as follows after logging in:
httpPost = new HttpPost(serverUrl+"file/");
json = new JSONObject();
JSONObject fileObject = new JSONObject();
fileObject.put("file", photodata); //photodata is a byte[] that is set before this point
fileObject.put("filename", "myfirstfile");
fileObject.put("filepath", "sites/default/files/myfirstimage.jpg");
json.put("file", fileObject);
se = new StringEntity(json.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
httpPost.setEntity(se);
//Execute HTTP post request
response = httpClient.execute(httpPost);
status_code = response.getStatusLine().getStatusCode();
I get 401 error although I'm logged in and using the same HttpClient object.
I also tried adding :
httpPost.setHeader("Cookie", SessionName+"="+sessionID);
which again gives me 401 error.
I'm also not sure whether I'm using the correct url, because I'm trying to use file.create method, but writing the url as "myip:myport/rest/file/create" gives wrong address.
My aim is to upload an image to a users node, so I guess after succesfully adding the file, I'll use node.create right?
I hope someone will help me get through this.
I found when I first started doing this that most of my errors were due to not authenticating correctly.. I'm not sure your method is correct.. I know this works.
Using Drupal Services 3, I login as such and then store my session cookie into shared preferences. dataOut is a JSON object which holds the needed user login, and password information.
String uri = URL + ENDPOINT + "user/login";
HttpPost httppost = new HttpPost(uri);
httppost.setHeader("Content-type", "application/json");
StringEntity se;
try {
se = new StringEntity(dataOut.toString());
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
"application/json"));
httppost.setEntity(se);
HttpResponse response = mHttpClient.execute(httppost);
mResponse = EntityUtils.toString(response.getEntity());
// save the sessid and session_name
JSONObject obj = new JSONObject(mResponse);
SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(mCtx);
SharedPreferences.Editor editor = settings.edit();
editor.putString("cookie", obj.getString("session_name") + "="
+ obj.getString("sessid"));
editor.putLong("sessionid_timestamp", new Date().getTime() / 100);
editor.commit();
} catch { //all of my catches here }
Once I have my session id stored.. I go about performing tasks on drupal like this.. The following code posts a node. I use the function getCookie() to grab the session cookie if it exists.. if not, then I log in, or if it's expired, I log in. (note, you need to set the cookie expire time in your drupal settings.php file (I think that's where it is if I remember correctly)
String uri = URL + ENDPOINT + "node";
HttpPost httppost = new HttpPost(uri);
httppost.setHeader("Content-type", "application/json");
String cookie = this.getCookie(mCtx);
httppost.setHeader("Cookie", cookie);
StringEntity se;
try {
se = new StringEntity(dataOut.toString());
httppost.setEntity(se);
HttpResponse response = mHttpClient.execute(httppost);
// response is here if you need it.
// mResponse = EntityUtils.toString(response.getEntity());
} catch { //catches }
The getCookie() function that keeps your cookie uptodate and working..
/**
* Takes the current time, the sessid and determines if we are still part of
* an active session on the drupal server.
*
* #return boolean
* #throws InternetNotAvailableException
* #throws ServiceNotAvailableException
*/
protected String getCookie(Context ctx)
throws InternetNotAvailableException {
SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(mCtx);
Long timestamp = settings.getLong("sessionid_timestamp", 0);
Long currenttime = new Date().getTime() / 100;
String cookie = settings.getString("cookie", null);
//mSESSION_LIFETIME is the session lifetime set on my drupal server
if (cookie == null || (currenttime - timestamp) >= mSESSION_LIFETIME) {
// the following are the classes I use to login.
// the important code is listed above.
// mUserAccount is the JSON object holding login,
// password etc.
JSONObject mUserAccount = UserAccount.getJSONUserAccount(ctx);
call(mUserAccount, JSONServerClient.USER_LOGIN);
return getCookie(ctx);
} else {
return cookie;
}
}
This really should enable you to take advantage of all that Services has to offer. Make sure your endpoints are correct, and also make sure your permissions are set. I cursed for hours before I realized I had not granted perms to make nodes to users.
So once you are logged in.. To upload a file to Drupal Services I use the following code to first convert the image to byteArray.. and then to Base64.
tring filePath = Environment.getExternalStorageDirectory()+ "/test.jpg";
imageView.setImageDrawable(Drawable.createFromPath(filePath));
Bitmap bm = BitmapFactory.decodeFile(filePath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] byteArrayImage = baos.toByteArray();
String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);
Once you have the encodedImage. Construct a JSON Object with the keys, file (required), filename (optional, but recommended), filesize (optional) and uid (optional, the poster I presume) JSON would therefore look like this at its simplist required form {"file":encodedImage}. Then, after making sure you have enabled the file resource on your server, POST the data to my-server/rest-endpoint/file. The response will include a fid in JSON. You can then assign this fid to the image field of a node you subsequently create using the node resource.