Skip to content

Commit

Permalink
Added DFU for Android
Browse files Browse the repository at this point in the history
  • Loading branch information
vikeri committed Jun 28, 2017
1 parent d50478f commit b0a9be3
Show file tree
Hide file tree
Showing 56 changed files with 10,920 additions and 53 deletions.
91 changes: 65 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,84 @@

# react-native-nordic-dfu

## Getting started

`$ npm install react-native-nordic-dfu --save`
`$ yarn add react-native-nordic-dfu`

### Mostly automatic installation

`$ react-native link react-native-nordic-dfu`

### Manual installation
## API

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

### startDFU

Starts the DFU process

**Parameters**

- `obj` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
- `obj.deviceAddress` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The MAC address for the device that should be updated
- `obj.deviceName` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the device in the update notification (optional, default `null`)
- `obj.filePath` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The file system path to the zip-file used for updating

#### iOS
**Examples**

1. In XCode, in the project navigator, right click `Libraries``Add Files to [your project's name]`
2. Go to `node_modules``react-native-nordic-dfu` and add `RNNordicDfu.xcodeproj`
3. In XCode, in the project navigator, select your project. Add `libRNNordicDfu.a` to your project's `Build Phases``Link Binary With Libraries`
4. Run your project (`Cmd+R`)<
```javascript
import { NordicDFU, DFUEmitter } from "react-native-nordic-dfu";

NordicDFU.startDFU({
deviceAddress: "C3:53:C0:39:2F:99",
name: "Pilloxa Pillbox",
filePath: "/data/user/0/com.nordicdfuexample/files/RNFetchBlobTmp4of.zip"
})
.then(res => console.log("Transfer done:", res))
.catch(console.log);
```

#### Android
Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)** A promise that resolves or rejects with the `deviceAddress` in the return value

1. Open up `android/app/src/main/java/[...]/MainActivity.java`
- Add `import com.pilloxa.RNNordicDfuPackage;` to the imports at the top of the file
- Add `new RNNordicDfuPackage()` to the list returned by the `getPackages()` method
2. Append the following lines to `android/settings.gradle`:
```
include ':react-native-nordic-dfu'
project(':react-native-nordic-dfu').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-nordic-dfu/android')
```
3. Insert the following lines inside the dependencies block in `android/app/build.gradle`:
```
compile project(':react-native-nordic-dfu')
```
### DFUEmitter

Event emitter for DFU state and progress events

**Examples**

## Usage
```javascript
import RNNordicDfu from 'react-native-nordic-dfu';
import { NordicDFU, DFUEmitter } from "react-native-nordic-dfu";

DFUEmitter.addlistener("DFUProgress", progress => {
console.log("DFU progress:", progress);
});

// TODO: What to do with the module?
RNNordicDfu;
DFUEmitter.addListener("DFUStateChanged", state => {
console.log("DFU State:", state);
})
```


## Full Example

See: [example/index.js](example/index.android.js)

## Manual installation

### iOS

1. In XCode, in the project navigator, right click `Libraries``Add Files to [your project's name]`
2. Go to `node_modules``react-native-nordic-dfu` and add `RNNordicDfu.xcodeproj`
3. In XCode, in the project navigator, select your project. Add `libRNNordicDfu.a` to your project's `Build Phases``Link Binary With Libraries`
4. Run your project (`Cmd+R`)&lt;

### Android

1. Open up `android/app/src/main/java/[...]/MainActivity.java`

- Add `import com.pilloxa.RNNordicDfuPackage;` to the imports at the top of the file
- Add `new RNNordicDfuPackage()` to the list returned by the `getPackages()` method

2. Append the following lines to `android/settings.gradle`:
include ':react-native-nordic-dfu'
project(':react-native-nordic-dfu').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-nordic-dfu/android')
3. Insert the following lines inside the dependencies block in `android/app/build.gradle`:
compile project(':react-native-nordic-dfu')
9 changes: 6 additions & 3 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ apply plugin: 'com.android.library'

android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
buildToolsVersion '23.0.1'
compileOptions.incremental = false


defaultConfig {
minSdkVersion 16
minSdkVersion 18
targetSdkVersion 22
versionCode 1
versionName "1.0"
Expand All @@ -32,5 +34,6 @@ repositories {

dependencies {
compile 'com.facebook.react:react-native:+'
compile 'no.nordicsemi.android:dfu:1.3.0'
}


3 changes: 3 additions & 0 deletions android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pilloxa">
<application>
<service android:name=".DfuService"/>
</application>

</manifest>

39 changes: 39 additions & 0 deletions android/src/main/java/com/pilloxa/DfuService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.pilloxa;

import no.nordicsemi.android.dfu.DfuBaseService;
import android.app.Activity;

public class DfuService 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 you press it. You can use NotificationActivity to check whether the new activity
* is a root activity (that means no other activity was open earlier) or that some
* other activity is already open. In the latter case the NotificationActivity will just be
* closed. The system will restore the previous activity. However, if the application has been
* closed during upload and you 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 using
* startActivities(...).
*/
return NotificationActivity.class;
}

@Override
protected boolean isDebug() {
// Here return true if you want the service to print more logs in LogCat.
// Library's BuildConfig in current version of Android Studio is always set to DEBUG=false, so
// make sure you return true or your.app.BuildConfig.DEBUG here.
return true;
}
}

55 changes: 55 additions & 0 deletions android/src/main/java/com/pilloxa/NotificationActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.pilloxa;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;

/**
* Created by viktor on 2017-06-26.
*/

public class NotificationActivity extends Activity {

private ReactInstanceManager reactInstanceManager;

private ReactContext getReactContext() {
reactInstanceManager = ((ReactApplication) getApplication())
.getReactNativeHost()
.getReactInstanceManager();
return reactInstanceManager.getCurrentReactContext();
}

public Class getMainActivityClass(ReactContext reactContext) {
String packageName = reactContext.getPackageName();
Intent launchIntent = reactContext.getPackageManager().getLaunchIntentForPackage(packageName);
String className = launchIntent.getComponent().getClassName();
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// If this activity is the root activity of the task, the app is not running
if (isTaskRoot()) {
ReactContext reactContext = getReactContext();
Class HostActivity = getMainActivityClass(reactContext);
// Start the app before finishing
final Intent intent = new Intent(this, HostActivity);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtras(getIntent().getExtras()); // copy all extras
startActivity(intent);
}

// Now finish, which will drop you to the activity at which you were at the top of the task stack
finish();
}
}
Loading

0 comments on commit b0a9be3

Please sign in to comment.