com.dsi.ant.antplus.pluginsampler.geocache.Dialog_GeoProgramDevice.java Source code

Java tutorial

Introduction

Here is the source code for com.dsi.ant.antplus.pluginsampler.geocache.Dialog_GeoProgramDevice.java

Source

/*
This software is subject to the license described in the License.txt file
included with this software distribution. You may not use this file except in compliance
with this license.
    
Copyright (c) Dynastream Innovations Inc. 2013
All rights reserved.
 */

package com.dsi.ant.antplus.pluginsampler.geocache;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

import com.dsi.ant.antplus.pluginsampler.Dialog_ProgressWaiter;
import com.dsi.ant.antplus.pluginsampler.R;
import com.dsi.ant.plugins.antplus.pcc.AntPlusGeocachePcc;
import com.dsi.ant.plugins.antplus.pcc.AntPlusGeocachePcc.GeocacheDeviceData;
import com.dsi.ant.plugins.antplus.pcc.AntPlusGeocachePcc.GeocacheRequestStatus;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;

/**
 * Dialog to allow programming a geocache device.
 */
public class Dialog_GeoProgramDevice extends DialogFragment {
    EditText editText_IdString;
    EditText editText_PIN;
    EditText editText_Latitude;
    EditText editText_Longitude;
    EditText editText_HintString;
    EditText editText_NumVisits;
    TextView textView_LastVisitDate;
    TextView textView_LastVisitTime;

    CheckBox checkBox_EnableIdString;
    CheckBox checkBox_EnablePIN;
    CheckBox checkBox_EnableLatitude;
    CheckBox checkBox_EnableLongitude;
    CheckBox checkBox_EnableHintString;
    CheckBox checkBox_EnableLastVisit;

    RadioButton radioButton_ClearExisitingData;

    private GeocacheDeviceData deviceData;
    private AntPlusGeocachePcc geoPcc;
    private ResultReceiver resultRcvr;
    private GregorianCalendar currentDisplayDatetime;

    /**
     * Constructor.
     * @param geoPcc The PCC instance the device is available on.
     * @param currentDeviceData The current device data of the device to program.
     * @param resultReceiver The receiver to handle the results of this request.
     */
    public Dialog_GeoProgramDevice(AntPlusGeocachePcc geoPcc, GeocacheDeviceData currentDeviceData,
            ResultReceiver resultReceiver) {
        this.geoPcc = geoPcc;
        this.deviceData = currentDeviceData;
        this.resultRcvr = resultReceiver;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        builder.setTitle("Program Device " + deviceData.deviceId);
        // Get the layout inflater
        LayoutInflater inflater = getActivity().getLayoutInflater();
        View detailsView = inflater.inflate(R.layout.dialog_geocache_programdevice, null);

        // Inflate and set the layout for the dialog
        // Pass null as the parent view because its going in the dialog layout
        builder.setView(detailsView);

        // Add action buttons
        //Note we override the positive button in show() below so we can prevent it from closing
        builder.setPositiveButton("Begin Programing", null);
        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //Let dialog dismiss
            }
        });

        checkBox_EnableIdString = (CheckBox) detailsView.findViewById(R.id.checkBox_EnableIdentifcationString);
        checkBox_EnablePIN = (CheckBox) detailsView.findViewById(R.id.checkBox_EnablePIN);
        checkBox_EnableLatitude = (CheckBox) detailsView.findViewById(R.id.checkBox_EnableLatitude);
        checkBox_EnableLongitude = (CheckBox) detailsView.findViewById(R.id.checkBox_EnableLongitude);
        checkBox_EnableHintString = (CheckBox) detailsView.findViewById(R.id.checkBox_EnableHintString);
        checkBox_EnableLastVisit = (CheckBox) detailsView.findViewById(R.id.checkBox_EnableLastVisitInfo);

        final TextView textView_NumVisitsTitle = (TextView) detailsView
                .findViewById(R.id.textView_NumberOfVisitsTitle);
        final TextView textView_LastVisitDateTitle = (TextView) detailsView
                .findViewById(R.id.textView_LastVisitDateTitle);
        final TextView textView_LastVisitTimeTitle = (TextView) detailsView
                .findViewById(R.id.textView_LastVisitTimeTitle);

        editText_IdString = (EditText) detailsView.findViewById(R.id.editText_IdentificationString);
        editText_PIN = (EditText) detailsView.findViewById(R.id.editText_PIN);
        editText_Latitude = (EditText) detailsView.findViewById(R.id.editText_Latitude);
        editText_Longitude = (EditText) detailsView.findViewById(R.id.editText_Longitude);
        editText_HintString = (EditText) detailsView.findViewById(R.id.editText_HintString);
        editText_NumVisits = (EditText) detailsView.findViewById(R.id.editText_NumberOfVisits);
        textView_LastVisitDate = (TextView) detailsView.findViewById(R.id.textView_LastVisitDate);
        textView_LastVisitTime = (TextView) detailsView.findViewById(R.id.textView_LastVisitTime);

        radioButton_ClearExisitingData = (RadioButton) detailsView.findViewById(R.id.radioButton_ClearExistingData);

        //Hook up checkboxes to enable/disable fields
        checkBox_EnableIdString.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                editText_IdString.setEnabled(isChecked);
                if (isChecked && editText_IdString.getText().length() == 0)
                    editText_IdString.setText("ID STR");
            }
        });
        checkBox_EnablePIN.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                editText_PIN.setEnabled(isChecked);
                if (isChecked && editText_PIN.getText().length() == 0)
                    editText_PIN.setText("123456");
            }
        });
        checkBox_EnableLatitude.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                editText_Latitude.setEnabled(isChecked);
                if (isChecked && editText_Latitude.getText().length() == 0)
                    editText_Latitude.setText("-40.1");
            }
        });
        checkBox_EnableLongitude.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                editText_Longitude.setEnabled(isChecked);
                if (isChecked && editText_Longitude.getText().length() == 0)
                    editText_Longitude.setText("-20.1");
            }
        });
        checkBox_EnableHintString.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                editText_HintString.setEnabled(isChecked);
                if (isChecked && editText_HintString.getText().length() == 0)
                    editText_HintString.setText("Hint string.");
            }
        });
        checkBox_EnableLastVisit.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                textView_NumVisitsTitle.setEnabled(isChecked);
                textView_LastVisitDateTitle.setEnabled(isChecked);
                textView_LastVisitTimeTitle.setEnabled(isChecked);
                editText_NumVisits.setEnabled(isChecked);
                textView_LastVisitDate.setEnabled(isChecked);
                textView_LastVisitTime.setEnabled(isChecked);

                if (isChecked) {
                    if (editText_NumVisits.length() == 0)
                        editText_NumVisits.setText("0");
                    if (textView_LastVisitDate.length() == 0)
                        textView_LastVisitDate.setText("dd/mmm/yyyy");
                    if (textView_LastVisitTime.length() == 0)
                        textView_LastVisitDate.setText("hh:mm");
                }
            }
        });

        //Set data
        editText_IdString.setText(String.valueOf(deviceData.programmableData.identificationString));
        editText_PIN.setText(String.valueOf(deviceData.programmableData.PIN));

        if (deviceData.programmableData.latitude != null)
            editText_Latitude.setText(
                    String.valueOf(deviceData.programmableData.latitude.setScale(5, BigDecimal.ROUND_HALF_UP)));
        else
            editText_Latitude.setText("");

        if (deviceData.programmableData.longitude != null)
            editText_Longitude.setText(
                    String.valueOf(deviceData.programmableData.longitude.setScale(5, BigDecimal.ROUND_HALF_UP)));
        else
            editText_Longitude.setText("");

        if (deviceData.programmableData.hintString != null)
            editText_HintString.setText(String.valueOf(deviceData.programmableData.hintString));
        else
            editText_HintString.setText("");

        if (deviceData.programmableData.numberOfVisits != null)
            editText_NumVisits.setText(String.valueOf(deviceData.programmableData.numberOfVisits));
        else
            editText_NumVisits.setText("");

        if (deviceData.programmableData.lastVisitTimestamp != null) {
            currentDisplayDatetime = deviceData.programmableData.lastVisitTimestamp;
            updateDateAndTime();
        } else {
            textView_LastVisitDate.setText("");
            textView_LastVisitTime.setText("");
        }

        //Hook up date and time fields to pickers
        textView_LastVisitDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (currentDisplayDatetime == null)
                    currentDisplayDatetime = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
                DatePickerDialog d = new DatePickerDialog(getActivity(), new OnDateSetListener() {
                    @Override
                    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                        currentDisplayDatetime.set(year, monthOfYear, dayOfMonth);
                        updateDateAndTime();
                    }
                }, currentDisplayDatetime.get(Calendar.YEAR), currentDisplayDatetime.get(Calendar.MONTH),
                        currentDisplayDatetime.get(Calendar.DAY_OF_MONTH));
                d.show();
            }
        });

        textView_LastVisitTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (currentDisplayDatetime == null)
                    currentDisplayDatetime = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
                TimePickerDialog d = new TimePickerDialog(getActivity(), new OnTimeSetListener() {
                    @Override
                    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                        currentDisplayDatetime.set(Calendar.HOUR_OF_DAY, hourOfDay);
                        currentDisplayDatetime.set(Calendar.MINUTE, minute);
                        updateDateAndTime();
                    }
                }, currentDisplayDatetime.get(Calendar.HOUR_OF_DAY), currentDisplayDatetime.get(Calendar.MINUTE),
                        false);
                d.show();
            }
        });

        return builder.create();
    }

    /**
     * Updates the last visit date and time display.
     */
    public void updateDateAndTime() {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                SimpleDateFormat df = new SimpleDateFormat("d MMM yyyy", Locale.CANADA);
                df.setTimeZone(TimeZone.getTimeZone("UTC"));
                SimpleDateFormat tf = new SimpleDateFormat("h:mm a", Locale.CANADA);
                tf.setTimeZone(TimeZone.getTimeZone("UTC"));
                Date d = currentDisplayDatetime.getTime();
                textView_LastVisitDate.setText(df.format(d));
                textView_LastVisitTime.setText(tf.format(d));
            }
        });
    }

    @Override
    public void onStart() {
        super.onStart(); //super.onStart() is where dialog.show() is actually called on the underlying dialog, so we have to do it after this point
        AlertDialog d = (AlertDialog) getDialog();
        if (d != null) {
            Button positiveButton = d.getButton(Dialog.BUTTON_POSITIVE);
            positiveButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //Read in user set values
                    final GeocacheDeviceData newDeviceData = new GeocacheDeviceData();

                    if (checkBox_EnableIdString.isChecked())
                        newDeviceData.programmableData.identificationString = editText_IdString.getText()
                                .toString();

                    if (checkBox_EnablePIN.isChecked())
                        newDeviceData.programmableData.PIN = Long.parseLong(editText_PIN.getText().toString());

                    if (checkBox_EnableLatitude.isChecked())
                        newDeviceData.programmableData.latitude = new BigDecimal(
                                editText_Latitude.getText().toString());

                    if (checkBox_EnableLongitude.isChecked())
                        newDeviceData.programmableData.longitude = new BigDecimal(
                                editText_Longitude.getText().toString());

                    if (checkBox_EnableHintString.isChecked())
                        newDeviceData.programmableData.hintString = editText_HintString.getText().toString();

                    if (checkBox_EnableLastVisit.isChecked()) {
                        newDeviceData.programmableData.numberOfVisits = Integer
                                .parseInt(editText_NumVisits.getText().toString());
                        newDeviceData.programmableData.lastVisitTimestamp = currentDisplayDatetime;
                    }

                    final Dialog_ProgressWaiter progressDialog = new Dialog_ProgressWaiter("Programming Device");

                    //Use the current deviceID and PIN
                    boolean reqSubmitted = geoPcc.requestDeviceProgramming(deviceData.deviceId,
                            deviceData.programmableData.PIN, radioButton_ClearExisitingData.isChecked(),
                            newDeviceData.programmableData, new AntPlusGeocachePcc.IProgrammingFinishedReceiver() {
                                @Override
                                public void onNewProgrammingFinished(GeocacheRequestStatus status) {
                                    StringBuilder error = new StringBuilder("Error Programming: ");

                                    switch (status) {
                                    case SUCCESS:
                                        getActivity().runOnUiThread(new Runnable() {
                                            @Override
                                            public void run() {
                                                progressDialog.dismiss();
                                                Bundle b = new Bundle();
                                                b.putParcelable(
                                                        GeocacheDeviceData.KEY_DEFAULT_GEOCACHEDEVICEDATAKEY,
                                                        newDeviceData);
                                                resultRcvr.send(0, b);
                                                dismiss();
                                            }
                                        });
                                        return;

                                    case FAIL_DEVICE_COMMUNICATION_FAILURE:
                                        //When this occurs, it also results in the device being removed from the list,
                                        //we should bail to scan screen on this result
                                        getActivity().runOnUiThread(new Runnable() {
                                            @Override
                                            public void run() {
                                                progressDialog.dismiss();
                                                resultRcvr.send(-1, null);
                                                dismiss();
                                            }
                                        });
                                        return;

                                    case FAIL_DEVICE_NOT_IN_LIST:
                                        error.append("Device no longer in list");
                                        break;
                                    case FAIL_ALREADY_BUSY_EXTERNAL:
                                        error.append("Device is busy");
                                        break;
                                    case FAIL_BAD_PARAMS:
                                        error.append("Bad Parameters");
                                        break;
                                    case FAIL_NO_PERMISSION:
                                        error.append("No Permission"); //shouldn't happen ever here because we always send matching PIN
                                        break;
                                    case FAIL_DEVICE_DATA_NOT_DOWNLOADED:
                                        error.append("Device Data Not Downloaded");
                                        break;
                                    case UNRECOGNIZED:
                                        //TODO This flag indicates that an unrecognized value was sent by the service, an upgrade of your PCC may be required to handle this new value.
                                        error.append("Unrecognized failure");
                                        break;
                                    }

                                    final String errorStr = error.toString();
                                    getActivity().runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            progressDialog.dismiss();
                                            Toast.makeText(getActivity(), errorStr, Toast.LENGTH_LONG).show();
                                        }
                                    });
                                }
                            }, progressDialog.getUpdateReceiver());

                    if (reqSubmitted)
                        progressDialog.show(getActivity().getSupportFragmentManager(), "ProgrammingProgressDialog");
                    else
                        Toast.makeText(getActivity(), "Error Programming Device: PCC already busy or dead",
                                Toast.LENGTH_SHORT).show();

                    //now both dialogs stay open. They get closed in the programming result handler.
                }
            });
        }
    }
}