I am performing login task and getting data from PHP server in json format. In response, I am getting a 'success' tag that containing User-ID
like this {"message":"You have been successfully login","success":"75"}
I get that value as "uid" in the same activity and move to next page. Now in next page, I want to check user profile. For that, I have to pass that "uid" as 'params' with url and get value from server. But don't understand how to do that.
In next activity page I am creating asyncTask to perform action.
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jsonParser.makeHttpRequest(PROFILE_URL, "GET",params);
// Check your log cat for JSON reponse
Log.d("Profile JSON: ", json.toString());
try {
// profile json object
profile = json.getJSONObject(TAG_PROFILE);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
Now I have to set the 'uid' in the place of params.
Use intent to pass data,
Intent intent = new Intent(getBaseContext(), SignoutActivity.class);
intent.putExtra("UID", uId);
startActivity(intent)
Use intent, but if you want to keep your uid for a long time , you can use SharedPrefferences
Method 1:
Class A {
String UID = "3";
public static void main(String[] args){
ClassB.setUid(3);
}
}
Class B {
public static String uid;
public static setUid(String id){
uid = id;
}
}
Method 2:
Intent intent = new Intent(getBaseContext(), SignoutActivity.class);
intent.putExtra("U_ID", uId);
startActivity(intent)
Beware about static variables, programmers dont usually like them and call them evil.
If what you're trying to do is transfer data from one activity to another, try adding an extra to your intent. After you've created the intent to launch the next page, add something like
intent.putExtra("uid", uid);
to add the uid as an extra. And on the next page, you can retrieve this data by
Intent intent = getIntent();
int uid = intent.getIntExtra("uid", defaultvalue);
In case you need to pass parameters along with GET method, you can simply add the respective values to the url:
public void getData(String uid) {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://www.yoursite.com/script.php?uid=" + uid);
HttpResponse response = httpclient.execute(httpget);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
If you want to pass parameters with POST method the code is a bit more complex:
public void postData(String uid) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>;
nameValuePairs.add(new BasicNameValuePair("uid", uid));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
In both cases you can get server response as stream:
InputStream s = response.getEntity().getContent();
The easiest way to get response body as a String is to call:
String body = EntityUtils.toString(response.getEntity());
Of course, there are numerous other ways to achive what you desire.
There are two ways to pass parameters with Get request.
http://myurl.com?variable1=value&variable2=value2
Passing arguments as headers in request.
As HttpClient is now deprecated in the API 22, so you should use the Google Volley https://developer.android.com/training/volley/simple.html
Adding parameters using volley library as
/**
* This method is used to add the new JSON request to queue.
* #param method - Type of request
* #param url - url of request
* #param params - parameters
* #param headerParams - header parameters
* #param successListener - success listener
* #param errorListener - error listener
*/
public void executeJSONRequest(int method, String url, final JSONObject params, final HashMap<String, String> headerParams,
Response.Listener successListener,
Response.ErrorListener errorListener) {
JsonObjectRequest request = new JsonObjectRequest(method, url, params,
successListener, errorListener) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
if (headerParams != null)
return headerParams;
else
return super.getHeaders();
}
};
// Add request to queue.
addRequestToQueue(request);
}
Related
Task
Create a one-time login feature using Android's authentication manager.
Current Process
I am currently using the Volley to read email and password from a form and send a request to a server
Required Change
To be able to create a one-time login for the use with credentials, using Android authentication manager following this post.
Question
1. My question lies in the implementation of the fetchTokenFromCredentials method under the getAuthToken of the authenticator class.
Here is the Java code snippet:
#Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options)
throws NetworkErrorException {
// We can add rejection of a request for a token type we
// don't support here
// Get the instance of the AccountManager that's making the
// request
final AccountManager am = AccountManager.get(mContext);
// See if there is already an authentication token stored
String authToken = am.peekAuthToken(account, authTokenType);
// If we have no token, use the account credentials to fetch
// a new one, effectively another logon
if (TextUtils.isEmpty(authToken)) {
final String password = am.getPassword(account);
if (password != null) {
authToken = fetchTokenFromCredentials(account.name, password, authTokenType)
}
}
// If we either got a cached token, or fetched a new one, hand
// it back to the client that called us.
if (!TextUtils.isEmpty(authToken)) {
final Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
result.putString(AccountManager.KEY_AUTHTOKEN, authToken);
return result;
}
// If we get here, then we don't have a token, and we don't have
// a password that will let us get a new one (or we weren't able
// to use the password we do have). We need to fetch
// information from the user, we do that by creating an Intent
// to an Activity child class.
final Intent intent = new Intent(mContext, LoginActivity.class);
// We want to give the Activity the information we want it to
// return to the AccountManager. We'll cover that with the
// KEY_ACCOUNT_AUTHENTICATOR_RESPONSE parameter.
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
// We'll also give it the parameters we've already looked up, or
// were given.
intent.putExtra(LoginActivity.ARG_IS_ADDING_NEW_ACCOUNT, false);
intent.putExtra(LoginActivity.ARG_ACCOUNT_NAME, account.name);
intent.putExtra(LoginActivity.ARG_ACCOUNT_TYPE, account.type);
intent.putExtra(LoginActivity.ARG_AUTH_TYPE, authTokenType);
// Remember that we have to return a Bundle, not an Intent, but
// we can tell the caller to run our intent to get its
// information with the KEY_INTENT parameter in the returned
// Bundle
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
Previously I was using Volley , so my implementation of fetchTokenfromCredentials was something like shown below. However, I cannot use the same implementation now because I need to 'return' an authentication string. Volley does the login asynchronously so even if i add a return type to the function below it will always return null. Question: How do i wrap around THIS situation. What alternatives can I use?
public void fetchTokenfromCredentials(String name, String password) {
JSONObject loginObject = new JSONObject();
try {
loginObject.put("email", email);
loginObject.put("password", password);
} catch(JSONException e) {
e.printStackTrace();
}
// assume predefined url and params
JsonObjectRequest loginRequest = new HeaderRequest(Request.Method.POST, url + params, loginObject, new Response.Listener < JSONObject > () {#Override
public void onResponse(JSONObject response) {
try {
JSONObject headers = response.getJSONObject("headers");
// A simple use class that stores the id, username etc.
user = new User(response.getInt("id"), response.getString("name"), response.getString("authentication_token"), response.getString("email"));
// Previous code started a new main activity intent here
} catch(JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Failed response");
}
});
RequestQueueSingleton.getInstance(this.getApplicationContext()).addToRequestQueue(loginRequest);
}
You can make a synchronous, blocking request with Volley. That request will perform the network request, while blocking the thread and allow you to set a return type.
I am not fluent with Volley (Retrofit, FTW!) but I am pretty sure it's doable.
Take a look at this answer for a Synchronous request - https://stackoverflow.com/a/23808857
This is how I wrote the fetchTokensFromCredentials(email,password) function using the android Http Client Library:
URL was created using a uri builder
Uri builtUri = Uri.parse(AccountGeneral.LOGIN_QUERY).buildUpon()
.build();
URL url = null;
try {
url = new URL(builtUri.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
// Stores result of the post response
String result = null;
// Create a JSON object for the email and password
JSONObject loginObject = new JSONObject();
try{
loginObject.put("email", email);
loginObject.put("password", password);
} catch(JSONException e) {
e.printStackTrace();
}
// Convert JSON to String
String data = loginObject.toString();
// Connection parameters
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setRequestMethod("POST");
try {
//Start POST request - Write
OutputStream outputStream = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
writer.write(data);
writer.close();
outputStream.close();
//Read response
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
bufferedReader.close();
result = sb.toString();
return result;
} finally {
urlConnection.disconnect();
}
I have an app that should send a the phone number and retrieve a value from the database, now I change the query and my code should retrieve values of multiple columns, So where changes should be in my code.
public class JSONTransmitter extends AsyncTask<JSONObject, Void, String>
{
HttpResponse response;
String url = "http://192.168.1.97:89/Derdeery/bankOsman.php";
private AsyncCallback asyncCallback;
public JSONTransmitter(Context context) {
// attach the callback to any context
asyncCallback = (AsyncCallback) context;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
asyncCallback.onResponse(result);
}
protected String doInBackground(JSONObject... data)
{
JSONObject json = data[0];
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 100000);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitNetwork().build());
JSONObject jsonResponse = null;
HttpPost post = new HttpPost(url);
String resFromServer = "";
try {
StringEntity se = new StringEntity("json=" + json.toString());
post.addHeader("content-type", "application/x-www-form-urlencoded");
post.setEntity(se);
HttpResponse response;
response = client.execute(post);
resFromServer = org.apache.http.util.EntityUtils.toString(response.getEntity());
Log.i("Response from server", resFromServer);
} catch (Exception e) {
e.printStackTrace();
}
return resFromServer;
}
public static interface AsyncCallback {
void onResponse(String res);
}
}
Here is something to consider:
First, in your php code (server-side), query your data perhaps separately. So for instance, you can get those that match column A and then query for those that match column B.
Generate Json for each (A and B accordingly)
Then create a single JSON object that contains the two sets of data like this:
{
"DataFromColumnA" : {},
"DataFromColumnB" : {}
}
Once you have made your HTTP request in your android code, you can get the specific data by getting "DataFromColumnA" json Object and B respectively.
I hope this helps you get your problem solved!
I am currently using android-async-http library to send a post/get requests. I didn't have any problem before but now i realize that it gives me timeout error if i send this request without image data. (There is no error if i send exact same request by putting image data as well.)
RequestParams params = new RequestParams();
params.add("mail", mail.getText().toString());
params.add("password", pass.getText().toString());
try {
if (!TextUtils.isEmpty(imagePath))
params.put("image", new File(imagePath));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
AsyncHttpClient client = new AsyncHttpClient();
client.setTimeout(60000);
client.post("some_url", params, myResponseHandler);
What is the reason of this?
Thanks in advance.
After comparing requests and responses, i found out that the case was content-type. With image it was posting multipart, and without it something else.
So i got into RequestParams class in library, and made these changes. Now it works fine. For further troubles i am posting changes that i've made.
I put a flag to determine this request should post as multipart or not:
private boolean shouldUseMultiPart = false;
I created a constructor to set this parameter:
public RequestParams(boolean shouldUseMultiPart) {
this.shouldUseMultiPart = shouldUseMultiPart;
init();
}
And then on getEntity() method i applied these lines:
/**
* Returns an HttpEntity containing all request parameters
*/
public HttpEntity getEntity() {
HttpEntity entity = null;
if (!fileParams.isEmpty()) {
...
} else {
if (shouldUseMultiPart) {
SimpleMultipartEntity multipartEntity = new SimpleMultipartEntity();
// Add string params
for (ConcurrentHashMap.Entry<String, String> entry : urlParams
.entrySet()) {
multipartEntity.addPart(entry.getKey(), entry.getValue());
}
// Add dupe params
for (ConcurrentHashMap.Entry<String, ArrayList<String>> entry : urlParamsWithArray
.entrySet()) {
ArrayList<String> values = entry.getValue();
for (String value : values) {
multipartEntity.addPart(entry.getKey(), value);
}
}
entity = multipartEntity;
} else {
try {
entity = new UrlEncodedFormEntity(getParamsList(), ENCODING);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
return entity;
}
i wrote those threads:
How to manage multiple Async Tasks efficiently in Android
Running multiple AsyncTasks at the same time -- not possible?
but didnt find answer for my question, maybe someone can help..
I have android app which makes Login POST and getting json response,
if the Json is OK i need to POST another data to get another response.
i have extends Async Class which doing the post to the URL:
public class AsyncHttpPost extends AsyncTask<String, String, String> {
private HashMap<String, String> mData = null;
public AsyncHttpPost(HashMap<String, String> data) {
mData = data;
}
#Override
protected String doInBackground(String... params) {
byte[] result = null;
String str = "";
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(params[0]);// in this case, params[0] is URL
try {
ArrayList<NameValuePair> nameValuePair = new ArrayList<NameValuePair>();
Iterator<String> it = mData.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
nameValuePair.add(new BasicNameValuePair(key, mData.get(key)));
}
post.setEntity(new UrlEncodedFormEntity(nameValuePair, "UTF-8"));
HttpResponse response = client.execute(post);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpURLConnection.HTTP_OK){
result = EntityUtils.toByteArray(response.getEntity());
str = new String(result, "UTF-8");
}
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (Exception e) {
return null;
}
return str;
}
#Override
protected void onPostExecute(String result) {
try {
JSONArray Loginjson = new JSONArray(result);
strStt = Loginjson.getJSONObject(0).getJSONObject("fields").getString("status");
if (strStt.equals("ERR")) {
ErrorMsg("Authentication failed");
} else if (strStt.equals("OK")) {
ErrorMsg("Login OK!!!");
ClientPage();
} else {
ErrorMsg("Connection Error");
}
} catch (JSONException e) {
ErrorMsg("Connection Error");
}
}
}
Now - i need to get another POST if the status is Error. do i need to make another Async class? with the same all procedures ? the issue is only the onPostExecute part is different.. actually the "doInBackground" will be always the same..
any idea how can i easily do multiple posts in the same activity?
Firstly, since your doInBackground() code will always stay the same, I recommend you move it into a general utility class.
Beyond that, you can go one of two ways:
Create a new AsyncTask for each type of request that can call your utility class, and have its own onPostExecute()
Create one AsyncTask that has a flag in it, which can be checked in the onPostExecute() method to see what code needs to be executed there. You will have to pass the flag in in the constructor or as a parameter in execute.
You can use a parameter at AsyncHttpPost constructor/execute or global variable to indicate if it is first or second POST (by other words - a flag). Then just create and execute another instance of AsyncHttpPost in onPostExecute (only if parameter/variable is set as "first POST").
I have an application in that i called webservice using this link,I have one webservice Url and another Url is getting as response from that url.I need to use that url as
public static final String TIME_CENTRAL_SERVER = "http://accounts.myexample.com/Services"; in the place of
"http://accounts.myexample.com/Services" i need to parse my json response.
I have check for that in google but couldn't get any answer can anyone help me regarding this, Thanks in advance.
If anyone have queries ask me.
First webservice call is like below
RestClient client = new RestClient(LOGIN_URL);
client.AddParam("accountType", "GOOGLE");
client.AddParam("source", "tboda-widgalytics-0.1");
client.AddParam("Email", _username);
client.AddParam("Passwd", _password);
client.AddParam("service", "analytics");
client.AddHeader("GData-Version", "2");
try {
client.Execute(RequestMethod.POST);
} catch (Exception e) {
e.printStackTrace();
}
String response = client.getResponse();
After parsing the response, if you want to do another Web Service call, just create another object of RestClient with different URL and Parameters and call execute method, like below,
RestClient client1 = new RestClient(GET_INFO_URL);
client1.AddParam("userid", "123");
try {
client1.Execute(RequestMethod.POST);
} catch (Exception e) {
e.printStackTrace();
}
String response1 = client1.getResponse();
finally i solved my issue with guidance of my team head below is the code which we have used in constants.java class
public static final String GET_CENTRAL_SERVER = String.format("%s/AccountService/security/ValidateAccess", TIMEMACHINE_ACCOUNTS_SERVER);
and add code snippet in serversync.java class
public String getCentralServer(Context context, String serial_number) throws Exception{
// TODO Auto-generated method stub
WebServiceClient client = new WebServiceClient(Constants.GET_CENTRAL_SERVER);
client.addParam("accesscode", String.valueOf(serial_number));
client.addParam("type", "2");
client.Execute(RequestMethod.GET);
String response = client.getResponse();
if (response != null){
response = response.replaceAll("\\\\/", "/");
response = response.replace("\"", "");
response = response.replace("\n","");
response = "http://" + response;
return response;
}
return null;
}