package it.geosolutions.geocollect.android.core.login; import it.geosolutions.android.map.utils.MapFilesProvider; import it.geosolutions.android.map.utils.ZipFileManager; import it.geosolutions.geocollect.android.app.BuildConfig; import it.geosolutions.geocollect.android.core.GeoCollectApplication; import it.geosolutions.geocollect.android.app.R; import it.geosolutions.geocollect.android.core.login.utils.LoginRequestInterceptor; import it.geosolutions.geocollect.android.core.login.utils.LoginUtil; import it.geosolutions.geocollect.android.core.login.utils.LoginUtil.LoginStatusCallback; import it.geosolutions.geocollect.android.core.login.utils.NetworkUtil; import it.geosolutions.geocollect.android.core.mission.PendingMissionListActivity; import it.geosolutions.geocollect.android.core.mission.utils.MissionUtils; import it.geosolutions.geocollect.android.core.mission.utils.PersistenceUtils; import it.geosolutions.geocollect.android.core.mission.utils.SpatialiteUtils; import it.geosolutions.geocollect.android.template.TemplateDownloadTask; import it.geosolutions.geocollect.model.config.MissionTemplate; import java.util.ArrayList; import java.util.HashMap; import retrofit.RetrofitError; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.annotation.TargetApi; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.res.Resources; import android.os.Build; import android.os.Bundle; import android.preference.PreferenceManager; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.CheckedTextView; import android.widget.ImageView; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; public class LogoutActivity extends Activity { private static final String TAG = LogoutActivity.class.getSimpleName(); private View mLogoutFormView; private View mLogoutStatusView; public final static int REQUEST_LOGOUT = 222; public final static int LOGGED_OUT = 333; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.logout_layout); mLogoutFormView = findViewById(R.id.logout_form); mLogoutStatusView = findViewById(R.id.logout_status); final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); final String email = prefs.getString(LoginActivity.PREFS_USER_EMAIL, null); final String pass = prefs.getString(LoginActivity.PREFS_PASSWORD, null); final String url = prefs.getString(LoginActivity.PREFS_LOGIN_URL, null); // check online if(!NetworkUtil.isOnline(getBaseContext())){ mLogoutFormView.setVisibility(View.VISIBLE); //if not online, see if values saved and fill tryToFillFormWithSavedData(); }else if(email != null && pass != null && url != null){ //login user to get credential data showProgress(true, false); LoginUtil.session(url, email, pass,new LoginStatusCallback() { @Override public void notLoggedIn(RetrofitError error) { //user is not logged in or some error occured, login again startLoginActivity(); } @Override public void loggedIn(final String authKey) { showProgress(false,true); setProps(email,null,null); } }); }else{ //missing data startLoginActivity(); } final Button logoutButton = (Button) findViewById(R.id.logout_button); logoutButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //clear user data final Editor ed = PreferenceManager.getDefaultSharedPreferences(getBaseContext()).edit(); ed.putString(LoginActivity.PREFS_USER_EMAIL, null); ed.putString(LoginActivity.PREFS_USER_FORENAME, null); ed.putString(LoginActivity.PREFS_USER_SURNAME, null); ed.putString(LoginActivity.PREFS_PASSWORD, null); ed.putString(LoginActivity.PREFS_AUTH_KEY, null); ed.putString(LoginActivity.PREFS_USER_ENTE, null); ed.commit(); Toast.makeText(getBaseContext(), getString(R.string.logout_logged_out),Toast.LENGTH_LONG).show(); Intent returnIntent = new Intent(); setResult(LOGGED_OUT,returnIntent); finish(); } }); updateTemplateList(); final ProgressBar progress = (ProgressBar) findViewById(R.id.update_missions_progress); final ImageView updateTemplatesButton = (ImageView) findViewById(R.id.update_missions_button); updateTemplatesButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { updateTemplatesButton.setVisibility(View.GONE); progress.setVisibility(View.VISIBLE); //update MissionTemplates final TemplateDownloadTask task = new TemplateDownloadTask() { @Override public void complete(final ArrayList<MissionTemplate> downloadedTemplates) { updateTemplatesButton.setVisibility(View.VISIBLE); progress.setVisibility(View.GONE); /** * download successful, elaborate result **/ // 1. update database ArrayList<MissionTemplate> validTemplates = new ArrayList<MissionTemplate>(); if (downloadedTemplates != null && downloadedTemplates.size() > 0) { jsqlite.Database spatialiteDatabase = SpatialiteUtils.openSpatialiteDB( LogoutActivity.this, "geocollect/genova.sqlite"); for (MissionTemplate t : downloadedTemplates) { if (!PersistenceUtils.createOrUpdateTablesForTemplate(t, spatialiteDatabase)) { Log.w(TAG, "error creating/updating table"); } else { // if insert successful add to list of valid templates validTemplates.add(t); } } } // 2. save valid templates PersistenceUtils.saveDownloadedTemplates(getBaseContext(), validTemplates); if(BuildConfig.DEBUG){ Log.d(TAG, "valid templates persisted"); } // 3. Update the currently selected template Editor ed = PreferenceManager.getDefaultSharedPreferences(getBaseContext()).edit(); ArrayList<MissionTemplate> loadedTemplates = PersistenceUtils.loadSavedTemplates(getBaseContext()); int templateIndex = 0; String selectedTemplateId = prefs.getString(PendingMissionListActivity.PREFS_SELECTED_TEMPLATE_ID, null); if(selectedTemplateId != null && !selectedTemplateId.isEmpty()){ for(MissionTemplate t : loadedTemplates){ if(t.id != null && t.id.equalsIgnoreCase(selectedTemplateId)){ ((GeoCollectApplication) getApplication()).setTemplate(t); ed.putInt(PendingMissionListActivity.PREFS_DOWNLOADED_TEMPLATE_INDEX, templateIndex); } templateIndex++; } } ed.commit(); // 4. Refresh UI updateTemplateList(); } }; final String authKey = prefs.getString(LoginActivity.PREFS_AUTH_KEY, null); String username = prefs.getString(LoginActivity.PREFS_USER_EMAIL, null); String password = prefs.getString(LoginActivity.PREFS_PASSWORD, null); String authorizationString = LoginRequestInterceptor.getB64Auth(username, password); task.execute(authKey, authorizationString); } }); final CheckedTextView ctv = (CheckedTextView) findViewById(R.id.startup_option_checkbox); // Initialize ctv.setChecked(getStartAsMap()); ctv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (ctv.isChecked()){ ctv.setChecked(false); ctv.setEnabled(false); if(!setStartAsMap(false)){ ctv.setChecked(true); } ctv.setEnabled(true); } else { ctv.setChecked(true); ctv.setEnabled(false); if(!setStartAsMap(true)){ ctv.setChecked(false); } ctv.setEnabled(true); } } }); } /** * Set the preference for the starting Activity * - TRUE: start with map * - FALSE: start with list * @param okMap * @return */ public boolean setStartAsMap(boolean okMap){ Editor ed = PreferenceManager.getDefaultSharedPreferences(getBaseContext()).edit(); ed.putBoolean(PendingMissionListActivity.PREFS_START_WITH_MAP, okMap); return ed.commit(); } /** * */ public void updateTemplateList() { final ArrayList<MissionTemplate> templates = PersistenceUtils.loadSavedTemplates(getBaseContext()); final HashMap <MissionTemplate,Boolean> downloads = new HashMap<MissionTemplate,Boolean>(); if(templates != null){ for(MissionTemplate t : templates){ boolean exists = MissionUtils.checkTemplateForBackgroundData(getBaseContext(), t); downloads.put(t, exists); if(BuildConfig.DEBUG){ Log.i(TAG,"adding to downloads "+t.title+" , id "+t.id +" exists "+Boolean.toString(exists)); } } } final ListView missionListview = (ListView) findViewById(R.id.mission_list); final MissionDownloadItemAdapter downloadsAdapter = new MissionDownloadItemAdapter(getBaseContext(), downloads); missionListview.setAdapter(downloadsAdapter); } private void tryToFillFormWithSavedData() { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); final String _user = prefs.getString(LoginActivity.PREFS_USER_EMAIL, null); final String _username_sur = prefs.getString(LoginActivity.PREFS_USER_SURNAME, null); final String _username_fore = prefs.getString(LoginActivity.PREFS_USER_FORENAME, null); final String _ente = prefs.getString(LoginActivity.PREFS_USER_ENTE, null); final String _username = _username_fore + " "+ _username_sur; if(_user != null && _username != null){ setProps(_user, _username, _ente); }else{ //user is probably not logged in and offline //TODO is it possible to use the app offline and logged out ? startLoginActivity(); } } public void setProps(final String user, final String userName, final String ente){ final TextView email_TV = (TextView) findViewById(R.id.logout_email_tv); final TextView name_TV = (TextView) findViewById(R.id.logout_username_tv); final TextView ente_TV = (TextView) findViewById(R.id.logout_ente_tv); if(user != null){ email_TV.setText(user); } if(userName != null){ name_TV.setText(userName); } if(ente != null){ ente_TV.setText(ente); } } /** * Shows the progress UI and hides the account details form. */ @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) private void showProgress(final boolean show, final boolean showForm) { // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow // for very easy animations. If available, use these APIs to fade-in // the progress spinner. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime); mLogoutStatusView.setVisibility(View.VISIBLE); mLogoutStatusView.animate().setDuration(shortAnimTime) .alpha(show ? 1 : 0) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mLogoutStatusView.setVisibility(show ? View.VISIBLE : View.GONE); } }); if(showForm){ mLogoutFormView.setVisibility(View.VISIBLE); mLogoutFormView.animate().setDuration(shortAnimTime) .alpha(show ? 0 : 1) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mLogoutFormView.setVisibility(show ? View.GONE: View.VISIBLE); } }); }else{ mLogoutFormView.setVisibility(View.GONE); } } else { // The ViewPropertyAnimator APIs are not available, so simply show // and hide the relevant UI components. mLogoutStatusView.setVisibility(show ? View.VISIBLE : View.GONE); mLogoutFormView.setVisibility(show ? View.GONE : View.VISIBLE); } } public void startLoginActivity(){ showProgress(false,false); startActivity(new Intent(LogoutActivity.this, LoginActivity.class)); finish(); } public class MissionDownloadItemAdapter extends BaseAdapter { private Context mContext; private HashMap<MissionTemplate, Boolean> mDownloads = new HashMap<MissionTemplate, Boolean>(); private MissionTemplate[] mKeys; public MissionDownloadItemAdapter(Context context, HashMap<MissionTemplate,Boolean> items) { mContext = context; mDownloads = items; mKeys = mDownloads.keySet().toArray(new MissionTemplate[mDownloads.size()]); } @Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if (v == null) { LayoutInflater vi; vi = LayoutInflater.from(mContext); v = vi.inflate(R.layout.download_mission_item, null); } final TextView titleTV = (TextView) v.findViewById(R.id.download_mission_title); final ImageView imageV = (ImageView) v.findViewById(R.id.download_mission_image); final MissionTemplate t = mKeys[position]; final boolean exists = mDownloads.get(t); titleTV.setText(t.title); //remove for reused views; v.setOnClickListener(null); if(exists){ imageV.setImageResource(R.drawable.ic_navigation_accept); }else{ v.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { final String mount = MapFilesProvider.getEnvironmentDirPath(getBaseContext()); final HashMap<String,Integer> urls = MissionUtils.getContentUrlsAndFileAmountForTemplate(t); Resources res = getResources(); for(String url : urls.keySet()){ String dialogMessage = res.getQuantityString(R.plurals.dialog_message_with_amount, urls.get(url), urls.get(url)); new ZipFileManager(LogoutActivity.this, mount, MapFilesProvider.getBaseDir(), url, null, dialogMessage ) { @Override public void launchMainActivity(final boolean success) { // //TODO necessary ? // if (getApplication() instanceof GeoCollectApplication) { // ((GeoCollectApplication) getApplication()).setupMBTilesBackgroundConfiguration(); // } if(success){ Toast.makeText(getBaseContext(), getString(R.string.download_successfull), Toast.LENGTH_SHORT).show(); mDownloads.remove(t); mDownloads.put(t, true); notifyDataSetChanged(); } } }; } } }); } return v; } @Override public int getCount() { return mDownloads.size(); } @Override public Object getItem(int position) { return mDownloads.get(mKeys[position]); } @Override public long getItemId(int arg0) { return arg0; } } /** * Get the preference for the starting Activity * - TRUE: start with map * - FALSE: start with list * @return boolean */ public boolean getStartAsMap(){ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); try { return sp.getBoolean(PendingMissionListActivity.PREFS_START_WITH_MAP, false); }catch(ClassCastException cce){ return false; } } }