Hi i need to save json data in sqlite. But iam getting following error.
Can't create handler inside thread that has not called
Looper.prepare().
This is my code. It is shwoing database open/database created...
/**
* Async task class to get json by making HTTP call
* */
private class GetDetails extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#SuppressLint("NewApi")
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Create an array to populate the spinner
branchlist = new ArrayList<String>();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
// System.out.println("response"+jsonStr);
if (jsonStr != null) {
try {
// jsonString is a string variable that holds the JSON
JSONArray itemArray=new JSONArray(jsonStr);
for (int i = 0; i < itemArray.length(); i++) {
value=itemArray.getString(i);
Log.e("json", i+"="+value);
dbhelper=new DataBaseHepler(getApplicationContext());
sqLiteDatabase=dbhelper.getWritableDatabase();
dbhelper.addinnformation(value,sqLiteDatabase);
Toast.makeText(getBaseContext(),"Data saved",Toast.LENGTH_LONG).show();
dbhelper.close();
branchlist.add(itemArray.getString(i));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ArrayAdapter<String> stringadapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_spinner_dropdown_item,
branchlist);
spinner1.setAdapter(stringadapter);
// spinner1
// .setAdapter(new ArrayAdapter<String>(MainActivity.this,
// android.R.layout.simple_spinner_dropdown_item,
// branchlist));
}
}
This error is due to Toast inside doInBackground(Void... arg0) method:
Toast.makeText(getBaseContext(),"Data saved",Toast.LENGTH_LONG).show();
Clearly the Android OS wont let threads other than the main thread change UI elements. Follow this link for more details on this: https://dzone.com/articles/android-%E2%80%93-multithreading-ui
Related
This question already has answers here:
How to parse JSON Array (Not Json Object) in Android
(11 answers)
Closed 6 years ago.
JSON LInk - http://jsonviewer.stack.hu/#http://www.saveme.ie/api/savings/
Im trying to fetch a JSON to fill a listview in Android with this background task but its saying there is a problem with the JSON. It seems to be because the array has no name.
How would i modify the code so it can fetch the array with no name?
private class GetSavings extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url);
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
**JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray savings = jsonObj.getJSONArray("savings");
// looping through All Contacts
for (int i = 0; i < savings.length(); i++) {
JSONObject c = savings.getJSONObject(i);
String title = c.getString("title");
}**
} 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);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
MainActivity.this, savingsList,
R.layout.list_item, new String[]{"name", "email",
"mobile"}, new int[]{R.id.name,
R.id.email, R.id.mobile});
lv.setAdapter(adapter);
}
}
Instead of casting it in JSONObject, cast it into JSONArray.
JSONArray jsonObj = new JSONArray(jsonStr);
and then traverse your array.
I have implemented an AsyncTask to get values of a web service and store them into an array, but something I am doing wrong because it says that "Invalid index 0, size is 0". The object "dia" is not well created. Here is my code:
private class GetValue extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
metereologia = new ArrayList<DiaTemperatura>();
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
eventos = jsonObj.getJSONArray("list");
// looping through All Contacts
for (int i = 0; i < eventos.length(); i++) {
JSONObject c = eventos.getJSONObject(i);
JSONObject temp = c.getJSONObject(TAG_TEMP);
String max = temp.getString(TAG_MAX);
String min = temp.getString(TAG_MIN);
String humedad = c.getString(TAG_HUMIDITY);
JSONObject weather = c.getJSONObject(TAG_WEATHER);
//String main = weather.getString(TAG_MAIN);
//String description = weather.getString(TAG_DESCRIPTION);
DiaTemperatura dia= new DiaTemperatura();
dia.setMyText(max);
metereologia.add(dia);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
TextView mitext = (TextView) getView().findViewById(R.id.temperatura);
mitext.setText(metereologia.get(0).getMyText());
}
}
It looks like you must be declaring metereologia outside your AsyncTask, then initialising and populating it in the task. This is not quite the correct way to use it. Your AsyncTask should return the result of its computation. You'll need to declare your task as:
private class GetValue extends AsyncTask<Void, Void, List<DiaTemperatura>> {
...
#Override
protected List<DiaTemperatura> doInBackground(Void... arg0) {
List<DiaTemperatura> metereologia = new ArrayList<DiaTemperatura>();
...
return metereologia;
}
and thus onPostExecute becomes:
#Override
protected void onPostExecute(List<DiaTemperatura> metereologia) {
I think that's right, it's off the top of my head...
Your error must be in the line mitext.setText(metereologia.get(0).getMyText()); Its will go for finding the value at the index 0 in your metereologia which its is not getting.
You can not directly set the value of your whole arraylist in such a way. You need to loop for the value whichever you want to set in your TextView.
There is nothing in the metereologia so when you try to get it with (metereologia.get(0).getMyText(), it results in an error, "Invalid index 0, size is 0".
1) For doing check work -
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
TextView mitext = (TextView) getView().findViewById(R.id.temperatura);
String content = "";
if(metereologia.size() == 0)
{
//a check that your metereologia size is 0.
}
for(int i=0;i<metereologia.size();i++)
content = content + metereologia.get(i).getMyText();
mitext.setText(content);
}
}
2) To get the value right-
More convenient way is to return the object metereologia from background and pass it to postExecute method and then process.This is explained by #dave.c.
protected void onPostExecute(List<DiaTemperatura> metereologia) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
TextView mitext = (TextView) getView().findViewById(R.id.temperatura);
String content = "";
if(metereologia.size() == 0)
{
//a check that your metereologia size is 0.
}
for(int i=0;i<metereologia.size();i++)
content = content + metereologia.get(i).getMyText();
mitext.setText(content);
}
}
I want to get an url from this link:
"http://graph.facebook.com/10202459285618351/picture?type=large&redirect=false"
it gives result:
{
"data": {
"url": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xap1/t1.0- 1/s200x200/10342822_10202261537234765_3194866551853134720_n.jpg",
"is_silhouette": false
}
}
I tried,
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(AccountActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
String jsonStr = sh.makeServiceCall(fbPicURL, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
fbRealURL = jsonObj.getString("url");
// Phone node is JSON Object
Toast.makeText(AccountActivity.this, fbRealURL,
Toast.LENGTH_LONG).show();
// tmp hashmap for single contact
}
catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
Toast.makeText(AccountActivity.this, fbRealURL,
Toast.LENGTH_LONG).show();
}
}
But returning null and its not crashing..
You have to get the data object first like this:
try {
JSONObject jsonObj = new JSONObject(jsonStr);
fbRealURLObj = jsonObj.getJSONObject("data");
fbRealURL = fbRealURLObj.getString("url");
// Phone node is JSON Object
Toast.makeText(AccountActivity.this, fbRealURL,
Toast.LENGTH_LONG).show();
// tmp hashmap for single contact
}
I have an AsyncTask that connects to a service and with an adapter set the result in a ListView. In the action bar I want to put a button to do the refresh action but the problem is that when I click this button and I call to the service it duplicates the results in the list view.
I have tried:
ListView myList=(ListView)findViewById(R.id.list);
myList.setAdapter(null);
if ((new Utils(this)).isConnected()){
new MyTask().execute();
}
My AsyncTask code:
private class MyTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MyActivity.this);
pDialog.setMessage("searching...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url+id, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONArray jsonObj = new JSONArray(jsonStr);
// looping through All Contacts
for (int i = 0; i < jsonObj.length(); i++) {
JSONObject c = jsonObj.getJSONObject(i);
String nick = c.getString("nick");
String minuto = c.getString("minuto");
String fecha = c.getString("fecha");
// tmp hashmap for single contact
HashMap<String, String> contact = new HashMap<String, String>();
// adding each child node to HashMap key => value
contact.put("nick", nick);
contact.put("minuto", minuto);
contact.put("fecha", fecha);
// adding contact to contact list
contactList.add(contact);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
DetallePelicula.this, contactList,
R.layout.list_rowopiniones, new String[] { "nick", "minuto",
"fecha" }, new int[] { R.id.title,
R.id.minuto, R.id.fecha });
ListView myList=(ListView)findViewById(R.id.list);
myList.setAdapter(adapter);
}
}
Somebody can help me? thanks
In your doInBackground, you are adding the new data to an already existing list. This means that, as you've mentioned, the data will duplicate.
Just add contactList.clear() to your onPreExecute method:
#Override
protected void onPreExecute() {
super.onPreExecute();
contactList.clear(); // Add this line
// Showing progress dialog
pDialog = new ProgressDialog(MyActivity.this);
pDialog.setMessage("searching...");
pDialog.setCancelable(false);
pDialog.show();
}
Im new to Android Development. I want to fill spinner by Json array which load from the Http request(by AsyncTask). My AsyncTask in seperate class called Load_spinnrs. I to do this?
here is my http request
try{
String DataSendingTo="http://www.mysite.com/AppRequest/load_data";
//HttpClient
HttpClient httpClient = new DefaultHttpClient();
//Post header
HttpPost httpPost = new HttpPost(DataSendingTo);
//Adding data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("authorized","001"));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// execute HTTP post request
HttpResponse response = httpClient.execute(httpPost);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null;) {
builder.append(line).append("\n");
}
JSONTokener tokener = new JSONTokener(builder.toString());
JSONArray finalResult = new JSONArray(tokener);
//How to load Spinner ?????
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
After you get array of JSON
You have to do like:
final String[] items = new String[jsonArray.length()];
// looping through All Contacts
for(int i = 0; i < jsonArray.length(); i++){
JSONObject c = jsonArray.getJSONObject(i);
// Storing each json item in variable
String name = c.getString(TAG_NAME);
items[i]=c.getString(TAG_NAME);
System.out.println("Hello events "+items);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String> (this, android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sp.setAdapter(adapter);
Populate an Android Spinner with JSON data from a RESTful web API
If you are extending AsyncTask in separate class then you will need to pass Activity context from which you are executing extending for accessing UI elements in on normal java class. for this you can use Load_spinnrs class constructor to get Activity context and use onPostExecute for accessing Spinner as:
class Load_spinnrs extends AsyncTask<String,String,String>{
Activity activity;
Context context;
public Load_spinnrs(Activity activity,Context context){
this.activity=activity;
this.context=context;
}
...
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
//access UI elements here..
Spinner mySpinner = (Spinner)activity.findViewById(R.id.my_spinner);
adapter = new ArrayAdapter<String> (context,
android.R.layout.simple_spinner_item, items);
//....
super.onPostExecute(result);
}
}
For pass Context start AsyncTask as from Activity:
Load_spinnrs load_spin=new Load_spinnrs(this,this);
load_spin.execute(parameters);
for easily understand, Load your Load_spinnrs class as, sub class of your main class.
for example;
public class Main_Class extends Activity
{
private Spinner spinner;
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.userprofiles);
//init spinner here
}
private class Load_spinnrs extends AsyncTask<Void, Void, String>{
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(Void... params) {
// your http request
}
#Override
protected void onPostExecute(String result) {
//update spinner here.
}
}
Here is the implementation in the AsyncTask to show the loading spinner and then dismiss it when the AsyncTask is complete.
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
<put code here>
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
}
}
}
Look at this may be help you:
GetServerData.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Server Request URL
String serverURL = "http://androidexample.com/media/webservice/getPage.php";
// Create Object and call AsyncTask execute Method
new LongOperation().execute(serverURL);
}
});
protected void onPreExecute() {
// NOTE: You can call UI Element here.
//UI Element
uiUpdate.setText("Output : ");
Dialog.setMessage("Downloading source..");
Dialog.show();
}
for more details you have :
http://androidexample.com/AsyncroTask_Example_To_Get_Server_Data_-_Android_Example/index.php?view=article_discription&aid=59&aaid=84
http://www.androidhive.info/2013/12/android-populating-spinner-data-from-mysql-database/
Best regards