diff --git a/.travis.yml b/.travis.yml
index c996c20..8f013db 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,15 +1,17 @@
language: android
-jdk: oraclejdk7
+dist: trusty
+jdk: openjdk8
android:
components:
- - build-tools-22.0.1
- - android-22
+ - build-tools-30.0.2
+ - android-29
- extra-android-m2repository
- extra-google-m2repository
licenses:
- '.+'
before_install:
- - chmod +x gradlew
+ - chmod +x gradlew
+ - yes | sdkmanager "build-tools;30.0.2"
script:
- ./gradlew check
diff --git a/library/.gitignore b/BLE-MIDI-library/.gitignore
similarity index 100%
rename from library/.gitignore
rename to BLE-MIDI-library/.gitignore
diff --git a/library/build.gradle b/BLE-MIDI-library/build.gradle
similarity index 64%
rename from library/build.gradle
rename to BLE-MIDI-library/build.gradle
index 35b48ee..ff1d46b 100644
--- a/library/build.gradle
+++ b/BLE-MIDI-library/build.gradle
@@ -1,8 +1,7 @@
apply plugin: 'com.android.library'
android {
- compileSdkVersion 22
- buildToolsVersion "22.0.1"
+ compileSdkVersion 29
defaultConfig {
minSdkVersion 18
@@ -23,24 +22,24 @@ android {
repositories {
maven {
- url 'https://github.com/kshoji/javax.sound.midi-for-Android/raw/master/javax.sound.midi/repository'
+ url 'https://github.com/kshoji/javax.sound.midi-for-Android/raw/develop/javax.sound.midi/repository'
}
mavenCentral()
}
dependencies {
- compile 'jp.kshoji:javax-sound-midi:0.0.3:@aar'
- //noinspection GradleDependency
- compile 'com.android.support:support-annotations:22.2.1'
- compile fileTree(dir: 'libs', include: ['*.jar'])
+ api 'jp.kshoji:javax-sound-midi:0.0.4:@aar'
+ api 'com.android.support:support-annotations:28.0.0'
+ compileOnly project(':UnityPlayerMock')
+ api fileTree(dir: 'libs', include: ['*.jar'])
}
apply plugin: 'maven'
group = 'jp.kshoji'
uploadArchives {
repositories.mavenDeployer {
- repository url: 'file://' + file('repository').absolutePath
- pom.version = '0.0.9'
+ repository url: 'file://' + file('../library/repository').absolutePath
+ pom.version = '0.0.10'
pom.artifactId = 'ble-midi'
}
}
diff --git a/library/lint.xml b/BLE-MIDI-library/lint.xml
similarity index 100%
rename from library/lint.xml
rename to BLE-MIDI-library/lint.xml
diff --git a/library/proguard-rules.pro b/BLE-MIDI-library/proguard-rules.pro
similarity index 100%
rename from library/proguard-rules.pro
rename to BLE-MIDI-library/proguard-rules.pro
diff --git a/library/src/main/AndroidManifest.xml b/BLE-MIDI-library/src/main/AndroidManifest.xml
similarity index 73%
rename from library/src/main/AndroidManifest.xml
rename to BLE-MIDI-library/src/main/AndroidManifest.xml
index 2b8194e..a56a8aa 100644
--- a/library/src/main/AndroidManifest.xml
+++ b/BLE-MIDI-library/src/main/AndroidManifest.xml
@@ -1,5 +1,9 @@
+
+
+
+
diff --git a/library/src/main/java/jp/kshoji/blemidi/central/BleMidiCallback.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/central/BleMidiCallback.java
similarity index 86%
rename from library/src/main/java/jp/kshoji/blemidi/central/BleMidiCallback.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/central/BleMidiCallback.java
index a9db260..18b57e0 100644
--- a/library/src/main/java/jp/kshoji/blemidi/central/BleMidiCallback.java
+++ b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/central/BleMidiCallback.java
@@ -47,7 +47,7 @@
public final class BleMidiCallback extends BluetoothGattCallback {
private final Map> midiInputDevicesMap = new HashMap<>();
private final Map> midiOutputDevicesMap = new HashMap<>();
- private final Map deviceAddressGattMap = new HashMap<>();
+ private final Map> deviceAddressGattMap = new HashMap<>();
private final Context context;
private OnMidiDeviceAttachedListener midiDeviceAttachedListener;
@@ -77,6 +77,7 @@ boolean isConnected(@NonNull BluetoothDevice device) {
}
}
+ private volatile static Object gattDiscoverServicesLock = null;
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
@@ -84,37 +85,55 @@ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState
// so, look `newState` parameter only.
if (newState == BluetoothProfile.STATE_CONNECTED) {
- if (!deviceAddressGattMap.containsKey(gatt.getDevice().getAddress())) {
- if (gatt.discoverServices()) {
- // successfully started discovering
- } else {
- // already disconnected
- disconnectByDeviceAddress(gatt.getDevice().getAddress());
+ if (deviceAddressGattMap.containsKey(gatt.getDevice().getAddress())) {
+ return;
+ }
+ // process a device for the same time
+ while (gattDiscoverServicesLock != null) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException ignored) {
}
}
+ if (deviceAddressGattMap.containsKey(gatt.getDevice().getAddress())) {
+ // same device has already registered
+ return;
+ }
+ gattDiscoverServicesLock = gatt;
+ if (gatt.discoverServices()) {
+ // successfully started discovering
+ } else {
+ // already disconnected
+ disconnectByDeviceAddress(gatt.getDevice().getAddress());
+ gattDiscoverServicesLock = null;
+ }
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
disconnectByDeviceAddress(gatt.getDevice().getAddress());
+ gattDiscoverServicesLock = null;
}
}
- @SuppressLint("NewApi")
+ @SuppressLint({"NewApi", "MissingPermission"})
@Override
public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (status != BluetoothGatt.GATT_SUCCESS) {
+ gattDiscoverServicesLock = null;
return;
}
final String gattDeviceAddress = gatt.getDevice().getAddress();
// find MIDI Input device
- if (midiInputDevicesMap.containsKey(gattDeviceAddress)) {
- synchronized (midiInputDevicesMap) {
+ synchronized (midiInputDevicesMap) {
+ if (midiInputDevicesMap.containsKey(gattDeviceAddress)) {
Set midiInputDevices = midiInputDevicesMap.get(gattDeviceAddress);
- for (MidiInputDevice midiInputDevice : midiInputDevices) {
- ((InternalMidiInputDevice) midiInputDevice).stop();
- midiInputDevice.setOnMidiInputEventListener(null);
+ if (midiInputDevices != null) {
+ for (MidiInputDevice midiInputDevice : midiInputDevices) {
+ ((InternalMidiInputDevice) midiInputDevice).stop();
+ midiInputDevice.setOnMidiInputEventListener(null);
+ }
}
midiInputDevicesMap.remove(gattDeviceAddress);
}
@@ -138,7 +157,8 @@ public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
}
// don't notify if the same device already connected
- if (!deviceAddressGattMap.containsKey(gattDeviceAddress)) {
+ if (!deviceAddressGattMap.containsKey(gattDeviceAddress))
+ {
if (midiDeviceAttachedListener != null) {
midiDeviceAttachedListener.onMidiInputDeviceAttached(midiInputDevice);
}
@@ -146,10 +166,8 @@ public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
}
// find MIDI Output device
- if (midiOutputDevicesMap.containsKey(gattDeviceAddress)) {
- synchronized (midiOutputDevicesMap) {
- midiOutputDevicesMap.remove(gattDeviceAddress);
- }
+ synchronized (midiOutputDevicesMap) {
+ midiOutputDevicesMap.remove(gattDeviceAddress);
}
MidiOutputDevice midiOutputDevice = null;
@@ -179,7 +197,12 @@ public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
if (midiInputDevice != null || midiOutputDevice != null) {
synchronized (deviceAddressGattMap) {
- deviceAddressGattMap.put(gattDeviceAddress, gatt);
+ List bluetoothGatts = deviceAddressGattMap.get(gattDeviceAddress);
+ if (bluetoothGatts == null) {
+ bluetoothGatts = new ArrayList<>();
+ deviceAddressGattMap.put(gattDeviceAddress, bluetoothGatts);
+ }
+ bluetoothGatts.add(gatt);
}
if (needsBonding && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
@@ -187,7 +210,12 @@ public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
BluetoothDevice bluetoothDevice = gatt.getDevice();
if (bluetoothDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
bluetoothDevice.createBond();
- bluetoothDevice.setPairingConfirmation(true);
+ try {
+ bluetoothDevice.setPairingConfirmation(true);
+ } catch (Throwable t) {
+ // SecurityException if android.permission.BLUETOOTH_PRIVILEGED not available
+ Log.d(Constants.TAG, t.getMessage());
+ }
if (bondingBroadcastReceiver != null) {
context.unregisterReceiver(bondingBroadcastReceiver);
@@ -214,6 +242,9 @@ public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
gatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH);
}
}
+
+ // all finished
+ gattDiscoverServicesLock = null;
}
@Override
@@ -221,18 +252,9 @@ public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteris
super.onCharacteristicChanged(gatt, characteristic);
Set midiInputDevices = midiInputDevicesMap.get(gatt.getDevice().getAddress());
- for (MidiInputDevice midiInputDevice : midiInputDevices) {
- ((InternalMidiInputDevice)midiInputDevice).incomingData(characteristic.getValue());
- }
- }
-
- @Override
- public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
- super.onDescriptorWrite(gatt, descriptor, status);
-
- if (descriptor != null) {
- if (Arrays.equals(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE, descriptor.getValue())) {
- gatt.setCharacteristicNotification(descriptor.getCharacteristic(), true);
+ if (midiInputDevices != null) {
+ for (MidiInputDevice midiInputDevice : midiInputDevices) {
+ ((InternalMidiInputDevice)midiInputDevice).incomingData(characteristic.getValue());
}
}
}
@@ -270,11 +292,13 @@ void disconnectDevice(@NonNull MidiOutputDevice midiOutputDevice) {
*/
private void disconnectByDeviceAddress(@NonNull String deviceAddress) {
synchronized (deviceAddressGattMap) {
- BluetoothGatt bluetoothGatt = deviceAddressGattMap.get(deviceAddress);
+ List bluetoothGatts = deviceAddressGattMap.get(deviceAddress);
- if (bluetoothGatt != null) {
- bluetoothGatt.disconnect();
- bluetoothGatt.close();
+ if (bluetoothGatts != null) {
+ for (BluetoothGatt bluetoothGatt : bluetoothGatts) {
+ bluetoothGatt.disconnect();
+ bluetoothGatt.close();
+ }
deviceAddressGattMap.remove(deviceAddress);
}
@@ -318,9 +342,13 @@ private void disconnectByDeviceAddress(@NonNull String deviceAddress) {
*/
public void terminate() {
synchronized (deviceAddressGattMap) {
- for (BluetoothGatt bluetoothGatt : deviceAddressGattMap.values()) {
- bluetoothGatt.disconnect();
- bluetoothGatt.close();
+ for (List bluetoothGatts : deviceAddressGattMap.values()) {
+ if (bluetoothGatts != null) {
+ for (BluetoothGatt bluetoothGatt : bluetoothGatts) {
+ bluetoothGatt.disconnect();
+ bluetoothGatt.close();
+ }
+ }
}
deviceAddressGattMap.clear();
}
diff --git a/library/src/main/java/jp/kshoji/blemidi/central/BleMidiCentralProvider.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/central/BleMidiCentralProvider.java
similarity index 80%
rename from library/src/main/java/jp/kshoji/blemidi/central/BleMidiCentralProvider.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/central/BleMidiCentralProvider.java
index ea4e147..66179b8 100644
--- a/library/src/main/java/jp/kshoji/blemidi/central/BleMidiCentralProvider.java
+++ b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/central/BleMidiCentralProvider.java
@@ -2,6 +2,7 @@
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
+import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
@@ -46,11 +47,30 @@ public final class BleMidiCentralProvider {
private final BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice bluetoothDevice, int rssi, byte[] scanRecord) {
+
if (bluetoothDevice.getType() != BluetoothDevice.DEVICE_TYPE_LE && bluetoothDevice.getType() != BluetoothDevice.DEVICE_TYPE_DUAL) {
return;
}
- bluetoothDevice.connectGatt(context, true, midiCallback);
+ if (context instanceof Activity) {
+ ((Activity) context).runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ bluetoothDevice.connectGatt(context, true, midiCallback);
+ }
+ });
+ } else {
+ if (Thread.currentThread() == context.getMainLooper().getThread()) {
+ bluetoothDevice.connectGatt(context, true, midiCallback);
+ } else {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ bluetoothDevice.connectGatt(context, true, midiCallback);
+ }
+ });
+ }
+ }
}
};
@@ -98,7 +118,25 @@ public void onScanResult(int callbackType, ScanResult result) {
}
if (!midiCallback.isConnected(bluetoothDevice)) {
- bluetoothDevice.connectGatt(BleMidiCentralProvider.this.context, true, midiCallback);
+ if (context instanceof Activity) {
+ ((Activity) context).runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ bluetoothDevice.connectGatt(BleMidiCentralProvider.this.context, true, midiCallback);
+ }
+ });
+ } else {
+ if (Thread.currentThread() == context.getMainLooper().getThread()) {
+ bluetoothDevice.connectGatt(BleMidiCentralProvider.this.context, true, midiCallback);
+ } else {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ bluetoothDevice.connectGatt(BleMidiCentralProvider.this.context, true, midiCallback);
+ }
+ });
+ }
+ }
}
}
}
@@ -175,7 +213,9 @@ public void run() {
public void stopScanDevice() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- bluetoothAdapter.getBluetoothLeScanner().stopScan(scanCallback);
+ final BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
+ bluetoothLeScanner.flushPendingScanResults(scanCallback);
+ bluetoothLeScanner.stopScan(scanCallback);
} else {
bluetoothAdapter.stopLeScan(leScanCallback);
}
@@ -265,7 +305,7 @@ public void setOnMidiDeviceDetachedListener(@Nullable OnMidiDeviceDetachedListen
* Terminates provider
*/
public void terminate() {
- stopScanDevice();
midiCallback.terminate();
+ stopScanDevice();
}
}
diff --git a/library/src/main/java/jp/kshoji/blemidi/device/MidiInputDevice.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/device/MidiInputDevice.java
similarity index 100%
rename from library/src/main/java/jp/kshoji/blemidi/device/MidiInputDevice.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/device/MidiInputDevice.java
diff --git a/library/src/main/java/jp/kshoji/blemidi/device/MidiOutputDevice.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/device/MidiOutputDevice.java
similarity index 100%
rename from library/src/main/java/jp/kshoji/blemidi/device/MidiOutputDevice.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/device/MidiOutputDevice.java
diff --git a/library/src/main/java/jp/kshoji/blemidi/listener/OnMidiDeviceAttachedListener.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/listener/OnMidiDeviceAttachedListener.java
similarity index 100%
rename from library/src/main/java/jp/kshoji/blemidi/listener/OnMidiDeviceAttachedListener.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/listener/OnMidiDeviceAttachedListener.java
diff --git a/library/src/main/java/jp/kshoji/blemidi/listener/OnMidiDeviceDetachedListener.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/listener/OnMidiDeviceDetachedListener.java
similarity index 100%
rename from library/src/main/java/jp/kshoji/blemidi/listener/OnMidiDeviceDetachedListener.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/listener/OnMidiDeviceDetachedListener.java
diff --git a/library/src/main/java/jp/kshoji/blemidi/listener/OnMidiInputEventListener.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/listener/OnMidiInputEventListener.java
similarity index 100%
rename from library/src/main/java/jp/kshoji/blemidi/listener/OnMidiInputEventListener.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/listener/OnMidiInputEventListener.java
diff --git a/library/src/main/java/jp/kshoji/blemidi/listener/OnMidiScanStatusListener.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/listener/OnMidiScanStatusListener.java
similarity index 100%
rename from library/src/main/java/jp/kshoji/blemidi/listener/OnMidiScanStatusListener.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/listener/OnMidiScanStatusListener.java
diff --git a/library/src/main/java/jp/kshoji/blemidi/peripheral/BleMidiPeripheralProvider.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/peripheral/BleMidiPeripheralProvider.java
similarity index 86%
rename from library/src/main/java/jp/kshoji/blemidi/peripheral/BleMidiPeripheralProvider.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/peripheral/BleMidiPeripheralProvider.java
index 56b5e18..d164d21 100644
--- a/library/src/main/java/jp/kshoji/blemidi/peripheral/BleMidiPeripheralProvider.java
+++ b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/peripheral/BleMidiPeripheralProvider.java
@@ -4,6 +4,7 @@
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattServer;
@@ -15,10 +16,7 @@
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertiseSettings;
import android.bluetooth.le.BluetoothLeAdvertiser;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.os.Build;
import android.os.ParcelUuid;
import android.support.annotation.NonNull;
@@ -81,6 +79,7 @@ public final class BleMidiPeripheralProvider {
private final BluetoothGattService midiGattService;
private final BluetoothGattCharacteristic midiCharacteristic;
private BluetoothGattServer gattServer;
+ private boolean gattServiceInitialized = false;
private final Map midiInputDevicesMap = new HashMap<>();
private final Map midiOutputDevicesMap = new HashMap<>();
@@ -154,13 +153,24 @@ public void startAdvertising() {
}
// these service will be listened.
- // FIXME these didn't used for service discovery
- boolean serviceInitialized = false;
- while (!serviceInitialized) {
+ while (!gattServiceInitialized) {
+ gattServer.clearServices();
try {
gattServer.addService(informationGattService);
+ while (gattServer.getService(informationGattService.getUuid()) == null) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException ignored) {
+ }
+ }
gattServer.addService(midiGattService);// NullPointerException, DeadObjectException thrown here
- serviceInitialized = true;
+ while (gattServer.getService(midiGattService.getUuid()) == null) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException ignored) {
+ }
+ }
+ gattServiceInitialized = true;
} catch (Exception e) {
Log.d(Constants.TAG, "Adding Service failed, retrying..");
@@ -208,26 +218,6 @@ public void stopAdvertising() {
} catch (IllegalStateException ignored) {
// BT Adapter is not turned ON
}
-
- if (gattServer != null) {
- try {
- gattServer.clearServices();
- } catch (Throwable ignored) {
- // android.os.DeadObjectException
- gattServer = null;
- }
- }
- }
-
- private boolean requireBonding = false;
-
- /**
- * Set if the Bluetooth LE device need `Pairing`
- *
- * @param needsPairing if true, request paring with the connecting device
- */
- public void setRequestPairing(boolean needsPairing) {
- this.requireBonding = needsPairing;
}
/**
@@ -262,6 +252,21 @@ public void disconnectDevice(@NonNull MidiOutputDevice midiOutputDevice) {
disconnectByDeviceAddress(midiOutputDevice.getDeviceAddress());
}
+ /**
+ * callback for disconnecting a bluetooth device
+ */
+ private final BluetoothGattCallback disconnectCallback = new BluetoothGattCallback() {
+ @Override
+ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
+ super.onConnectionStateChange(gatt, status, newState);
+ Log.d(Constants.TAG, "onConnectionStateChange status: " + status + ", newState: " + newState);
+ // disconnect the device
+ if (gatt != null) {
+ gatt.disconnect();
+ }
+ }
+ };
+
/**
* Disconnects the device by its address
*
@@ -272,33 +277,7 @@ private void disconnectByDeviceAddress(@NonNull String deviceAddress) {
BluetoothDevice bluetoothDevice = bluetoothDevicesMap.get(deviceAddress);
if (bluetoothDevice != null) {
gattServer.cancelConnection(bluetoothDevice);
- }
-
- bluetoothDevicesMap.remove(deviceAddress);
- }
-
- synchronized (midiInputDevicesMap) {
- MidiInputDevice midiInputDevice = midiInputDevicesMap.get(deviceAddress);
- if (midiInputDevice != null) {
- midiInputDevicesMap.remove(deviceAddress);
-
- ((InternalMidiInputDevice) midiInputDevice).stop();
- midiInputDevice.setOnMidiInputEventListener(null);
-
- if (midiDeviceDetachedListener != null) {
- midiDeviceDetachedListener.onMidiInputDeviceDetached(midiInputDevice);
- }
- }
- }
-
- synchronized (midiOutputDevicesMap) {
- MidiOutputDevice midiOutputDevice = midiOutputDevicesMap.get(deviceAddress);
- if (midiOutputDevice != null) {
- midiOutputDevicesMap.remove(deviceAddress);
-
- if (midiDeviceDetachedListener != null) {
- midiDeviceDetachedListener.onMidiOutputDeviceDetached(midiOutputDevice);
- }
+ bluetoothDevice.connectGatt(context, true, disconnectCallback);
}
}
}
@@ -311,15 +290,24 @@ public void terminate() {
synchronized (bluetoothDevicesMap) {
for (BluetoothDevice bluetoothDevice : bluetoothDevicesMap.values()) {
- if (gattServer != null) {
- gattServer.cancelConnection(bluetoothDevice);
- }
+ gattServer.cancelConnection(bluetoothDevice);
+ bluetoothDevice.connectGatt(context, true, disconnectCallback);
}
bluetoothDevicesMap.clear();
}
if (gattServer != null) {
- gattServer.close();
+ try {
+ gattServer.clearServices();
+ gattServiceInitialized = false;
+ } catch (Throwable ignored) {
+ // android.os.DeadObjectException
+ }
+ try {
+ gattServer.close();
+ } catch (Throwable ignored) {
+ // android.os.DeadObjectException
+ }
gattServer = null;
}
@@ -347,37 +335,7 @@ public void onConnectionStateChange(BluetoothDevice device, int status, int newS
switch (newState) {
case BluetoothProfile.STATE_CONNECTED:
- // check bond status
- if (requireBonding && device.getBondState() == BluetoothDevice.BOND_NONE) {
- // create bond
- device.createBond();
- device.setPairingConfirmation(true);
-
- IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
- context.registerReceiver(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
-
- if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
- final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
-
- if (state == BluetoothDevice.BOND_BONDED) {
- BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-
- // successfully bonded
- context.unregisterReceiver(this);
-
- // connecting to the device
- connectMidiDevice(device);
- }
- }
- }
- }, filter);
- } else {
- // connecting to the device
- connectMidiDevice(device);
- }
+ connectMidiDevice(device);
break;
case BluetoothProfile.STATE_DISCONNECTED:
@@ -461,8 +419,32 @@ public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId,
public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite, responseNeeded, offset, value);
+ byte[] descriptorValue = descriptor.getValue();
+ try {
+ System.arraycopy(value, 0, descriptorValue, offset, value.length);
+ descriptor.setValue(descriptorValue);
+ } catch (IndexOutOfBoundsException ignored) {
+ }
+
gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, new byte[] {});
}
+
+ @Override
+ public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
+ super.onDescriptorReadRequest(device, requestId, offset, descriptor);
+
+ if (offset == 0) {
+ gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, descriptor.getValue());
+ } else {
+ final byte[] value = descriptor.getValue();
+ byte[] result = new byte[value.length - offset];
+ try {
+ System.arraycopy(value, offset, result, 0, result.length);
+ } catch (IndexOutOfBoundsException ignored) {
+ }
+ gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, result);
+ }
+ }
};
/**
@@ -501,8 +483,7 @@ private void connectMidiDevice(@NonNull BluetoothDevice device) {
*/
@NonNull
public Set getMidiInputDevices() {
- Set result = new HashSet<>();
- result.addAll(midiInputDevicesMap.values());
+ Set result = new HashSet<>(midiInputDevicesMap.values());
return Collections.unmodifiableSet(result);
}
@@ -513,8 +494,7 @@ public Set getMidiInputDevices() {
*/
@NonNull
public Set getMidiOutputDevices() {
- Set result = new HashSet<>();
- result.addAll(midiOutputDevicesMap.values());
+ Set result = new HashSet<>(midiOutputDevicesMap.values());
return Collections.unmodifiableSet(result);
}
diff --git a/library/src/main/java/jp/kshoji/blemidi/service/AbstractBleMidiService.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/service/AbstractBleMidiService.java
similarity index 100%
rename from library/src/main/java/jp/kshoji/blemidi/service/AbstractBleMidiService.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/service/AbstractBleMidiService.java
diff --git a/library/src/main/java/jp/kshoji/blemidi/service/BleMidiCentralService.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/service/BleMidiCentralService.java
similarity index 100%
rename from library/src/main/java/jp/kshoji/blemidi/service/BleMidiCentralService.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/service/BleMidiCentralService.java
diff --git a/library/src/main/java/jp/kshoji/blemidi/service/BleMidiPeripheralService.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/service/BleMidiPeripheralService.java
similarity index 100%
rename from library/src/main/java/jp/kshoji/blemidi/service/BleMidiPeripheralService.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/service/BleMidiPeripheralService.java
diff --git a/library/src/main/java/jp/kshoji/blemidi/util/BleMidiDeviceUtils.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/util/BleMidiDeviceUtils.java
similarity index 100%
rename from library/src/main/java/jp/kshoji/blemidi/util/BleMidiDeviceUtils.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/util/BleMidiDeviceUtils.java
diff --git a/library/src/main/java/jp/kshoji/blemidi/util/BleMidiParser.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/util/BleMidiParser.java
similarity index 97%
rename from library/src/main/java/jp/kshoji/blemidi/util/BleMidiParser.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/util/BleMidiParser.java
index ef594e9..a10c5c0 100644
--- a/library/src/main/java/jp/kshoji/blemidi/util/BleMidiParser.java
+++ b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/util/BleMidiParser.java
@@ -61,7 +61,7 @@ public final class BleMidiParser {
// for Timestamp
private static final int MAX_TIMESTAMP = 8192;
- private static final int BUFFER_LENGTH_MILLIS = 30;
+ private static final int BUFFER_LENGTH_MILLIS = 50;
private int timestamp = 0;
private int lastTimestamp;
private long lastTimestampRecorded = 0;
@@ -164,12 +164,17 @@ private long calculateEventFireTime(final int timestamp) {
return currentTimeMillis;
}
- int adjustedTimestamp = timestamp;
- if (timestamp + MAX_TIMESTAMP / 2 < lastTimestamp) {
- adjustedTimestamp += MAX_TIMESTAMP;
+ final long elapsedRealtime = currentTimeMillis - lastTimestampRecorded;
+ // realTimestampPeriod: how many times MAX_TIMESTAMP passed
+ long realTimestampPeriod = (lastTimestamp + elapsedRealtime) / MAX_TIMESTAMP;
+ if (realTimestampPeriod > 0 && timestamp > 7000) {
+ realTimestampPeriod--;
}
-
- final long result = BUFFER_LENGTH_MILLIS + adjustedTimestamp - lastTimestamp + lastTimestampRecorded;
+ final long lastTimestampStarted = lastTimestampRecorded - lastTimestamp;
+ // result: time to wait
+ final long result = BUFFER_LENGTH_MILLIS // buffer
+ + lastTimestampStarted + realTimestampPeriod * MAX_TIMESTAMP + timestamp // time to fire event
+ - currentTimeMillis; // current time
lastTimestamp = timestamp;
lastTimestampRecorded = currentTimeMillis;
@@ -764,7 +769,7 @@ public void run() {
*
* @param data incoming data
*/
- public void parse(@NonNull byte[] data) {
+ public synchronized void parse(@NonNull byte[] data) {
if (data.length > 1) {
int header = data[0] & 0xff;
for (int i = 1; i < data.length; i++) {
diff --git a/library/src/main/java/jp/kshoji/blemidi/util/BleUtils.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/util/BleUtils.java
similarity index 83%
rename from library/src/main/java/jp/kshoji/blemidi/util/BleUtils.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/util/BleUtils.java
index 503f3b5..125a8e0 100644
--- a/library/src/main/java/jp/kshoji/blemidi/util/BleUtils.java
+++ b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/util/BleUtils.java
@@ -23,13 +23,13 @@ public class BleUtils {
* @param context the context
* @return true if supported
*/
- public static boolean isBleSupported(@NonNull Context context) {
+ public static boolean isBleSupported(@NonNull final Context context) {
try {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) == false) {
return false;
}
- BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
+ final BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
final BluetoothAdapter bluetoothAdapter;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
@@ -41,7 +41,7 @@ public static boolean isBleSupported(@NonNull Context context) {
if (bluetoothAdapter != null) {
return true;
}
- } catch (Throwable t) {
+ } catch (final Throwable ignored) {
// ignore exception
}
return false;
@@ -54,7 +54,7 @@ public static boolean isBleSupported(@NonNull Context context) {
* @return true if supported
*/
@SuppressLint("NewApi")
- public static boolean isBlePeripheralSupported(@NonNull Context context) {
+ public static boolean isBlePeripheralSupported(@NonNull final Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return false;
}
@@ -74,8 +74,8 @@ public static boolean isBlePeripheralSupported(@NonNull Context context) {
* @param context the context
* @return true if bluetooth enabled
*/
- public static boolean isBluetoothEnabled(@NonNull Context context) {
- BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
+ public static boolean isBluetoothEnabled(@NonNull final Context context) {
+ final BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
if (bluetoothManager == null) {
return false;
@@ -106,7 +106,7 @@ public static boolean isBluetoothEnabled(@NonNull Context context) {
*
* @param activity the activity
*/
- public static void enableBluetooth(@NonNull Activity activity) {
+ public static void enableBluetooth(@NonNull final Activity activity) {
activity.startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE), REQUEST_CODE_BLUETOOTH_ENABLE);
}
}
diff --git a/library/src/main/java/jp/kshoji/blemidi/util/BleUuidUtils.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/util/BleUuidUtils.java
similarity index 100%
rename from library/src/main/java/jp/kshoji/blemidi/util/BleUuidUtils.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/util/BleUuidUtils.java
diff --git a/library/src/main/java/jp/kshoji/blemidi/util/Constants.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/util/Constants.java
similarity index 100%
rename from library/src/main/java/jp/kshoji/blemidi/util/Constants.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/util/Constants.java
diff --git a/library/src/main/java/jp/kshoji/blemidi/util/ReusableByteArrayOutputStream.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/util/ReusableByteArrayOutputStream.java
similarity index 100%
rename from library/src/main/java/jp/kshoji/blemidi/util/ReusableByteArrayOutputStream.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/util/ReusableByteArrayOutputStream.java
diff --git a/library/src/main/java/jp/kshoji/javax/sound/midi/BleMidiSystem.java b/BLE-MIDI-library/src/main/java/jp/kshoji/javax/sound/midi/BleMidiSystem.java
similarity index 56%
rename from library/src/main/java/jp/kshoji/javax/sound/midi/BleMidiSystem.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/javax/sound/midi/BleMidiSystem.java
index 6ed552e..98bcb7c 100644
--- a/library/src/main/java/jp/kshoji/javax/sound/midi/BleMidiSystem.java
+++ b/BLE-MIDI-library/src/main/java/jp/kshoji/javax/sound/midi/BleMidiSystem.java
@@ -14,6 +14,7 @@
import jp.kshoji.blemidi.peripheral.BleMidiPeripheralProvider;
import jp.kshoji.blemidi.util.BleUtils;
import jp.kshoji.javax.sound.midi.ble.BleMidiDevice;
+import jp.kshoji.javax.sound.midi.ble.BleMidiSynthesizer;
/**
* {@link jp.kshoji.javax.sound.midi.MidiSystem} initializer for BLE MIDI
@@ -24,7 +25,8 @@ public final class BleMidiSystem implements OnMidiDeviceAttachedListener, OnMidi
private static BleMidiPeripheralProvider peripheralProvider;
private static BleMidiCentralProvider centralProvider;
- private static final Map midiDeviceMap = new HashMap<>();
+ private final Map midiDeviceMap = new HashMap<>();
+ private final Map midiSynthesizerMap = new HashMap<>();
private final Context context;
/**
@@ -32,7 +34,7 @@ public final class BleMidiSystem implements OnMidiDeviceAttachedListener, OnMidi
*
* @param context the context
*/
- public BleMidiSystem(@NonNull Context context) {
+ public BleMidiSystem(@NonNull final Context context) {
this.context = context.getApplicationContext();
}
@@ -70,7 +72,7 @@ public void terminate() {
}
synchronized (midiDeviceMap) {
- for (BleMidiDevice bleMidiDevice : midiDeviceMap.values()) {
+ for (final BleMidiDevice bleMidiDevice : midiDeviceMap.values()) {
bleMidiDevice.close();
}
@@ -115,64 +117,111 @@ public void stopAdvertising() {
}
@Override
- public void onMidiInputDeviceAttached(@NonNull MidiInputDevice midiInputDevice) {
+ public void onMidiInputDeviceAttached(@NonNull final MidiInputDevice midiInputDevice) {
+ final BleMidiDevice addedDevice;
synchronized (midiDeviceMap) {
- BleMidiDevice existingDevice = midiDeviceMap.get(midiInputDevice.getDeviceAddress());
+ final BleMidiDevice existingDevice = midiDeviceMap.get(midiInputDevice.getDeviceAddress());
if (existingDevice != null) {
+ addedDevice = existingDevice;
existingDevice.setMidiInputDevice(midiInputDevice);
MidiSystem.addMidiDevice(existingDevice);
} else {
- BleMidiDevice midiDevice = new BleMidiDevice(midiInputDevice, null);
+ final BleMidiDevice midiDevice = new BleMidiDevice(midiInputDevice, null);
+ addedDevice = midiDevice;
midiDeviceMap.put(midiInputDevice.getDeviceAddress(), midiDevice);
MidiSystem.addMidiDevice(midiDevice);
}
}
+
+ synchronized (midiSynthesizerMap) {
+ final BleMidiSynthesizer existingSynthesizer = midiSynthesizerMap.get(midiInputDevice.getDeviceAddress());
+ if (existingSynthesizer == null) {
+ final BleMidiSynthesizer synthesizer = new BleMidiSynthesizer(addedDevice);
+ MidiSystem.addSynthesizer(synthesizer);
+ midiSynthesizerMap.put(midiInputDevice.getDeviceAddress(), synthesizer);
+ }
+ }
}
@Override
- public void onMidiOutputDeviceAttached(@NonNull MidiOutputDevice midiOutputDevice) {
+ public void onMidiOutputDeviceAttached(@NonNull final MidiOutputDevice midiOutputDevice) {
+ final BleMidiDevice addedDevice;
synchronized (midiDeviceMap) {
- BleMidiDevice existingDevice = midiDeviceMap.get(midiOutputDevice.getDeviceAddress());
- if (existingDevice != null) {
+ final BleMidiDevice existingDevice = midiDeviceMap.get(midiOutputDevice.getDeviceAddress());
+ if (existingDevice == null) {
+ final BleMidiDevice midiDevice = new BleMidiDevice(null, midiOutputDevice);
+ addedDevice = midiDevice;
+ midiDeviceMap.put(midiOutputDevice.getDeviceAddress(), midiDevice);
+ MidiSystem.addMidiDevice(midiDevice);
+ } else {
+ addedDevice = existingDevice;
existingDevice.setMidiOutputDevice(midiOutputDevice);
MidiSystem.addMidiDevice(existingDevice);
+ }
+ }
+
+ synchronized (midiSynthesizerMap) {
+ final BleMidiSynthesizer existingSynthesizer = midiSynthesizerMap.get(midiOutputDevice.getDeviceAddress());
+ if (existingSynthesizer == null) {
+ final BleMidiSynthesizer synthesizer = new BleMidiSynthesizer(addedDevice);
+ midiSynthesizerMap.put(midiOutputDevice.getDeviceAddress(), synthesizer);
+ MidiSystem.addSynthesizer(synthesizer);
} else {
- BleMidiDevice midiDevice = new BleMidiDevice(null, midiOutputDevice);
- midiDeviceMap.put(midiOutputDevice.getDeviceAddress(), midiDevice);
- MidiSystem.addMidiDevice(midiDevice);
+ try {
+ existingSynthesizer.setReceiver(addedDevice.getReceiver());
+ } catch (final MidiUnavailableException ignored) {
+ }
}
}
}
@Override
- public void onMidiInputDeviceDetached(@NonNull MidiInputDevice midiInputDevice) {
+ public void onMidiInputDeviceDetached(@NonNull final MidiInputDevice midiInputDevice) {
+ String removedDeviceAddress = null;
synchronized (midiDeviceMap) {
- BleMidiDevice existingDevice = midiDeviceMap.get(midiInputDevice.getDeviceAddress());
+ final BleMidiDevice existingDevice = midiDeviceMap.get(midiInputDevice.getDeviceAddress());
if (existingDevice != null) {
existingDevice.setMidiInputDevice(null);
if (existingDevice.getMidiOutputDevice() == null) {
// both of devices are disconnected
+ removedDeviceAddress = midiInputDevice.getDeviceAddress();
midiDeviceMap.remove(midiInputDevice.getDeviceAddress());
MidiSystem.removeMidiDevice(existingDevice);
}
}
}
+
+ if (removedDeviceAddress != null) {
+ synchronized (midiSynthesizerMap) {
+ MidiSystem.removeSynthesizer(midiSynthesizerMap.get(removedDeviceAddress));
+ midiSynthesizerMap.remove(removedDeviceAddress);
+ }
+ }
}
@Override
- public void onMidiOutputDeviceDetached(@NonNull MidiOutputDevice midiOutputDevice) {
+ public void onMidiOutputDeviceDetached(@NonNull final MidiOutputDevice midiOutputDevice) {
+ String removedDeviceAddress = null;
synchronized (midiDeviceMap) {
- BleMidiDevice existingDevice = midiDeviceMap.get(midiOutputDevice.getDeviceAddress());
+ final BleMidiDevice existingDevice = midiDeviceMap.get(midiOutputDevice.getDeviceAddress());
if (existingDevice != null) {
existingDevice.setMidiOutputDevice(null);
if (existingDevice.getMidiInputDevice() == null) {
// both of devices are disconnected
+ removedDeviceAddress = midiOutputDevice.getDeviceAddress();
midiDeviceMap.remove(midiOutputDevice.getDeviceAddress());
MidiSystem.removeMidiDevice(existingDevice);
}
}
}
+
+ if (removedDeviceAddress != null) {
+ synchronized (midiSynthesizerMap) {
+ MidiSystem.removeSynthesizer(midiSynthesizerMap.get(removedDeviceAddress));
+ midiSynthesizerMap.remove(removedDeviceAddress);
+ }
+ }
}
}
diff --git a/library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiDevice.java b/BLE-MIDI-library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiDevice.java
similarity index 86%
rename from library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiDevice.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiDevice.java
index a2d28d7..5879806 100644
--- a/library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiDevice.java
+++ b/BLE-MIDI-library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiDevice.java
@@ -20,7 +20,9 @@
* @author K.Shoji
*/
public final class BleMidiDevice implements MidiDevice {
+ @Nullable
private BleMidiReceiver receiver;
+ @Nullable
private BleMidiTransmitter transmitter;
private boolean isOpened;
@@ -34,7 +36,7 @@ public final class BleMidiDevice implements MidiDevice {
* @param midiInputDevice the input device
* @param midiOutputDevice the output device
*/
- public BleMidiDevice(@Nullable MidiInputDevice midiInputDevice, @Nullable MidiOutputDevice midiOutputDevice) {
+ public BleMidiDevice(@Nullable final MidiInputDevice midiInputDevice, @Nullable final MidiOutputDevice midiOutputDevice) {
this.midiInputDevice = midiInputDevice;
this.midiOutputDevice = midiOutputDevice;
@@ -124,37 +126,45 @@ public int getMaxTransmitters() {
return transmitter == null ? 0 : 1;
}
+ @NonNull
@Override
public Receiver getReceiver() throws MidiUnavailableException {
+ if (receiver == null) {
+ throw new MidiUnavailableException("Receiver not found");
+ }
return receiver;
}
@NonNull
@Override
public List getReceivers() {
- ArrayList receivers = new ArrayList<>();
+ final List receivers = new ArrayList<>();
if (receiver != null) {
receivers.add(receiver);
}
return Collections.unmodifiableList(receivers);
}
+ @NonNull
@Override
public Transmitter getTransmitter() throws MidiUnavailableException {
+ if (transmitter == null) {
+ throw new MidiUnavailableException("Tranmitter not found");
+ }
return transmitter;
}
@NonNull
@Override
public List getTransmitters() {
- ArrayList transmitters = new ArrayList<>();
+ final List transmitters = new ArrayList<>();
if (transmitter != null) {
transmitters.add(transmitter);
}
return Collections.unmodifiableList(transmitters);
}
- public void setMidiInputDevice(@Nullable MidiInputDevice midiInputDevice) {
+ public void setMidiInputDevice(@Nullable final MidiInputDevice midiInputDevice) {
this.midiInputDevice = midiInputDevice;
if (transmitter != null) {
transmitter.close();
@@ -171,7 +181,7 @@ public MidiInputDevice getMidiInputDevice() {
return midiInputDevice;
}
- public void setMidiOutputDevice(@Nullable MidiOutputDevice midiOutputDevice) {
+ public void setMidiOutputDevice(@Nullable final MidiOutputDevice midiOutputDevice) {
this.midiOutputDevice = midiOutputDevice;
if (receiver != null) {
receiver.close();
diff --git a/library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiReceiver.java b/BLE-MIDI-library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiReceiver.java
similarity index 100%
rename from library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiReceiver.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiReceiver.java
diff --git a/BLE-MIDI-library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiSynthesizer.java b/BLE-MIDI-library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiSynthesizer.java
new file mode 100644
index 0000000..ea8723b
--- /dev/null
+++ b/BLE-MIDI-library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiSynthesizer.java
@@ -0,0 +1,207 @@
+package jp.kshoji.javax.sound.midi.ble;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import java.util.List;
+
+import jp.kshoji.javax.sound.midi.Instrument;
+import jp.kshoji.javax.sound.midi.MidiChannel;
+import jp.kshoji.javax.sound.midi.MidiUnavailableException;
+import jp.kshoji.javax.sound.midi.Patch;
+import jp.kshoji.javax.sound.midi.Receiver;
+import jp.kshoji.javax.sound.midi.Soundbank;
+import jp.kshoji.javax.sound.midi.Synthesizer;
+import jp.kshoji.javax.sound.midi.Transmitter;
+import jp.kshoji.javax.sound.midi.VoiceStatus;
+import jp.kshoji.javax.sound.midi.impl.MidiChannelImpl;
+
+/**
+ * {@link jp.kshoji.javax.sound.midi.Synthesizer} implementation
+ *
+ * @author K.Shoji
+ */
+public class BleMidiSynthesizer implements Synthesizer {
+ private final BleMidiDevice bleMidiDevice;
+ private MidiChannel[] channels;
+ private VoiceStatus[] voiceStatuses;
+
+ /**
+ * Constructor
+ *
+ * @param bleMidiDevice the device
+ */
+ public BleMidiSynthesizer(final BleMidiDevice bleMidiDevice) {
+ this.bleMidiDevice = bleMidiDevice;
+
+ Receiver receiver = null;
+ try {
+ receiver = this.bleMidiDevice.getReceiver();
+ } catch (final MidiUnavailableException ignored) {
+ }
+
+ if (receiver == null) {
+ // empty
+ channels = new MidiChannel[0];
+ voiceStatuses = new VoiceStatus[0];
+ } else {
+ // 16 channels
+ voiceStatuses = new VoiceStatus[16];
+ channels = new MidiChannel[16];
+ for (int channel = 0; channel < 16; channel++) {
+ voiceStatuses[channel] = new VoiceStatus();
+ channels[channel] = new MidiChannelImpl(channel, receiver, voiceStatuses[channel]);
+ }
+ }
+ }
+
+ @NonNull
+ @Override
+ public MidiChannel[] getChannels() {
+ return channels;
+ }
+
+ @Override
+ public long getLatency() {
+ return 0;
+ }
+
+ @Override
+ public int getMaxPolyphony() {
+ return 127;
+ }
+
+ @NonNull
+ @Override
+ public VoiceStatus[] getVoiceStatus() {
+ return voiceStatuses;
+ }
+
+ @Nullable
+ @Override
+ public Soundbank getDefaultSoundbank() {
+ return null;
+ }
+
+ @Override
+ public boolean isSoundbankSupported(@NonNull final Soundbank soundbank) {
+ return false;
+ }
+
+ @NonNull
+ @Override
+ public Instrument[] getAvailableInstruments() {
+ return new Instrument[0];
+ }
+
+ @NonNull
+ @Override
+ public Instrument[] getLoadedInstruments() {
+ return new Instrument[0];
+ }
+
+ @Override
+ public boolean remapInstrument(@NonNull final Instrument from, @NonNull final Instrument to) {
+ return false;
+ }
+
+ @Override
+ public boolean loadAllInstruments(@NonNull final Soundbank soundbank) {
+ return false;
+ }
+
+ @Override
+ public void unloadAllInstruments(@NonNull final Soundbank soundbank) {
+
+ }
+
+ @Override
+ public boolean loadInstrument(@NonNull final Instrument instrument) {
+ return false;
+ }
+
+ @Override
+ public void unloadInstrument(@NonNull final Instrument instrument) {
+
+ }
+
+ @Override
+ public boolean loadInstruments(@NonNull final Soundbank soundbank, @NonNull final Patch[] patchList) {
+ return false;
+ }
+
+ @Override
+ public void unloadInstruments(@NonNull final Soundbank soundbank, @NonNull final Patch[] patchList) {
+
+ }
+
+ @NonNull
+ @Override
+ public Info getDeviceInfo() {
+ return bleMidiDevice.getDeviceInfo();
+ }
+
+ @Override
+ public void open() throws MidiUnavailableException {
+ bleMidiDevice.open();
+ }
+
+ @Override
+ public void close() {
+ bleMidiDevice.close();
+ }
+
+ @Override
+ public boolean isOpen() {
+ return bleMidiDevice.isOpen();
+ }
+
+ @Override
+ public long getMicrosecondPosition() {
+ return -1;
+ }
+
+ @Override
+ public int getMaxReceivers() {
+ return bleMidiDevice.getMaxReceivers();
+ }
+
+ @Override
+ public int getMaxTransmitters() {
+ return bleMidiDevice.getMaxTransmitters();
+ }
+
+ @NonNull
+ @Override
+ public Receiver getReceiver() throws MidiUnavailableException {
+ return bleMidiDevice.getReceiver();
+ }
+
+ @NonNull
+ @Override
+ public List getReceivers() {
+ return bleMidiDevice.getReceivers();
+ }
+
+ @NonNull
+ @Override
+ public Transmitter getTransmitter() throws MidiUnavailableException {
+ return bleMidiDevice.getTransmitter();
+ }
+
+ @NonNull
+ @Override
+ public List getTransmitters() {
+ return bleMidiDevice.getTransmitters();
+ }
+
+ public void setReceiver(final Receiver receiver) {
+ // 16 channels
+ voiceStatuses = new VoiceStatus[16];
+ channels = new MidiChannel[16];
+ for (int channel = 0; channel < 16; channel++) {
+ voiceStatuses[channel] = new VoiceStatus();
+ channels[channel] = new MidiChannelImpl(channel, receiver, voiceStatuses[channel]);
+ }
+ }
+}
diff --git a/library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiTransmitter.java b/BLE-MIDI-library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiTransmitter.java
similarity index 100%
rename from library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiTransmitter.java
rename to BLE-MIDI-library/src/main/java/jp/kshoji/javax/sound/midi/ble/BleMidiTransmitter.java
diff --git a/BLE-MIDI-library/src/main/java/jp/kshoji/unity/midi/BleMidiUnityPlugin.java b/BLE-MIDI-library/src/main/java/jp/kshoji/unity/midi/BleMidiUnityPlugin.java
new file mode 100644
index 0000000..69882f3
--- /dev/null
+++ b/BLE-MIDI-library/src/main/java/jp/kshoji/unity/midi/BleMidiUnityPlugin.java
@@ -0,0 +1,452 @@
+package jp.kshoji.unity.midi;
+
+import java.util.HashMap;
+import java.util.Locale;
+import android.content.Context;
+import android.os.Build;
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
+
+import com.unity3d.player.UnityPlayer;
+import jp.kshoji.blemidi.central.BleMidiCentralProvider;
+import jp.kshoji.blemidi.device.MidiInputDevice;
+import jp.kshoji.blemidi.device.MidiOutputDevice;
+import jp.kshoji.blemidi.listener.OnMidiDeviceAttachedListener;
+import jp.kshoji.blemidi.listener.OnMidiDeviceDetachedListener;
+import jp.kshoji.blemidi.listener.OnMidiInputEventListener;
+
+/**
+ * BLE MIDI Plugin for Unity
+ * @author K.Shoji
+ */
+public class BleMidiUnityPlugin {
+ private static final String GAME_OBJECT_NAME = "MidiManager";
+
+ private final OnMidiInputEventListener midiInputEventListener = new OnMidiInputEventListener() {
+
+ private String serializeMidiMessage(String deviceAddress, int[] data) {
+ StringBuilder sb = new StringBuilder(deviceAddress);
+ for (int i = 0; i < data.length; i++) {
+ sb.append(",");
+ sb.append(String.format(Locale.ROOT, "%d", data[i]));
+ if (i == data.length - 1) {
+ return sb.toString();
+ }
+ }
+ return sb.toString();
+ }
+
+ private String serializeMidiMessage(String deviceAddress, int cable, byte[] data) {
+ StringBuilder sb = new StringBuilder(deviceAddress);
+ sb.append(",");
+ sb.append(String.format(Locale.ROOT, "%d", cable));
+ for (int i = 0; i < data.length; i++) {
+ sb.append(",");
+ sb.append(String.format(Locale.ROOT, "%d", data[i] & 0xff));
+ if (i == data.length - 1) {
+ return sb.toString();
+ }
+ }
+ return sb.toString();
+ }
+
+ private String serializeMidiMessage(String deviceAddress, int[] data1, byte[] data2) {
+ StringBuilder sb = new StringBuilder(deviceAddress);
+ for (int i = 0; i < data1.length; i++) {
+ sb.append(",");
+ sb.append(String.format(Locale.ROOT, "%d", data1[i]));
+ }
+ for (int i = 0; i < data2.length; i++) {
+ sb.append(",");
+ sb.append(String.format(Locale.ROOT, "%d", data2[i] & 0xff));
+ }
+ return sb.toString();
+ }
+
+ private String serializeMidiMessage(String deviceAddress, int[] data1, long data2) {
+ StringBuilder sb = new StringBuilder(deviceAddress);
+ for (int i = 0; i < data1.length; i++) {
+ sb.append(",");
+ sb.append(String.format(Locale.ROOT, "%d", data1[i]));
+ }
+ sb.append(",");
+ sb.append(String.format(Locale.ROOT, "%d", data2));
+ return sb.toString();
+ }
+
+ private static final int cable = 0;
+
+ @Override
+ public void onMidiNoteOff(final MidiInputDevice sender, int channel, int note, int velocity) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiNoteOff", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable, channel, note, velocity}));
+ }
+
+ @Override
+ public void onMidiNoteOn(final MidiInputDevice sender, int channel, int note, int velocity) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiNoteOn", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable, channel, note, velocity}));
+ }
+
+ @Override
+ public void onMidiPolyphonicAftertouch(final MidiInputDevice sender, int channel, int note, int pressure) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiPolyphonicAftertouch", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable, channel, note, pressure}));
+ }
+
+ @Override
+ public void onMidiControlChange(final MidiInputDevice sender, int channel, int function, int value) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiControlChange", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable, channel, function, value}));
+ }
+
+ @Override
+ public void onMidiProgramChange(final MidiInputDevice sender, int channel, int program) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiProgramChange", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable, channel, program}));
+ }
+
+ @Override
+ public void onMidiChannelAftertouch(final MidiInputDevice sender, int channel, int pressure) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiChannelAftertouch", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable, channel, pressure}));
+ }
+
+ @Override
+ public void onMidiPitchWheel(final MidiInputDevice sender, int channel, int amount) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiPitchWheel", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable, channel, amount}));
+ }
+
+ @Override
+ public void onMidiSystemExclusive(final MidiInputDevice sender, @NonNull final byte[] systemExclusive) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiSystemExclusive", serializeMidiMessage(sender.getDeviceAddress(), cable, systemExclusive));
+ }
+
+ @Override
+ public void onMidiTimeCodeQuarterFrame(MidiInputDevice sender, int timing) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiTimeCodeQuarterFrame", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable, timing}));
+ }
+
+ @Override
+ public void onMidiSongSelect(MidiInputDevice sender, int song) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiSongSelect", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable, song}));
+ }
+
+ @Override
+ public void onMidiSongPositionPointer(MidiInputDevice sender, int position) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiSongPositionPointer", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable, position}));
+ }
+
+ @Override
+ public void onMidiTuneRequest(MidiInputDevice sender) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiTuneRequest", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable}));
+ }
+
+ @Override
+ public void onMidiTimingClock(MidiInputDevice sender) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiTimingClock", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable}));
+ }
+
+ @Override
+ public void onMidiStart(MidiInputDevice sender) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiStart", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable}));
+ }
+
+ @Override
+ public void onMidiContinue(MidiInputDevice sender) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiContinue", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable}));
+ }
+
+ @Override
+ public void onMidiStop(MidiInputDevice sender) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiStop", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable}));
+ }
+
+ @Override
+ public void onMidiActiveSensing(MidiInputDevice sender) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiActiveSensing", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable}));
+ }
+
+ @Override
+ public void onMidiReset(MidiInputDevice sender) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiReset", serializeMidiMessage(sender.getDeviceAddress(), new int[] {cable}));
+ }
+
+ @Override
+ public void onRPNMessage(@NonNull MidiInputDevice sender, int channel, int function, int value) {
+
+ }
+
+ @Override
+ public void onNRPNMessage(@NonNull MidiInputDevice sender, int channel, int function, int value) {
+
+ }
+ };
+
+ public void sendMidiNoteOn(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 5) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiNoteOn(Integer.parseInt(split[2]), Integer.parseInt(split[3]), Integer.parseInt(split[4]));
+ }
+ }
+
+ public void sendMidiNoteOff(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 5) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiNoteOff(Integer.parseInt(split[2]), Integer.parseInt(split[3]), Integer.parseInt(split[4]));
+ }
+ }
+
+ public void sendMidiPolyphonicAftertouch(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 5) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiPolyphonicAftertouch(Integer.parseInt(split[2]), Integer.parseInt(split[3]), Integer.parseInt(split[4]));
+ }
+ }
+
+ public void sendMidiControlChange(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 5) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiControlChange(Integer.parseInt(split[2]), Integer.parseInt(split[3]), Integer.parseInt(split[4]));
+ }
+ }
+
+ public void sendMidiProgramChange(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 4) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiProgramChange(Integer.parseInt(split[2]), Integer.parseInt(split[3]));
+ }
+ }
+
+ public void sendMidiChannelAftertouch(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 4) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiChannelAftertouch(Integer.parseInt(split[2]), Integer.parseInt(split[3]));
+ }
+ }
+
+ public void sendMidiPitchWheel(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 4) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiPitchWheel(Integer.parseInt(split[2]), Integer.parseInt(split[3]));
+ }
+ }
+
+ public void sendMidiSystemExclusive(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 1) {
+ return;
+ }
+ byte[] sysEx = new byte[split.length - 1];
+ for (int i = 0; i < split.length - 1; i++) {
+ sysEx[i] = (byte) (Integer.parseInt(split[i + 1]) & 0xff);
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiSystemExclusive(sysEx);
+ }
+ }
+
+ public void sendMidiTimeCodeQuarterFrame(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 3) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiTimeCodeQuarterFrame(Integer.parseInt(split[2]));
+ }
+ }
+
+ public void sendMidiSongSelect(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 3) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiSongSelect(Integer.parseInt(split[2]));
+ }
+ }
+
+ public void sendMidiSongPositionPointer(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 3) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiSongPositionPointer(Integer.parseInt(split[2]));
+ }
+ }
+
+ public void sendMidiTuneRequest(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 1) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiTuneRequest();
+ }
+ }
+
+ public void sendMidiTimingClock(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 1) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiTimingClock();
+ }
+ }
+
+ public void sendMidiStart(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 1) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiStart();
+ }
+ }
+
+ public void sendMidiContinue(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 1) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiContinue();
+ }
+ }
+
+ public void sendMidiStop(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 2) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiStop();
+ }
+ }
+
+ public void sendMidiActiveSensing(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 1) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiActiveSensing();
+ }
+ }
+
+ public void sendMidiReset(String serializedMidiMessage) {
+ String[] split = serializedMidiMessage.split(",");
+ if (split.length < 1) {
+ return;
+ }
+ MidiOutputDevice midiOutputDevice = midiOutputDeviceMap.get(split[0]);
+ if (midiOutputDevice != null) {
+ midiOutputDevice.sendMidiReset();
+ }
+ }
+
+ private BleMidiCentralProvider bleMidiCentralProvider;
+ HashMap midiOutputDeviceMap = new HashMap<>();
+
+ public void initialize(Context context) {
+ bleMidiCentralProvider = new BleMidiCentralProvider(context);
+ bleMidiCentralProvider.setOnMidiDeviceAttachedListener(new OnMidiDeviceAttachedListener() {
+ @Override
+ public void onMidiInputDeviceAttached(@NonNull MidiInputDevice midiInputDevice) {
+ midiInputDevice.setOnMidiInputEventListener(midiInputEventListener);
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiInputDeviceAttached", midiInputDevice.getDeviceAddress());
+ }
+
+ @Override
+ public void onMidiOutputDeviceAttached(@NonNull MidiOutputDevice midiOutputDevice) {
+ midiOutputDeviceMap.put(midiOutputDevice.getDeviceAddress(), midiOutputDevice);
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiOutputDeviceAttached", midiOutputDevice.getDeviceAddress());
+ }
+ });
+
+ bleMidiCentralProvider.setOnMidiDeviceDetachedListener(new OnMidiDeviceDetachedListener() {
+ @Override
+ public void onMidiInputDeviceDetached(@NonNull MidiInputDevice midiInputDevice) {
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiInputDeviceDetached", midiInputDevice.getDeviceAddress());
+ }
+
+ @Override
+ public void onMidiOutputDeviceDetached(@NonNull MidiOutputDevice midiOutputDevice) {
+ midiOutputDeviceMap.remove(midiOutputDevice.getDeviceAddress());
+ UnityPlayer.UnitySendMessage(GAME_OBJECT_NAME, "OnMidiOutputDeviceDetached", midiOutputDevice.getDeviceAddress());
+ }
+ });
+ }
+
+ /**
+ * Starts scan device
+ * @param timeoutInMilliSeconds timeout in msec, 0 : no timeout
+ */
+ public void startScanDevice(int timeoutInMilliSeconds) {
+ bleMidiCentralProvider.startScanDevice(timeoutInMilliSeconds);
+ }
+
+ /**
+ * Stops scan device
+ */
+ public void stopScanDevice() {
+ bleMidiCentralProvider.stopScanDevice();
+ }
+
+
+ /**
+ * Obtains device name for deviceId
+ * @param deviceId the device id
+ * @return device name, product name, or null
+ */
+ public String getDeviceName(String deviceId) {
+ MidiOutputDevice device = midiOutputDeviceMap.get(deviceId);
+ if (device != null) {
+ if (!TextUtils.isEmpty(device.getDeviceName())) {
+ return device.getDeviceName();
+ }
+ }
+ return null;
+ }
+
+ public void terminate() {
+ if (bleMidiCentralProvider != null) {
+ bleMidiCentralProvider.stopScanDevice();
+ bleMidiCentralProvider.terminate();
+ }
+ }
+}
diff --git a/library/src/main/res/values/uuids.xml b/BLE-MIDI-library/src/main/res/values/uuids.xml
similarity index 100%
rename from library/src/main/res/values/uuids.xml
rename to BLE-MIDI-library/src/main/res/values/uuids.xml
diff --git a/README.md b/README.md
index add8c9a..3d5c6b5 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
BLE MIDI for Android
====================
-[![Build Status](https://travis-ci.org/kshoji/BLE-MIDI-for-Android.svg?branch=master)](https://travis-ci.org/kshoji/BLE-MIDI-for-Android)
+[![Build Status](https://travis-ci.com/kshoji/BLE-MIDI-for-Android.svg?branch=develop)](https://travis-ci.com/kshoji/BLE-MIDI-for-Android)
MIDI over Bluetooth LE library for Android `API Level 18`(4.3, JellyBean) or later
@@ -30,9 +30,6 @@ Repository Overview
- Sample Project: `sample`
- Includes `BleMidiCentralActivity`, and `BleMidiPeripheralActivity` examples.
-Pre-compiled sample app is available on [Google Play Market](https://play.google.com/store/apps/details?id=jp.kshoji.blemidi.sample).
-
![QR Code](https://dl.dropboxusercontent.com/u/3968074/qr_ble_midi_sample.png)
-
Usage of the library
--------------------
diff --git a/UnityPlayerMock/.gitignore b/UnityPlayerMock/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/UnityPlayerMock/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/UnityPlayerMock/build.gradle b/UnityPlayerMock/build.gradle
new file mode 100644
index 0000000..40b7f78
--- /dev/null
+++ b/UnityPlayerMock/build.gradle
@@ -0,0 +1,9 @@
+apply plugin: 'java'
+
+sourceCompatibility = JavaVersion.VERSION_1_8
+targetCompatibility = JavaVersion.VERSION_1_8
+
+jar {
+ archiveBaseName = 'unityplayermock'
+ archiveVersion = '0.0.1'
+}
diff --git a/UnityPlayerMock/src/main/java/com/unity3d/player/UnityPlayer.java b/UnityPlayerMock/src/main/java/com/unity3d/player/UnityPlayer.java
new file mode 100644
index 0000000..998d083
--- /dev/null
+++ b/UnityPlayerMock/src/main/java/com/unity3d/player/UnityPlayer.java
@@ -0,0 +1,6 @@
+package com.unity3d.player;
+
+public class UnityPlayer {
+ public static void UnitySendMessage(String gameObjectName, String onMidiInputDeviceAttached, String deviceAddress) {
+ }
+}
diff --git a/build.gradle b/build.gradle
index a6fcfe1..d1e5c6f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,10 +2,11 @@
buildscript {
repositories {
- jcenter()
+ mavenCentral()
+ google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:1.5.0'
+ classpath 'com.android.tools.build:gradle:4.2.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -14,6 +15,7 @@ buildscript {
allprojects {
repositories {
- jcenter()
+ mavenCentral()
+ google()
}
}
diff --git a/gradle.properties b/gradle.properties
index 5d08ba7..07cd1b8 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -15,4 +15,6 @@
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
\ No newline at end of file
+# org.gradle.parallel=true
+android.useAndroidX=true
+org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=512m
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 55897a6..01104c9 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Thu Nov 27 10:31:49 JST 2014
+#Fri Oct 30 09:54:11 JST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.aar b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.aar
new file mode 100644
index 0000000..1b1620d
Binary files /dev/null and b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.aar differ
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.aar.md5 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.aar.md5
new file mode 100644
index 0000000..4afe9a9
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.aar.md5
@@ -0,0 +1 @@
+3563199dee261b713fc3dba42a511abb
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.aar.sha1 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.aar.sha1
new file mode 100644
index 0000000..a75d82a
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.aar.sha1
@@ -0,0 +1 @@
+151405d0259818a2b4c740446b24886d2a815e10
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.pom b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.pom
new file mode 100644
index 0000000..4e26c2e
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.pom
@@ -0,0 +1,31 @@
+
+
+ 4.0.0
+ jp.kshoji
+ ble-midi
+ 0.0.10-SNAPSHOT
+ aar
+
+
+ jp.kshoji
+ javax-sound-midi
+ 0.0.4-SNAPSHOT
+ aar
+
+ compile
+
+
+ *
+ *
+
+
+
+
+ com.android.support
+ support-annotations
+ 22.2.1
+ compile
+
+
+
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.pom.md5 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.pom.md5
new file mode 100644
index 0000000..f9e23bd
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.pom.md5
@@ -0,0 +1 @@
+64fc113574406285d6943cff268ff589
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.pom.sha1 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.pom.sha1
new file mode 100644
index 0000000..93c7a43
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20201109.103103-1.pom.sha1
@@ -0,0 +1 @@
+e7909d82e68d605dda312932da31f6eaf3fe0807
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.aar b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.aar
new file mode 100644
index 0000000..2259690
Binary files /dev/null and b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.aar differ
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.aar.md5 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.aar.md5
new file mode 100644
index 0000000..e549e3a
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.aar.md5
@@ -0,0 +1 @@
+2bf2274c5ddbbed2d6ee578ae1b9f6f1
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.aar.sha1 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.aar.sha1
new file mode 100644
index 0000000..8dd98e9
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.aar.sha1
@@ -0,0 +1 @@
+44e9a5fbf9d4a71e0f033202869b914bd8151f43
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.pom b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.pom
new file mode 100644
index 0000000..cba601b
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.pom
@@ -0,0 +1,31 @@
+
+
+ 4.0.0
+ jp.kshoji
+ ble-midi
+ 0.0.10-SNAPSHOT
+ aar
+
+
+ jp.kshoji
+ javax-sound-midi
+ 0.0.4-SNAPSHOT
+ aar
+
+ compile
+
+
+ *
+ *
+
+
+
+
+ com.android.support
+ support-annotations
+ 28.0.0
+ compile
+
+
+
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.pom.md5 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.pom.md5
new file mode 100644
index 0000000..564c62c
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.pom.md5
@@ -0,0 +1 @@
+b4f64e6296f5857f199449dd126a4af7
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.pom.sha1 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.pom.sha1
new file mode 100644
index 0000000..b6f5024
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210531.055408-2.pom.sha1
@@ -0,0 +1 @@
+22b1b0971bedaf24f915ac7ccffc58dbb4de2395
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.aar b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.aar
new file mode 100644
index 0000000..7e305e5
Binary files /dev/null and b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.aar differ
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.aar.md5 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.aar.md5
new file mode 100644
index 0000000..b972e9d
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.aar.md5
@@ -0,0 +1 @@
+3e6f5b23437833ea4825f3d0a5ab184f
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.aar.sha1 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.aar.sha1
new file mode 100644
index 0000000..d19602c
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.aar.sha1
@@ -0,0 +1 @@
+68da6afa473ba2ee0de5bd7a7bca407431e50227
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.pom b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.pom
new file mode 100644
index 0000000..cba601b
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.pom
@@ -0,0 +1,31 @@
+
+
+ 4.0.0
+ jp.kshoji
+ ble-midi
+ 0.0.10-SNAPSHOT
+ aar
+
+
+ jp.kshoji
+ javax-sound-midi
+ 0.0.4-SNAPSHOT
+ aar
+
+ compile
+
+
+ *
+ *
+
+
+
+
+ com.android.support
+ support-annotations
+ 28.0.0
+ compile
+
+
+
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.pom.md5 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.pom.md5
new file mode 100644
index 0000000..564c62c
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.pom.md5
@@ -0,0 +1 @@
+b4f64e6296f5857f199449dd126a4af7
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.pom.sha1 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.pom.sha1
new file mode 100644
index 0000000..b6f5024
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210604.045028-3.pom.sha1
@@ -0,0 +1 @@
+22b1b0971bedaf24f915ac7ccffc58dbb4de2395
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.aar b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.aar
new file mode 100644
index 0000000..ee1a40d
Binary files /dev/null and b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.aar differ
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.aar.md5 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.aar.md5
new file mode 100644
index 0000000..eca38bd
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.aar.md5
@@ -0,0 +1 @@
+eba66b743dd45edc997ccb66135c9f8f
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.aar.sha1 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.aar.sha1
new file mode 100644
index 0000000..3e1b143
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.aar.sha1
@@ -0,0 +1 @@
+6b7cb1b5edacef9c7df433410b0fd37898d32623
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.pom b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.pom
new file mode 100644
index 0000000..cba601b
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.pom
@@ -0,0 +1,31 @@
+
+
+ 4.0.0
+ jp.kshoji
+ ble-midi
+ 0.0.10-SNAPSHOT
+ aar
+
+
+ jp.kshoji
+ javax-sound-midi
+ 0.0.4-SNAPSHOT
+ aar
+
+ compile
+
+
+ *
+ *
+
+
+
+
+ com.android.support
+ support-annotations
+ 28.0.0
+ compile
+
+
+
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.pom.md5 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.pom.md5
new file mode 100644
index 0000000..564c62c
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.pom.md5
@@ -0,0 +1 @@
+b4f64e6296f5857f199449dd126a4af7
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.pom.sha1 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.pom.sha1
new file mode 100644
index 0000000..b6f5024
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/ble-midi-0.0.10-20210612.070708-4.pom.sha1
@@ -0,0 +1 @@
+22b1b0971bedaf24f915ac7ccffc58dbb4de2395
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/maven-metadata.xml b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/maven-metadata.xml
new file mode 100644
index 0000000..76beea6
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/maven-metadata.xml
@@ -0,0 +1,25 @@
+
+
+ jp.kshoji
+ ble-midi
+ 0.0.10-SNAPSHOT
+
+
+ 20210612.070708
+ 4
+
+ 20210612070708
+
+
+ aar
+ 0.0.10-20210612.070708-4
+ 20210612070708
+
+
+ pom
+ 0.0.10-20210612.070708-4
+ 20210612070708
+
+
+
+
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/maven-metadata.xml.md5 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/maven-metadata.xml.md5
new file mode 100644
index 0000000..d7b023b
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/maven-metadata.xml.md5
@@ -0,0 +1 @@
+80aa06aa83d90ebf8d55ce79a8cc2803
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/maven-metadata.xml.sha1 b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/maven-metadata.xml.sha1
new file mode 100644
index 0000000..313f2f8
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10-SNAPSHOT/maven-metadata.xml.sha1
@@ -0,0 +1 @@
+0dcbf25dd55629b28dc07bc7d618661b8e20e964
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.aar b/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.aar
new file mode 100644
index 0000000..ee1a40d
Binary files /dev/null and b/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.aar differ
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.aar.md5 b/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.aar.md5
new file mode 100644
index 0000000..eca38bd
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.aar.md5
@@ -0,0 +1 @@
+eba66b743dd45edc997ccb66135c9f8f
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.aar.sha1 b/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.aar.sha1
new file mode 100644
index 0000000..3e1b143
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.aar.sha1
@@ -0,0 +1 @@
+6b7cb1b5edacef9c7df433410b0fd37898d32623
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.pom b/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.pom
new file mode 100644
index 0000000..1e80e06
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.pom
@@ -0,0 +1,31 @@
+
+
+ 4.0.0
+ jp.kshoji
+ ble-midi
+ 0.0.10
+ aar
+
+
+ jp.kshoji
+ javax-sound-midi
+ 0.0.4-SNAPSHOT
+ aar
+
+ compile
+
+
+ *
+ *
+
+
+
+
+ com.android.support
+ support-annotations
+ 28.0.0
+ compile
+
+
+
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.pom.md5 b/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.pom.md5
new file mode 100644
index 0000000..7b6bbdb
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.pom.md5
@@ -0,0 +1 @@
+bfc9c48513c3c0f74b50313b5b12d30b
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.pom.sha1 b/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.pom.sha1
new file mode 100644
index 0000000..25f3b83
--- /dev/null
+++ b/library/repository/jp/kshoji/ble-midi/0.0.10/ble-midi-0.0.10.pom.sha1
@@ -0,0 +1 @@
+8fdcbee40a1d78af78cd09eb1ee7923de46752e3
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/maven-metadata.xml b/library/repository/jp/kshoji/ble-midi/maven-metadata.xml
index df662f2..fa9e248 100644
--- a/library/repository/jp/kshoji/ble-midi/maven-metadata.xml
+++ b/library/repository/jp/kshoji/ble-midi/maven-metadata.xml
@@ -2,8 +2,8 @@
jp.kshoji
ble-midi
- 0.0.1
+ 0.0.10
0.0.1
0.0.2-SNAPSHOT
@@ -19,7 +19,9 @@
0.0.7
0.0.8
0.0.9
+ 0.0.10-SNAPSHOT
+ 0.0.10
- 20151215053958
+ 20210701002824
diff --git a/library/repository/jp/kshoji/ble-midi/maven-metadata.xml.md5 b/library/repository/jp/kshoji/ble-midi/maven-metadata.xml.md5
index a1db34b..b9e4235 100644
--- a/library/repository/jp/kshoji/ble-midi/maven-metadata.xml.md5
+++ b/library/repository/jp/kshoji/ble-midi/maven-metadata.xml.md5
@@ -1 +1 @@
-b92c0a930ddf88bc20a5fb32a5b45d20
+6a42a9d5d48a8fcb97bd51906e871600
\ No newline at end of file
diff --git a/library/repository/jp/kshoji/ble-midi/maven-metadata.xml.sha1 b/library/repository/jp/kshoji/ble-midi/maven-metadata.xml.sha1
index e8e4bd2..2217d78 100644
--- a/library/repository/jp/kshoji/ble-midi/maven-metadata.xml.sha1
+++ b/library/repository/jp/kshoji/ble-midi/maven-metadata.xml.sha1
@@ -1 +1 @@
-5da16141807740ebb9c05ee9a647514647f13f76
+bc6f59bcc579a36878a6f79680dce773510a147a
\ No newline at end of file
diff --git a/sample-wear/build.gradle b/sample-wear/build.gradle
index 06c041f..17a712b 100644
--- a/sample-wear/build.gradle
+++ b/sample-wear/build.gradle
@@ -1,12 +1,12 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 22
- buildToolsVersion "22.0.1"
+ compileSdkVersion 30
defaultConfig {
applicationId "jp.kshoji.blemidi.sample"
minSdkVersion 22
+ targetSdkVersion 30
versionCode 3
versionName "1.2"
}
@@ -32,9 +32,9 @@ repositories {
}
dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
- compile project(":library")
- compile 'com.google.android.support:wearable:1.2.0'
- provided 'com.google.android.wearable:wearable:1.0.0'
- compile 'com.google.android.gms:play-services-wearable:8.3.0'
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation project(':BLE-MIDI-library')
+ implementation 'com.google.android.support:wearable:2.8.1'
+ compileOnly 'com.google.android.wearable:wearable:2.8.1'
+ implementation 'com.google.android.gms:play-services-wearable:17.1.0'
}
diff --git a/sample/build.gradle b/sample/build.gradle
index 4d79934..e28fb09 100644
--- a/sample/build.gradle
+++ b/sample/build.gradle
@@ -1,12 +1,12 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 22
- buildToolsVersion "22.0.1"
+ compileSdkVersion 30
defaultConfig {
applicationId "jp.kshoji.blemidi.sample"
minSdkVersion 18
+ targetSdkVersion 29
versionCode 3
versionName "1.2"
}
@@ -32,8 +32,8 @@ repositories {
}
dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
wearApp project(':sample-wear')
- compile project(":library")
- compile 'com.google.android.gms:play-services:8.3.0'
+ implementation project(':BLE-MIDI-library')
+ api 'com.android.support:support-annotations:28.0.0'
}
diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml
index 184ac90..5deb7b9 100644
--- a/sample/src/main/AndroidManifest.xml
+++ b/sample/src/main/AndroidManifest.xml
@@ -2,10 +2,7 @@
-
-
-
-
+
= Build.VERSION_CODES.M) {
+ if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+ if (!shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
+ scanDuration = duration;
+ requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_FINE_LOCATION);
+ return;
+ }
+ }
+ }
+
+ // already has permission
+ bleMidiCentralProvider.startScanDevice(duration);
+ }
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@@ -74,13 +95,25 @@ public boolean onOptionsItemSelected(MenuItem item) {
if (isScanning) {
bleMidiCentralProvider.stopScanDevice();
} else {
- bleMidiCentralProvider.startScanDevice(0);
+ startScanDeviceWithRequestingPermission(scanDuration);
}
return true;
}
return super.onOptionsItemSelected(item);
}
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ if (requestCode == PERMISSION_REQUEST_FINE_LOCATION) {
+ if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
+ bleMidiCentralProvider.startScanDevice(0);
+ }
+ }
+ }
+ }
+
// User interface
final Handler midiInputEventHandler = new Handler(new Handler.Callback() {
@Override
@@ -576,7 +609,7 @@ public void onMidiScanStatusChanged(boolean isScanning) {
});
// scan devices for 30 seconds
- bleMidiCentralProvider.startScanDevice(30000);
+ startScanDeviceWithRequestingPermission(30000);
}
@Override
@@ -616,8 +649,6 @@ public void onDismiss(DialogInterface dialog) {
@Override
protected void onDestroy() {
- super.onDestroy();
-
if (bleMidiCentralProvider != null) {
bleMidiCentralProvider.terminate();
}
@@ -643,6 +674,8 @@ protected void onDestroy() {
audioTrack = null;
}
}
+
+ super.onDestroy();
}
/**
diff --git a/sample/src/main/java/jp/kshoji/blemidi/sample/PeripheralActivity.java b/sample/src/main/java/jp/kshoji/blemidi/sample/PeripheralActivity.java
index 0b615f1..201ec05 100644
--- a/sample/src/main/java/jp/kshoji/blemidi/sample/PeripheralActivity.java
+++ b/sample/src/main/java/jp/kshoji/blemidi/sample/PeripheralActivity.java
@@ -594,8 +594,6 @@ public void onDismiss(DialogInterface dialog) {
@Override
protected void onDestroy() {
- super.onDestroy();
-
if (bleMidiPeripheralProvider != null) {
bleMidiPeripheralProvider.terminate();
}
@@ -621,6 +619,8 @@ protected void onDestroy() {
audioTrack = null;
}
}
+
+ super.onDestroy();
}
/**
diff --git a/settings.gradle b/settings.gradle
index 3c268ab..f5c297b 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include ':library', ':sample', ':sample-wear'
+include ':BLE-MIDI-library', ':sample', ':sample-wear', ':UnityPlayerMock'