package org.commcare.dalvik.activities;
import java.io.File;
import java.util.ArrayList;
import org.commcare.android.framework.CommCareActivity;
import org.commcare.android.framework.ManagedUi;
import org.commcare.android.framework.UiElement;
import org.commcare.android.tasks.MultimediaInflaterTask;
import org.commcare.android.tasks.templates.CommCareTask;
import org.commcare.android.util.FileUtil;
import org.commcare.dalvik.R;
import org.commcare.dalvik.dialogs.CustomProgressDialog;
import org.javarosa.core.services.locale.Localization;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
/**
* @author ctsims
*
*/
@ManagedUi(R.layout.screen_multimedia_inflater)
public class MultimediaInflaterActivity extends CommCareActivity<MultimediaInflaterActivity> {
private static final String LOG_TAG = "CommCare-MultimediaInflator";
private static final int REQUEST_FILE_LOCATION = 1;
public static final String EXTRA_FILE_DESTINATION = "ccodk_mia_filedest";
@UiElement(value = R.id.screen_multimedia_inflater_prompt, locale="mult.install.prompt")
TextView txtDisplayPrompt;
@UiElement(value = R.id.screen_multimedia_install_messages, locale="mult.install.state.empty")
TextView txtInteractiveMessages;
@UiElement(R.id.screen_multimedia_inflater_location)
EditText editFileLocation;
@UiElement(R.id.screen_multimedia_inflater_filefetch)
ImageButton btnFetchFiles;
@UiElement(value = R.id.screen_multimedia_inflater_install, locale="mult.install.button")
Button btnInstallMultimedia;
boolean done = false;
/* (non-Javadoc)
* @see org.commcare.android.framework.CommCareActivity#onCreate(android.os.Bundle)
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
btnFetchFiles.setOnClickListener(new OnClickListener() {
/*
* (non-Javadoc)
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
@Override
public void onClick(View v) {
//Go fetch us a file path!
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("file/*");
try {
startActivityForResult(intent, REQUEST_FILE_LOCATION);
} catch(ActivityNotFoundException e) {
Toast.makeText(MultimediaInflaterActivity.this, Localization.get("mult.install.no.browser"), Toast.LENGTH_LONG).show();
}
}
});
final String destination = this.getIntent().getStringExtra(EXTRA_FILE_DESTINATION);
btnInstallMultimedia.setOnClickListener(new OnClickListener() {
/*
* (non-Javadoc)
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
@Override
public void onClick(View v) {
MultimediaInflaterTask<MultimediaInflaterActivity> task = new MultimediaInflaterTask<MultimediaInflaterActivity>() {
/*
* (non-Javadoc)
* @see org.commcare.android.tasks.templates.CommCareTask#deliverResult(java.lang.Object, java.lang.Object)
*/
@Override
protected void deliverResult( MultimediaInflaterActivity receiver, Boolean result) {
if(result == Boolean.TRUE){
receiver.done = true;
receiver.evalState();
receiver.setResult(Activity.RESULT_OK);
receiver.finish();
return;
} else {
//assume that we've already set the error message, but make it look scary
receiver.TransplantStyle(txtInteractiveMessages, R.layout.template_text_notification_problem);
}
}
/*
* (non-Javadoc)
* @see org.commcare.android.tasks.templates.CommCareTask#deliverUpdate(java.lang.Object, java.lang.Object[])
*/
@Override
protected void deliverUpdate(MultimediaInflaterActivity receiver, String... update) {
receiver.updateProgress(update[0], CommCareTask.GENERIC_TASK_ID);
receiver.txtInteractiveMessages.setText(update[0]);
}
/*
* (non-Javadoc)
* @see org.commcare.android.tasks.templates.CommCareTask#deliverError(java.lang.Object, java.lang.Exception)
*/
@Override
protected void deliverError(MultimediaInflaterActivity receiver, Exception e) {
receiver.txtInteractiveMessages.setText(Localization.get("mult.install.error", new String[] {e.getMessage()}));
receiver.TransplantStyle(txtInteractiveMessages, R.layout.template_text_notification_problem);
}
};
task.connect(MultimediaInflaterActivity.this);
task.execute(editFileLocation.getText().toString(), destination);
}
});
try {
//Go populate the location by default if it exists. (Note: If we are recreating, this will get overridden
//in the restore instance state)
searchForDefault();
} catch(Exception e) {
//This is helper code and Android is suuuuuppppeerr touchy about file system stuff, so don't eat it if
//something changes
e.printStackTrace();
Log.e(LOG_TAG, "Error while trying to get default location");
}
}
/*
* (non-Javadoc)
* @see android.app.Activity#onActivityResult(int, int, android.content.Intent)
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if(requestCode == REQUEST_FILE_LOCATION) {
if(resultCode == Activity.RESULT_OK) {
String filePath = intent.getData().getPath();
editFileLocation.setText(filePath);
}
}
}
/* (non-Javadoc)
* @see org.commcare.android.framework.CommCareActivity#onResume()
*/
@Override
protected void onResume() {
super.onResume();
evalState();
}
private void evalState() {
if(done) {
txtInteractiveMessages.setText(Localization.get("mult.install.state.done"));
this.TransplantStyle(txtInteractiveMessages, R.layout.template_text_notification);
btnInstallMultimedia.setEnabled(false);
return;
}
String location = editFileLocation.getText().toString();
if("".equals(location)) {
txtInteractiveMessages.setText(Localization.get("mult.install.state.empty"));
this.TransplantStyle(txtInteractiveMessages, R.layout.template_text_notification);
btnInstallMultimedia.setEnabled(false);
return;
}
if(!(new File(location)).exists()) {
txtInteractiveMessages.setText(Localization.get("mult.install.state.invalid.path"));
this.TransplantStyle(txtInteractiveMessages, R.layout.template_text_notification_problem);
btnInstallMultimedia.setEnabled(false);
return;
}
else {
txtInteractiveMessages.setText(Localization.get("mult.install.state.ready"));
this.TransplantStyle(txtInteractiveMessages, R.layout.template_text_notification);
btnInstallMultimedia.setEnabled(true);
return;
}
}
/* (non-Javadoc)
* @see org.commcare.android.tasks.templates.CommCareTaskConnector#taskCancelled(int)
*/
@Override
public void taskCancelled(int id) {
txtInteractiveMessages.setText(Localization.get("mult.install.cancelled"));
this.TransplantStyle(txtInteractiveMessages, R.layout.template_text_notification_problem);
}
private static final long MAX_TIME_TO_TRY = 400;
/**
* Go through all of the obvious storage locations where the zip file might be and see if it's there.
*/
private void searchForDefault() {
//We're only gonna spend a certain amount of time trying to find a good match
long start = System.currentTimeMillis();
//Get all of the "roots" where stuff might be
ArrayList<File> roots = new ArrayList<File>();
//And stage a place to list folders we'll scan
ArrayList<File> folders = new ArrayList<File>();
if(Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED || Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED_READ_ONLY) {
roots.add(Environment.getExternalStorageDirectory());
}
for(String s : FileUtil.getExternalMounts()) {
roots.add(new File(s));
}
//Now add all of our folders from our roots. We're only going one level deep
for(File r : roots) {
//Add the root too
folders.add(r);
//Now add all subfolders
for(File f : r.listFiles()) {
if(f.isDirectory()) {
folders.add(f);
}
}
}
File bestMatch = null;
//Now scan for the actual file
for(File folder : folders) {
for(File f : folder.listFiles()) {
String name = f.getName().toLowerCase();
//This is just what we expect the file will be called
if(name.startsWith("commcare") && name.endsWith(".zip")) {
if(bestMatch == null) {
bestMatch = f;
} else {
//If we have one, take the newer one
if(bestMatch.lastModified() < f.lastModified()) {
bestMatch = f;
}
}
}
}
//For now, actually, if we have a good match, just bail without finding the "best" one
if(bestMatch != null) {
break;
}
if(System.currentTimeMillis() - start > MAX_TIME_TO_TRY) {
Log.i(LOG_TAG, "Had to bail on looking for a default file, was taking too long");
break;
}
}
if(bestMatch != null) {
//If we found a good match, awesome!
editFileLocation.setText(bestMatch.getAbsolutePath());
}
}
/*
* (non-Javadoc)
* @see org.commcare.android.framework.CommCareActivity#generateProgressDialog(int)
*
* Implementation of generateProgressDialog() for DialogController -- other methods
* handled entirely in CommCareActivity
*/
@Override
public CustomProgressDialog generateProgressDialog(int taskId) {
if(taskId == CommCareTask.GENERIC_TASK_ID) {
String title = Localization.get("mult.install.title");
String message = Localization.get("mult.install.progress", new String[] {"0"});
return CustomProgressDialog.newInstance(title, message, taskId);
}
System.out.println("WARNING: taskId passed to generateProgressDialog does not match "
+ "any valid possibilities in MultiMediaInflaterActivity");
return null;
}
}