package org.commcare.dalvik.activities; import org.commcare.android.database.user.models.FormRecord; import org.commcare.android.framework.CommCareActivity; import org.commcare.android.framework.ManagedUi; import org.commcare.android.framework.UiElement; import org.commcare.android.javarosa.AndroidLogger; import org.commcare.android.tasks.ExceptionReportTask; import org.commcare.android.tasks.ProcessAndSendTask; import org.commcare.android.util.FormUploadUtil; import org.commcare.android.util.SessionUnavailableException; import org.commcare.android.util.StorageUtils; import org.commcare.dalvik.R; import org.commcare.dalvik.application.CommCareApplication; import org.commcare.dalvik.services.CommCareSessionService; import org.javarosa.core.services.Logger; import android.annotation.SuppressLint; import android.content.SharedPreferences; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; /** * @author ctsims * */ @ManagedUi(R.layout.screen_recovery) public class RecoveryActivity extends CommCareActivity<RecoveryActivity> { private static final int SEND_TASK_ID = 100; private static final int RECOVER_TASK_ID = 101; @UiElement(R.id.screen_recovery_unsent_message) TextView txtUnsentForms; @UiElement(R.id.screen_recovery_unsent_button) Button sendForms; @UiElement(R.id.screen_recovery_app_install_message) TextView appState; @UiElement(R.id.screen_recovery_app_install_button) Button btnRecoverApp; @UiElement(R.id.screen_recovery_progress) TextView txtUserMessage; /* (non-Javadoc) * @see org.commcare.android.framework.CommCareActivity#onCreate(android.os.Bundle) */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if(this.getDestroyedActivityState() != null) { //We just rotated or whatever, don't re-initialize everything } else { //Fresh Start, statewise. updateSendFormsState(); updateRecoverAppState(); } sendForms.setOnClickListener(new OnClickListener() { /* * (non-Javadoc) * @see android.view.View.OnClickListener#onClick(android.view.View) */ @SuppressLint("NewApi") @Override public void onClick(View v) { FormRecord[] records = StorageUtils.getUnsentRecords(CommCareApplication._().getUserStorage(FormRecord.class)); SharedPreferences settings = CommCareApplication._().getCurrentApp().getAppPreferences(); ProcessAndSendTask<RecoveryActivity> mProcess = new ProcessAndSendTask<RecoveryActivity>(RecoveryActivity.this, settings.getString("PostURL", RecoveryActivity.this.getString(R.string.PostURL)), SEND_TASK_ID, true){ /* (non-Javadoc) * @see org.commcare.android.tasks.templates.CommCareTask#onPreExecute() */ @Override protected void onPreExecute() { super.onPreExecute(); displayMessage("Submitting form(s) to the server..."); } /* * (non-Javadoc) * @see org.commcare.android.tasks.templates.CommCareTask#deliverResult(java.lang.Object, java.lang.Object) */ @Override protected void deliverResult(RecoveryActivity receiver, Integer result) { if(result == ProcessAndSendTask.PROGRESS_LOGGED_OUT) { receiver.displayMessage("Log-in expired during send. Please press back and log in again"); return; } int successfulSends = this.getSuccesfulSends(); if(result == FormUploadUtil.FULL_SUCCESS) { receiver.displayMessage("Send succesful. All " + successfulSends + " forms were submitted"); } else if(result == FormUploadUtil.FAILURE) { String remainder = successfulSends > 0 ? " Only " + successfulSends + " were submitted" : ""; receiver.displayMessage("There were errors submitting the forms." + remainder); } else if(result == FormUploadUtil.TRANSPORT_FAILURE){ receiver.displayMessage("Unable to contact the remote server."); } else { } } /* * (non-Javadoc) * @see org.commcare.android.tasks.templates.CommCareTask#deliverUpdate(java.lang.Object, java.lang.Object[]) */ @Override protected void deliverUpdate(RecoveryActivity receiver, Long... update) { //we don't need to deliver updates here, it happens on the notification bar } /* * (non-Javadoc) * @see org.commcare.android.tasks.templates.CommCareTask#deliverError(java.lang.Object, java.lang.Exception) */ @Override protected void deliverError(RecoveryActivity receiver,Exception e) { Logger.log(AndroidLogger.TYPE_ERROR_ASSERTION,"Error in recovery form send: " + ExceptionReportTask.getStackTrace(e)); receiver.displayMessage("Error while sending : " + e.getMessage()); } }; mProcess.setListeners(CommCareApplication._().getSession().startDataSubmissionListener()); mProcess.connect(RecoveryActivity.this); //Execute on a true multithreaded chain. We should probably replace all of our calls with this //but this is the big one for now. if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) { mProcess.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, records); } else { mProcess.execute(records); } } }); btnRecoverApp.setOnClickListener(new OnClickListener() { /* * (non-Javadoc) * @see android.view.View.OnClickListener#onClick(android.view.View) */ @Override public void onClick(View v) { displayMessage("App recovery is not yet enabled. Please clear user data (After sending all of your forms!) and re-install."); } }); } protected void displayMessage(String text) { txtUserMessage.setText(text); } /* (non-Javadoc) * @see org.commcare.android.framework.CommCareActivity#startBlockingForTask(int) */ @Override public void startBlockingForTask(int id) { btnRecoverApp.setEnabled(false); sendForms.setEnabled(false); } /* (non-Javadoc) * @see org.commcare.android.framework.CommCareActivity#stopBlockingForTask(int) */ @Override public void stopBlockingForTask(int id) { updateSendFormsState(); updateRecoverAppState(); } private void updateRecoverAppState() { btnRecoverApp.setEnabled(false); if(!CommCareApplication._().isStorageAvailable()) { appState.setText("app state unavailable."); return; } if(CommCareApplication._().getAppResourceState() == CommCareApplication.STATE_CORRUPTED) { appState.setText("App install is corrupt. Make sure forms are sent before attempting recovery."); btnRecoverApp.setEnabled(true); return; } else { appState.setText("App is installed and valid"); btnRecoverApp.setEnabled(false); return; } } private void updateSendFormsState() { sendForms.setEnabled(false); if(!CommCareApplication._().isStorageAvailable()) { txtUnsentForms.setText("unsent forms unavailable."); return; } try { CommCareSessionService session = CommCareApplication._().getSession(); } catch(SessionUnavailableException sue) { txtUnsentForms.setText("Couldn't read unsent forms. Not Logged in"); return; } try { FormRecord[] records = StorageUtils.getUnsentRecords(CommCareApplication._().getUserStorage(FormRecord.class)); if(records.length == 0) { txtUnsentForms.setText("This device has no unsent forms"); } else{ txtUnsentForms.setText("There are " + records.length + " unsent form(s) on this device"); sendForms.setEnabled(true); } } catch(Exception e) { Logger.log(AndroidLogger.TYPE_ERROR_ASSERTION, e.getMessage()); txtUnsentForms.setText("Couldn't read unsent forms. Error : " + e.getMessage()); } } /* (non-Javadoc) * @see org.commcare.android.framework.CommCareActivity#onResume() */ @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); } }