I have developed an android application by following this tutorial http://programmerguru.com/android-tutorial/how-to-sync-sqlite-on-android-to-mysql-db/
But its not working when iam running in the emulator Here is my code which i got stuck
When i run the application in the emulator its not working.
public class MainActivity extends Activity {
//DB Class to perform DB related operations
DBController controller = new DBController(this);
//Progress Dialog Object
ProgressDialog prgDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Get User records from SQLite DB
ArrayList<HashMap<String, String>> userList = controller.getAllUsers();
//
if(userList.size()!=0){
//Set the User Array list in ListView
ListAdapter adapter = new SimpleAdapter( MainActivity.this,userList, R.layout.view_user_entry, new String[] { "userId","userName"}, new int[] {R.id.userId, R.id.userName});
ListView myList=(ListView)findViewById(android.R.id.list);
myList.setAdapter(adapter);
//Display Sync status of SQLite DB
Toast.makeText(getApplicationContext(), controller.getSyncStatus(), Toast.LENGTH_LONG).show();
}
//Initialize Progress Dialog properties
prgDialog = new ProgressDialog(this);
prgDialog.setMessage("Synching SQLite Data with Remote MySQL DB. Please wait...");
prgDialog.setCancelable(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//When Sync action button is clicked
if (id == R.id.refresh) {
//Sync SQLite DB data to remote MySQL DB
syncSQLiteMySQLDB();
return true;
}
return super.onOptionsItemSelected(item);
}
//Add User method getting called on clicking (+) button
public void addUser(View view) {
Intent objIntent = new Intent(getApplicationContext(), NewUser.class);
startActivity(objIntent);
}
public void syncSQLiteMySQLDB(){
//Create AsycHttpClient object
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
ArrayList<HashMap<String, String>> userList = controller.getAllUsers();
if(userList.size()!=0){
if(controller.dbSyncCount() != 0){
prgDialog.show();
params.put("usersJSON", controller.composeJSONfromSQLite());
client.post("http://localhost/sqlitemysqlsync/insertuser.php",params ,new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
System.out.println(response);
prgDialog.hide();
try {
JSONArray arr = new JSONArray(response);
System.out.println(arr.length());
for(int i=0; i<arr.length();i++){
JSONObject obj = (JSONObject)arr.get(i);
System.out.println(obj.get("id"));
System.out.println(obj.get("status"));
controller.updateSyncStatus(obj.get("id").toString(),obj.get("status").toString());
}
Toast.makeText(getApplicationContext(), "DB Sync completed!", Toast.LENGTH_LONG).show();
} catch (JSONException e) {
// TODO Auto-generated catch block
Toast.makeText(getApplicationContext(), "Error Occured [Server's JSON response might be invalid]!", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
#Override
public void onFailure(int statusCode, Throwable error,
String content) {
// TODO Auto-generated method stub
prgDialog.hide();
if(statusCode == 404){
Toast.makeText(getApplicationContext(), "Requested resource not found", Toast.LENGTH_LONG).show();
}else if(statusCode == 500){
Toast.makeText(getApplicationContext(), "Something went wrong at server end", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(getApplicationContext(), "Unexpected Error occcured! [Most common Error: Device might not be connected to Internet]", Toast.LENGTH_LONG).show();
}
}
});
}else{
Toast.makeText(getApplicationContext(), "SQLite and Remote MySQL DBs are in Sync!", Toast.LENGTH_LONG).show();
}
}else{
Toast.makeText(getApplicationContext(), "No data in SQLite DB, please do enter User name to perform Sync action", Toast.LENGTH_LONG).show();
}
}
}
Here iam not understanding whether to keep localhost or my machines IP Address
client.post("http://localhost/sqlitemysqlsync/insertuser.php",params ,new AsyncHttpResponseHandler
Please Help me to solve this
localhost will not work , connect your mobile device to the same WAN using wifi as your pc, find the Ip of your machine and use the same in place of localhost.
Connect your phone and laptop to the same wifi connection.
Go to cmd type ip config.
Look for wireless wifi ipv4.
Note it type on local host space http://192.168.1.0/sqlitemysqlsync/insertuser.php
Then run
Related
I have an activity that calls JSON data from a foreign database.
Below is my ideal case for my app:
The JSON data is parsed and inserted into an SQLite database on Android
Next activity is started and the newly inserted data is read from the SQLite database
What actually happens:
The JSON data is parsed and inserted into an SQLite database on Android
The next activity is started while data is still being inserted and returns zero when reading from the desired databse for my ListArray in that activity.
How do I force Android to wait until database insertion is completed before starting the next activity?
EDIT
My doInBackground looks as follows:
#Override
protected String doInBackground(String... params) {
StringRequest strReq = new StringRequest(Request.Method.GET,
str, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");
// Check for error node in json
if (!error) {
JSONArray jObjInside = jObj.getJSONArray("service_prov_services");
for (int i = 0; i < jObjInside.length(); i++) {
// Now store the user in SQLite
try {
// JSONObject user = jObj.getJSONObject("user");
String service_prov_type = jObj.getString("service_prov_type");
String service_prov_name = jObj.getString("service_prov_name");
String addr_street = jObj.getString("addr_street");
String addr_num = jObj.getString("addr_number");
String addr_plz = jObj.getString("addr_plz");
String addr_city = jObj.getString("addr_city");
JSONObject elem = jObjInside.getJSONObject(i);
if(elem != null){
String service_id = elem.getString("service_id");
String service_type = elem.getString("service_type");
String service_measure = elem.getString("service_measure");
// Inserting row in userServiceProvServices table
db.addUserServiceProvServices(service_id, service_prov_type,
service_prov_name, addr_street, addr_num, addr_plz, addr_city, service_type, service_measure);
Log.d("post_url for service", addr_plz );
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getActivity().getApplicationContext(), "Json error: " +
e.getMessage(), Toast.LENGTH_LONG).show();
}
}
} else {
// Error in login. Get the error message
String errorMsg = jObj.getString("error_msg");
Toast.makeText(getActivity().getApplicationContext(),
errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getActivity().getApplicationContext(), "Json error: " +
e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Login Error: " + error.getMessage());
Toast.makeText(getActivity().getApplicationContext(),
error.getMessage(), Toast.LENGTH_LONG).show();
}
});
Log.d("test string to appcntr",strReq.toString());
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
return params[0];
}
onPostExecute looks as follows:
#Override
protected void onPostExecute(String Result) {
//super.onPostExecute(Result);
pdLoading.dismiss();
//this method will be running on UI thread
Log.d(TAG, "Stamp: " + Result);
Bundle args = new Bundle();
args.putString("stampID", Result);
ProviderServiceListFragment frag = new ProviderServiceListFragment();
frag.setArguments(args);
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame,
frag)
.commit();
}
With the way I am doing it now, my next Fragment is already called, although the data has not finished being entered into the database. This means the ListArray in the follwoing Fragment is empty because of the missing database data.
I worked on this for a month and finally figured it out for myself (stupid nube I am..) So here is a piece of code inserting a record to sqlite.
On the chosen event ("onClick actionbutton1") a new AsyncTask is created with doInBackground, onPreExecute and onPostExecute.
onPreExecute will setMessage() and show() the progressDialog which will start spinning
onPostExecute will handle the new/next Activity
READ BELOW FOR doInBackground!!
actionButton1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final ProgressDialog progressDialog = new ProgressDialog(AddUpdateEvf.this);
new AsyncTask<Void, Void, Boolean>() {
protected Boolean doInBackground(Void... params) {
doOneThing();
return null;
}
#Override
protected void onPreExecute() {
progressDialog.setMessage("Processing...");
progressDialog.show();
}
protected void onPostExecute(Boolean result) {
evaluationFormOps.close();
progressDialog.dismiss();
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(AddUpdateEvf.this);
alertDialogBuilder.setMessage("Added to Database...")
.setCancelable(false)
.setPositiveButton("Continue", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
i = new Intent(AddUpdateEvf.this, ViewProduct.class);
i.putExtra(EXTRA_ADD_UPDATE, "View");
i.putExtra(EXTRA_PRODUCT_ID, hiddenTextId.getText().toString());
i.putExtra(EXTRA_PRODUCT_NO, productNo_tv.toString());
startActivity(i);
dialog.dismiss();
finish();
}
});
AlertDialog alert = alertDialogBuilder.create();
alert.show();
}
private void doOneThing() {
makeDbRequest();
do {
evfId = newEvf.getEvfId();
}
while (evfId<1);
}
}.execute();
}
});
Note this snippet in the above code called in doInBackground():
private void doOneThing() {
makeDbRequest();
do {
evfId = newEvf.getEvfId();
}
while (evfId<1);
}
Note: The makeDbRequest() handles the insert to sqlite by setting the values and then passing it to another class which handles the cursor and puts the values etc.
Heres a small snippet of relevant code in that class (which you should already have mastered...):
public Evf addEvf(Evf evf, String dBsuccess){
ContentValues values = new ContentValues();
values.put(TableHelper.PRODUCT_IDE,evf.getPRODUCTId());
values.put(TableHelper.CSCORE,evf.getcScore());
values.put(TableHelper.FSCORE,evf.getfScore());
values.put(TableHelper.TSCORE,evf.gettScore());
values.put(TableHelper.WEIGHT,evf.getWeight());
values.put(TableHelper.TEMP,evf.getTemp());
values.put(TableHelper.STATUS,evf.getStatus());
values.put(TableHelper.TIMESTAMP, String.valueOf(evf.getTimeStamp()));
values.put(TableHelper.LOADED, dBsuccess);
long insertid = database.insert(TableHelper.TABLE_EVFS,null,values);
evf.setEvfId((int) insertid);
return evf;
}
So above you can see the Id of, in my case evaluationform(Evf), being set to the insert id. This happens after the insert and you can set any value in your object class (the one with getters and setters...Evf())
Finally, use the do...while statement above to "listen" for the value being set in the object class
This can obviously only happen if the insert was finished and the onPosteExecute takes care of the rest
Hope it helps, crit is welcome, PEACHES!!
Use AsyncTask to process the Database insertion process & then use the onPostExecute method to move away from the current activity.
private class ProcessDatabase extends AsyncTask<String, String, String> {
String sampleData;
#Override
protected String doInBackground(String... params) {
//Call your Database Insert method here.
//In this example, I am inserting sampleData to the DB
return null;
}
#Override
protected void onPostExecute(String result) {
//This gets triggered when the process is complete
}
}
You can start the AsyncTask by adding the following code in your onCreate or where ever you want to start the DB Insertion process:
//in this case I am just passing a string, You can create your own
//custom class & send that as well
ProcessDatabase.execute(myData);
Refer this link for more information. Good luck!
The StringRequest is an Asynchronous request, so upon the executing the those lines onPostExecute will called immediately, so there is no guarantee that the sql update will complete before the next activity is launched.
Call the nextActivity at the end of the onResponse callback method of the StringRequest which way you can guarantee to insert the data to db first and then call the nextActivity.
private void makeJsonRequest(String str) {
StringRequest strReq = new StringRequest(Request.Method.GET,
str, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");
// Check for error node in json
if (!error) {
JSONArray jObjInside = jObj.getJSONArray("service_prov_services");
for (int i = 0; i < jObjInside.length(); i++) {
// Now store the user in SQLite
try {
// JSONObject user = jObj.getJSONObject("user");
String service_prov_type = jObj.getString("service_prov_type");
String service_prov_name = jObj.getString("service_prov_name");
String addr_street = jObj.getString("addr_street");
String addr_num = jObj.getString("addr_number");
String addr_plz = jObj.getString("addr_plz");
String addr_city = jObj.getString("addr_city");
JSONObject elem = jObjInside.getJSONObject(i);
if (elem != null) {
String service_id = elem.getString("service_id");
String service_type = elem.getString("service_type");
String service_measure = elem.getString("service_measure");
// Inserting row in userServiceProvServices table
db.addUserServiceProvServices(service_id, service_prov_type,
service_prov_name, addr_street, addr_num, addr_plz, addr_city, service_type, service_measure);
Log.d("post_url for service", addr_plz);
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getActivity().getApplicationContext(), "Json error: " +
e.getMessage(), Toast.LENGTH_LONG).show();
}
}
goNextActivity();
} else {
// Error in login. Get the error message
String errorMsg = jObj.getString("error_msg");
Toast.makeText(getActivity().getApplicationContext(),
errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getActivity().getApplicationContext(), "Json error: " +
e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Login Error: " + error.getMessage());
Toast.makeText(getActivity().getApplicationContext(),
error.getMessage(), Toast.LENGTH_LONG).show();
}
});
Log.d("test string to appcntr", strReq.toString());
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
private void goNextActivity(){
//this method will be running on UI thread
ProviderServiceListFragment frag = new ProviderServiceListFragment();
frag.setArguments(args);
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame,
frag)
.commit();
}
I have an application wherein, it retrieves data from DB and displays it in a list view but I want it to refresh after adding new data to database without using:
Intent i = new Intent (MyActivity.this,MyActivity.class);
startActivity (i);
Here is my code:
public class MainActivity extends ActionBarActivity {
//DB Class to perform DB related operations
DBController controller = new DBController(this);
//Progress Dialog Object
ProgressDialog prgDialog;
EditText userName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userName = (EditText) findViewById(R.id.userName);
//Get User records from SQLite DB
ArrayList<HashMap<String, String>> userList = controller.getAllUsers();
//
if (userList.size() != 0) {
//Set the User Array list in ListView
ListAdapter adapter = new SimpleAdapter(MainActivity.this, userList, R.layout.view_user_entry, new String[]{"userId", "userName"}, new int[]{R.id.userId, R.id.userName});
ListView myList = (ListView) findViewById(android.R.id.list);
myList.setAdapter(adapter);
//Display Sync status of SQLite DB
Toast.makeText(getApplicationContext(), controller.getSyncStatus(), Toast.LENGTH_LONG).show();
}
//Initialize Progress Dialog properties
prgDialog = new ProgressDialog(this);
prgDialog.setMessage("Synching SQLite Data with Remote MySQL DB. Please wait...");
prgDialog.setCancelable(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//When Sync action button is clicked
if (id == R.id.refresh) {
//Sync SQLite DB data to remote MySQL DB
syncSQLiteMySQLDB();
return true;
}
return super.onOptionsItemSelected(item);
}
//Add User method getting called on clicking (+) button
public void addUser(View view) {
Intent objIntent = new Intent(getApplicationContext(), NewUser.class);
startActivity(objIntent);
}
public void syncSQLiteMySQLDB() {
//Create AsycHttpClient object
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
ArrayList<HashMap<String, String>> userList = controller.getAllUsers();
if (userList.size() != 0) {
if (controller.dbSyncCount() != 0) {
prgDialog.show();
params.put("usersJSON", controller.composeJSONfromSQLite());
client.post("http://192.168.2.4:9000/sqlitemysqlsync/insertuser.php", params, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
System.out.println(response);
prgDialog.hide();
try {
JSONArray arr = new JSONArray(response);
System.out.println(arr.length());
for (int i = 0; i < arr.length(); i++) {
JSONObject obj = (JSONObject) arr.get(i);
System.out.println(obj.get("id"));
System.out.println(obj.get("status"));
controller.updateSyncStatus(obj.get("id").toString(), obj.get("status").toString());
}
Toast.makeText(getApplicationContext(), "DB Sync completed!", Toast.LENGTH_LONG).show();
} catch (JSONException e) {
// TODO Auto-generated catch block
Toast.makeText(getApplicationContext(), "Error Occured [Server's JSON response might be invalid]!", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
#Override
public void onFailure(int statusCode, Throwable error,
String content) {
// TODO Auto-generated method stub
prgDialog.hide();
if (statusCode == 404) {
Toast.makeText(getApplicationContext(), "Requested resource not found", Toast.LENGTH_LONG).show();
} else if (statusCode == 500) {
Toast.makeText(getApplicationContext(), "Something went wrong at server end", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Unexpected Error occcured! [Most common Error: Device might not be connected to Internet]", Toast.LENGTH_LONG).show();
}
}
});
} else {
Toast.makeText(getApplicationContext(), "SQLite and Remote MySQL DBs are in Sync!", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(getApplicationContext(), "No data in SQLite DB, please do enter User name to perform Sync action", Toast.LENGTH_LONG).show();
}
}
/**
* Called when Save button is clicked
* #param view
*/
public void addNewUser(View view) {
HashMap<String, String> queryValues = new HashMap<String, String>();
queryValues.put("userName", userName.getText().toString());
if (userName.getText().toString() != null
&& userName.getText().toString().trim().length() != 0) {
controller.insertUser(queryValues);
} else {
Toast.makeText(getApplicationContext(), "Please enter User name",
Toast.LENGTH_LONG).show();
}
}
#Override
protected void onResume() {
super.onResume();
}
}
Call clear() on the adapter then notifyDatasetChanged(), this will get rid of old data in the list. At this time you can reload you database cursor.
It is all working and i have added my method to check if there is internet connection, and if there isn't change activity. But it is changing activity immediately before loading progress bar. Where should i add this method so first progress bar is loaded and if there is no internet connection, change activity.
Also if anyone have some suggestion about this checking internet connection, i would appricieate any answer.
This is my activity where i'm using that method:
public class ListaPreporuka extends AppCompatActivity {
// Log tag
private static final String TAG = ListaPreporuka.class.getSimpleName();
// Movies json url
private static final String url = "http://www.nadji-ekipu.org/wp-content/uploads/2015/07/movies.txt";
private ProgressDialog pDialog;
private List<Movie> movieList = new ArrayList<Movie>();
private ListView listView;
private CustomListAdapter adapter;
private static String Title ="title";
private static String bitmap ="thumbnailUrl";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lista_preporuka);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayUseLogoEnabled(true);
getSupportActionBar().setLogo(R.drawable.ic_horor_filmovi_ikonica);
Intent newActivity2=new Intent();
setResult(RESULT_OK, newActivity2);
listView = (ListView) findViewById(R.id.list);
adapter = new CustomListAdapter(this, movieList);
listView.setAdapter(adapter);
pDialog = new ProgressDialog(this);
// Showing progress dialog before making http request
pDialog.setMessage("Učitavanje...");
pDialog.show();
// Creating volley request obj
JsonArrayRequest movieReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Movie movie = new Movie();
movie.setTitle(obj.getString("title"));
movie.setThumbnailUrl(obj.getString("image"));
movie.setRating(((Number) obj.get("rating"))
.doubleValue());
movie.setYear(obj.getInt("releaseYear"));
// Genre is json array
final JSONArray genreArry = obj.getJSONArray("genre");
ArrayList<String> genre = new ArrayList<String>();
for (int j = 0; j < genreArry.length(); j++) {
genre.add((String) genreArry.get(j));
}
movie.setGenre(genre);
// adding movie to movies array
movieList.add(movie);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
noInternet();
// Adding request to request queue
AppController.getInstance().addToRequestQueue(movieReq);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String name = ((TextView) view.findViewById(R.id.title))
.getText().toString();
bitmap = ((Movie)movieList.get(position)).getThumbnailUrl();
Intent intent = new Intent(ListaPreporuka.this, MoviesSingleActivity.class);
intent.putExtra(Title, name);
intent.putExtra("images", bitmap);
intent.putExtra("Year", movieList.get(position).getYear());
startActivity(intent);
overridePendingTransition(R.anim.slide_in, R.anim.slide_out);
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
//WHERE SHOULD I ADD THIS METHOD FOR MAKING MY ACTIVITY SHOW FIRST PROGRESS BAR AND IF THERE IS NO INTERNET CONNECTION, SHOW ANOTHER ACTIVITY
private void noInternet() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null) {
if (!info.isConnected()) {
}
}
else {
Toast.makeText(this, "No Internet Connection", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(ListaPreporuka.this, NoConnection.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
overridePendingTransition(R.anim.slide_in, R.anim.slide_out);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
if (item.getItemId() == android.R.id.home) {
finish();
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
return true;
}
return false;
}
#Override
public void onBackPressed() {
super.onBackPressed();
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
}
You are making some http request. So you want to chek if there is internet connection available right?
So first put a check if internet connection is available.
Wherever you are doing your other operations ..
if(internet connection is present){
//make http request;
}else{
// display appropriate message and switch to your new activity
}
You can call your method in the same place but with some delay, if you want simple answer. Something like this:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 100ms
}
}, 100);
But, I think, you should better use this method to show dialog:
public static ProgressDialog show (Context context, CharSequence title, CharSequence message, boolean indeterminate, boolean cancelable, DialogInterface.OnCancelListener cancelListener)
Implement DialogInterface.OnCancelListener, call your intent with transition to the new activity in onCancel callback of OnCancelListener.
And use pDialog.cancel() in else statement of noInternet() method.
I am working on a articles application like techcrunch I am parsing data from json.
I am parsing title,author and image from json.
Articles are displayed in list-view.
I want to do offline caching means when there is no internet user can read the articles.
Here is my code-
public class OneFragment extends Fragment {
public OneFragment(){}
private static final String TAG = OneFragment.class.getSimpleName();
// Movies json url
private static String URL = "http://url";
private ProgressDialog pDialog;
private List<Movie> movieList = new ArrayList<Movie>();
private ListView listView;
private CustomListAdapter adapter;
int current_page = 0;
int mPreLast;
SwipeRefreshLayout swipeView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.swip, container, false);
swipeView = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe);
swipeView.setColorScheme(android.R.color.holo_blue_dark, android.R.color.holo_blue_light, android.R.color.holo_green_light, android.R.color.holo_green_dark);
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Loading...");
pDialog.show();
pDialog.setCancelable(false);
swipeView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
// TODO Auto-generated method stub
swipeView.setRefreshing(true);
Log.d("Swipe", "Refreshing Number");
( new Handler()).postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
swipeView.setRefreshing(false);
onStart();
}
}, 3000);
}
});
listView = (ListView) rootView.findViewById(R.id.list49);
listView.setOnScrollListener(new AbsListView.OnScrollListener()
{
#Override
public void onScrollStateChanged(AbsListView absListView, int i)
{
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
int lastItem = firstVisibleItem + visibleItemCount;
if(lastItem == totalItemCount){
if (mPreLast != lastItem)
{
mPreLast = lastItem;
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Loading more articles...");
pDialog.show();
//pDialog.setCancelable(false);
onStart();
}
}
}
});
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int Position,
long offset) {
// TODO Auto-generated method stub
Movie item = (Movie) adapter.getItem(Position);
Intent intent = new Intent(rootView.getContext(), SingleArticle.class);
single.title = item.getTitle();
single.author = item.getAuthor();
startActivity(intent);
}
});
//pDialog = new ProgressDialog(this);
// Showing progress dialog before making http request
return rootView;
}
#Override
public void onStart(){
super.onStart();
// calling adapter changes here, just
// to avoid getactivity()null
// increment current page
current_page += 1;
// Next page request
URL = "http://url" + current_page;
//adapter = new CustomListAdapter(this, movieList);
int currentPosition = listView.getFirstVisiblePosition();
adapter = new CustomListAdapter(getActivity(), movieList);
listView.setAdapter(adapter);
listView.setSelectionFromTop(currentPosition + 1, 0);
// changing action bar color
//getActivity().getActionBar().setBackground(
//new ColorDrawable(Color.parseColor("#1b1b1b")));
// Creating volley request obj
JsonArrayRequest movieReq = new JsonArrayRequest(URL,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Movie movie = new Movie();
movie.setTitle(obj.getString("title"));
movie.setAuthor(obj.getString("author"));
// adding movie to movies array
movieList.add(movie);
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
},new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
new AlertDialog.Builder(getActivity())
.setTitle("No Connectivity ")
.setMessage("Please check your internet connectivity!")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// continue with delete
}
})
//.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
//public void onClick(DialogInterface dialog, int which) {
// do nothing
//}
//})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
hidePDialog();
}
});
AppController.getInstance().addToRequestQueue(movieReq);
//listView.setAdapter(adapter);
}
private View getActionBar() {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
}
This probably isn't the best way to do it, but it worked for me.
You might find this helpful: http://www.vogella.com/tutorials/JavaSerialization/article.html
I had to do the same in some project. This is what I did:
public final class cacheThis {
private cacheThis() {}
public static void writeObject(Context context, String fileName, Object object) throws IOException {
FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(object);
oos.flush();
oos.close();
fos.close();
}
public static Object readObject(Context context, String fileName) throws IOException,
ClassNotFoundException {
FileInputStream fis = context.openFileInput(fileName);
ObjectInputStream ois = new ObjectInputStream(fis);
Object object = ois.readObject();
fis.close();
return object;
}
}
To write to file:
cacheThis.writeObject(YourActivity.this, fileName, movieList);
To read from file:
movieList.addAll((List<Movie>) cacheThis.readObject(
VideoActivity.this, fileName));
You have to have your Movie class implements Serializable
You must save the json offline. It can be Db or file system. I will prefer to go with Db part.
The approach is ,every time you get data from server save first in you db then from db you can show it to your UI.
Inserting in Db can be slow but you can use beginTransaction and other methods which will make it lighting fast.
Now How can you save data in Db. You have two ways
You can parse json first and create the table structure for name,url and other fields then run the query
Or store the whole json in Db without parsing .By using GSON or other json parsers this approch will be quite helpful.
I saw you are using Volley. Volley has built-in HTTP Cache mechanism.
So the easiest way is to support HTTP cache headers in your backend. It is very easy and it is transparent to the client side. Volley does the hard work. You can find information here
If you don't have access to the URL you use, you must use internal database to support your application. ContentProvider API is the best way to do that. And the following library is a great library to construct a database and write to it.
https://github.com/TimotheeJeannin/ProviGen
Basically you need to write every item that you pull from the internet to the database and the ListView should show the items from the database using ContentProvider you have just created. When the user opens the app, show the data from the database and then immediately try to pull the new data from your backend.
below is the code of a sign up form, when we CLICK second time to submit the entered details, the application collapses and hags just displaying the dialog_thread....On executing very first time it rum perfectly..............The code of dialog_thread is given after onClick()....Please help me, how to get rid of this problem and let the application run smoothly.....
PLZ HELP ME FAST...
public void onClick(View arg0)
{
// TODO Auto-generated method stub
alert_dialog ad=new alert_dialog();
try
{
if(arg0==signup)
{
if(password.getText().toString().equals(confirm_password.getText().toString()))
{
//**** Start loading dialog thread
dt=new dialog_thread(this);
Log.i("dialog thread","Object created");
dt.start();
Log.i("dialog thread","thread started");
String message=null;
Integer success=null;
//************ Encrypt the password
String encrypt_password=new md5(password.getText().toString()).getEncryped();
//************* create name value pair
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("username",username.getText().toString()));
nameValuePairs.add(new BasicNameValuePair("password",encrypt_password));
nameValuePairs.add(new BasicNameValuePair("email",email.getText().toString()));
nameValuePairs.add(new BasicNameValuePair("func","signup"));
nameValuePairs.add(new BasicNameValuePair("user_type",s.getSelectedItem().toString()));
DBConnect db=new DBConnect();
String result=db.fetch_data(nameValuePairs);
//******** Toast.makeText(this, result, Toast.LENGTH_LONG).show();
//************* Parse JSONArray returned
JSONArray jArray = new JSONArray(result);
for(int i=0;i<jArray.length();i++)
{
JSONObject json_data = jArray.getJSONObject(i);
success=json_data.getInt("success");
message=json_data.getString("message");
}
//************ Stop loading dialog thread
dt.stop_execution();
if(success==1)
Toast.makeText(this,"You have sucessfully signed up", Toast.LENGTH_LONG).show();
else
{
ad.alertbox(this, "", message);
}
}
else
ad.alertbox(this, "", "Error : Please enter the same password");
}
}catch(Exception e)
{
Log.i("Exception in signup",e.toString());
}
}
}
(THIS CODE IS IN A DIFFERENT FILE)
class dialog_thread extends Thread
{
ProgressDialog pd;
Context c;
String title="Working ...";
String msg="Please Wait ...";
dialog_thread(Context cont)
{
c=cont;
}
dialog_thread(Context cont,String title,String msg)
{
c=cont;
this.title=title;
this.msg=msg;
}
public void run()
{
// TODO Auto-generated method stub
try
{
Looper.prepare();
pd = ProgressDialog.show(c, this.title, this.msg, true, false);
Handler handler = new Handler()
{
public void handleMessage(Message msg)
{
//pd.dismiss();
Log.i("Handler","Inside handler");
Log.i("dissmissing thread",msg.toString());
}
};
handler.sendEmptyMessage(0);
Log.i("TRy block","Executed");
Looper.loop();
}
catch(Exception e)
{
Log.i("Exception in dialog thread",e.toString());
}
//************************ Run ends here
}
public void stop_execution()
{
pd.dismiss();
this.stop();
}
//**************** Class ends here
}
In Java you cant restart a thread. In your onClick recreate the thread. Simply calling its constructor again will work. It works the first time because the thread hasn't been stopped yet. After the first edit when you return from handling the action the thread is stopped and so the second time around it crashes because you are trying to restart a stopped thread.
Hope that helps.