Cannot show the Toast through the Callback function - java

Here is the httpPost to send the data to server and get the response.
public void httpPost(String URL ) {
new Thread(new Runnable() {
#Override
public void run() {
try {
URL url = new URL(URL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.connect();
int responseCode = connection.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK){
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
stringBuilder.setLength(0);
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
callback.success(stringBuilder.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
Here is the Callback function to setup the string from server response.
public interface Callback{
void success(String string);
}
Click the button and post the data to server. Here can get the response of the string from Callback function but it cannot show the toast.
button.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onClick(View view) {
server.httpPost("https://google.com/index.php?username=Peter");
server.callback =new Server.Callback() {
#Override
public void success(String response) {
Log.d("test",response);
Toast.makeText(AddActivity.this, response,Toast.LENGTH_SHORT).show();
}
};
}
});

You must run the Toast on UI thread using the following code:
<Activity>.runOnUiThread(new Runnable() {
#Override
public void run() {
(Toast and other UI changes here...)
}
});

Related

App crashes when connection is lost while using HttpUrlConnection

i'm making a class that get json data from an external url, it is working fine if there is a connection. also shows an error if there isn't.
the problem is if the connection lost while the class is getting data the app crashes.
here is my code:
//I always check connection before calling the class
class GetPost extends AsyncTask<String, String, String>
{
Context c;
String res;
public GetPost(Context c){
this.c=c;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
Earn.statu.setText("Loading post...");
}
#Override
protected String doInBackground(String[] p1)
{
try{
URL u = new URL(p1[0]);
HttpURLConnection con = (HttpURLConnection) u.openConnection();
InputStream is = con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
res = br.readLine();
}
catch (MalformedURLException e){}
catch (IOException e){}
return res;
}
#Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
try{
JSONObject jo = new JSONObject(res);
Earn.getVideoData(c,
jo.getString("pid"),
jo.getInt("duration"),
jo.getInt("id")
);
}catch(JSONException a){}
}
so guys is there any solution to prevent the app from crashing?
Set timeout on request by example:
try {
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
con.setRequestMethod("HEAD");
con.setConnectTimeout(5000); //set timeout to 5 seconds
return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
} catch (java.net.SocketTimeoutException e) {
return false;
} catch (java.io.IOException e) {
return false;
}

background and run continuous without close

I make mobile lost gps tracking application, that code will be running in only activity..
my application strategy is.
1) if found http://192.168.43.164/imei_000000000000000.txt file then find
"track" or "find_mobile" string in imei_000000000000000.txt.
2) if "track" or "find_mobile" string is found in imei_000000000000000.txt file then post
"http://192.168.43.164/add.php?long_itude=22.00023&lat_itude=22.00023." link
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
new Thread(new Runnable() {
#Override
public void run() {
final ArrayList<String> urls = new ArrayList<String>();
try{
URL url = new URL("http://192.168.43.164/imei_000000000000000.txt");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(60000);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String str;
while ((str = in.readLine()) != null)
{
urls.add(str);
}
in.close();
} catch (Exception e){
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
li = urls.get(0);
if (li.equals("track") || li.equals("find_mobile")) {
try{
URL url = new URL("http://192.168.43.164/add.php?long_itude=22.00023&lat_itude=22.00023");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(60000);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String str;
while ((str = in.readLine()) != null)
{
urls.add(str);
}
in.close();
} catch (Exception e){
e.printStackTrace();
}
Toast.makeText(getBaseContext(), "hello", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getBaseContext(), "not found"+ li, Toast.LENGTH_SHORT).show();
}
}
} );
}
}).start();
}
},5,5, TimeUnit.SECONDS);
posted code will work fine, but it's code working only in activity.
I want make that code background and run continuous without close.
use new thread = (Thread) function

Fetching Data from JSON using AsyncTask

I have created a fragment which if it is activated it will show MySQL data but it takes time to fetch the data and show it on a custom ListView.
I tried to implement AsyncTask so that while fetching the data you can do something else on the fragment while waiting but am having this error.
"FATAL EXCEPTION: main java.lang.NullPointerException"
Here is the code
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_markets,container,false);
//lvMarkets.setAdapter(new CustomAdapter(getActivity().getApplicationContext(),Symbols,Prices,Balances));
DBHelper db = new DBHelper(getActivity().getApplicationContext());
final ListView lvMarkets = (ListView)getActivity().findViewById(R.id.lvMarkets);
final String c_androidid = Settings.Secure.getString(getActivity().getContentResolver(), Settings.Secure.ANDROID_ID);
final Cursor rs = db.getID(c_androidid);
rs.moveToFirst();
final String c_login = rs.getString(rs.getColumnIndex(DBHelper.c_login));
AsyncTaskRunner taskRunner = new AsyncTaskRunner();
taskRunner.execute(c_login);
lvMarkets.setAdapter(jAdapter);
return rootView;
}
private class AsyncTaskRunner extends AsyncTask<String,String,String>
{
#Override
protected String doInBackground(String... params)
{
final String fin_login=params[0];
StringRequest stringRequest = new StringRequest(Request.Method.POST,url, new Response.Listener<String>() {
#Override
public void onResponse(String response)
{
Log.d(debug,response);
try
{
jsonArray =new JSONArray(response);
jAdapter= new JsonAdapter(getActivity(),jsonArray,login);
}
catch (JSONException e)
{
Log.d(debug,e.toString());
}
}
}, new Response.ErrorListener()
{
public void onErrorResponse(VolleyError error)
{
Log.d(debug,error.toString());
}
}){
#Override
protected Map<String,String>getParams()
{
Map<String,String> params=new HashMap<String,String>();
params.put("c_login",fin_login);
return params;
}
};
RequestQueue queue = Volley.newRequestQueue(getActivity().getApplicationContext());
queue.add(stringRequest);
return fin_login;
}
}
Hope someone could point out what went wrong with my code and someone could also point out on how to fetch data on online much more faster.
Thanks...
Try this:
private void parsingValues() {
URL obj = null;
HttpURLConnection con = null;
String USER_AGENT = "Mozilla/5.0";
try {
//parameter to post
String POST_PARAMS = "deviceos=" + deveiceOs + "&devicetype=" + deviceType +"&deviceid=" ;
obj = new URL("Your URI");
con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", USER_AGENT);
// For POST only - START
con.setDoOutput(true);
OutputStream os = con.getOutputStream();
os.write(POST_PARAMS.getBytes());
os.flush();
os.close();
int responseCode = con.getResponseCode();
System.out.println("POST Response Code :: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { //success
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//getResponse
String subsResponse = response.toString();
final JSONObject responsesubs = new JSONObject(subsResponse);
//Here your parsing process
}
}
});
} else {
System.out.println("POST request not worked");
}
} catch (Exception e) {
e.printStackTrace();
}
}
// Call this method to your doinbackground of Asynhronous Task(parsingValues())

Android handler only sends one message

I am trying to implement a REST interface in android and I need a Thread in the background sending "I am alive" messages to an ip address. To do so I created a Thread Called RestPostThread that runs in the background while I do stuff in my UI thread.
The problem is that after sending the first message to the RestPostThread I can't quit the looper or send a different message to it with another IP or something.
Here are the code for both the UI and the RestPostThread:
public class MainActivity extends AppCompatActivity{
Handler workerThreadHandler;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
final TextView text1 = (TextView) findViewById(R.id.text1);
final TextView text2 = (TextView) findViewById(R.id.text2);
setSupportActionBar(toolbar);
final RestPostThread RPT = new RestPostThread();
RPT.start();
while(workerThreadHandler == null ) {
workerThreadHandler = RPT.getThreadHandler();
}
Button buttonStop = (Button) findViewById(R.id.buttonStop);
buttonStop.setOnClickListener(new View.OnClickListener(){
public void onClick(View view) {
try {
workerThreadHandler.getLooper().quit();
}catch(Exception e){
text1.setText(e.getMessage());
text2.setText( "Exception!");
}
}
});
Button buttonSend = (Button) findViewById(R.id.buttonSend);
buttonSend.setOnClickListener(new View.OnClickListener(){
public void onClick(View view) {
try {
text1.setText(new RestGet().execute(editText.getText().toString()).get());
text2.setText("everything went well!");
}catch(Exception e){
text1.setText(e.getMessage());
text2.setText( "Exception!");
}
}
});
}
And here is the code for the RestPostThread:
public class RestPostThread extends Thread {
public Handler mHandler;
#Override
public void run(){
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
Log.d("MYASDASDPOASODAPO", "dentro mensaje");
while (!msg.obj.equals(null)) {
try {
Thread.sleep(1000);
URL url = new URL(msg.obj.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
String input = "<Instruction><type>put_me_in</type><room>Room 1</room></Instruction>";
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED) {
// throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output;
String aux = new String();
while ((output = br.readLine()) != null) {
aux = aux + output;
}
conn.disconnect();
//return aux;
} catch(MalformedURLException e) {
e.printStackTrace();
//return null;
} catch(IOException e) {
e.printStackTrace();
//return null;
} catch(Exception e) {
}
}
Log.d("CLOSING MESSAGE", "Closing thread");
}
};
Looper.loop();
}
public Handler getThreadHandler() {
return this.mHandler;
}
Have a look at HandlerThread for dealing with a thread to handle just messages. Your Handler should not loop on a message like that, it won't work. It's the Looper's job to deal with new, incoming Message or Runnable objects sent to the Handler which is bound to the Looper.
Regardless, you should take a closer look at using a Loader to handle REST type APIs; or, explore a 3rd party library, such as retrofit, for dealing with REST.
I managed to solve the issue. The problem was that I was wrapping everything inside this:
while (!msg.obj.equals(null)) {}
I implemented handlers in both this thread and the UI thread and now I have communication back and forth between the both, my RestPostThread looks like this now:
public class RestPostThread extends Thread {
public Handler mHandler,uiHandler;
public RestPostThread(Handler handler) {
uiHandler = handler;
}
#Override
public void run(){
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
try {
//Thread.sleep(1000);
URL url = new URL(msg.obj.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
String input = "<Instruction><type>put_me_in</type><room>Room 1</room></Instruction>";
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED) {
// throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output;
String aux = new String();
while ((output = br.readLine()) != null) {
aux = aux + output;
}
conn.disconnect();
Message msg2 = uiHandler.obtainMessage();
msg2.obj = aux;
uiHandler.sendMessage(msg2);
}catch(MalformedURLException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}catch(Exception e){
}
}
};
Looper.loop();
}
public Handler getThreadHandler() {
return this.mHandler;
}
}
And in my MainActivity I have this handler that allows me to "loop" (basically is just going back and forth between the RestPostThread and the UIThread) my Post message until I decide to stop from the MainActivity changing the boolean loop:
public Handler uiHandler = new Handler() {
public void handleMessage(Message inputMessage) {
Log.d("FROM UI THREAD",inputMessage.obj.toString());
if(loop) {
Message msg = workerThreadHandler.obtainMessage();
String url = "http://192.168.1.224:9000/xml/android_reply";
msg.obj = url;
workerThreadHandler.sendMessageDelayed(msg,1000);
}
}
};

How to stop HttpURLConnection.getInputStream()?

Below is my code:
private HttpURLConnection connection;
private InputStream is;
public void upload() {
try {
URL url = new URL(URLPath);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(30000);
connection.setReadTimeout(30000);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.connect();
is = connection.getInputStream();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopupload() {
connection = null;
is = null;
}
When I upload file, the line is = connection.getInputStream(); will spend a lot of time to get reply. So I want to implement a stop function as stopupload(). But if I call stopupload() while the code is handling at line is = connection.getInputStream();, it still needs to wait for its reply.
I want to stop waiting at once while implement stopupload(). How can I do it?
But if I call stopupload() while the code is handling at line is =
connection.getInputStream();, it still needs to wait for its reply.
Starting from HoneyComb, all network operations are not allowed to be executed over main thread. To avoid getting NetworkOnMainThreadException, you may use Thread or AsyncTask.
I want to stop waiting at once while implement stopupload(). How can I
do it?
Below code gives the user to stop uploading after 2 seconds, but you can modify the sleep times (should be less than 5 seconds) accordingly.
upload:
public void upload() {
try {
URL url = new URL(URLPath);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(30000);
connection.setReadTimeout(30000);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.connect();
// run uploading activity within a Thread
Thread t = new Thread() {
public void run() {
is = connection.getInputStream();
if (is == null) {
throw new RuntimeException("stream is null");
}
// sleep 2 seconds before "stop uploading" button appears
mHandler.postDelayed(new Runnable() {
public void run() {
mBtnStop.setVisibility(View.VISIBLE);
}
}, 2000);
}
};
t.start();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
if (connection != null) {
connection.disconnect();
}
}
}
onCreate:
#Override
public void onCreate(Bundle savedInstanceState) {
// more codes...
Handler mHandler = new Handler();
mBtnStop = (Button) findViewById(R.id.btn_stop);
mBtnStop.setBackgroundResource(R.drawable.stop_upload);
mBtnStop.setOnClickListener(mHandlerStop);
mBtnStop.setVisibility(View.INVISIBLE);
View.OnClickListener mHandlerStop = new View.OnClickListener() {
#Override
public void onClick(View v) {
stopUpload(); // called when "stop upload" button is clicked
}
};
// more codes...
}
private HttpURLConnection connection;
private InputStream is;
public void upload() {
try {
URL url = new URL(URLPath);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(30000);
connection.setReadTimeout(30000);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.connect();
Thread t = new Thread() {
public void run() {
is = connection.getInputStream();
}
};
t.start()
} catch (Exception e) {
e.printStackTrace();
}catch (InterruptedException e) {
stopupload(connection ,is, t);
}
}
public void stopupload(HttpURLConnection connection ,InputStream is,Thread t) {
if(connection != null ){
try {
t.interupt();
running = false;
connection=null;
is=null;
} catch (Exception e) {
}
}
}
Wrap the code that uses HttpURLConnection inside a Future, as described here.

Categories