This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Cannot get Android-DFU-Library to "start"

I am trying to use the Android-DFU-Library.  I have successfully implemented it in my project (the implementation key in gradle). However, even utilizing the documentation and example programs, I cannot get it to work.  (I have made the iOS version work)

I created my DfuProgressListener, I have created a DfuServiceInitiator, I have set the path fo the ZIP file (via setZip), and when I call "start"... nothing.  Note, I am not doing this inside of an activity.  This code is part of an Android library (AAR) that we use for isolating our bluetooth subsystem from companies we license our devices to.  We handle all the low level BLE operations in here, such as setting up and enabling all our custom characteristics, as well as taking data we receive from our device and putting it into packages to return.  The "context" that is passed in is the application context of the app that instantiates this library. 

My code:

public void updateGen2Firmware(Context context, String path) {
Log.v (TAG, "Starting");

final DfuServiceInitiator starter = new DfuServiceInitiator(macAddress).setDeviceName(deviceName).setKeepBond(false);
starter.setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true);

Log.v (TAG, "Setting zip to: " + path);

starter.setZip(path);

Log.v (TAG, "setting up progress listener");
DfuServiceListenerHelper.registerProgressListener(context, mDfuProgressListener);

Log.v (TAG, "calling the 'start' of starter");

starter.start(context, DfuBaseService.class);
}



  • Hello,

    You have to extend the DfuBaseService.class with your own class. The base one is abstract and requires few methods to be overridden. Have a look at his example: https://github.com/NordicSemiconductor/Android-nRF-Toolbox/blob/master/app/src/main/java/no/nordicsemi/android/nrftoolbox/dfu/DfuService.java

    This is explained in the documentation: github.com/.../documentation

    In this class you may also modify the notification that will be displayed during DFU. If you don't want any notification, disable them using the initiator.

    Also, setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled should be used only if your fw is based on SDK 12.x., and setKeepBond only when your device is bonded. The false parameter assumes that after successful dfu the target will loose all the bond information.

    Hope that helped!

    Aleksander

  • I'm doing this inside of a library, not as part of an application.  "getNotificationTarget()" is defined as follows:

    protected Class<? extends Activity> getNotificationTarget

    How can I use that when I have no Activity being used in the library? 

  • You may return null and disable notifications, and provide then, if you want, on your own based on the progress listener.

  • I did that.  Still nothing after calling "start"

    I've updated the code to use my new class:

    public void updateGen2Firmware(Context context, String path) {
    Log.v (TAG, "Starting");

    final DfuServiceInitiator starter = new DfuServiceInitiator(macAddress).setDeviceName(deviceName).setKeepBond(false);
    starter.setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true);

    Log.v (TAG, "Setting zip to: " + path);

    starter.setZip(path);

    Log.v (TAG, "setting up progress listener");
    DfuServiceListenerHelper.registerProgressListener(context, mDfuProgressListener);

    Log.v (TAG, "calling the 'start' of starter");

    starter.start(context, NordicDfuService.class);
    }


    And here is the implementation of that class:

    import android.app.Activity;

    import no.nordicsemi.android.dfu.DfuBaseService;

    public class NordicDfuService extends DfuBaseService {
    @Override
    protected Class<? extends Activity> getNotificationTarget() {

    /*
    * As a target activity the NotificationActivity is returned, not the MainActivity. This is because the notification must create a new task:
    *
    * intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    *
    * when user press it. Using NotificationActivity we can check whether the new activity is a root activity (that means no other activity was open before)
    * or that there is other activity already open. In the later case the notificationActivity will just be closed. System will restore the previous activity.
    * However if the application has been closed during upload and user click the notification a NotificationActivity will be launched as a root activity.
    * It will create and start the main activity and terminate itself.
    *
    * This method may be used to restore the target activity in case the application was closed or is open. It may also be used to recreate an activity
    * history (see NotificationActivity).
    */
    //return NotificationActivity.class;
    return null;

    }

    @Override
    protected boolean isDebug() {

    // return BuildConfig.DEBUG;
    return true;

    }
    }



    It really doesn't look like it is even starting.

    Note - I am using SDK12, so all the buttonless / bonding stuff should be right.  

Related