App crashes without catching any exception [duplicate] - java

This question already has answers here:
Unfortunately MyApp has stopped. How can I solve this?
(23 answers)
Can't create handler inside thread that has not called Looper.prepare() Android
(2 answers)
Can't create handler inside thread that has not called Looper.prepare()
(30 answers)
Closed 3 years ago.
So i'm into a tutorial at Udemy "The Complete Android N Developer Course" and trying to make lecture 86 about a weather app.
I use the API from here https://openweathermap.org/current#cityid and use JSON to get the data needed.
The app is working properly when i input a correct city name, but when the input is wrong or empty the app crashes without catching any exceptions.
I don't know why it is crashing and where to look. So i give you all the code i wrote. I tried to implement if statements here and there to try and find it but without any luck.
I would like to know where the problem is and how to fix it so the app doesn't crash anymore.
Thanks in advance.
public class MainActivity extends AppCompatActivity {
EditText editText;
String city = "";
TextView textView;
public void getWeather (View view) {
try {
city = URLEncoder.encode(editText.getText().toString(), "UTF-8");
if (editText.getText().toString() == "") {
Toast.makeText(MainActivity.this, "Could not find weather", Toast.LENGTH_SHORT).show();
textView.setText("Please enter a city.");
} else {
DownloadTask task = new DownloadTask();
task.execute("http://api.openweathermap.org/data/2.5/weather?q=" + city + "&appid=c6ef169a79d84674ef7e1414301eb5c4");
}
InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(editText.getWindowToken(), 0);
} catch (UnsupportedEncodingException e1) {
Toast.makeText(MainActivity.this, "UnsupportedEncodingException", Toast.LENGTH_SHORT).show();
}catch (Exception e) {
Toast.makeText(MainActivity.this, "General exception (getWeather)", Toast.LENGTH_SHORT).show();
}
}
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection)url.openConnection();
InputStream in = null;
in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = reader.read();
}
return result;
} catch (MalformedURLException e1) {
Toast.makeText(MainActivity.this, "MalformedURLException", Toast.LENGTH_SHORT).show();
} catch (IOException e2) {
Toast.makeText(MainActivity.this, "IOException", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(MainActivity.this, "General exception (doInBackground)", Toast.LENGTH_SHORT).show();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
String message = "";
JSONObject jsonObject = null;
jsonObject = new JSONObject(result);
String weatherInfo = jsonObject.getString("weather");
JSONArray jsonArray = new JSONArray(weatherInfo);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonPart = jsonArray.getJSONObject(i);
String main = "";
String description = "";
main = jsonPart.getString("main");
description = jsonPart.getString("description");
if (main != "" && description != "") {
message += main + ": " + description + "\r\n";
}
}
if (message != "") {
textView.setText(message);
} else {
Toast.makeText(MainActivity.this, "Could not find weather", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e1) {
Toast.makeText(MainActivity.this, "JSONException", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(MainActivity.this, "General exception (onPostExecute)", Toast.LENGTH_SHORT).show();
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText);
textView = (TextView) findViewById(R.id.textView);
}
}

It is because you're trying to changes UI with background thread inside the doInBackground(Params...) method of AsyncTask with this line:
try {
...
return result;
} catch (MalformedURLException e1) {
Toast.makeText(MainActivity.this, "MalformedURLException", Toast.LENGTH_SHORT).show();
} catch (IOException e2) {
Toast.makeText(MainActivity.this, "IOException", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(MainActivity.this, "General exception (doInBackground)", Toast.LENGTH_SHORT).show();
}
You should not call Toast inside the doInBackground(Params...). Do that inside the onPostExecute(Result).
You can avoid that by either ignoring the error or returning specific text in doInBackground. Something like this:
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String result = "";
...
try {
...
return result;
} catch (MalformedURLException e1) {
result= "MalformedURLException";
} catch (IOException e2) {
result= "IOException";
} catch (Exception e) {
// do nothing and returning empty
result= "Exception";
}
return result;
}
#Override
protected void onPostExecute(String result) {
// check if there is an error
String errorMessage = "";
switch(result) {
case "MalformedURLException":
errorMessage = "MalformedURLException";
break;
case ""IOException":
errorMessage = "IOException";
break;
case "Exception":
errorMessage = "Exception";
break;
}
// there is an error, show a message.
if(!errorMessage.isEmpty()) {
Toast.makeText(MainActivity.this, "Could not find weather: " + errorMessage, Toast.LENGTH_SHORT).show();
return; // stop the process.
}
// do something when no error found.
}
}

Related

Exctracting more than one field at time from a JSon file

I was developing a simple application that exctracts some fields of a JSon that tells me in real time what weather is in that exact moment, and I have exctracted only one filed, and I was asking myself: Is it possible to extract more than on field at time?
Here is the the link from where i parse the Json:
https://fcc-weather-api.glitch.me/api/current?lat=35&lon=139
And here's my code:
public class MainActivity extends AppCompatActivity {
Button btnHit;
TextView txtJson;
ProgressDialog pd;
ArrayMap<Integer, String> arrayMap = new ArrayMap<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnHit = (Button) findViewById(R.id.btnHit);
txtJson = (TextView) findViewById(R.id.tvJsonItem);
btnHit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new JsonTask().execute("https://fcc-weather-api.glitch.me/api/current?lat=35&lon=139");
}
});
}
public class JsonTask extends AsyncTask<String, String, String> {
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(MainActivity.this);
pd.setMessage("Please wait");
pd.setCancelable(false);
pd.show();
}
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
Log.d("Response: ", "> " + line);
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (pd.isShowing()) {
pd.dismiss();
}
try {
JSONObject Object = new JSONObject(result);
JSONArray arr = new JSONArray(Object.getString("weather"));
for (int i = 0; i < arr.length(); i++) {
JSONObject jsonPart = arr.getJSONObject(i);
//txtJson.append("main: " + jsonPart.getString("main") + '\n');
arrayMap.put(i, jsonPart.getString("main"));
txtJson.append("main: " + arrayMap.get(i) + '\n');
}
} catch (JSONException e) {
e.printStackTrace();
//txtJson.setText(result);
}
//txtJson.setText(result);
}
}
}
If I understand correctly you want to extract other object alongwith main from the array weather
"weather": [
{
"id": 701,
"main": "Mist",
"description": "mist",
"icon": "https://cdn.glitch.com/6e8889e5-7a72-48f0-a061-863548450de5%2F50n.png?1499366021876"
}
If that is the requirement then you can use the same process like you have done just change the name of the object.
arrayMap.put(i, jsonPart.getString("description"));
or
you can use gson and convert the object in pojo class in one go. Then use the object of the pojo and access the data.
Hope it helps.

Json parsing error: Value <?xml of type java.lang.String cannot be converted to JSONArray [duplicate]

This question already has an answer here:
JSON error "Value at result of type java.lang.String cannot be converted to JSONArray" in android
(1 answer)
Closed 5 years ago.
I am new to programming and I have small problem i am trying to make an app that will use json to read flickr api but i am getting the error mention in the description i was looking around but none of the solutions worked so i came here to ask
public class JSONPareser {
final String TAG = "JSONParser";
public String makeServiceCall(String reqUrl) {
String response = null;
try {
URL url = new URL(reqUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
// read the response
InputStream in = new BufferedInputStream(conn.getInputStream());
response = convertStreamToString(in);
} catch (MalformedURLException e) {
Log.e(TAG, "MalformedURLException: " + e.getMessage());
} catch (ProtocolException e) {
Log.e(TAG, "ProtocolException: " + e.getMessage());
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
return response;
}
private String convertStreamToString(InputStream is) throws UnsupportedEncodingException {
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"UTF-8"),8);
StringBuilder sb = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line).append('\n');
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
that is my parser class and here is when i am calling json object
public class getData extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(MainActivity.this);
dialog.setMessage("Please wait");
dialog.setCancelable(false);
dialog.show();
}
#Override
protected Void doInBackground(Void... params) {
String url = "https://api.flickr.com/services/feeds/photos_public.gne";
JSONPareser pareser = new JSONPareser();
String jsonStr = pareser.makeServiceCall(url);
if (jsonStr != null) {
try {
JSONArray jsonArray = new JSONArray(jsonStr);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
FlickrModel model = new FlickrModel();
model.setLink(obj.getString("link"));
model.setDescription(obj.getString("description"));
model.setTitle(obj.getString("title"));
model.setAuthor(obj.getString("author"));
model.setTags(obj.getString("tags"));
flickrList.add(model);
}
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e(TAG, "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (dialog.isShowing()) {
dialog.dismiss();
}
thank you so much
Your service seens to be returning a XML instead of JSON, see the header

Json object parsing error using http request

I am having an issue when http request is attempted the code that does the parsing works well...i tried to put a sample json string into the variable result and commented out all the code related to http request...i found the code works fine.But when i do a http request it is not working.Thank you in advance.The following is my code
`
public class MainActivity extends AppCompatActivity {
String result = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
onclick();
}
public void onclick(){
Asynctaskrunner run = new Asynctaskrunner();
run.execute("http://headers.jsontest.com/");
TextView text = (TextView) findViewById(R.id.textView);
TextView text1 = (TextView) findViewById(R.id.textView2);
final TextView text2= (TextView) findViewById(R.id.textView5);
final TextView text3 = (TextView) findViewById(R.id.textView6);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
JSONObject json = new JSONObject(result);
String name = json.getString("Accept-Language");
String salary = json.getString("Host");
text2.setText(name);
text3.setText(salary);
}catch (Exception e){
e.printStackTrace();
}
}
}
);
}
//-----------------------------------
private class Asynctaskrunner extends AsyncTask<String,Void,Void>{
private String response;
#Override
protected Void doInBackground(String... params) {
try {
URL url = new URL(params[0]);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
InputStream in = new BufferedInputStream(conn.getInputStream());
response=convertStreamToString(in);
} catch (MalformedURLException e) {
Log.e(TAG, "MalformedURLException: " + e.getMessage());
} catch (ProtocolException e) {
Log.e(TAG, "ProtocolException: " + e.getMessage());
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
result=response;
TextView textView = (TextView) findViewById(R.id.textView4);
return null;
}
private String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line).append('\n');
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
}`
String name = json.getString("Accept-Language");
the problem is here! JSON response is not returning any value for the Accept-Language key.
This is the response.
{
"X-Cloud-Trace-Context": "8bc66db5c468f43daff9c6a69fa7d0be/11367517399452323805",
"Host": "headers.jsontest.com",
"User-Agent": "Dalvik/2.1.0 (Linux; U; Android 6.0.1; D6503 Build/23.5.A.0.570)"
}
Change it with other key!
String trace = json.getString("X-Cloud-Trace-Context");
String host = json.getString("Host");
String agent = json.getString("User-Agent");

Error Parsing JSON data on executing PHP script

this is my php script
<?php
try{
$con = new PDO('mysql:host=localhost;dbname=pfe'/*info db*/,'root'/*login*/, ''/*mdp*/);
}
catch (Exception $e)
{
die('Erreur : '.$e->getMessage());
}
$msg = $_GET['msg'];
$mail = $_GET['mail'];
$result = $con->prepare("INSERT INTO message ( `msg`, `mail`)
VALUES ('{$msg}', '{$mail}')");
$result->execute();
if($result == true) {
echo '{"query_result":"SUCCESS"}';
}
else{
echo '{"query_result":"FAILURE"}';
}
my script i think is good cause i tried it with my browser it works but with android does not insert the data
and this is java class,
EditText msg,mail;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
msg = (EditText) findViewById(R.id.editText);
mail = (EditText) findViewById(R.id.editText2);
}
public void signup(View v) {
String message = msg.getText().toString();
String email = mail.getText().toString();
Toast.makeText(this, "wait...", Toast.LENGTH_SHORT).show();
new Insertinto(this).execute(message, email);
}
public class Insertinto extends AsyncTask<String, Void, String> {
private Context context;
public Insertinto(Context context) {
this.context = context;
}
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... arg0) {
String msg = arg0[0];
String mail = arg0[1];
String link;
String data;
BufferedReader bufferedReader;
String result;
try {
data = "?msg=" + URLEncoder.encode(msg, "UTF-8");
data += "&mail=" + URLEncoder.encode(mail, "UTF-8");
link = "http://192.168.43.93/dysfonction.php" + data;
URL url = new URL(link);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
result = bufferedReader.readLine();
return result;
} catch (Exception e) {
return new String("Exception: " + e.getMessage());
}
}
this is json
protected void onPostExecute(String result) {
String jsonStr = result;
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
String query_result = jsonObj.getString("query_result");
if (query_result.equals("SUCCESS")) {
Toast.makeText(context, "Data inserted successfully", Toast.LENGTH_SHORT).show();
} else if (query_result.equals("FAILURE")) {
Toast.makeText(context, "Data could not be inserted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Couldn't connect to database.", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(context, "Error parsing JSON data.", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(context, "Couldn't get any JSON data.", Toast.LENGTH_SHORT).show();
}
}
}
}
when i execute it show me "Error parsing JSON data" i didn't find where is the pbm.
debug and check the result received in the postExecute(); and from next time paste the logcat as well..
Try to change this to
if($result == true) {
echo '{"query_result":"SUCCESS"}';
}else{
echo '{"query_result":"FAILURE"}';
}
this
if($result == true) {
$data = array(
'query_result' => 'SUCCESS'
);
}else{
$data = array(
'query_result' => 'FAILURE'
);
}
echo json_encode($data);
It seems to be your java code is so clear. So sent response from php code like above may be works.
in the place of
result = bufferedReader.readLine();
use
result = bufferedReader.readLine().toString();

Starting new Activity causes app to crash

I am attempting to start a new Intent inside onPostExecute() method after an AsyncTask. The app always crashes however and there are no error logs. The System.out.println() calls return the expected output.
#Override
protected JSONObject doInBackground(Void... params) {
// TODO: attempt authentication against a network service.
try {
// Use the email address minus the '#' prefix as temp username.
String[] uList = (mEmail.split("#"));
String mUsername = uList[0];
Serverrequest request = new Serverrequest();
JSONObject userObj = request.getJSON(
"http://10.0.2.2:3700/api/login", mUsername, mPassword);
if (userObj != null) {
// Account exists, return user
return userObj;
} else {
System.out.println("Null response");
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
// TODO: register the new account here.
JSONObject newUser = new JSONObject();
try {
newUser.put("username", "Charlie");
} catch (JSONException e) {
}
return newUser;
}
#Override
protected void onPostExecute(final JSONObject user) {
try {
mAuthTask = null;
showProgress(false);
System.out.println(user);
String username = user.getString("username");
System.out.println(username);
SharedPreferences prefs = getSharedPreferences("wordsmith", MODE_PRIVATE);
prefs.edit().putString("username", username).apply();
} catch (JSONException e) {
e.printStackTrace();
}
Intent intent = new Intent(LoginActivity.this, StartScreenActivity.class);
intent.putExtra("user", user.toString());
LoginActivity.this.finish();
startActivity(intent);

Categories

Resources