Files
MINDdroidCV/MINDdroidCV_MINDSTORMS/src/com/lego/minddroid/NXJUploader.java
2011-10-12 13:16:02 +02:00

400 lines
13 KiB
Java

/**
* Copyright 2011 Guenther Hoelzl
*
* This file is part of MINDdroid.
*
* MINDdroid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MINDdroid is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MINDdroid. If not, see <http://www.gnu.org/licenses/>.
**/
package com.lego.minddroid;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
/**
* This class is for uploading programs to the NXT brick via Bluetooth.
* Special programs will be able to communicate with MINDdroid, so no PC
* is required for playing with a robot.
*/
public class NXJUploader extends Activity implements UploadThreadListener, DialogListener, BTConnectable
{
private static final int DIALOG_NXT = 0;
private static final int DIALOG_FILE = 1;
// preinstalled modules on res/raw/directoy
private static String[] preinstalledNXJstring = new String[]
{ "AlphaRex.nxj",
"MINDGameZ.nxj"
};
private static final int REQUEST_CONNECT_DEVICE = 1000;
private static final int REQUEST_ENABLE_BT = 2000;
private BTCommunicator mNXT;
private UploadThread uploadThread;
private Handler handler;
private ProgressDialog progressDialog;
private int uploadStatus;
private int runningDialog;
private boolean pairing;
private boolean btErrorPending = false;
private static boolean btOnByUs = false;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.nxjuploader);
initLayout();
// Create objects for communication
mNXT = new BTCommunicator(this, null, BluetoothAdapter.getDefaultAdapter(), getResources());
handler = new Handler();
// Create and launch the upload thread
uploadThread = new UploadThread(this, getResources());
uploadThread.setBluetoothCommunicator(mNXT);
uploadThread.start();
}
@Override
protected void onStart() {
super.onStart();
if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
}
/**
* Called when the activity is destroyed.
*/
@Override
protected void onDestroy() {
super.onDestroy();
// request the uploadthread to stop
uploadThread.requestStop();
}
/**
* Asks if bluetooth was switched on during the runtime of the app. For saving
* battery we switch it off when the app is terminated.
* @return true, when bluetooth was switched on by the app
*/
public static boolean isBtOnByUs() {
return btOnByUs;
}
/**
* Sets a flag when bluetooth was switched on durin runtime
* @param btOnByUs true, when bluetooth was switched on by the app
*/
public static void setBtOnByUs(boolean btOnByUs) {
NXJUploader.btOnByUs = btOnByUs;
}
/**
* @return true, when currently pairing
*/
@Override
public boolean isPairing() {
return pairing;
}
/**
* Displays a message as a toast
*/
public void showToast(String message) {
Toast toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
toast.show();
return;
}
/**
* Displays a message from resID as a toast
*/
public void showToast(int resID) {
Toast toast = Toast.makeText(this, resID, Toast.LENGTH_SHORT);
toast.show();
return;
}
/**
* Displays resp. updates a progress dialog
*/
public void showProgressDialog(String message, int maxProgress, int currentProgress) {
boolean initialized = false;
if (progressDialog == null) {
initialized = true;
progressDialog = new ProgressDialog(this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(false);
progressDialog.setMessage(message);
}
progressDialog.setMax(maxProgress);
progressDialog.setProgress(currentProgress);
if (initialized)
progressDialog.show();
}
/**
* Displays resp. updates a progress dialog
*/
public void showProgressDialog(String message) {
if (progressDialog == null) {
progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
progressDialog.setMessage(message);
progressDialog.show();
}
}
/**
* Dismisses an existing progress dialog
*/
public void dismissProgressDialog() {
if (progressDialog != null) {
progressDialog.dismiss();
progressDialog = null;
}
}
/**
* Initializes the values on the main screen
*/
private void initLayout() {
initNXTButton();
initFileButton();
initUploadButton();
}
/**
* Initializes the "SELECT NXT" button
*/
private void initNXTButton() {
Button fileButton = (Button) findViewById(R.id.nxt_button);
fileButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
selectNXT();
}
});
}
/**
* Initializes the "SELECT FILE" button
*/
private void initFileButton() {
Button fileButton = (Button) findViewById(R.id.file_button);
fileButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
showFileDialog();
}
});
}
/**
* Starts the NXT selection activity
*/
private void selectNXT() {
Intent serverIntent = new Intent(this, DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
}
/**
* Shows the file dialog
*/
private void showFileDialog() {
NXJFileDialog fileDialog = new NXJFileDialog(this, this);
if (fileDialog.refreshFileList(preinstalledNXJstring) == 0)
showToast(R.string.nxj_no_files);
else {
runningDialog = DIALOG_FILE;
fileDialog.show();
}
}
/*
* This is the method for returning values of dialogs
* @param the selected text
*/
@Override
public void dialogUpdate(String text) {
TextView textView;
switch (runningDialog) {
case DIALOG_NXT:
textView = (TextView) findViewById(R.id.nxt_name);
textView.setText(text);
break;
case DIALOG_FILE:
textView = (TextView) findViewById(R.id.nxj_file_name);
textView.setText(text);
break;
}
}
/**
* Initializes the "UPLOAD" button
*/
private void initUploadButton() {
Button uploadButton = (Button) findViewById(R.id.upload_button);
uploadButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
TextView nxtTextView = (TextView) findViewById(R.id.nxt_name);
String macAddress = nxtTextView.getText().toString();
if (macAddress.compareTo("") == 0) {
showToast(R.string.nxj_please_select_nxt);
return;
}
macAddress = macAddress.substring(macAddress.lastIndexOf('-')+1);
TextView nxjTextView = (TextView) findViewById(R.id.nxj_file_name);
String fileName = nxjTextView.getText().toString();
if (fileName.compareTo("") == 0) {
showToast(R.string.nxj_please_select_file);
return;
}
uploadThread.enqueueUpload(macAddress, fileName);
}
});
}
/**
* This will be called by the UploadThread to signal an update of the
* current status.
* @param status The current state of the UploadThread
*/
@Override
public void handleUploadThreadUpdate(final int status) {
handler.post(new Runnable() {
@Override
public void run() {
if (status != uploadStatus) {
dismissProgressDialog();
uploadStatus = status;
}
showUploadStatus();
}
});
}
/**
* Shows the current status of the uploader either in
* a progress bar or in toast in case of an error.
*/
private void showUploadStatus() {
switch (uploadStatus) {
case UploadThread.CONNECTING:
showProgressDialog(getResources().getString(R.string.nxj_connecting));
break;
case UploadThread.UPLOADING:
showProgressDialog(getResources().getString(R.string.nxj_uploading),
uploadThread.getFileLength(),
uploadThread.getBytesUploaded());
break;
default:
dismissProgressDialog();
}
switch (uploadThread.getErrorCode()) {
case UploadThread.NO_ERROR:
break;
case UploadThread.OPEN_BT_ERROR:
if (pairing)
showToast(R.string.nxj_bluetooth_pairing);
else
showBTErrorDialog();
break;
case UploadThread.CLOSE_BT_ERROR:
showBTErrorDialog();
break;
case UploadThread.OPEN_FILE_ERROR:
showToast(R.string.nxj_file_open_error);
break;
case UploadThread.UPLOAD_ERROR:
showBTErrorDialog();
break;
default:
showToast(R.string.nxj_other_error);
}
uploadThread.resetErrorCode();
}
/**
* Shows an error dialog when there's an error regarding
* bluettooth transfer.
*/
private void showBTErrorDialog() {
if (btErrorPending == false) {
btErrorPending = true;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getResources().getString(R.string.bt_error_dialog_title))
.setMessage(getResources().getString(R.string.bt_error_dialog_message)).setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
btErrorPending = false;
dialog.cancel();
}
});
builder.create().show();
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CONNECT_DEVICE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
// Get the device infos
String infos = data.getExtras().getString(DeviceListActivity.DEVICE_NAME_AND_ADDRESS);
pairing = data.getExtras().getBoolean(DeviceListActivity.PAIRING);
TextView textView = (TextView) findViewById(R.id.nxt_name);
textView.setText(infos);
}
break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
switch (resultCode) {
case Activity.RESULT_OK:
btOnByUs = true;
break;
case Activity.RESULT_CANCELED:
showToast(R.string.bt_needs_to_be_enabled);
finish();
break;
}
break;
}
}
}