From 91c5d2ba0060451adc417f2e5ad9d90c7c7a42a2 Mon Sep 17 00:00:00 2001 From: drizea Date: Thu, 12 Jul 2012 15:39:45 +0300 Subject: [PATCH] added splash screen + make each method throw conenction exceptions The splash screen is not finished, it must be included in the application logic Each method that conencts to EG server now throws NoNetworkAvailableException, NoServerAvailalbeException and if necessary, SessionNotFoundException --- Open-ILS/src/Android/AndroidManifest.xml | 15 ++- .../src/Android/res/drawable/background_splash.xml | 9 ++ .../src/Android/res/drawable/evergreen_logo.png | Bin 0 -> 4657 bytes Open-ILS/src/Android/res/drawable/main_logo.png | Bin 0 -> 36363 bytes .../src/Android/res/layout/activity_splash.xml | 38 +++++++ .../android/accountAccess/AccountAccess.java | 123 ++++++++++++--------- .../accountAccess/SessionNotFoundException.java | 2 +- .../checkout/ItemsCheckOutListView.java | 78 ++++++++++--- .../android/accountAccess/fines/FinesActivity.java | 36 +++++- .../android/accountAccess/holds/HoldDetails.java | 62 +++++++++-- .../android/accountAccess/holds/HoldsListView.java | 20 +++- .../android/accountAccess/holds/PlaceHold.java | 29 ++++- .../evergreen/android/globals/GlobalConfigs.java | 33 ++++-- ...essToHttpAddress.java => NoAccessToServer.java} | 2 +- .../globals/ShowNetworkNotAvailableRunnable.java | 33 ++++++ .../globals/ShowServerNotAvailableRunnable.java | 34 ++++++ .../src/org/evergreen/android/globals/Utils.java | 81 +++++++++++--- .../android/searchCatalog/SearchCatalog.java | 90 +++++---------- .../searchCatalog/SearchCatalogListView.java | 50 +++++++-- .../evergreen/android/searchCatalog/TabsView.java | 18 ++- .../android/views/ApplicationPreferences.java | 57 +++++----- .../android/views/splashscreen/LoadingTask.java | 70 ++++++++++++ .../android/views/splashscreen/SplashActivity.java | 42 +++++++ 23 files changed, 704 insertions(+), 218 deletions(-) create mode 100644 Open-ILS/src/Android/res/drawable/background_splash.xml create mode 100644 Open-ILS/src/Android/res/drawable/evergreen_logo.png create mode 100644 Open-ILS/src/Android/res/drawable/main_logo.png create mode 100644 Open-ILS/src/Android/res/layout/activity_splash.xml rename Open-ILS/src/Android/src/org/evergreen/android/globals/{NoAccessToHttpAddress.java => NoAccessToServer.java} (66%) create mode 100644 Open-ILS/src/Android/src/org/evergreen/android/globals/ShowNetworkNotAvailableRunnable.java create mode 100644 Open-ILS/src/Android/src/org/evergreen/android/globals/ShowServerNotAvailableRunnable.java create mode 100644 Open-ILS/src/Android/src/org/evergreen/android/views/splashscreen/LoadingTask.java create mode 100644 Open-ILS/src/Android/src/org/evergreen/android/views/splashscreen/SplashActivity.java diff --git a/Open-ILS/src/Android/AndroidManifest.xml b/Open-ILS/src/Android/AndroidManifest.xml index a22d27079a..357b319462 100644 --- a/Open-ILS/src/Android/AndroidManifest.xml +++ b/Open-ILS/src/Android/AndroidManifest.xml @@ -14,14 +14,21 @@ > - + > + - + + + + + + + + + \ No newline at end of file diff --git a/Open-ILS/src/Android/res/drawable/evergreen_logo.png b/Open-ILS/src/Android/res/drawable/evergreen_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3448dba9ccbd0ebf8e866ab502cda08fca1b9ccd GIT binary patch literal 4657 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 O0000 + + + + + + + + + + + \ No newline at end of file diff --git a/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/AccountAccess.java b/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/AccountAccess.java index bfcf2ce8a8..1608ae1f36 100644 --- a/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/AccountAccess.java +++ b/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/AccountAccess.java @@ -11,6 +11,8 @@ import java.util.Map; import org.evergreen.android.accountAccess.checkout.CircRecord; import org.evergreen.android.accountAccess.fines.FinesRecord; import org.evergreen.android.accountAccess.holds.HoldRecord; +import org.evergreen.android.globals.NoAccessToServer; +import org.evergreen.android.globals.NoNetworkAccessException; import org.evergreen.android.globals.Utils; import org.evergreen.android.searchCatalog.RecordInfo; import org.opensrf.Method; @@ -19,6 +21,8 @@ import org.opensrf.net.http.HttpConnection; import org.opensrf.net.http.HttpRequest; import org.opensrf.util.OSRFObject; +import android.net.ConnectivityManager; + /** * The Class AuthenticateUser. * Singleton class @@ -226,6 +230,8 @@ public class AccountAccess { * */ public String authToken = null; + private ConnectivityManager cm; + /** The auth time. */ private Integer authTime = null; @@ -243,10 +249,11 @@ public class AccountAccess { * * @param httpAddress the http address */ - private AccountAccess(String httpAddress) { + private AccountAccess(String httpAddress, ConnectivityManager cm) { this.httpAddress = httpAddress; - + this.cm = cm; + try { // configure the connection @@ -268,10 +275,10 @@ public class AccountAccess { return false; } - public static AccountAccess getAccountAccess(String httpAddress){ + public static AccountAccess getAccountAccess(String httpAddress, ConnectivityManager cm){ if(accountAccess == null){ - accountAccess = new AccountAccess(httpAddress); + accountAccess = new AccountAccess(httpAddress,cm); } System.out.println(" Addresses " + httpAddress + " " + accountAccess.httpAddress); if(!httpAddress.equals(accountAccess.httpAddress)) @@ -347,7 +354,7 @@ public class AccountAccess { /** * Authenticate. */ - public boolean authenticate(){ + public boolean authenticate() throws NoNetworkAccessException, NoAccessToServer{ String seed = authenticateInit(); @@ -383,12 +390,12 @@ public class AccountAccess { * Authenticate init. * @return seed for phase 2 of login */ - private String authenticateInit() { + private String authenticateInit() throws NoAccessToServer,NoNetworkAccessException{ String seed = null; System.out.println("Send request to " + httpAddress); - Object resp = (Object) Utils.doRequest(conn, SERVICE_AUTH, METHOD_AUTH_INIT, new Object[]{userName}); + Object resp = (Object) Utils.doRequest(conn, SERVICE_AUTH, METHOD_AUTH_INIT, cm,new Object[]{userName}); if(resp != null) seed = resp.toString(); @@ -405,7 +412,7 @@ public class AccountAccess { * @param seed the seed * @returns bollean if auth was ok */ - private boolean authenticateComplete(String seed) { + private boolean authenticateComplete(String seed) throws NoAccessToServer, NoNetworkAccessException { //calculate hash to pass to server for authentication process phase 2 //seed = "b18a9063e0c6f49dfe7a854cc6ab5775"; @@ -422,7 +429,7 @@ public class AccountAccess { System.out.println("Password " + password); System.out.println("Compelx param " + complexParam); - Object resp = Utils.doRequest(conn, SERVICE_AUTH, METHOD_AUTH_COMPLETE, new Object[]{complexParam}); + Object resp = Utils.doRequest(conn, SERVICE_AUTH, METHOD_AUTH_COMPLETE, cm, new Object[]{complexParam}); if(resp == null) return false; @@ -453,7 +460,7 @@ public class AccountAccess { //------------------------Checked Out Items Section -------------------------// - public ArrayList getItemsCheckedOut(){ + public ArrayList getItemsCheckedOut() throws SessionNotFoundException, NoNetworkAccessException, NoAccessToServer{ ArrayList circRecords = new ArrayList(); @@ -473,7 +480,7 @@ public class AccountAccess { List out_id; - Object resp = Utils.doRequest(conn, SERVICE_ACTOR, METHOD_FETCH_CHECKED_OUT_SUM, new Object[]{authToken, userID}); + Object resp = Utils.doRequest(conn, SERVICE_ACTOR, METHOD_FETCH_CHECKED_OUT_SUM, authToken, cm, new Object[]{authToken, userID}); long_overdue_id = (List)((Map)resp).get("long_overdue"); claims_returned_id = (List)((Map)resp).get("claims_returned"); @@ -527,9 +534,9 @@ public class AccountAccess { * @param : target_copy from circ * @returns : "circ" OSRFObject */ - private OSRFObject retrieveCircRecord(String id){ + private OSRFObject retrieveCircRecord(String id) throws SessionNotFoundException, NoNetworkAccessException, NoAccessToServer{ - OSRFObject circ = (OSRFObject) Utils.doRequest(conn, SERVICE_CIRC, METHOD_FETCH_CIRC_BY_ID, new Object[]{authToken,id}); + OSRFObject circ = (OSRFObject) Utils.doRequest(conn, SERVICE_CIRC, METHOD_FETCH_CIRC_BY_ID, authToken, cm, new Object[]{authToken,id}); return circ; } @@ -539,7 +546,7 @@ public class AccountAccess { * Usefull info : title and author * (for acp : dummy_title, dummy_author) */ - private OSRFObject fetchInfoForCheckedOutItem(Integer target_copy, CircRecord circRecord){ + private OSRFObject fetchInfoForCheckedOutItem(Integer target_copy, CircRecord circRecord) throws NoNetworkAccessException, NoAccessToServer{ if(target_copy == null) return null; @@ -566,17 +573,17 @@ public class AccountAccess { return result; } - private OSRFObject fetchModsFromCopy(Integer target_copy){ + private OSRFObject fetchModsFromCopy(Integer target_copy) throws NoNetworkAccessException, NoAccessToServer{ //sync request - OSRFObject mvr = (OSRFObject) Utils.doRequest(conn, SERVICE_SEARCH, METHOD_FETCH_MODS_FROM_COPY, new Object[]{target_copy}); + OSRFObject mvr = (OSRFObject) Utils.doRequest(conn, SERVICE_SEARCH, METHOD_FETCH_MODS_FROM_COPY, cm, new Object[]{target_copy}); return mvr; } - private OSRFObject fetchAssetCopy(Integer target_copy){ + private OSRFObject fetchAssetCopy(Integer target_copy) throws NoNetworkAccessException, NoAccessToServer{ - OSRFObject acp = (OSRFObject) Utils.doRequest(conn, SERVICE_SEARCH, METHOD_FETCH_COPY, new Object[]{target_copy}); + OSRFObject acp = (OSRFObject) Utils.doRequest(conn, SERVICE_SEARCH, METHOD_FETCH_COPY, cm, new Object[]{target_copy}); return acp; } @@ -586,14 +593,14 @@ public class AccountAccess { /* Method used to renew a circulation record based on target_copy_id * Returns many objects, don't think they are needed */ - public void renewCirc(Integer target_copy) throws MaxRenewalsException{ + public void renewCirc(Integer target_copy) throws MaxRenewalsException, SessionNotFoundException, NoNetworkAccessException, NoAccessToServer{ HashMap complexParam = new HashMap(); complexParam.put("patron", this.userID); complexParam.put("copyid", target_copy); complexParam.put("opac_renewal", 1); - Object a_lot = (Object) Utils.doRequest(conn, SERVICE_CIRC, METHOD_RENEW_CIRC, new Object[]{authToken,complexParam}); + Object a_lot = (Object) Utils.doRequest(conn, SERVICE_CIRC, METHOD_RENEW_CIRC, authToken, cm, new Object[]{authToken,complexParam}); Map resp = (Map)a_lot; @@ -607,16 +614,16 @@ public class AccountAccess { //------------------------Holds Section --------------------------------------// - public Object fetchOrgSettings(Integer org_id, String setting){ + public Object fetchOrgSettings(Integer org_id, String setting)throws SessionNotFoundException, NoNetworkAccessException, NoAccessToServer{ - OSRFObject response = (OSRFObject) Utils.doRequest(conn, SERVICE_ACTOR, METHOD_FETCH_ORG_SETTINGS, new Object[]{org_id,setting}); + OSRFObject response = (OSRFObject) Utils.doRequest(conn, SERVICE_ACTOR, METHOD_FETCH_ORG_SETTINGS, cm, new Object[]{org_id,setting}); return response; } - public List getHolds(){ + public List getHolds() throws SessionNotFoundException, NoNetworkAccessException, NoAccessToServer{ ArrayList holds = new ArrayList(); @@ -624,7 +631,7 @@ public class AccountAccess { //fields of interest : expire_time List listHoldsAhr = null; - listHoldsAhr = (List) Utils.doRequest(conn, SERVICE_CIRC, METHOD_FETCH_HOLDS, new Object[]{authToken,userID}); + listHoldsAhr = (List) Utils.doRequest(conn, SERVICE_CIRC, METHOD_FETCH_HOLDS, authToken, cm, new Object[]{authToken,userID}); for(int i=0;i part = (List)Utils.doRequest(conn,SERVICE_FIELDER,"open-ils.fielder.bmp.atomic",new Object[]{param}); + List part = (List)Utils.doRequest(conn,SERVICE_FIELDER,"open-ils.fielder.bmp.atomic", cm, new Object[]{param}); Map partObj =(Map)part.get(0); Integer recordID = (Integer)partObj.get("record"); String part_label = (String)partObj.get("label"); - OSRFObject holdInfo = (OSRFObject)Utils.doRequest(conn,SERVICE_SEARCH, METHOD_FETCH_RMODS, new Object[]{recordID}); + OSRFObject holdInfo = (OSRFObject)Utils.doRequest(conn,SERVICE_SEARCH, METHOD_FETCH_RMODS, cm, new Object[]{recordID}); holdObj.part_label = part_label; holdObj.title = holdInfo.getString("title"); @@ -785,11 +792,11 @@ public class AccountAccess { } - public Object fetchHoldStatus(OSRFObject hold, HoldRecord holdObj){ + public Object fetchHoldStatus(OSRFObject hold, HoldRecord holdObj) throws SessionNotFoundException, NoNetworkAccessException, NoAccessToServer{ Integer hold_id = hold.getInt("id"); // MAP : potential_copies, status, total_holds, queue_position, estimated_wait - Object hold_status = Utils.doRequest(conn,SERVICE_CIRC, METHOD_FETCH_HOLD_STATUS, new Object[]{authToken,hold_id}); + Object hold_status = Utils.doRequest(conn,SERVICE_CIRC, METHOD_FETCH_HOLD_STATUS, authToken, cm, new Object[]{authToken,hold_id}); //get status holdObj.status = ((Map)hold_status).get("status"); @@ -798,11 +805,11 @@ public class AccountAccess { } - public boolean cancelHold(OSRFObject hold){ + public boolean cancelHold(OSRFObject hold) throws SessionNotFoundException, NoNetworkAccessException, NoAccessToServer{ Integer hold_id = hold.getInt("id"); - Object response = Utils.doRequest(conn,SERVICE_CIRC, METHOD_CANCEL_HOLD, new Object[]{authToken,hold_id}); + Object response = Utils.doRequest(conn,SERVICE_CIRC, METHOD_CANCEL_HOLD, authToken, cm, new Object[]{authToken,hold_id}); //delete successful if(response.toString().equals("1")) @@ -812,7 +819,8 @@ public class AccountAccess { } - public Object updateHold(OSRFObject ahr,Integer pickup_lib, boolean email_notify, boolean phone_notify, String phone, boolean suspendHold, String expire_time,String thaw_date){ + public Object updateHold(OSRFObject ahr,Integer pickup_lib, boolean email_notify, boolean phone_notify, String phone, boolean suspendHold, String expire_time,String thaw_date) + throws SessionNotFoundException, NoNetworkAccessException, NoAccessToServer{ //TODO verify that object is correct passed to the server ahr.put("pickup_lib", pickup_lib); //pick-up lib @@ -824,12 +832,13 @@ public class AccountAccess { //only if it is frozen ahr.put("thaw_date",thaw_date); - Object response = Utils.doRequest(conn,SERVICE_CIRC, METHOD_UPDATE_HOLD, new Object[]{authToken,ahr}); + Object response = Utils.doRequest(conn,SERVICE_CIRC, METHOD_UPDATE_HOLD, authToken, cm, new Object[]{authToken,ahr}); return response; } - public String[] createHold(Integer recordID, Integer pickup_lib, boolean email_notify, boolean phone_notify, String phone, boolean suspendHold, String expire_time,String thaw_date){ + public String[] createHold(Integer recordID, Integer pickup_lib, boolean email_notify, boolean phone_notify, String phone, boolean suspendHold, String expire_time,String thaw_date) + throws SessionNotFoundException, NoNetworkAccessException, NoAccessToServer{ OSRFObject ahr = new OSRFObject("ahr"); ahr.put("target", recordID); @@ -851,7 +860,7 @@ public class AccountAccess { //extra parameters (not mandatory for hold creation) - Object response = Utils.doRequest(conn,SERVICE_CIRC, METHOD_CREATE_HOLD, new Object[]{authToken,ahr}); + Object response = Utils.doRequest(conn,SERVICE_CIRC, METHOD_CREATE_HOLD, authToken, cm, new Object[]{authToken,ahr}); String[] resp = new String[3]; //if we can get hold ID then we return true @@ -879,7 +888,8 @@ public class AccountAccess { return resp; } // ?? return boolean - public Object isHoldPossible(Integer pickup_lib,Integer recordID){ + public Object isHoldPossible(Integer pickup_lib,Integer recordID) + throws SessionNotFoundException, NoNetworkAccessException, NoAccessToServer{ HashMap mapAsk = getHoldPreCreateInfo(recordID, pickup_lib); @@ -896,12 +906,13 @@ public class AccountAccess { //"patronid":2,"depth":0,"pickup_lib":"8","partid":null} - Object response = Utils.doRequest(conn,SERVICE_CIRC, METHOD_VERIFY_HOLD_POSSIBLE, new Object[]{authToken,mapAsk}); + Object response = Utils.doRequest(conn,SERVICE_CIRC, METHOD_VERIFY_HOLD_POSSIBLE, authToken, cm, new Object[]{authToken,mapAsk}); return response; } //return - public HashMap getHoldPreCreateInfo(Integer recordID, Integer pickup_lib){ + public HashMap getHoldPreCreateInfo(Integer recordID, Integer pickup_lib) + throws NoNetworkAccessException, NoAccessToServer{ HashMap param = new HashMap(); @@ -909,7 +920,7 @@ public class AccountAccess { param.put("pickup_lib",pickup_lib); param.put("record", recordID); - Map response = (Map)Utils.doRequest(conn, SERVICE_SEARCH, "open-ils.search.metabib.record_to_descriptors", new Object[]{param}); + Map response = (Map)Utils.doRequest(conn, SERVICE_SEARCH, "open-ils.search.metabib.record_to_descriptors", cm, new Object[]{param}); Object obj = response.get("metarecord"); System.out.println(obj); @@ -930,10 +941,11 @@ public class AccountAccess { //----------------------------Fines Summary------------------------------------// - public float[] getFinesSummary(){ + public float[] getFinesSummary() + throws SessionNotFoundException, NoNetworkAccessException, NoAccessToServer{ //mous object - OSRFObject finesSummary = (OSRFObject) Utils.doRequest(conn,SERVICE_ACTOR, METHOD_FETCH_FINES_SUMMARY, new Object[]{authToken,userID}); + OSRFObject finesSummary = (OSRFObject) Utils.doRequest(conn,SERVICE_ACTOR, METHOD_FETCH_FINES_SUMMARY, authToken, cm, new Object[]{authToken,userID}); float fines[] = new float[3]; try{ @@ -947,11 +959,12 @@ public class AccountAccess { return fines; } - public ArrayList getTransactions(){ + public ArrayList getTransactions() + throws SessionNotFoundException, NoNetworkAccessException, NoAccessToServer{ ArrayList finesRecords = new ArrayList(); - Object transactions = Utils.doRequest(conn,SERVICE_ACTOR, METHOD_FETCH_TRANSACTIONS, new Object[]{authToken,userID}); + Object transactions = Utils.doRequest(conn,SERVICE_ACTOR, METHOD_FETCH_TRANSACTIONS, authToken, cm, new Object[]{authToken,userID}); //get Array @@ -971,9 +984,10 @@ public class AccountAccess { //---------------------------------------Book bags-----------------------------------// - public Object getBookbags(){ + public Object getBookbags() + throws SessionNotFoundException, NoNetworkAccessException, NoAccessToServer{ - Object response = Utils.doRequest(conn,SERVICE_ACTOR, METHOD_FLESH_CONTAINERS, new Object[]{authToken,userID,"biblio","bookbag"}); + Object response = Utils.doRequest(conn,SERVICE_ACTOR, METHOD_FLESH_CONTAINERS, authToken, cm, new Object[]{authToken,userID,"biblio","bookbag"}); List bookbags = (List)response; @@ -986,9 +1000,10 @@ public class AccountAccess { return bookbags; } - private Object getBookbagContent(Integer bookbagID){ + private Object getBookbagContent(Integer bookbagID) + throws SessionNotFoundException, NoNetworkAccessException, NoAccessToServer{ - return Utils.doRequest(conn,SERVICE_ACTOR, METHOD_FLESH_PUBLIC_CONTAINER, new Object[]{authToken,"biblio",bookbagID}); + return Utils.doRequest(conn,SERVICE_ACTOR, METHOD_FLESH_PUBLIC_CONTAINER, authToken, cm, new Object[]{authToken,"biblio",bookbagID}); } } diff --git a/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/SessionNotFoundException.java b/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/SessionNotFoundException.java index 9329373a32..ee4afa96db 100644 --- a/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/SessionNotFoundException.java +++ b/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/SessionNotFoundException.java @@ -5,6 +5,6 @@ public class SessionNotFoundException extends Exception{ /** * */ - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 123232L; } diff --git a/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/checkout/ItemsCheckOutListView.java b/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/checkout/ItemsCheckOutListView.java index 390fdb25da..0e740c1da4 100644 --- a/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/checkout/ItemsCheckOutListView.java +++ b/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/checkout/ItemsCheckOutListView.java @@ -6,6 +6,10 @@ import java.util.List; import org.evergreen.android.R; import org.evergreen.android.accountAccess.AccountAccess; import org.evergreen.android.accountAccess.MaxRenewalsException; +import org.evergreen.android.accountAccess.SessionNotFoundException; +import org.evergreen.android.globals.NoAccessToServer; +import org.evergreen.android.globals.NoNetworkAccessException; +import org.evergreen.android.globals.Utils; import android.app.Activity; import android.app.ProgressDialog; @@ -56,7 +60,23 @@ public class ItemsCheckOutListView extends Activity{ @Override public void run() { - circRecords = accountAccess.getItemsCheckedOut(); + + try { + circRecords = accountAccess.getItemsCheckedOut(); + } catch (NoNetworkAccessException e) { + Utils.showNetworkNotAvailableDialog(context); + } catch (NoAccessToServer e) { + Utils.showServerNotAvailableDialog(context); + + }catch (SessionNotFoundException e) { + //TODO other way? + try{ + if(accountAccess.authenticate()) + circRecords = accountAccess.getItemsCheckedOut(); + }catch(Exception eauth){ + System.out.println("Exception in reAuth"); + } + } runOnUiThread(new Runnable() { @@ -183,22 +203,52 @@ public class ItemsCheckOutListView extends Activity{ } }); - try{ - ac.renewCirc(record.getTargetCopy()); - }catch(MaxRenewalsException e){ - runOnUiThread(new Runnable() { + + try { + ac.renewCirc(record.getTargetCopy()); + } catch (MaxRenewalsException e1) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + progressDialog.dismiss(); + Toast.makeText(context, "Max renewals reached", Toast.LENGTH_SHORT).show(); + } + }); - @Override - public void run() { - progressDialog.dismiss(); - Toast.makeText(context, "Max renewals reached", Toast.LENGTH_SHORT).show(); + refresh = false; + } catch (SessionNotFoundException e1) { + try{ + if(accountAccess.authenticate()) + ac.renewCirc(record.getTargetCopy()); + }catch(Exception eauth){ + System.out.println("Exception in reAuth"); } - }); - - refresh = false; - } + } catch (NoNetworkAccessException e1) { + Utils.showNetworkNotAvailableDialog(context); + } catch (NoAccessToServer e1) { + Utils.showServerNotAvailableDialog(context); + } + if(refresh){ - circRecords = accountAccess.getItemsCheckedOut(); + + try { + circRecords = accountAccess.getItemsCheckedOut(); + } catch (NoNetworkAccessException e) { + Utils.showNetworkNotAvailableDialog(context); + } catch (NoAccessToServer e) { + Utils.showServerNotAvailableDialog(context); + + }catch (SessionNotFoundException e) { + //TODO other way? + try{ + if(accountAccess.authenticate()) + circRecords = accountAccess.getItemsCheckedOut(); + }catch(Exception eauth){ + System.out.println("Exception in reAuth"); + } + } + listAdapter.clear(); for(int i=0;i finesRecords = ac.getTransactions(); + ArrayList frecords = null; + try { + frecords = ac.getTransactions(); + } catch (SessionNotFoundException e) { + + try{ + if(ac.authenticate()) + frecords = ac.getTransactions(); + }catch(Exception e1){} + + } catch (NoNetworkAccessException e) { + Utils.showNetworkNotAvailableDialog(context); + } catch (NoAccessToServer e) { + Utils.showServerNotAvailableDialog(context); + } + final ArrayList finesRecords = frecords; + final float[] fines = finesR; runOnUiThread(new Runnable() { @Override public void run() { diff --git a/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/holds/HoldDetails.java b/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/holds/HoldDetails.java index 56c932ca68..d9422aa3e9 100644 --- a/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/holds/HoldDetails.java +++ b/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/holds/HoldDetails.java @@ -6,7 +6,11 @@ import java.util.Date; import org.evergreen.android.R; import org.evergreen.android.accountAccess.AccountAccess; +import org.evergreen.android.accountAccess.SessionNotFoundException; import org.evergreen.android.globals.GlobalConfigs; +import org.evergreen.android.globals.NoAccessToServer; +import org.evergreen.android.globals.NoNetworkAccessException; +import org.evergreen.android.globals.Utils; import android.app.Activity; import android.app.AlertDialog; @@ -195,8 +199,28 @@ public class HoldDetails extends Activity { @Override public void run() { - accountAccess.cancelHold(record.ahr); - + + try { + accountAccess.cancelHold(record.ahr); + } catch (NoNetworkAccessException e) { + Utils.showNetworkNotAvailableDialog(context); + } catch (NoAccessToServer e) { + Utils.showServerNotAvailableDialog(context); + + }catch (SessionNotFoundException e) { + //TODO other way? + try{ + if(accountAccess.authenticate()) + accountAccess.cancelHold(record.ahr); + }catch(Exception eauth){ + System.out.println("Exception in reAuth"); + } + } + + + + + runOnUiThread(new Runnable() { @Override public void run() { @@ -228,11 +252,35 @@ public class HoldDetails extends Activity { if (thaw_date != null) thaw_date_s = GlobalConfigs.getStringDate(thaw_date); - accountAccess.updateHold(record.ahr, selectedOrgPos, - email_notification.isChecked(), phone_notification - .isChecked(), - phone_number.getText().toString(), suspendHold - .isChecked(), expire_date_s, thaw_date_s); + + + try { + accountAccess.updateHold(record.ahr, selectedOrgPos, + email_notification.isChecked(), phone_notification + .isChecked(), + phone_number.getText().toString(), suspendHold + .isChecked(), expire_date_s, thaw_date_s); + } catch (NoNetworkAccessException e) { + Utils.showNetworkNotAvailableDialog(context); + } catch (NoAccessToServer e) { + Utils.showServerNotAvailableDialog(context); + + }catch (SessionNotFoundException e) { + //TODO other way? + try{ + if(accountAccess.authenticate()) + accountAccess.updateHold(record.ahr, selectedOrgPos, + email_notification.isChecked(), phone_notification + .isChecked(), + phone_number.getText().toString(), suspendHold + .isChecked(), expire_date_s, thaw_date_s); + }catch(Exception eauth){ + System.out.println("Exception in reAuth"); + } + } + + + runOnUiThread(new Runnable() { @Override diff --git a/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/holds/HoldsListView.java b/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/holds/HoldsListView.java index eb55fba50c..bc64a57097 100644 --- a/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/holds/HoldsListView.java +++ b/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/holds/HoldsListView.java @@ -5,6 +5,10 @@ import java.util.List; import org.evergreen.android.R; import org.evergreen.android.accountAccess.AccountAccess; +import org.evergreen.android.accountAccess.SessionNotFoundException; +import org.evergreen.android.globals.NoAccessToServer; +import org.evergreen.android.globals.NoNetworkAccessException; +import org.evergreen.android.globals.Utils; import android.app.Activity; import android.app.ProgressDialog; @@ -58,7 +62,21 @@ public class HoldsListView extends Activity{ @Override public void run() { - holdRecords = accountAccess.getHolds(); + try { + holdRecords = accountAccess.getHolds(); + } catch (SessionNotFoundException e) { + //TODO other way? + try{ + if(accountAccess.authenticate()) + holdRecords = accountAccess.getHolds(); + }catch(Exception eauth){ + System.out.println("Exception in reAuth"); + } + } catch (NoNetworkAccessException e) { + Utils.showNetworkNotAvailableDialog(context); + } catch (NoAccessToServer e) { + Utils.showServerNotAvailableDialog(context); + } runOnUiThread(new Runnable() { @Override diff --git a/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/holds/PlaceHold.java b/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/holds/PlaceHold.java index ecd366eb10..d5c762b6a2 100644 --- a/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/holds/PlaceHold.java +++ b/Open-ILS/src/Android/src/org/evergreen/android/accountAccess/holds/PlaceHold.java @@ -6,7 +6,11 @@ import java.util.Date; import org.evergreen.android.R; import org.evergreen.android.accountAccess.AccountAccess; +import org.evergreen.android.accountAccess.SessionNotFoundException; import org.evergreen.android.globals.GlobalConfigs; +import org.evergreen.android.globals.NoAccessToServer; +import org.evergreen.android.globals.NoNetworkAccessException; +import org.evergreen.android.globals.Utils; import org.evergreen.android.searchCatalog.RecordInfo; import android.app.Activity; @@ -138,9 +142,10 @@ public class PlaceHold extends Activity{ progressDialog = ProgressDialog.show(context, "Please wait", "Placing hold"); } }); + //TODO verify hold possible - accountAccess.getHoldPreCreateInfo(record_id, 4); - accountAccess.isHoldPossible(4, record_id); + //accountAccess.getHoldPreCreateInfo(record_id, 4); + //accountAccess.isHoldPossible(4, record_id); String expire_date_s = null; @@ -155,8 +160,26 @@ public class PlaceHold extends Activity{ if(globalConfigs.organisations.size() > selectedOrgPos) selectedOrgID = globalConfigs.organisations.get(selectedOrgPos).id; - final String[] holdPlaced = accountAccess.createHold(record_id,selectedOrgID,email_notification.isChecked(),phone_notification.isChecked(),phone_number.getText().toString(),suspendHold.isChecked(),expire_date_s,thaw_date_s); + + + String[] stringResponse = new String[]{"false"}; + try { + stringResponse = accountAccess.createHold(record_id,selectedOrgID,email_notification.isChecked(),phone_notification.isChecked(),phone_number.getText().toString(),suspendHold.isChecked(),expire_date_s,thaw_date_s); + } catch (SessionNotFoundException e) { + + try{ + if(accountAccess.authenticate()) + stringResponse = accountAccess.createHold(record_id,selectedOrgID,email_notification.isChecked(),phone_notification.isChecked(),phone_number.getText().toString(),suspendHold.isChecked(),expire_date_s,thaw_date_s); + }catch(Exception e1){} + + } catch (NoNetworkAccessException e) { + Utils.showNetworkNotAvailableDialog(context); + } catch (NoAccessToServer e) { + Utils.showServerNotAvailableDialog(context); + } + final String[] holdPlaced = stringResponse; + runOnUiThread(new Runnable() { @Override public void run() { diff --git a/Open-ILS/src/Android/src/org/evergreen/android/globals/GlobalConfigs.java b/Open-ILS/src/Android/src/org/evergreen/android/globals/GlobalConfigs.java index a681d895ef..33a2808582 100644 --- a/Open-ILS/src/Android/src/org/evergreen/android/globals/GlobalConfigs.java +++ b/Open-ILS/src/Android/src/org/evergreen/android/globals/GlobalConfigs.java @@ -8,6 +8,7 @@ import java.util.Date; import java.util.StringTokenizer; import org.evergreen.android.accountAccess.AccountAccess; +import org.evergreen.android.accountAccess.SessionNotFoundException; import org.evergreen.android.searchCatalog.Organisation; import org.evergreen.android.views.ApplicationPreferences; import org.open_ils.idl.IDLParser; @@ -73,11 +74,11 @@ public class GlobalConfigs { boolean noNetworkAccess = false; System.out.println("Check for network conenctivity"); try{ - Utils.checkNetworkStatus((ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE), context); + Utils.checkNetworkStatus((ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE)); }catch(NoNetworkAccessException e){ noNetworkAccess = true; - }catch(NoAccessToHttpAddress e){ + }catch(NoAccessToServer e){ System.out.println("No access to network"); Intent preferencesAnctivity = new Intent(context, ApplicationPreferences.class); @@ -94,8 +95,10 @@ public class GlobalConfigs { //authenticate - AccountAccess ac = AccountAccess.getAccountAccess(GlobalConfigs.httpAddress); - ac.authenticate(); + AccountAccess ac = AccountAccess.getAccountAccess(GlobalConfigs.httpAddress,(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE)); + try{ + ac.authenticate(); + }catch(Exception e){} //TODO getorg hidding levels //getOrgHiddentDepth(); @@ -130,14 +133,16 @@ public class GlobalConfigs { public void getOrganisations(){ String orgFile = null; + + + organisations = new ArrayList(); + try{ //using https: address orgFile = Utils.getNetPageContent(httpAddress+collectionsRequest); System.out.println("Request org " + httpAddress + collectionsRequest ); }catch(Exception e){}; - - organisations = new ArrayList(); - + if(orgFile != null){ organisations = new ArrayList(); @@ -274,12 +279,16 @@ public class GlobalConfigs { for(int i=0; i getSearchResults(String searchWords, Integer offset){ + public ArrayList getSearchResults(String searchWords, Integer offset) throws NoNetworkAccessException, NoAccessToServer{ ArrayList resultsRecordInfo = new ArrayList(); @@ -139,45 +145,26 @@ public class SearchCatalog { { System.out.println("Exception in JSON " + e.getMessage()); } + - System.out.println("JSON argument " + complexParm); - method.addParam(complexParm); - method.addParam(searchWords); - method.addParam(1); - - - // sync test - HttpRequest req = new GatewayRequest(conn, SERVICE, method).send(); - Object resp; - - //why in while ? - + Object resp = Utils.doRequest(conn, SERVICE, METHOD_MULTICASS_SEARCH, cm, new Object[]{complexParm,searchWords,1}); + ArrayList ids = new ArrayList(); - - - while ( (resp = req.recv()) != null){ - System.out.println("Sync Response: " + resp); + + System.out.println("Sync Response: " + resp); - Map response = (Map) resp; + Map response = (Map) resp; - System.out.println(" ids : " + response.get("ids") + " " ); + System.out.println(" ids : " + response.get("ids") + " " ); - List> result_ids = (List) response.get("ids"); + List> result_ids = (List) response.get("ids"); - visible =Integer.parseInt((String)response.get("count")); + visible =Integer.parseInt((String)response.get("count")); for(int i=0;i list = (List)Utils.doRequest(conn, SERVICE, METHOD_COPY_LOCATION_COUNTS, new Object[]{recordID, orgID, orgDepth}); + public Object getLocationCount(Integer recordID, Integer orgID, Integer orgDepth) throws NoNetworkAccessException, NoAccessToServer{ + List list = (List)Utils.doRequest(conn, SERVICE, METHOD_COPY_LOCATION_COUNTS, cm, new Object[]{recordID, orgID, orgDepth}); return list; + } /** diff --git a/Open-ILS/src/Android/src/org/evergreen/android/searchCatalog/SearchCatalogListView.java b/Open-ILS/src/Android/src/org/evergreen/android/searchCatalog/SearchCatalogListView.java index 677e9a2425..30aa9964ab 100644 --- a/Open-ILS/src/Android/src/org/evergreen/android/searchCatalog/SearchCatalogListView.java +++ b/Open-ILS/src/Android/src/org/evergreen/android/searchCatalog/SearchCatalogListView.java @@ -6,13 +6,16 @@ import java.util.List; import org.evergreen.android.R; import org.evergreen.android.accountAccess.holds.PlaceHold; import org.evergreen.android.globals.GlobalConfigs; - -import com.google.android.maps.ItemizedOverlay; +import org.evergreen.android.globals.NoAccessToServer; +import org.evergreen.android.globals.NoNetworkAccessException; +import org.evergreen.android.globals.Utils; import android.app.Activity; +import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; +import android.net.ConnectivityManager; import android.os.Bundle; import android.util.Log; import android.view.ContextMenu; @@ -78,7 +81,7 @@ public class SearchCatalogListView extends Activity{ globalConfigs = GlobalConfigs.getGlobalConfigs(this); context = this; - search = SearchCatalog.getInstance(); + search = SearchCatalog.getInstance((ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE)); recordList= new ArrayList(); @@ -111,6 +114,7 @@ public class SearchCatalogListView extends Activity{ // Set the ListView adapter lv.setAdapter(adapter); + searchResults = new ArrayList(); registerForContextMenu(lv); @@ -135,7 +139,16 @@ public class SearchCatalogListView extends Activity{ @Override public void run() { - searchResults = search.getSearchResults(text,recordList.size()-1); + + searchResults.clear(); + + try { + searchResults = search.getSearchResults(text,recordList.size()-1); + } catch (NoNetworkAccessException e) { + Utils.showNetworkNotAvailableDialog(context); + } catch (NoAccessToServer e) { + Utils.showServerNotAvailableDialog(context); + } runOnUiThread(new Runnable() { @@ -202,7 +215,7 @@ public class SearchCatalogListView extends Activity{ progressDialog = new ProgressDialog(context); progressDialog.setMessage("Fetching data"); - progressDialog.show(); + //progressDialog.show(); if(text.length()>0){ @@ -210,14 +223,26 @@ public class SearchCatalogListView extends Activity{ @Override public void run() { - searchResults = search.getSearchResults(text,0); + searchResults.clear(); + + try { + searchResults = search.getSearchResults(text,0); + } catch (NoNetworkAccessException e) { + System.out.println("no network access in search"); + SearchCatalogListView.this.runOnUiThread(Utils.showNetworkNotAvailableDialog(context)); + + } catch (NoAccessToServer e) { + SearchCatalogListView.this.runOnUiThread(Utils.showServerNotAvailableDialog(context)); + } + runOnUiThread(new Runnable() { @Override public void run() { recordList.clear(); + if(searchResults.size()>0){ for(int j=0;j list = new ArrayList(); - for(int i=0;i adapter = new ArrayAdapter(this,android.R.layout.simple_spinner_item,list); choseOrganisation.setAdapter(adapter); diff --git a/Open-ILS/src/Android/src/org/evergreen/android/searchCatalog/TabsView.java b/Open-ILS/src/Android/src/org/evergreen/android/searchCatalog/TabsView.java index f3063ed570..c458dd8317 100644 --- a/Open-ILS/src/Android/src/org/evergreen/android/searchCatalog/TabsView.java +++ b/Open-ILS/src/Android/src/org/evergreen/android/searchCatalog/TabsView.java @@ -1,6 +1,9 @@ package org.evergreen.android.searchCatalog; import org.evergreen.android.R; +import org.evergreen.android.globals.NoAccessToServer; +import org.evergreen.android.globals.NoNetworkAccessException; +import org.evergreen.android.globals.Utils; import org.evergreen.android.utils.ui.AdvancedDetailsFragment; import org.evergreen.android.utils.ui.BaseSampleActivity; import org.evergreen.android.utils.ui.BasicDetailsFragment; @@ -8,6 +11,8 @@ import org.evergreen.android.utils.ui.TabPageIndicator; import org.evergreen.android.utils.ui.TestFragment; import org.evergreen.android.utils.ui.TestFragmentAdapter; +import android.content.Context; +import android.net.ConnectivityManager; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; @@ -32,11 +37,16 @@ public class TabsView extends BaseSampleActivity { mAdapter = new SearchFragmentAdapter(getSupportFragmentManager()); - search = SearchCatalog.getInstance(); - search.getLocationCount(record.doc_id, orgID, orgDepth); - - + search = SearchCatalog.getInstance((ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE)); + try { + search.getLocationCount(record.doc_id, orgID, orgDepth); + } catch (NoNetworkAccessException e) { + Utils.showNetworkNotAvailableDialog(this); + } catch (NoAccessToServer e) { + Utils.showServerNotAvailableDialog(this); + } + //mAdapter.getItem(0). mPager = (ViewPager)findViewById(R.id.pager); diff --git a/Open-ILS/src/Android/src/org/evergreen/android/views/ApplicationPreferences.java b/Open-ILS/src/Android/src/org/evergreen/android/views/ApplicationPreferences.java index e470e05138..9d7fec30de 100644 --- a/Open-ILS/src/Android/src/org/evergreen/android/views/ApplicationPreferences.java +++ b/Open-ILS/src/Android/src/org/evergreen/android/views/ApplicationPreferences.java @@ -3,7 +3,7 @@ package org.evergreen.android.views; import org.evergreen.android.R; import org.evergreen.android.accountAccess.AccountAccess; import org.evergreen.android.globals.GlobalConfigs; -import org.evergreen.android.globals.NoAccessToHttpAddress; +import org.evergreen.android.globals.NoAccessToServer; import org.evergreen.android.globals.NoNetworkAccessException; import org.evergreen.android.globals.Utils; @@ -87,9 +87,9 @@ public class ApplicationPreferences extends PreferenceActivity implements OnShar public void run() { boolean routeToAddress = true; - AccountAccess account = AccountAccess.getAccountAccess(GlobalConfigs.httpAddress); + AccountAccess account = AccountAccess.getAccountAccess(GlobalConfigs.httpAddress,(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE)); try{ - Utils.checkNetworkStatus((ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE), context); + Utils.checkNetworkStatus((ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE)); }catch(NoNetworkAccessException e){ routeToAddress = false; @@ -108,7 +108,7 @@ public class ApplicationPreferences extends PreferenceActivity implements OnShar } }); - }catch(NoAccessToHttpAddress e){ + }catch(NoAccessToServer e){ Log.d(TAG, " no route to hoast"); routeToAddress = false; @@ -125,30 +125,35 @@ public class ApplicationPreferences extends PreferenceActivity implements OnShar if(routeToAddress){ - if(account.authenticate()){ - - runOnUiThread(new Runnable() { - - @Override - public void run() { - if(reference != null){ - progressDialog.dismiss(); - Toast.makeText(context, "Autenthication successfully established :" + GlobalConfigs.httpAddress, Toast.LENGTH_LONG).show(); + + try{ + if(account.authenticate()){ + + runOnUiThread(new Runnable() { + + @Override + public void run() { + if(reference != null){ + progressDialog.dismiss(); + Toast.makeText(context, "Autenthication successfully established :" + GlobalConfigs.httpAddress, Toast.LENGTH_LONG).show(); + } } - } - }); - }else{ - runOnUiThread(new Runnable() { - - @Override - public void run() { - if(reference != null){ - progressDialog.dismiss(); - Toast.makeText(context, "Please check username and password ", Toast.LENGTH_LONG).show(); + }); + }else{ + runOnUiThread(new Runnable() { + + @Override + public void run() { + if(reference != null){ + progressDialog.dismiss(); + Toast.makeText(context, "Please check username and password ", Toast.LENGTH_LONG).show(); + } } - } - }); - } + }); + } + + }catch(Exception e){} + } else runOnUiThread(new Runnable() { diff --git a/Open-ILS/src/Android/src/org/evergreen/android/views/splashscreen/LoadingTask.java b/Open-ILS/src/Android/src/org/evergreen/android/views/splashscreen/LoadingTask.java new file mode 100644 index 0000000000..2854f21e4d --- /dev/null +++ b/Open-ILS/src/Android/src/org/evergreen/android/views/splashscreen/LoadingTask.java @@ -0,0 +1,70 @@ +package org.evergreen.android.views.splashscreen; + +import android.os.AsyncTask; +import android.util.Log; +import android.widget.ProgressBar; + +public class LoadingTask extends AsyncTask { + + public interface LoadingTaskFinishedListener { + void onTaskFinished(); // If you want to pass something back to the listener add a param to this method + } + + // This is the progress bar you want to update while the task is in progress + private final ProgressBar progressBar; + // This is the listener that will be told when this task is finished + private final LoadingTaskFinishedListener finishedListener; + + /** + * A Loading task that will load some resources that are necessary for the app to start + * @param progressBar - the progress bar you want to update while the task is in progress + * @param finishedListener - the listener that will be told when this task is finished + */ + public LoadingTask(ProgressBar progressBar, LoadingTaskFinishedListener finishedListener) { + this.progressBar = progressBar; + this.finishedListener = finishedListener; + } + + @Override + protected Integer doInBackground(String... params) { + Log.i("Tutorial", "Starting task with url: "+params[0]); + if(resourcesDontAlreadyExist()){ + downloadResources(); + } + // Perhaps you want to return something to your post execute + return 1234; + } + + private boolean resourcesDontAlreadyExist() { + // Here you would query your app's internal state to see if this download had been performed before + // Perhaps once checked save this in a shared preference for speed of access next time + return true; // returning true so we show the splash every time + } + + + private void downloadResources() { + // We are just imitating some process thats takes a bit of time (loading of resources / downloading) + int count = 10; + for (int i = 0; i < count; i++) { + + // Update the progress bar after every step + int progress = (int) ((i / (float) count) * 100); + publishProgress(progress); + + // Do some long loading things + try { Thread.sleep(1000); } catch (InterruptedException ignore) {} + } + } + + @Override + protected void onProgressUpdate(Integer... values) { + super.onProgressUpdate(values); + progressBar.setProgress(values[0]); // This is ran on the UI thread so it is ok to update our progress bar ( a UI view ) here + } + + @Override + protected void onPostExecute(Integer result) { + super.onPostExecute(result); + finishedListener.onTaskFinished(); // Tell whoever was listening we have finished + } +} \ No newline at end of file diff --git a/Open-ILS/src/Android/src/org/evergreen/android/views/splashscreen/SplashActivity.java b/Open-ILS/src/Android/src/org/evergreen/android/views/splashscreen/SplashActivity.java new file mode 100644 index 0000000000..8b265d393f --- /dev/null +++ b/Open-ILS/src/Android/src/org/evergreen/android/views/splashscreen/SplashActivity.java @@ -0,0 +1,42 @@ +package org.evergreen.android.views.splashscreen; + + + +import org.evergreen.android.R; +import org.evergreen.android.views.MainScreenDashboard; +import org.evergreen.android.views.splashscreen.LoadingTask.LoadingTaskFinishedListener; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.widget.ProgressBar; + +public class SplashActivity extends Activity implements LoadingTaskFinishedListener { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // Show the splash screen + setContentView(R.layout.activity_splash); + // Find the progress bar + ProgressBar progressBar = (ProgressBar) findViewById(R.id.activity_splash_progress_bar); + // Start your loading + new LoadingTask(progressBar, this).execute("www.google.co.uk"); // Pass in whatever you need a url is just an example we don't use it in this tutorial + } + + // This is the callback for when your async task has finished + @Override + public void onTaskFinished() { + completeSplash(); + } + + private void completeSplash(){ + startApp(); + finish(); // Don't forget to finish this Splash Activity so the user can't return to it! + } + + private void startApp() { + Intent intent = new Intent(SplashActivity.this, MainScreenDashboard.class); + startActivity(intent); + } +} \ No newline at end of file -- 2.11.0