package net.wigle.wigleandroid;
import java.util.List;
import net.wigle.wigleandroid.background.ApiListener;
import net.wigle.wigleandroid.background.ObservationImporter;
import net.wigle.wigleandroid.background.ObservationUploader;
import net.wigle.wigleandroid.background.TransferListener;
import net.wigle.wigleandroid.background.FileUploaderTask;
import net.wigle.wigleandroid.background.KmlWriter;
import net.wigle.wigleandroid.model.Pair;
import net.wigle.wigleandroid.model.QueryArgs;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Address;
import android.location.Geocoder;
import android.media.AudioManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONException;
import org.json.JSONObject;
/**
* configure settings
*/
public final class DataFragment extends Fragment implements ApiListener, TransferListener, DialogListener {
private static final int MENU_EXIT = 11;
private static final int MENU_ERROR_REPORT = 13;
private static final int CSV_RUN_DIALOG = 120;
private static final int CSV_DB_DIALOG = 121;
private static final int KML_RUN_DIALOG = 122;
private static final int KML_DB_DIALOG = 123;
private static final int BACKUP_DIALOG = 124;
private static final int IMPORT_DIALOG = 125;
private static final int ZERO_OUT_DIALOG = 126;
private static final int MAX_OUT_DIALOG = 127;
/** Called when the activity is first created. */
@Override
public void onCreate( final Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setHasOptionsMenu(true);
// set language
MainActivity.setLocale( getActivity() );
// force media volume controls
getActivity().setVolumeControlStream( AudioManager.STREAM_MUSIC );
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.data, container, false);
setupQueryButtons( view );
setupCsvButtons( view );
setupKmlButtons(view);
setupBackupDbButton(view);
setupImportObservedButton(view);
setupMarkerButtons(view);
return view;
}
private void setupQueryButtons( final View view ) {
Button button = (Button) view.findViewById( R.id.search_button );
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View buttonView) {
final QueryArgs queryArgs = new QueryArgs();
String fail = null;
String field = null;
boolean okValue = false;
for (final int id : new int[]{R.id.query_address, R.id.query_ssid, R.id.query_bssid}) {
if (fail != null) {
break;
}
final EditText editText = (EditText) view.findViewById(id);
final String text = editText.getText().toString().trim();
if ("".equals(text)) {
continue;
}
try {
switch (id) {
case R.id.query_address:
field = getString(R.string.address);
Geocoder gc = new Geocoder(getActivity());
List<Address> addresses = gc.getFromLocationName(text, 1);
if (addresses.size() < 1) {
fail = getString(R.string.no_address_found);
break;
}
queryArgs.setAddress(addresses.get(0));
okValue = true;
break;
case R.id.query_ssid:
field = getString(R.string.ssid);
queryArgs.setSSID(text);
okValue = true;
break;
case R.id.query_bssid:
field = getString(R.string.bssid);
queryArgs.setBSSID(text);
okValue = true;
break;
default:
MainActivity.error("setupButtons: bad id: " + id);
}
} catch (Exception ex) {
fail = getString(R.string.problem_with_field) + " '" + field + "': " + ex.getMessage();
break;
}
}
if (fail == null && !okValue) {
fail = "No query fields specified";
}
if (fail != null) {
// toast!
Toast.makeText(getActivity(), fail, Toast.LENGTH_SHORT).show();
} else {
ListFragment.lameStatic.queryArgs = queryArgs;
// start db result activity
final Intent settingsIntent = new Intent(getActivity(), DBResultActivity.class);
startActivity(settingsIntent);
}
}
});
button = (Button) view.findViewById( R.id.reset_button );
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View buttonView) {
for (final int id : new int[]{R.id.query_address, R.id.query_ssid}) {
final EditText editText = (EditText) view.findViewById(id);
editText.setText("");
}
}
});
}
/**
* TransferListener interface
*/
@Override
public void requestComplete(final JSONObject json, final boolean isCache)
throws WiGLEAuthException {
// nothing
}
@Override
public void transferComplete() {
// also nothing
}
private void setupCsvButtons( final View view ) {
// actually need this Activity context, for dialogs
final Button csvRunExportButton = (Button) view.findViewById( R.id.csv_run_export_button );
csvRunExportButton.setOnClickListener( new OnClickListener() {
@Override
public void onClick( final View buttonView ) {
MainActivity.createConfirmation( getActivity(),
DataFragment.this.getString(R.string.data_export_csv), MainActivity.DATA_TAB_POS, CSV_RUN_DIALOG);
}
});
final Button csvExportButton = (Button) view.findViewById( R.id.csv_export_button );
csvExportButton.setOnClickListener( new OnClickListener() {
@Override
public void onClick( final View buttonView ) {
MainActivity.createConfirmation( getActivity(),
DataFragment.this.getString(R.string.data_export_csv_db), MainActivity.DATA_TAB_POS, CSV_DB_DIALOG);
}
});
}
private void setupKmlButtons( final View view ) {
final Button kmlRunExportButton = (Button) view.findViewById( R.id.kml_run_export_button );
kmlRunExportButton.setOnClickListener( new OnClickListener() {
@Override
public void onClick( final View buttonView ) {
MainActivity.createConfirmation( getActivity(),
DataFragment.this.getString(R.string.data_export_kml_run), MainActivity.DATA_TAB_POS, KML_RUN_DIALOG);
}
});
final Button kmlExportButton = (Button) view.findViewById( R.id.kml_export_button );
kmlExportButton.setOnClickListener( new OnClickListener() {
@Override
public void onClick( final View buttonView ) {
MainActivity.createConfirmation( getActivity(),
DataFragment.this.getString(R.string.data_export_kml_db), MainActivity.DATA_TAB_POS, KML_DB_DIALOG);
}
});
}
private void setupBackupDbButton( final View view ) {
final Button kmlExportButton = (Button) view.findViewById( R.id.backup_db_button );
if ( ! MainActivity.hasSD() ) {
kmlExportButton.setEnabled(false);
}
kmlExportButton.setOnClickListener( new OnClickListener() {
@Override
public void onClick( final View buttonView ) {
MainActivity.createConfirmation( getActivity(),
DataFragment.this.getString(R.string.data_backup_db), MainActivity.DATA_TAB_POS, BACKUP_DIALOG);
}
});
}
private void setupImportObservedButton( final View view ) {
final Button importObservedButton = (Button) view.findViewById( R.id.import_observed_button );
importObservedButton.setOnClickListener( new OnClickListener() {
@Override
public void onClick( final View buttonView ) {
MainActivity.createConfirmation( getActivity(),
DataFragment.this.getString(R.string.data_import_observed), MainActivity.DATA_TAB_POS, IMPORT_DIALOG);
}
});
}
@SuppressLint("SetTextI18n")
private void setupMarkerButtons( final View view ) {
final SharedPreferences prefs = getActivity().getSharedPreferences(ListFragment.SHARED_PREFS, 0);
// db marker reset button and text
final TextView tv = (TextView) view.findViewById(R.id.reset_maxid_text);
tv.setText( getString(R.string.setting_high_up) + " " + prefs.getLong( ListFragment.PREF_DB_MARKER, 0L ) );
final Button resetMaxidButton = (Button) view.findViewById(R.id.reset_maxid_button);
resetMaxidButton.setOnClickListener( new OnClickListener() {
@Override
public void onClick( final View buttonView ) {
MainActivity.createConfirmation( getActivity(), getString(R.string.setting_zero_out),
MainActivity.DATA_TAB_POS, ZERO_OUT_DIALOG);
}
});
// db marker maxout button and text
final TextView maxtv = (TextView) view.findViewById(R.id.maxout_maxid_text);
final long maxDB = prefs.getLong( ListFragment.PREF_MAX_DB, 0L );
maxtv.setText( getString(R.string.setting_max_start) + " " + maxDB );
final Button maxoutMaxidButton = (Button) view.findViewById(R.id.maxout_maxid_button);
maxoutMaxidButton.setOnClickListener( new OnClickListener() {
@Override
public void onClick( final View buttonView ) {
MainActivity.createConfirmation( getActivity(), getString(R.string.setting_max_out),
MainActivity.DATA_TAB_POS, MAX_OUT_DIALOG);
}
} );
}
@SuppressLint("SetTextI18n")
@Override
public void handleDialog(final int dialogId) {
final SharedPreferences prefs = getActivity().getSharedPreferences(ListFragment.SHARED_PREFS, 0);
final SharedPreferences.Editor editor = prefs.edit();
final View view = getView();
switch (dialogId) {
case CSV_RUN_DIALOG: {
// actually need this Activity context, for dialogs
ObservationUploader observationUploader = new ObservationUploader(getActivity(),
ListFragment.lameStatic.dbHelper, DataFragment.this, true, false, true);
observationUploader.start();
break;
}
case CSV_DB_DIALOG: {
ObservationUploader observationUploader = new ObservationUploader(getActivity(),
ListFragment.lameStatic.dbHelper, DataFragment.this, true, true, false);
observationUploader.start();
break;
}
case KML_RUN_DIALOG: {
KmlWriter kmlWriter = new KmlWriter( getActivity(), ListFragment.lameStatic.dbHelper,
ListFragment.lameStatic.runNetworks );
kmlWriter.start();
break;
}
case KML_DB_DIALOG: {
KmlWriter kmlWriter = new KmlWriter( getActivity(), ListFragment.lameStatic.dbHelper );
kmlWriter.start();
break;
}
case BACKUP_DIALOG: {
BackupTask task = new BackupTask(DataFragment.this, MainActivity.getMainActivity(DataFragment.this));
task.execute();
break;
}
case IMPORT_DIALOG: {
final MainActivity mainActivity = MainActivity.getMainActivity(DataFragment.this);
if (mainActivity != null) {
mainActivity.setTransferring();
}
// actually need this Activity context, for dialogs
final ObservationImporter task = new ObservationImporter(getActivity(),
ListFragment.lameStatic.dbHelper,
new ApiListener() {
@Override
public void requestComplete(JSONObject object, boolean cached) {
if (mainActivity != null) {
mainActivity.transferComplete();
}
}
});
try {
task.startDownload(this);
} catch (WiGLEAuthException waex) {
//moot due to bundle handling
}
break;
}
case ZERO_OUT_DIALOG: {
editor.putLong( ListFragment.PREF_DB_MARKER, 0L );
editor.apply();
if (view != null) {
final TextView tv = (TextView) view.findViewById(R.id.reset_maxid_text);
tv.setText(getString(R.string.setting_max_id) + " 0");
}
break;
}
case MAX_OUT_DIALOG: {
final long maxDB = prefs.getLong( ListFragment.PREF_MAX_DB, 0L );
editor.putLong( ListFragment.PREF_DB_MARKER, maxDB );
editor.apply();
if (view != null) {
// set the text on the other button
final TextView tv = (TextView) view.findViewById(R.id.reset_maxid_text);
tv.setText(getString(R.string.setting_max_id) + " " + maxDB);
}
break;
}
default:
MainActivity.warn("Data unhandled dialogId: " + dialogId);
}
}
/**
* way to background load the data and show progress on the gui thread
*/
public static class BackupTask extends AsyncTask<Object, Integer, Integer> {
private final Fragment fragment;
private final MainActivity mainActivity;
private Pair<Boolean,String> dbResult;
public BackupTask ( final Fragment fragment, final MainActivity mainActivity ) {
this.fragment = fragment;
this.mainActivity = mainActivity;
mainActivity.setTransferring();
}
@Override
protected Integer doInBackground( Object... obj ) {
dbResult = ListFragment.lameStatic.dbHelper.copyDatabase(this);
// dbResult = new Pair<Boolean,String>(Boolean.TRUE, "meh");
return 0;
}
@SuppressLint("SetTextI18n")
@Override
protected void onProgressUpdate( Integer... progress ) {
final View view = fragment.getView();
if (view != null) {
final TextView tv = (TextView) view.findViewById( R.id.backup_db_text );
if (tv != null) {
tv.setText( mainActivity.getString(R.string.backup_db_text) + "\n" + progress[0] + "%" );
}
}
}
@Override
protected void onPostExecute( Integer result ) {
mainActivity.transferComplete();
final View view = fragment.getView();
if (view != null) {
final TextView tv = (TextView) view.findViewById( R.id.backup_db_text );
if (tv != null) {
tv.setText( mainActivity.getString(R.string.backup_db_text) );
}
}
final BackupDialog dialog = BackupDialog.newInstance(dbResult.getFirst(), dbResult.getSecond());
final FragmentManager fm = mainActivity.getSupportFragmentManager();
try {
dialog.show(fm, "backup-dialog");
}
catch (final IllegalStateException ex) {
MainActivity.error("Error showing backup dialog: " + ex, ex);
}
}
public void progress( int progress ) {
publishProgress(progress);
}
public static class BackupDialog extends DialogFragment {
public static BackupDialog newInstance(final boolean status, final String message) {
final BackupDialog frag = new BackupDialog();
final Bundle args = new Bundle();
args.putBoolean("status", status);
args.putString("message", message);
frag.setArguments(args);
return frag;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final FragmentActivity activity = getActivity();
final AlertDialog.Builder builder = new AlertDialog.Builder( activity );
builder.setCancelable( true );
final Bundle bundle = getArguments();
builder.setTitle( activity.getString( bundle.getBoolean("status") ? R.string.status_success : R.string.status_fail ));
builder.setMessage( bundle.getString("message") );
final AlertDialog ad = builder.create();
// ok
ad.setButton( DialogInterface.BUTTON_POSITIVE, activity.getString(R.string.ok), new DialogInterface.OnClickListener() {
@Override
public void onClick( final DialogInterface dialog, final int which ) {
try {
dialog.dismiss();
}
catch ( Exception ex ) {
// guess it wasn't there anyways
MainActivity.info( "exception dismissing alert dialog: " + ex );
}
} });
return ad;
}
}
}
@Override
public void onResume() {
MainActivity.info( "resume data." );
super.onResume();
getActivity().setTitle(R.string.data_activity_name);
}
/* Creates the menu items */
@Override
public void onCreateOptionsMenu (final Menu menu, final MenuInflater inflater) {
// MenuItem item = menu.add( 0, MENU_SETTINGS, 0, getString(R.string.menu_settings) );
// item.setIcon( android.R.drawable.ic_menu_preferences );
MenuItem item = menu.add( 0, MENU_ERROR_REPORT, 0, getString(R.string.menu_error_report) );
item.setIcon( android.R.drawable.ic_menu_report_image );
// item = menu.add( 0, MENU_EXIT, 0, getString(R.string.menu_exit) );
// item.setIcon( android.R.drawable.ic_menu_close_clear_cancel );
super.onCreateOptionsMenu(menu, inflater);
}
/* Handles item selections */
@Override
public boolean onOptionsItemSelected( final MenuItem item ) {
switch ( item.getItemId() ) {
case MENU_EXIT:
final MainActivity main = MainActivity.getMainActivity();
main.finish();
return true;
case MENU_ERROR_REPORT:
final Intent errorReportIntent = new Intent( getActivity(), ErrorReportActivity.class );
startActivity( errorReportIntent );
break;
}
return false;
}
}