POSt request to web API server (InputStream error in android studio) - android

I'm trying to add users' registeration data to a web api server but when I click on register button in UI after entering the data , the android monitor shows this error :
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
*this is my code :
----> the onClick function for registeration button :
public void register_register(View view) {
Name = name.getText().toString();
Email = email.getText().toString();
Password = password.getText().toString();
// make object from user to insert data
User user = new User(Name, Email, Password);
//convert data from user object to a json object
JSONObject jUser = new JSONObject();
JSONArray aUser = new JSONArray();
try {
jUser.put("Name", user.name);
jUser.put("Email", user.email);
jUser.put("Password", user.password);
//inserting JSON object inside JSON array
aUser.put(jUser);
Log.i("my Json object", jUser.toString());
Log.i("my Json array", aUser.toString());
String jsonData = aUser.toString();
new DoRegister().execute(jsonData);
//clear all edit texts
name.getText().clear();
email.getText().clear();
password.getText().clear();
} catch (JSONException e) {
e.printStackTrace();
}
}
-------> this is my posting class that extends from AsyncTask :
class DoRegister extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... params) {
String jsonData = params[0];
try {
URL url = new URL(API);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.connect();
//send data
OutputStream dos = connection.getOutputStream();
dos.write(jsonData.getBytes());
//receive & read data response
InputStream is = connection.getInputStream();
String result = "";
int byteCharacter;
while ((byteCharacter = is.read()) != -1) {
result += (char) byteCharacter;
}
Log.i("my Json api" , "here :" + result);
is.close();
dos.close();
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
Toast.makeText(getApplicationContext() , "Done" , Toast.LENGTH_SHORT).show();
}
}
------> This is what being shown in android monitor
java.io.FileNotFoundException: http://(my api here)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
at com.example.heshamadawy.registeration.RegisterActivity$DoRegister.doInBackground(RegisterActivity.java:102)
at com.example.heshamadawy.registeration.RegisterActivity$DoRegister.doInBackground(RegisterActivity.java:78)
Please help me and thank you guys :)

ok , I changed my code to Volley library and everything is okay right now ..
If you had the same problem try to use Volley , it's simple ,easy and better
best wishes for you all :)

Related

How can I improve the speed of retrieving data from internet in an AsyncTask?

In my following code I am trying to retrieve some JSON data by passing an URL. It works fine but does take some time in fetching data from the Internet. Even though the data isn't that bulky but still it takes like few seconds and then I can see data in log. But I really want to improve the speed with which I could improve retrieving data from internet.
public class DownloadData extends AsyncTask<String, Void, String> {
private static final String TAG = "DownloadData";
#Override
protected String doInBackground(String... strings) {
try {
URL url = new URL(strings[0]);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("GET");
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
String result = "";
int data;
data = inputStreamReader.read();
while (data != -1) {
char currentChar = (char) data;
result += currentChar;
data = inputStreamReader.read();
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "Failed";
}
#Override
protected void onPostExecute(String s) {
Log.d(TAG, "downloaded JSON Data: " + s);
}
}
Dont read characters one by one. Takes too much time. Use .readLine() instead.
Dont use string concatenation as that takes a lot of time too. Instead use a StringBuilder to add the lines to.

How to Handle connection timeout in async task

I have a problem that I haven't solved yet and I need help.
When internet is slow application crashes. how can can I check connection timeout in asyntask.
I made an app that sometimes connect to web service to get data and i do that using async task
I want to make alert dialog on connection timeout when user can choose whether they want to retry or cancel, if they choose retry it will try to connect again
public class login extends AsyncTask<Void,Void,Void> {
InputStream ins;
String status, result, s = null, data = "",js;
int ss;
int responseCode;
#Override
protected void onPreExecute() {
super.onPreExecute();
pdlg.setTitle("Checking");
pdlg.setMessage("Please wait");
pdlg.setCancelable(false);
pdlg.show();
}
#Override
protected Void doInBackground(Void... params) {
StringBuilder sb = new StringBuilder();
ArrayList al;
try {
URL url = new URL("http://....login.php");
String param = "username=" + uname + "&password=" + pass;
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setConnectTimeout(15000);
connection.setReadTimeout(15000);
connection.setDoInput(true);
connection.setDoOutput(true);
OutputStream os = connection.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
bw.write(param);
bw.flush();
bw.close();
responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
}
data = sb.toString();
JSONObject json = new JSONObject(data);
status=json.getString("Status");//{"Login Status":"Success","Receipt Details":"No data available"}
// js=json.getString("Login");//{"Login":"Failed"}
} catch (MalformedURLException e) {
Log.i("MalformedURLException", e.getMessage());
} catch (IOException e) {
Log.i("IOException", e.getMessage());
} catch (JSONException e) {
Log.i("JSONException", e.getMessage());
}
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
String status1=status.trim();
if (status1.equals("Success")) {
Toast.makeText(getApplicationContext(), "Login Succes !!", Toast.LENGTH_SHORT).show();
Intent i = new Intent(Login.this, Home.class);
startActivity(i);
finish();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("first_time", false);
editor.putString("userrname", uname);
editor.putString("password",pass);
editor.apply();
Toast.makeText(getApplicationContext(),"welcome : "+uname,Toast.LENGTH_LONG).show();
}
else {
Toast t=Toast.makeText(Login.this, "Username or Password is Incorrect", Toast.LENGTH_LONG);
t.setGravity(Gravity.BOTTOM,0,0);
t.show();
}
pdlg.dismiss();
}
}
You can use getErrorStream() ,
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream inp;
// if some error in connection
inp = connection.getErrorStream();
check this answer for more details..
according to the doc it returns
an error stream if any, null if there have been no errors, the
connection is not connected or the
server sent no useful data
.
use this two catch blocks to handle ConnectionTimeOut and socketTimeOut Exceptions
catch (SocketTimeoutException bug) {
Toast.makeText(getApplicationContext(), "Socket Timeout", Toast.LENGTH_LONG).show();
}
catch (ConnectTimeoutException bug) {
Toast.makeText(getApplicationContext(), "Connection Timeout", Toast.LENGTH_LONG).show();
}
For Connection time out add SocketTimeoutException in your catch block and its crashing because without null checking, you are trying to trim the string in onPostExecute
You should do like this, and check before using status
if(TextUtil.isEmpty(status)) {
pdlg.dismiss();
// We are getting empty response
return;
}
String status1=status.trim();
You can catch the Connection timeout exception in your code and then set the status according to your requirement and check for that status in onPostExecute to show the alert Dialog
try {
URL url = new URL("http://....login.php");
String param = "username=" + uname + "&password=" + pass;
// Your URL connection code here
catch (ConnectTimeoutException e) {
Log.e(TAG, "Timeout", e);
status="timeout"
} catch (SocketTimeoutException e) {
Log.e(TAG, " Socket timeout", e);
status="timeout"
}
in onPostExecute
if (status.equals("timeout")) {
// Show Alert Dialog.
}
What you are trying to do is previously done in some great networking lib. So I urge you to use one of the widley used network lib.
Volley.
Or if you want to understand you can just check the response status(or status code should be 408. I guess for connection time out) if it will return "connection time out" then you can call your code to the http client again to perform your task, you can also add a retry count to try for 2-3 times and then give up and send response to onpostexecute method.
Hope this helps.

Read Lan ,Long from Json URL and assign the lat and long to map 's markers?

i am new to android ,, i am trying to read json file from URL , and get the lat ,and long , and
assine the values to markers and show it in map ,my question how to get lan, long, after reading the content of json ??
here is the json url data
json data on the URL
{"properties":{"1":{"name":"Villa For
Sale","lat":"35.2474962142","lng":"-91.3480163353","price":"$100,000","image1":"http:\/\/wpl28.realtyna.com\/theme28\/wp-content\/uploads\/WPL\/91\/thimg_12_800x420.jpg","image2":"http:\/\/wpl28.realtyna.com\/theme28\/wp-content\/uploads\/WPL\/85\/thimg_2_800x420.jpg"},"2":{"name":"Apartment For Rent","lat":"35.9542249162","lng":"-101.21893164","price":"$40,000","image1":"ht
in android i want to get the lat, long and assing each value to a market
map
//this method should get json data from onPostExecute(String s)
public void the_received_data(String received_data){
}
class Read_JSON extends AsyncTask<String ,String ,String >{
MainActivity mainActivity;
// class to handle reading json file
#Override
protected String doInBackground(String... params) {
HttpURLConnection connection =null;
BufferedReader data =null;
InputStream json_data;
try {
URL url = new URL(params[0]);
connection =(HttpURLConnection)url.openConnection();
connection.connect();
//holding the data into stream
json_data =connection.getInputStream();
data = new BufferedReader(new InputStreamReader(json_data));
StringBuffer stringBuffer = new StringBuffer();
//read the data from the bufferedredaer line by line
String line ="";
while((line =data.readLine()) != null){
stringBuffer.append(line);
}
return stringBuffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally{
if(connection !=null){connection.disconnect();}
try {
if(data != null){
data.close();}
} catch (IOException e) {
e.printStackTrace();
}
}
return null; }
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
mainActivity.the_received_data(s);
}
}
After getting string response, just parse that to JSONObject like below sample example & then you can get Latitude & Longitude.
JSONObject jsonObj = new JSONObject("{"name":"myName","address":"myAddress"}");
String my_name = jsonObj.getString("myName");

How to perform network operation in AsyncTask - Android

I am new to Android and I am using the a button click to send a push notification using GCM. I have the function to perform the GCM push. I need it to be converted from the function to a AsyncTask class. I saw a lot from the internet and still facing trouble. Can anyone help me to convert it ?
The push function
public void sendPush(int position){
pushProgressBar.setVisibility = (View.VISIBLE)
try {
// Prepare JSON containing the GCM message content. What to send and where to send.
JSONObject jGcmData = new JSONObject();
JSONObject jData = new JSONObject();
jData.put("message", "Hello");
// Where to send GCM message.
TinyDB tinyDB = new TinyDB(mContext);
ArrayList<String> userToken = tinyDB.getListString("tokenList");
String tokenToSend = userToken.get(position);
jGcmData.put("to", tokenToSend);
// What to send in GCM message.
jGcmData.put("data", jData);
// Create connection to send GCM Message request.
URL url = new URL("https://android.googleapis.com/gcm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "key=" + R.string.apikey);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestMethod("POST");
conn.setDoOutput(true);
// Send GCM message content.
OutputStream outputStream = conn.getOutputStream();
outputStream.write(jGcmData.toString().getBytes());
// Read GCM response.
InputStream inputStream = conn.getInputStream();
String resp = IOUtils.toString(inputStream);
System.out.println(resp);
System.out.println("Check your device/emulator for notification or logcat for " +
"confirmation of the receipt of the GCM message.");
pushProgressBar.setVisibility = (View.GONE)
} catch (IOException e) {
System.out.println("Unable to send GCM message.");
System.out.println("Please ensure that API_KEY has been replaced by the server " +
"API key, and that the device's registration token is correct (if specified).");
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
Thanks in advance. Hope I learn from this.
Example basic AsyncTask:
class PushTask extends AsyncTask<Integer, Integer, Integer> {
#Override
protected void onPreExecute() {
pushProgressBar.setVisibility = (View.VISIBLE);
}
#Override
protected Integer doInBackground(Integer... position) {
int post = position[0];
int respCode = 0;
try {
//your sending code here..
//got gcm code
respCode = 1;
} catch (IOException e) {
//json IOException
//cannot send gcm
respCode = 2;
} catch (JSONException e) {
//json Exception
respCode = 3;
}
return respCode;
}
#Override
protected void onPostExecute(Integer response) {
switch(response)
case 1:
System.out.println("Check your device/emulator for notification or logcat for " +
"confirmation of the receipt of the GCM message.");
break;
case 2:
System.out.println("Please ensure that API_KEY has been replaced by the server " +
"API key, and that the device's registration token is correct (if specified).");
break;
case 3:
//print json Exception error
break;
default:
break;
pushProgressBar.setVisibility = (View.GONE);
}
}
You can execute the class by execute
new PushTask().execute(1 or your position);
This is example only, you can modified the code according your requirement.

how to create a gridview of images dynamically

i am working on an app in which i have to populate gridview of images dynamically. I am getting an array of image ids from server, i am decoding json array and getting the image ids. now i have stored all the images in my drawable folder, i want to show the images of the ids i am getting from the json, but i am stuck at this point i don't know how this. help
this is my main activity
public class MainActivity extends Activity {
GridView grid ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
grid = (GridView)findViewById(R.id.grid_view);
grid.setAdapter(new Adapter(this));
Button play = (Button)findViewById(R.id.play);
play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
playgame();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
protected void playgame() throws JSONException {
if(cardcount >=1 ){
BufferedReader reader=null;
data_to_send = "userId=" + userId ;
try
{
Log.e("inside try block", "get text");
// Defined URL where to send data
URL url = new URL("http://172.16.10.5/Ankur/andapp/request_Play.php");
// Send POST data request
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data_to_send);
wr.flush();
// Get the server response
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
// Read Server Response
while((line = reader.readLine()) != null)
{
// Append server response in string
sb.append(line + "\n");
Log.e("inside", "while loop");
}
play_response = sb.toString();
}
catch(Exception ex)
{
}
finally
{
try
{
reader.close();
}
catch(Exception ex) {}
}
Log.e("play response from the server", ""+play_response);
}else
{
Toast.makeText(getApplicationContext(), "Sorry you don't have cards.buy a new card now", Toast.LENGTH_LONG).show();
}
JSONObject jo = new JSONObject(play_response);
pos1 = jo.getString("0");
pos2 = jo.getString("1");
pos3 = jo.getString("2");
pos4= jo.getString("3");
pos5 = jo.getString("4");
pos6= jo.getString("5");
pos7= jo.getString("6");
pos8= jo.getString("7");
pos9= jo.getString("8");
Log.e("value of 1st place of array", "array value "+pics[7]);
}
i recommend to use Loader. see this [documentation] (http://developer.android.com/guide/components/loaders.html)
thus you can transfer images loading in not ui thread in Loade

Categories

Resources