Requesting JSON data and inserting into fragment - android

I have 3 tabs in my app, each having its own Fragment. I need to populate each tab's Fragment with data that needs to be retrieved from my website's REST API.
To my understanding, the onCreate/onCreateView method in the Fragment class is where I should request the JSON data (how do I request it?).
Then I would loop through the data and insert it into separate lists or cards (how do I do this?).
Sorry for the beginner questions, but I'm not sure where to begin.

There are two ways to do this
1) through native android
private void makeGetRequest() {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://www.example.com");
// replace with your url
HttpResponse response;
try {
response = client.execute(request);
Log.d("Response of GET request", response.toString());
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
2) use third party libraries.Please refer this url https://github.com/square/retrofit
Example
https://github.com/square/retrofit/blob/master/samples/src/main/java/com/example/retrofit/SimpleService.java
This library will do all the things like GET,POST,Sync,Async and Error Handling.

you have to use AsyncTask When youre requesting anything from server, Asynctask runs in backgrouns so your UI thread will no be blocked by it.
Otherwise you can try using Volly library dosen't need an AsyncTask to work. It will work in background thread anyway '
It also provides you with sucess failure handlers(if youre into ajax and all it'll easier for you)
take a look at Volly Library

Related

Android post authorization

I am trying to do a http post to my server to check if the login credentials are valid with help of this tutorial. I need to make a request to my server but i have to add Authorization, i get the string with the function getB64Auth from this answer. the function logs the right variable, (the same as i use with postman). But for some reason my program stops running if i run my code. I already tried adding the code from the comments but it didn't help.
What am i doing wrong?
private String getB64Auth (String login, String pass) {
String source=login+":"+pass;
String ret="Basic "+Base64.encodeToString(source.getBytes(),Base64.URL_SAFE| Base64.NO_WRAP);
Log.d("authy", ret);
return ret;
}
/** Called when the user clicks the Login button */
public void login(View view) {
// Getting username and password
EditText userText = (EditText) findViewById(R.id.inputLoginUsername);
EditText passText = (EditText) findViewById(R.id.inputLoginPassword);
String usernameInput = userText.getText().toString();
String passwordInput = passText.getText().toString();
String authorizationString = getB64Auth(usernameInput,passwordInput );
// Do something in response to button
// 1. Create an object of HttpClient
HttpClient httpClient = new DefaultHttpClient();
// 2. Create an object of HttpPost
// I have my real server name down here
HttpPost httpPost = new HttpPost("https://myservername.com/login");
// 3. Add POST parameters
httpPost.setHeader("Authorization", authorizationString);
// 5. Finally making an HTTP POST request
try {
HttpResponse response = httpClient.execute(httpPost);
Log.d("win", "win1");
// write response to log
Log.d("Http Post Response:", response.toString());
} catch (ClientProtocolException e) {
Log.d("fail", "Fail 3");
// Log exception
e.printStackTrace();
} catch (IOException e) {
Log.d("fail", "Fail 4");
// Log exception
e.printStackTrace();
}
}
When i run my code the app stops working, i can find the log authy but i cant find any fail succes logs.
The things i have changed in the example are step 3.
ive added my authorization there.
and removed step 4 cause i dont need it.
Working postman example, with the same request i want to make in android.
You can see I get a response, and only set Authorization on my request.
I cant find any decent post/authorization tutorials so i hope i'm looking at the right direction.
It's an android 4.* project
Just a few suggestions about such issues:
Check permissions (INTERNET is the one you would need)
Applications like Charles / Fiddler let you sniff the Http traffic from the device so you could investigate what is being sent
If the application is crashing - check the LogCat messages (for example it could contain a message explaining which permission is missing)
Regarding this message:
The application may be doing too much work on its main thread.
This usually means that you are doing some heavy operations in the main thread - for example parsing the Json from the Http response. Generally you'd like to do all these operations in a background thread and use the main one to update the UI only.

Android authentication using JSON

I have a Python/Django server that is the API for a web service.
I'm building an Android application that will communicate with the API and authenticate users, and enable them do all pulls/pushes from the server.
My trouble is with the particular communication with the server. Currently I use my WiFi network, and run the server like so python manage.py runserver 192.168.1.3:8000 so that it is available to any test device on my LAN.
The API is written so it returns http status messages with every response, so that I can tell the success or failure of a request before parsing the JSON reply.
On my Android side, I have used HttpURLConnection because it has the getHeaderField(null) method that I use to pick the http status message from the response. I get a status message 200 [success] when I 'ping' my server - this is a sort-of proof of concept.
My real issue is authentication. My API requires I send it a JSON with data, and it returns a JSON response [with an http status message in the head].
I can't seem to figure out how to do this. The JSON action I've seen around the interwebs are merely picking, or posting.
I am wondering how I can POST and pick up a response from the server.
Extra information
- Server supports HEAD and GET and OPTIONS.
- Assuming server home is 192.168.1.3, user login/register would be in 192.168.1.3/user, events would be in 192.168.1.3/events and so on..
- This was the closest I got to figuring out a solution, but not quite..
CODE from the AsyncTask
protected JSONObject doInBackground(String... params) {
publishProgress(true);
/*Create a new HttpClient and Post Header*/
JSONObject result=null;
HttpClient httpclient = new DefaultHttpClient();
try {
URL url = new URL(cons.PROTOCOL,cons.SERVER,cons.PORT,"/user");
HttpPost httppost = new HttpPost(url.toURI());
HttpResponse response =null;
/*Add your data*/
JSONObject j1=new JSONObject();
JSONObject json=new JSONObject();
j1.put("username", "test");
j1.put("email","test#test.com");
j1.put("password","password");
j1.put("first_name","John");
j1.put("last_name","Doe");
json.put("user",j1);
json.put("mobile_number","256774622240");
StringEntity 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);
Log.i("jazz","It's ALIVE!!!!!");
Log.i("jazz",response.getStatusLine().toString());
} catch (ClientProtocolException e) {
/* TODO Auto-generated catch block*/
} catch (IOException e) {
// TODO Auto-generated catch block
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
If your are building your HttpPostRequest well, and you only want to know how to attach JSON, here you are a possible solution for it:
StringEntity formEntity = new StringEntity(yourJsonObject.toString());
yourPostRequest.setEntity(formEntity);
I hope this helps!
PS:In addition, let me recommend you the use of this component:
https://github.com/matessoftwaresolutions/AndroidHttpRestService
I've used it in an Android app that is connecting to a python server API and it makes http request easier for your Android client.
Okay, so I'm now answering my own question :D
The issue was with the path variable in the URL string.
This is the format of one of the URL constructors based on this document.
URL(String protocol, String host, int port, String file)
Since I am posting the JSON to the /user path, that's the one I insert into the constructor as the directory.
So, my URL was formed like so:
URL url= new URL("http",cons.SERVER,cons.PORT,"/user/");
My mistake in the beginning was using /user instead of /user/
but other than that, the URL structure and connections are all alright.

Parse large image from SOAP/XML in android

Hi I am working on an android app which relies on being able to fetch images among other data from our server, i.e., the image is contained in a tag as part of the response. The communication with the server is based on WCF and SOAP.
Up until the point where we need to fetch images it has worked fine. But when we need to fetch an image from the server the app takes a substantial amount of time and consumes a lot of memory when parsing the response from the server containing the image. The images we are working with are typically of the size of 1500 x 1000 pixels. The image itself is transmitted as a base64 encoded byte array.
Currently we are parsing the response using a DOM xml parser, which I know to be prone to huge memory consumption but insofar has not given any problems(aside from parsing images). Furthermore some minor tests using XMLPull, which seems to be the recommended XML parser on the android platform, has resolved in pretty much the same issue, huge memory and time consumption.
I suspect that the issue stems from the image being converted to a string or byte array both of which should consume quite a bit of memory considering the size of the image.
Bellow is an example of the code we currently are using to parse the response:
public static Document parseResponse(InputStream response)
{
Document parsedResponse = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
try {
builder = factory.newDocumentBuilder();
parsedResponse = builder.parse(response);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return parsedResponse;
}
And the response is fetched using an Async-Task using the following code:
protected Document doInBackground(ServerRequest... requests) {
ServerRequest request = requests[0];
HttpPost postRequest = request.postMethod;
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
HttpConnectionParams.setSoTimeout(httpParams, 10000);
DefaultHttpClient client = new DefaultHttpClient(httpParams);
HttpResponse response = null;
try {
response = client.execute(postRequest);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Document parsedResponse = null;
try {
InputStream stream = response.getEntity().getContent();
parsedResponse = ServerRequest.parseResponse(stream);
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return parsedResponse;
}
Currently it is not possible to fetch the image itself using a URL, i.e., it comes as part of the XML from the server, otherwise something like Android Hive - Custom ListView with Image and Text would probably be the way to go.
Before delving into something like kSOAP2 I would like to find out if there was a simple fix to the above approach or if I've missed something simple.
I have searched lot of on internet for your alternate solution. But it seems that memory constraints is always in middle of the way for phone.
Really 1500 * 1000 px image is too huge for android mobile to eat. I was also faced the same problem in one of my projects.
Only way is you can parse that string on server side, store it temporarily and pass the image path in response. This is the best approach i am feeling right now. I am still searching for solution. If found, i will let you know.
Your above approach will slow down the mobile and also kill the useful apps services running in background. :(

How to quickly test an HTTP post response in an Android emulator

Let's say I want to perform a quick HTTP post to a website within my android app.
If I were to set up the http client and send the post all in the onCreate method of the main screen (inside the UI thread) just for testing purposes, what would I use to quickly see what the response is to the post?
I tried something quick and dirty below inside the onCreate method when the app first opens and nothing really happens, is there something more I need to do/obviously my toast idea is just bad...
HttpClient httpClient = new DefaultHttpClient();
HttpPost post = new HttpPost("http://forecast.weather.gov/zipcity.php?inputstring=04419");
HttpResponse httpResp;
try {
httpResp = httpClient.execute(post);
StatusLine status = httpResp.getStatusLine();
Toast.makeText(getApplicationContext(), (CharSequence) status, Toast.LENGTH_SHORT).show();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
LogCat is your friend. It gives you a view of what's happening inside the device. Then in your code add statements like this:
Log.i("MyClassName","HTTP response is " + httpResponseString);
It's common to create a class member variable called "TAG" and pass that as the first parameter, e.g.:
private String TAG = "MyClassName";
....
Log.i(TAG,"HTTP response is " + httpResponseString);
You can view LogCat using DDMS (Dalvik Debug Monitor), an IDE (Eclipse, IntelliJ IDEA, etc), and there's loads of LogCat apps in the Android Market that you can run on the phone.

Submit form with POST data in Android app

I've been searching the web for a way to do this for about a week now, and I just can't seem to figure it out.
I'm trying to implement an app that my college can use to allow users to log in to various services on the campus with ease. The way it works currently is they go to an online portal, select which service they want, fill in their user name and pwd, and click login. The form data is sent via post (it includes several hidden values as well as just the user name and pwd) to the corresponding login script which then signs them in and loads the service.
I've been trying to come at the problem in two ways. I first tried a WebView, but it doesn't seem to want to support all of the html that normally makes this form work. I get all of the elements I need, fields for user and pwd as well as a login button, but clicking the button doesn't do anything. I wondered if I needed to add an onclick handler for it, but I can't see how as the button is implemented in the html of the webview not using a separate android element.
The other possibility was using the xml widgets to create the form in a nice relative layout, which seems to load faster and looks better on the android screen. I used EditText fields for the input, a spinner widget for the service select, and the button widget for the login. I know how to make the onclick and item select handlers for the button and spinner, respectively, but I can't figure out how to send that data via POST in an intent that would then launch a browser. I can do an intent with the action url, but can't get the POST data to feed into it.
So here is what I have right now...
HttpParams params = new BasicHttpParams();
HttpClient client = new DefaultHttpClient(params);
HttpPost post = new HttpPost(action);
String endResult = null;
try
{
post.setEntity(new UrlEncodedFormEntity(myList));
}
catch (UnsupportedEncodingException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
try
{
String response = client.execute(post, new BasicResponseHandler());
endResult = response;
}
catch (ClientProtocolException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
So my question now... is how do I take the endResult screen, which should be the page returned after I logged in to my service, and display it in a browser?
What's wrong with them just using the built in browser? You can also submit a form using UrlEncodedFormEntity and HttpClient.
HttpParams params = new DefaultHttpParams(); // setup whatever params you what
HttpClient client = new DefaultHttpClient(params);
HttpPost post = new HttpPost("someurl");
post.setEntity(new UrlEncodedFormEntity()); // with list of key-value pairs
client.execute(post, new ResponseHandler(){}); // implement ResponseHandler to handle response correctly.
Okay and after you have the response in a string. The response since its a page is going to be in html. You need to use a WebView to show the html. WebView has a method loadData() that takes a string of html and displays it.
Based on #RobbyPonds answer, for the benefit of people wandering past here, below is a generic implementation to post and receive a response from a URI (NOTE Also contains waiting implementation to return a response, probably not every day implementation of network call):
private static String responseValue;
#SuppressWarnings({ "unchecked", "rawtypes" })
public static String sendPostToTargetAndWaitForResponse() throws ClientProtocolException, IOException {
final Thread currentThread = Thread.currentThread();
synchronized (currentThread) {
HttpParams params = new BasicHttpParams();
HttpClient client = new DefaultHttpClient(params);
HttpPost post = new HttpPost(HTTP_POST_URI);
// List Creation with post data for UrlEncodedFormEntity
ArrayList<NameValuePair> mList = new ArrayList<NameValuePair>();
mList.add(new NameValuePair() {
#Override
public String getValue() {
return getSampleJSON();
}
#Override
public String getName() {
return "json";
}
});
post.setEntity(new UrlEncodedFormEntity(mList)); // with list of key-value pairs
client.execute(post, new ResponseHandler(){
#Override
public Object handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
responseValue = EntityUtils.toString(response.getEntity(), "UTF-8");
synchronized (currentThread) {
currentThread.notify();
}
return null;
}
});
try {
currentThread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
return responseValue;
}
}

Categories

Resources