Application version 1.14.2.

Disconnecting event added.
Aligning with DFU lib changes.
Graddle version 1.2.3.
This commit is contained in:
Aleksander Nowakowski
2015-07-22 14:25:29 +02:00
parent 4d4771ccc3
commit 57bb54637f
11 changed files with 131 additions and 148 deletions

View File

@@ -69,6 +69,8 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.2.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/design/22.2.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
@@ -89,10 +91,10 @@
<orderEntry type="library" exported="" name="gson-2.3.1" level="project" /> <orderEntry type="library" exported="" name="gson-2.3.1" level="project" />
<orderEntry type="library" exported="" name="design-22.2.0" level="project" /> <orderEntry type="library" exported="" name="design-22.2.0" level="project" />
<orderEntry type="library" exported="" name="nrf-logger-v2.0" level="project" /> <orderEntry type="library" exported="" name="nrf-logger-v2.0" level="project" />
<orderEntry type="library" exported="" name="support-v4-22.2.0" level="project" /> <orderEntry type="library" exported="" name="support-v4-22.2.1" level="project" />
<orderEntry type="library" exported="" name="support-annotations-22.2.0" level="project" />
<orderEntry type="library" exported="" name="achartengine-1.1.0" level="project" /> <orderEntry type="library" exported="" name="achartengine-1.1.0" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-22.2.0" level="project" /> <orderEntry type="library" exported="" name="support-annotations-22.2.1" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-22.2.1" level="project" />
<orderEntry type="module" module-name="dfu" exported="" /> <orderEntry type="module" module-name="dfu" exported="" />
</component> </component>
</module> </module>

View File

@@ -7,8 +7,8 @@ android {
applicationId "no.nordicsemi.android.nrftoolbox" applicationId "no.nordicsemi.android.nrftoolbox"
minSdkVersion 18 minSdkVersion 18
targetSdkVersion 22 targetSdkVersion 22
versionCode 34 versionCode 35
versionName "1.14.1" versionName "1.14.2"
} }
buildTypes { buildTypes {
release { release {
@@ -20,7 +20,7 @@ android {
dependencies { dependencies {
compile fileTree(dir: 'libs', include: ['*.jar']) compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0' compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.android.support:design:22.2.0' compile 'com.android.support:design:22.2.0'
compile project(':dfu') compile project(':dfu')
compile files('libs/achartengine-1.1.0.jar') compile files('libs/achartengine-1.1.0.jar')

View File

@@ -23,8 +23,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="no.nordicsemi.android.nrftoolbox" package="no.nordicsemi.android.nrftoolbox"
android:installLocation="auto" android:installLocation="auto"
android:versionCode="34" android:versionCode="35"
android:versionName="1.14.1" > android:versionName="1.14.2" >
<uses-sdk <uses-sdk
android:minSdkVersion="18" android:minSdkVersion="18"

View File

@@ -28,12 +28,10 @@ import android.app.NotificationManager;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.CursorLoader; import android.content.CursorLoader;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.content.Loader; import android.content.Loader;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@@ -64,7 +62,10 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import no.nordicsemi.android.error.GattError; import no.nordicsemi.android.dfu.DfuProgressListener;
import no.nordicsemi.android.dfu.DfuProgressListenerAdapter;
import no.nordicsemi.android.dfu.DfuServiceListenerHelper;
import no.nordicsemi.android.dfu.DfuServiceInitiator;
import no.nordicsemi.android.nrftoolbox.AppHelpFragment; import no.nordicsemi.android.nrftoolbox.AppHelpFragment;
import no.nordicsemi.android.nrftoolbox.R; import no.nordicsemi.android.nrftoolbox.R;
import no.nordicsemi.android.nrftoolbox.dfu.adapter.FileBrowserAppsAdapter; import no.nordicsemi.android.nrftoolbox.dfu.adapter.FileBrowserAppsAdapter;
@@ -127,32 +128,93 @@ public class DfuActivity extends AppCompatActivity implements LoaderCallbacks<Cu
private int mFileTypeTmp; // This value is being used when user is selecting a file not to overwrite the old value (in case he/she will cancel selecting file) private int mFileTypeTmp; // This value is being used when user is selecting a file not to overwrite the old value (in case he/she will cancel selecting file)
private boolean mStatusOk; private boolean mStatusOk;
private final BroadcastReceiver mDfuUpdateReceiver = new BroadcastReceiver() { private final DfuProgressListener mDfuProgressListener = new DfuProgressListenerAdapter() {
@Override @Override
public void onReceive(final Context context, final Intent intent) { public void onDeviceConnecting(final String deviceAddress) {
// DFU is in progress or an error occurred mProgressBar.setIndeterminate(true);
final String action = intent.getAction(); mTextPercentage.setText(R.string.dfu_status_connecting);
}
if (DfuService.BROADCAST_PROGRESS.equals(action)) { @Override
final int progress = intent.getIntExtra(DfuService.EXTRA_DATA, 0); public void onDfuProcessStarting(final String deviceAddress) {
final int currentPart = intent.getIntExtra(DfuService.EXTRA_PART_CURRENT, 1); mProgressBar.setIndeterminate(true);
final int totalParts = intent.getIntExtra(DfuService.EXTRA_PARTS_TOTAL, 1); mTextPercentage.setText(R.string.dfu_status_starting);
updateProgressBar(progress, currentPart, totalParts, false, false); }
} else if (DfuService.BROADCAST_ERROR.equals(action)) {
final int error = intent.getIntExtra(DfuService.EXTRA_DATA, 0);
final boolean connectionStateError = intent.getIntExtra(DfuService.EXTRA_ERROR_TYPE, DfuService.ERROR_TYPE_OTHER) == DfuService.ERROR_TYPE_COMMUNICATION_STATE;
updateProgressBar(error, 0, 0, true, connectionStateError);
// We have to wait a bit before canceling notification. This is called before DfuService creates the last notification. @Override
new Handler().postDelayed(new Runnable() { public void onEnablingDfuMode(final String deviceAddress) {
@Override mProgressBar.setIndeterminate(true);
public void run() { mTextPercentage.setText(R.string.dfu_status_switching_to_dfu);
// if this activity is still open and upload process was completed, cancel the notification }
final NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(DfuService.NOTIFICATION_ID); @Override
} public void onFirmwareValidating(final String deviceAddress) {
}, 200); mProgressBar.setIndeterminate(true);
} mTextPercentage.setText(R.string.dfu_status_validating);
}
@Override
public void onDeviceDisconnecting(final String deviceAddress) {
mProgressBar.setIndeterminate(true);
mTextPercentage.setText(R.string.dfu_status_disconnecting);
}
@Override
public void onDfuCompleted(final String deviceAddress) {
mTextPercentage.setText(R.string.dfu_status_completed);
// let's wait a bit until we cancel the notification. When canceled immediately it will be recreated by service again.
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
onTransferCompleted();
// if this activity is still open and upload process was completed, cancel the notification
final NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(DfuService.NOTIFICATION_ID);
}
}, 200);
}
@Override
public void onDfuAborted(final String deviceAddress) {
mTextPercentage.setText(R.string.dfu_status_aborted);
// let's wait a bit until we cancel the notification. When canceled immediately it will be recreated by service again.
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
onUploadCanceled();
// if this activity is still open and upload process was completed, cancel the notification
final NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(DfuService.NOTIFICATION_ID);
}
}, 200);
}
@Override
public void onProgressChanged(final String deviceAddress, final int percent, final float speed, final float avgSpeed, final int currentPart, final int partsTotal) {
mProgressBar.setIndeterminate(false);
mProgressBar.setProgress(percent);
mTextPercentage.setText(getString(R.string.progress, percent));
if (partsTotal > 1)
mTextUploading.setText(getString(R.string.dfu_status_uploading_part, currentPart, partsTotal));
else
mTextUploading.setText(R.string.dfu_status_uploading);
}
@Override
public void onError(final String deviceAddress, final int error, final int errorType, final String message) {
showErrorMessage(message);
// We have to wait a bit before canceling notification. This is called before DfuService creates the last notification.
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// if this activity is still open and upload process was completed, cancel the notification
final NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(DfuService.NOTIFICATION_ID);
}
}, 200);
} }
}; };
@@ -231,25 +293,14 @@ public class DfuActivity extends AppCompatActivity implements LoaderCallbacks<Cu
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
// We are using LocalBroadcastReceiver instead of normal BroadcastReceiver for optimization purposes DfuServiceListenerHelper.registerProgressListener(this, mDfuProgressListener);
final LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(this);
broadcastManager.registerReceiver(mDfuUpdateReceiver, makeDfuUpdateIntentFilter());
} }
@Override @Override
protected void onPause() { protected void onPause() {
super.onPause(); super.onPause();
final LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(this); DfuServiceListenerHelper.unregisterProgressListener(this, mDfuProgressListener);
broadcastManager.unregisterReceiver(mDfuUpdateReceiver);
}
private static IntentFilter makeDfuUpdateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(DfuService.BROADCAST_PROGRESS);
intentFilter.addAction(DfuService.BROADCAST_ERROR);
intentFilter.addAction(DfuService.BROADCAST_LOG);
return intentFilter;
} }
private void isBLESupported() { private void isBLESupported() {
@@ -743,17 +794,15 @@ public class DfuActivity extends AppCompatActivity implements LoaderCallbacks<Cu
final boolean keepBond = preferences.getBoolean(SettingsFragment.SETTINGS_KEEP_BOND, false); final boolean keepBond = preferences.getBoolean(SettingsFragment.SETTINGS_KEEP_BOND, false);
final Intent service = new Intent(this, DfuService.class); final DfuServiceInitiator starter = new DfuServiceInitiator(mSelectedDevice.getAddress())
service.putExtra(DfuService.EXTRA_DEVICE_ADDRESS, mSelectedDevice.getAddress()); .setDeviceName(mSelectedDevice.getName())
service.putExtra(DfuService.EXTRA_DEVICE_NAME, mSelectedDevice.getName()); .setKeepBond(keepBond);
service.putExtra(DfuService.EXTRA_FILE_MIME_TYPE, mFileType == DfuService.TYPE_AUTO ? DfuService.MIME_TYPE_ZIP : DfuService.MIME_TYPE_OCTET_STREAM); if (mFileType == DfuService.TYPE_AUTO)
service.putExtra(DfuService.EXTRA_FILE_TYPE, mFileType); starter.setZip(mFileStreamUri, mFilePath);
service.putExtra(DfuService.EXTRA_FILE_PATH, mFilePath); else {
service.putExtra(DfuService.EXTRA_FILE_URI, mFileStreamUri); starter.setBinOrHex(mFileType, mFileStreamUri, mFilePath).setInitFile(mInitFileStreamUri, mInitFilePath);
service.putExtra(DfuService.EXTRA_INIT_FILE_PATH, mInitFilePath); }
service.putExtra(DfuService.EXTRA_INIT_FILE_URI, mInitFileStreamUri); starter.start(this, DfuService.class);
service.putExtra(DfuService.EXTRA_KEEP_BOND, keepBond);
startService(service);
} }
private void showUploadCancelDialog() { private void showUploadCancelDialog() {
@@ -789,72 +838,6 @@ public class DfuActivity extends AppCompatActivity implements LoaderCallbacks<Cu
// do nothing // do nothing
} }
private void updateProgressBar(final int progress, final int part, final int total, final boolean error, final boolean connectionError) {
switch (progress) {
case DfuService.PROGRESS_CONNECTING:
mProgressBar.setIndeterminate(true);
mTextPercentage.setText(R.string.dfu_status_connecting);
break;
case DfuService.PROGRESS_STARTING:
mProgressBar.setIndeterminate(true);
mTextPercentage.setText(R.string.dfu_status_starting);
break;
case DfuService.PROGRESS_ENABLING_DFU_MODE:
mProgressBar.setIndeterminate(true);
mTextPercentage.setText(R.string.dfu_status_switching_to_dfu);
break;
case DfuService.PROGRESS_VALIDATING:
mProgressBar.setIndeterminate(true);
mTextPercentage.setText(R.string.dfu_status_validating);
break;
case DfuService.PROGRESS_DISCONNECTING:
mProgressBar.setIndeterminate(true);
mTextPercentage.setText(R.string.dfu_status_disconnecting);
break;
case DfuService.PROGRESS_COMPLETED:
mTextPercentage.setText(R.string.dfu_status_completed);
// let's wait a bit until we cancel the notification. When canceled immediately it will be recreated by service again.
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
onTransferCompleted();
// if this activity is still open and upload process was completed, cancel the notification
final NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(DfuService.NOTIFICATION_ID);
}
}, 200);
break;
case DfuService.PROGRESS_ABORTED:
mTextPercentage.setText(R.string.dfu_status_aborted);
// let's wait a bit until we cancel the notification. When canceled immediately it will be recreated by service again.
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
onUploadCanceled();
// if this activity is still open and upload process was completed, cancel the notification
final NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(DfuService.NOTIFICATION_ID);
}
}, 200);
break;
default:
mProgressBar.setIndeterminate(false);
if (error) {
showErrorMessage(progress, connectionError);
} else {
mProgressBar.setProgress(progress);
mTextPercentage.setText(getString(R.string.progress, progress));
if (total > 1)
mTextUploading.setText(getString(R.string.dfu_status_uploading_part, part, total));
else
mTextUploading.setText(R.string.dfu_status_uploading);
}
break;
}
}
private void showProgressBar() { private void showProgressBar() {
mProgressBar.setVisibility(View.VISIBLE); mProgressBar.setVisibility(View.VISIBLE);
mTextPercentage.setVisibility(View.VISIBLE); mTextPercentage.setVisibility(View.VISIBLE);
@@ -884,12 +867,9 @@ public class DfuActivity extends AppCompatActivity implements LoaderCallbacks<Cu
mTextPercentage.setText(null); mTextPercentage.setText(null);
} }
private void showErrorMessage(final int code, final boolean connectionError) { private void showErrorMessage(final String message) {
clearUI(false); clearUI(false);
if (connectionError) showToast("Upload failed: " + message);
showToast("Upload failed: " + GattError.parseConnectionError(code));
else
showToast("Upload failed: " + GattError.parse(code));
} }
private void clearUI(final boolean clearDevice) { private void clearUI(final boolean clearDevice) {

View File

@@ -204,15 +204,19 @@ public abstract class BleManager<E extends BleManagerCallbacks> {
/** /**
* Disconnects from the device. Does nothing if not connected. * Disconnects from the device. Does nothing if not connected.
* @return true if device is to be disconnected. False if it was already disconnected.
*/ */
public void disconnect() { public boolean disconnect() {
mUserDisconnected = true; mUserDisconnected = true;
if (mConnected && mBluetoothGatt != null) { if (mConnected && mBluetoothGatt != null) {
Logger.v(mLogSession, "Disconnecting..."); Logger.v(mLogSession, "Disconnecting...");
mCallbacks.onDeviceDisconnecting();
Logger.d(mLogSession, "gatt.disconnect()"); Logger.d(mLogSession, "gatt.disconnect()");
mBluetoothGatt.disconnect(); mBluetoothGatt.disconnect();
return true;
} }
return false;
} }
/** /**
@@ -618,7 +622,7 @@ public abstract class BleManager<E extends BleManagerCallbacks> {
@Override @Override
public final void onConnectionStateChange(final BluetoothGatt gatt, final int status, final int newState) { public final void onConnectionStateChange(final BluetoothGatt gatt, final int status, final int newState) {
Logger.v(mLogSession, "[Callback] Connection state changed with status: " + status + " and new state: " + newState + " (" + stateToString(newState) + ")"); Logger.d(mLogSession, "[Callback] Connection state changed with status: " + status + " and new state: " + newState + " (" + stateToString(newState) + ")");
if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) { if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) {
// Notify the parent activity/service // Notify the parent activity/service

View File

@@ -33,7 +33,7 @@ public interface BleManagerCallbacks {
public void onDeviceConnected(); public void onDeviceConnected();
/** /**
* Called when user pressed the DISCONNECT button. * Called when user initialized disconnection.
*/ */
public void onDeviceDisconnecting(); public void onDeviceDisconnecting();
@@ -43,8 +43,8 @@ public interface BleManagerCallbacks {
public void onDeviceDisconnected(); public void onDeviceDisconnected();
/** /**
* Some profiles may use this method to notify user that the link was lost. You must call this method in your Ble Manager instead of {@link #onDeviceDisconnected()} while you discover * This callback is invoked when the Ble Manager lost connection to a device that has been connected with autoConnect option. Otherwise a {@link #onDeviceDisconnected()}
* disconnection not initiated by the user. * method will be called on such event.
*/ */
public void onLinklossOccur(); public void onLinklossOccur();
@@ -64,7 +64,7 @@ public interface BleManagerCallbacks {
public void onDeviceReady(); public void onDeviceReady();
/** /**
* Called when battery value has been received from the device * Called when battery value has been received from the device.
* *
* @param value * @param value
* the battery value in percent * the battery value in percent
@@ -77,7 +77,7 @@ public interface BleManagerCallbacks {
public void onBondingRequired(); public void onBondingRequired();
/** /**
* Called when the device has been successfully bonded * Called when the device has been successfully bonded.
*/ */
public void onBonded(); public void onBonded();
@@ -92,7 +92,7 @@ public interface BleManagerCallbacks {
public void onError(final String message, final int errorCode); public void onError(final String message, final int errorCode);
/** /**
* Called when service discovery has finished but the main services were not found on the device. This may occur when connecting to bonded device that does not support required services. * Called when service discovery has finished but the main services were not found on the device.
*/ */
public void onDeviceNotSupported(); public void onDeviceNotSupported();
} }

View File

@@ -82,18 +82,12 @@ public abstract class BleProfileService extends Service implements BleManagerCal
* Disconnects from the sensor. * Disconnects from the sensor.
*/ */
public final void disconnect() { public final void disconnect() {
onDeviceDisconnecting();
if (!mConnected) { if (!mConnected) {
mBleManager.close(); mBleManager.close();
onDeviceDisconnected(); onDeviceDisconnected();
return; return;
} }
// Notify user about changing the state to DISCONNECTING
final Intent broadcast = new Intent(BROADCAST_CONNECTION_STATE);
broadcast.putExtra(EXTRA_CONNECTION_STATE, STATE_DISCONNECTING);
LocalBroadcastManager.getInstance(BleProfileService.this).sendBroadcast(broadcast);
mBleManager.disconnect(); mBleManager.disconnect();
} }
@@ -278,7 +272,10 @@ public abstract class BleProfileService extends Service implements BleManagerCal
@Override @Override
public void onDeviceDisconnecting() { public void onDeviceDisconnecting() {
// do nothing // Notify user about changing the state to DISCONNECTING
final Intent broadcast = new Intent(BROADCAST_CONNECTION_STATE);
broadcast.putExtra(EXTRA_CONNECTION_STATE, STATE_DISCONNECTING);
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
} }
@Override @Override

View File

@@ -398,7 +398,6 @@ public abstract class BleProfileServiceReadyActivity<E extends BleProfileService
showDeviceScanningDialog(getFilterUUID(), isDiscoverableRequired()); showDeviceScanningDialog(getFilterUUID(), isDiscoverableRequired());
} else { } else {
Logger.v(mLogSession, "Disconnecting..."); Logger.v(mLogSession, "Disconnecting...");
onDeviceDisconnecting();
mService.disconnect(); mService.disconnect();
} }
} else { } else {

View File

@@ -230,9 +230,10 @@ public class ProximityManager extends BleManager<ProximityManagerCallbacks> {
} }
@Override @Override
public void disconnect() { public boolean disconnect() {
super.disconnect(); final boolean result = super.disconnect();
closeGattServer(); closeGattServer();
return result;
} }
@Override @Override

View File

@@ -5,7 +5,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:1.1.0' classpath 'com.android.tools.build:gradle:1.2.3'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files

Binary file not shown.