I have a class called App which is this one:
public class App{
public static void main(String[] args){
StreamingData dataStream = new StreamingData("urlString");
dataStream.StreamHttpRequest();
}
}
and this class called StreamingData that has two methods, the StreamHttpRequest that intervally calls the httpRequest every 1 second as shown below:
public class StreamingData {
private String url;
private JSONObject httpResponse;
public StreamingData(String url){
this.url = url;
}
public void httpRequest() throws Exception{
try {
URL obj = new URL(this.url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
BufferedReader in = new BufferedReader(new
InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
setHttpResponse(new JSONObject(response.toString()));
} catch (ConnectException e){
e.printStackTrace
}
}
public void setHttpResponse(JSONObject httpResponse) {
this.httpResponse = httpResponse;
}
public JSONObject getHttpResponse() {
System.out.println(this.httpResponse.toString());
return this.httpResponse;
}
public void StreamHttpRequest() {
final long timeInterval = 1000;
Runnable runnable = new Runnable() {
public void run() {
while(true){
try {
httpRequest();
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(timeInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
Whenever I call the getHttpResponse from the httpRequest method, or pretty much every method from the StreamingData class it returns the whole json response, but when I try to retrieve it from the App class like this
// code as shown above
StreamingData netDataStream = new StreamingData("urlString");
JSONObject netDataHttpResponse = netDataStream.getHttpResponse();
it returns Exception in thread "main" java.lang.NullPointerException and the json is empty.
How can I get the json response to another class (e.g. the App)? Because for now I cannot use it outside the StreamingData class.
Thank you very much for your help,
csymvoul
You're working with threads. That means that the httpResponse field value will be set once the http request performs (async).
here:
StreamingData netDataStream = new StreamingData("urlString");
JSONObject netDataHttpResponse = netDataStream.getHttpResponse();
You're asking for the response immediatelly (when the http response is not ready).
You could add some kind of listener to your StreamingData class , so that you can call on some method when the response is ready:
public class HttpResponseListener {
void onResponse(JSONObject httpResponse){...}
}
Then you could do something like...
StreamingData netDataStream = new StreamingData("urlString" , new HttpResponseListener());
And call httpResponseListener.onResponse when the httpResponse object is set.
public void setHttpResponse(JSONObject httpResponse) {
this.httpResponse = httpResponse;
httpResponseListener.onResponse(httpResponse);
}
That is if you still want to use Http request / reponses with threads.
Related
I have a problem in my Android app.
I use a login portal generated by an activity Login Activity, and I want to send username and password to my web API. So I created a java class who use HttpURLConnection for contacting my API. This class was tested (with Netbeans) and everything work perfectly !
But when I call my function who connecting at the API in my Android app, nothing, any request is send. I added Internet permission in androidManifest, always nothing
androidManifest.xml :
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ben.myapp">
<!-- Autorisation -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
.....
</manifest>
My java class :
public static String verifyLoginAndGetData (String userMail, String userPassword) throws IOException {
URL urlGetRequest = new URL("http://my.api.com/index?param1...");
// HTTP Connexion
HttpURLConnection apiConnexion = (HttpURLConnection) urlGetRequest.openConnection();
// Method
apiConnexion.setRequestMethod("GET");
try {
// Response code
int responseCode = apiConnexion.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// Read the response
BufferedReader in = new BufferedReader(new InputStreamReader(apiConnexion.getInputStream()));
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// Return response
return response.toString();
} else {
return "false";
}
} finally {
apiConnexion.disconnect();
}
} catch (Exception e){
Log.i("Exception", e.toString());
return "false";
}
Where I call this function :
public class LoginDataSource {
public Result<LoggedInUser> login(String username, String password) {
String resultAPI = my_class.verifyLoginAndGetData(username, password);
}
}
variables username and password are not empty.
what am I supposed to use ? Or what i should do ?
Thank you for helping me :)
BenjaminFB
First of all have this run on a separate thread from the ui if not done already,for this id do this
new Thread(new Runnable() {
#Override
public void run() {
try {
Log.e("Download ",verifyLoginAndGetData("username","password"));
} catch (IOException e) {
Log.e("Exception ",""+e.getMessage());
}
}
}).start();
Next thing.am not sure about the api you are dealing with however id
recommend using a network config file to allow cleartext traffic to
your site if it uses cleartext traffic and specify it on your application in manifest.
Another thing, remember the internet permission on your manifest
Other than that,for me this works with the google url www.google.com using get
public static String verifyLoginAndGetData (String userMail, String userPassword) throws IOException {
URL urlGetRequest = new URL("http://www.google.com");
// HTTP Connexion
HttpURLConnection apiConnexion = (HttpURLConnection) urlGetRequest.openConnection();
// Method
apiConnexion.setRequestMethod("GET");
try {
// Response code
int responseCode = apiConnexion.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// Read the response
BufferedReader in = new BufferedReader(new InputStreamReader(apiConnexion.getInputStream()));
StringBuffer response = new StringBuffer();
String inputLine = null;
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// Return response
return response.toString();
} else {
return "false";
}
} finally {
Log.e("Disconnection", "e.toString()");
apiConnexion.disconnect();
}
}
To return data to another class or to the activity thread, yo can use a handler or interface .below is how i would use an interface
interface data_inter{
void onDataReceived(String data);
}
data_inter inter=new data_inter() {
#Override
public void onDataReceived(String data) {
Log.e("Downloaded: ",data);
Toast.makeText(cntx,"Downloaded: "+data,Toast.LENGTH_LONG).show();
((EditText)findViewById(R.id.focuser)).setText("Downloaded: "+data);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cntx=this;
new Thread(new Runnable() {
#Override
public void run() {
try {
String responce=verifyLoginAndGetData("","");
runOnUiThread(new Runnable() {
#Override
public void run() {
inter.onDataReceived(responce);
}
});
} catch (IOException e) {
Log.e("Exception ",""+e.getMessage());
}
}
}).start();}
Yes it work !!
I did what #code-demon told me to do :
Add at the Manifest
android:usesCleartextTraffic="true"
And use thred but I couldn't get any value back from API response, so I did research and came across it: stackoverflow post.
Finally I developed that :
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<String> callable = new Callable<String>() {
#Override
public String call() throws IOException {
// Call my API get function
return verifyLoginAndGetData(username, password);
}
};
Future<String> future = executor.submit(callable);
executor.shutdown();
// Get in String, the API response
String resultAPI = future.get();
this code is ok for get data from server but if my API is POST Method how to pass params to server by POSt Request and fetch data. code is here, please let me know
public class GetTripTeportData extends AsyncTask<String, Integer,String> {
#Override
protected void onPreExecute() {...}
#Override
protected String doInBackground(String... params) {
String responseBodyText = null;
OkHttpClient client = new OkHttpClient();
try {
Request request = new Request.Builder().url(excelApi).build();
Response response = null;
response = client.newCall(request).execute();//.....
responseBodyText = response.body().string();
JSONObject resultData = new JSONObject(responseBodyText);
JSONArray itemArray = resultData.getJSONArray("data");
for (int i=0; i<itemArray.length();i++){
JSONObject jobject = itemArray.getJSONObject(i);
String iduser = jobject.getString("id");
String vehicleno = jobject.getString("vehicleno");
String startdate = jobject.getString("startdate");
allList.add(new ExcelReportAdminResponse(iduser,vehicleno,startdate));
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
return responseBodyText;
}
#Override
protected void onPostExecute(String s) {......}
}
To post data with default http client with async task you can do as below:
First create network utility class as below:
public class NetworkUtilities {
public static String postData(String Url, String message ){
try {
URL url = new URL(Url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000); /*milliseconds*/
conn.setConnectTimeout(15000); /* milliseconds */
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setFixedLengthStreamingMode(message.getBytes().length);
conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
conn.setRequestProperty("X-Requested-With", "XMLHttpRequest");
conn.connect();
OutputStream os = new BufferedOutputStream(conn.getOutputStream());
os.write(message.getBytes());
os.flush();
InputStream is = conn.getInputStream();
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
catch (Exception e){
Log.e("Exception: " , e.toString());
}
finally {
// os.close();
//is.close();
//conn.disconnect();
}
return "";
}
}
Then write async task to call that postData() method from NetworkUtilities class as below:
private class PostDataAsync extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
return NetworkUtilities.postData(params[0], params[1]);
}
#Override
protected void onPostExecute(String result) {
Log.e("Data response: ", result);
}
#Override
protected void onPreExecute() {
// TODO: Loader and stuff to add later here.
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
Then to call that async task means to call api do as below:
String message = "";
try {
JSONObject jsonBody = new JSONObject();
jsonBody.put("user_id", session.getSession());
message = jsonBody.toString();
} catch (Exception e) {
Log.e("JSON error: ", e.toString());
}
PostDataAsync postData = new PostDataAsync();
postData.execute("YOUR_POST_API_URL_HERE", message);
By using this way you can be able to post data with async task.
For POST call with JSON body
final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, /*YOUR JSON REQUEST*/ jsonString);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try {
Response response = client.newCall(request).execute();
} catch(IOException io){
// do something
}
in this below code i can not get result from getValue from Foo class and thats return null but that must be return value. result is correct and this function could not return that. for example this is my class:
public class JsonService {
private JSONObject json = new JSONObject();
public JsonService(final String username, final String password) throws Exception{
json.put("username", username);
json.put("password", password);
}
public class Foo implements Runnable {
private String result;
#Override
public void run() {
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000);
HttpResponse response;
try {
HttpPost post = new HttpPost("http://www.example.com/json_android.php");
StringEntity se = new StringEntity( json.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(se);
response = client.execute(post);
if(response!=null){
InputStream stream = response.getEntity().getContent();
result = convertToString(stream);
/*
I can Log result with below line
*/
Log.e("response is: ", result);
/*
result is {"username = ":"Hello"}
*/
}
} catch(Exception e) {
e.printStackTrace();
Log.e("Error", String.valueOf(e));
}
}
public String getValue() {
/*
return in this fucntion not working
*/
return result;
}
}
public String request() throws ExecutionException, InterruptedException {
Foo foo = new Foo();
new Thread(foo).start();
return foo.getValue();
}
How to get result correctly from Foo and return that from reauest() ? please help me. thanks
Use a FutureTask and implement a Callable.
public class Foo implements Callable<String> {
#Override
public String call() {
String result = null;
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000);
HttpResponse response;
try {
HttpPost post = new HttpPost("http://www.example.com/json_android.php");
StringEntity se = new StringEntity( json.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(se);
response = client.execute(post);
if(response!=null){
InputStream stream = response.getEntity().getContent();
result = convertToString(stream);
/*
I can Log result with below line
*/
Log.e("response is: ", result);
/*
result is {"username = ":"Hello"}
*/
}
} catch(Exception e) {
e.printStackTrace();
Log.e("Error", String.valueOf(e));
}
return result;
}
}
and than use it with the FutureTask
public String request() throws ExecutionException, InterruptedException {
Foo foo = new Foo();
FutureTask<String> fooFuture = new FutureTask<String>(foo);
new Thread(fooFuture).start();
return fooFuture.get();
}
the method of get from class FutureTask (at the above answer return fooFuture.get();) is a blocking function that means when you call it from UI thread it blocks the UI thread so cause your app sends you ANR error. My suggestion to solve it is using LocalBroadCastManager and when the computation finished it sends a local broadcast and in your UI you will get the result at the onReceive from the Extra that is embedded in the intent.
another solution is using ruOnUiThread or passing the handler from UI thread. and last one is using post method of widgets.
I have a class that implements a listener so that when another class that has an async tasks has been completed then the data can be returned with the use of this listener. The async task is being completed but the listener is not passing the data when it's obtained in the post execute function.
Async Task
Public class AdFetcher extends AsyncTask<String,Void,String>
{
private HTTPListener listener;
//sets the listeners
public AdFetcher(HTTPListener listener)
{
this.listener = listener;
}
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return responseString;
}
#Override
protected void onPostExecute(String result)
{
//Tries to deserialization and if there is an exception then its added to the Stack Trace.
try
{
JSONObject data = new JSONObject(result);
if(listener==null)
throw new NullPointerException();
//Calls onComplete function in the class/Activity that implemented the listener.
listener.onComplete(data);
}
catch (JSONException e)
{
e.printStackTrace();
}
}
}
Listener
public interface HTTPListener{
/**
* Callback function that must be implemented
* to get result from HTTP worker thread.
* #param result
*/
public void onComplete (JSONObject result);
}//end HttpListener interface
Class Implementing the listener
public class AdManager implements HTTPListener
{
//will store the current context of the application.
private Context context;
private Utility utils;
private String url;
private WebView client;
public AdManager(Context context,WebView client)
{
this.client = client;
this.context = context;
}
public void getAd()
{
utils = new Utility();
url = utils.BuildUrl();
new AdFetcher(this).execute(url);
}
public void onComplete(JSONObject result)
{
try
{ Log.e("RESULTS",result.getString("adtype"));
if(result.getString("error") == "null")
{
if(result.getString("adtype") == "banner")
{ //loads the banner image in the webview.
String html = "<img src=\""+result.getString("adimage")+"\">";
String mime = "text/html";
String encoding = "utf-8";
client.setVisibility(View.VISIBLE);
client.getSettings().setJavaScriptEnabled(true);
client.loadDataWithBaseURL(null, html, mime, encoding, null);
}
}
}
catch (JSONException e)
{
e.printStackTrace();
}
}
}
I want to post String data over HttpClient in android
but i'm tired after receive response status code 503 - service unavailable and
return response as Html code for our url.
I write in the following Code in JAVA Application and i return the data but when I write the same code in Android Application i receive an exception file I/O not found, I'm Puzzled for this case:
public void goButton(View v)
{
try{
URL url = new URL("https://xxxxxxxxx");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
Test ts= new ApiRequest("null","getUserbyID",new String[] { "66868706" });
String payLoad = ts.toString(); //toSting is override method that create //JSON Object
System.out.println("--->>> " + payLoad);
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
System.out.println("=================>>> "+ payLoad);
wr.write(payLoad);
wr.flush();
BufferedReader rd = new BufferedReader(new nputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
System.out.println("-->> " + line);
response += line;
}
wr.close();
rd.close();
System.out.println("=================>>> "+ response);
} catch (Exception e) {
e.printStackTrace();
System.out.println("=================>>> " + e.toString());
throw new RuntimeException(e);
}
I try to put this code in AsynTask, Thread but i receive the same response status code.
I write in the following Android code as an example data
public void goButton(View v)
{
try{
new Thread(new Runnable() {
public void run() {
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(),
10000); // Timeout Limit
HttpResponse response;
String url = "https://xxxxxxxxxxxxx";
JSONObject json = new JSONObject();
try {
HttpPost post = new HttpPost(url);
post.setHeader("Content-type", "application/json");
json.put("service","null");
json.put("method", getUserByID.toString());
json.put("parameters", "1111");
System.out.println(">>>>>>>>>>>" + json.toString());
StringEntity se = new StringEntity(json.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,
"application/json"));
post.setEntity(se);
String response = client.execute(post);
if (response != null) {
String temp = EntityUtils.toString(response.getEntity());
System.out.println(">>>>>>>>>>>" + temp);
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(">>>>>>>>>>>" + e.getMessage());
}
}
}).start();
}
Please Help me to find solution for this problem :(
Thank you in advance
Here is an code snippet , hoping it will help you.
1)An function which carries the http get service
private String SendDataFromAndroidDevice() {
String result = "";
try {
HttpClient httpclient = new DefaultHttpClient();
HttpGet getMethod = new HttpGet("your url + data appended");
BufferedReader in = null;
BasicHttpResponse httpResponse = (BasicHttpResponse) httpclient
.execute(getMethod);
in = new BufferedReader(new InputStreamReader(httpResponse
.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
while ((line = in.readLine()) != null) {
sb.append(line);
}
in.close();
result = sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
2) An Class which extends AsyncTask
private class HTTPdemo extends
AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {}
#Override
protected String doInBackground(String... params) {
String result = SendDataFromAndroidDevice();
return result;
}
#Override
protected void onProgressUpdate(Void... values) {}
#Override
protected void onPostExecute(String result) {
if (result != null && !result.equals("")) {
try {
JSONObject resObject = new JSONObject(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
3) Inside your onCreate method
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView("your layout");
if ("check here where network/internet is avaliable") {
new HTTPdemo().execute("");
}
}
This code snippet ,
Android device will send the data via URL towards Server
now server needs to fetch that data from the URL
Hey Mohammed Saleem
The code snippet provided by me works in the following way,
1)Android device send the URL+data to server
2)Server [say ASP.NET platform used] receive the data and gives an acknowledgement
Now the Code which should be written at client side (Android) is provided to you, the later part of receiving that data at server is
Server needs to receive the data
An webservice should be used to do that
Implement an webservice at server side
The webservice will be invoked whenever android will push the URL+data
Once you have the data ,manipulated it as you want