Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #23 pending mutability issue on android 12+ & add missing ContextCompat.RECEIVER_EXPORTED for broadcast receivers #26

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
5 changes: 2 additions & 3 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 31
compileSdkVersion 33
defaultConfig {
applicationId "me.aflak.libraries"
minSdkVersion 15
targetSdkVersion 31
targetSdkVersion 33
versionCode 2
versionName "1.0"
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
Expand All @@ -27,7 +27,7 @@ dependencies {
androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation project(path: ':arduino')
}
6 changes: 3 additions & 3 deletions arduino/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ ext {
}

android {
compileSdkVersion 31
compileSdkVersion 33

defaultConfig {
minSdkVersion 15
targetSdkVersion 31
targetSdkVersion 33
versionCode 9
versionName "1.4.6"

Expand All @@ -49,7 +49,7 @@ dependencies {
androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.appcompat:appcompat:1.6.1'

api 'com.github.felHR85:UsbSerial:6.1.0'
}
Expand Down
70 changes: 42 additions & 28 deletions arduino/src/main/java/me/aflak/arduino/Arduino.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package me.aflak.arduino;

import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
Expand All @@ -8,15 +9,19 @@
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.os.Build;
import android.util.Log;

import androidx.core.content.ContextCompat;

import com.felhr.usbserial.UsbSerialDevice;
import com.felhr.usbserial.UsbSerialInterface;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

/**
* Created by Omar on 21/05/2017.
Expand All @@ -34,7 +39,7 @@ public class Arduino implements UsbSerialInterface.UsbReadCallback {

private int baudRate;
private boolean isOpened;
private List<Integer> vendorIds;
private List<String> vendorIds;
private List<Byte> bytesReceived;
private byte delimiter;

Expand All @@ -57,19 +62,27 @@ private void init(Context context, int baudRate) {
this.baudRate = baudRate;
this.isOpened = false;
this.vendorIds = new ArrayList<>();
this.vendorIds.add(9025);
this.vendorIds.add("9025");
this.vendorIds.add("1027");
this.vendorIds.add("5824");
this.vendorIds.add("4292");
this.vendorIds.add("1659");
this.vendorIds.add("4966");
this.vendorIds.add("1A86");

this.bytesReceived = new ArrayList<>();
this.delimiter = DEFAULT_DELIMITER;
}

@SuppressLint("NewApi")
public void setArduinoListener(ArduinoListener listener) {
this.listener = listener;

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
intentFilter.addAction(ACTION_USB_DEVICE_PERMISSION);
context.registerReceiver(usbReceiver, intentFilter);
context.registerReceiver(usbReceiver, intentFilter, Context.RECEIVER_EXPORTED);

lastArduinoAttached = getAttachedArduino();
if (lastArduinoAttached != null && listener != null) {
Expand All @@ -81,12 +94,13 @@ public void unsetArduinoListener() {
this.listener = null;
}

@SuppressLint("NewApi")
public void open(UsbDevice device) {
PendingIntent permissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_DEVICE_PERMISSION), PendingIntent.FLAG_MUTABLE);
PendingIntent permissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_DEVICE_PERMISSION), PendingIntent.FLAG_IMMUTABLE);
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_USB_DEVICE_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
context.registerReceiver(usbReceiver, filter);
context.registerReceiver(usbReceiver, filter, Context.RECEIVER_EXPORTED);
usbManager.requestPermission(device, permissionIntent);
}

Expand All @@ -112,15 +126,15 @@ public void send(byte[] bytes) {
}
}

public void setDelimiter(byte delimiter){
public void setDelimiter(byte delimiter) {
this.delimiter = delimiter;
}

public void setBaudRate(int baudRate){
public void setBaudRate(int baudRate) {
this.baudRate = baudRate;
}

public void addVendorId(int id){
public void addVendorId(String id) {
vendorIds.add(id);
}

Expand All @@ -132,7 +146,7 @@ public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case UsbManager.ACTION_USB_DEVICE_ATTACHED:
device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (hasId(device.getVendorId())) {
if (hasId(String.valueOf(device.getVendorId()))) {
lastArduinoAttached = device;
if (listener != null) {
listener.onArduinoAttached(device);
Expand All @@ -141,7 +155,7 @@ public void onReceive(Context context, Intent intent) {
break;
case UsbManager.ACTION_USB_DEVICE_DETACHED:
device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (hasId(device.getVendorId())) {
if (hasId(String.valueOf(device.getVendorId()))) {
if (listener != null) {
listener.onArduinoDetached();
}
Expand All @@ -150,7 +164,7 @@ public void onReceive(Context context, Intent intent) {
case ACTION_USB_DEVICE_PERMISSION:
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (hasId(device.getVendorId())) {
if (hasId(String.valueOf(device.getVendorId()))) {
connection = usbManager.openDevice(device);
serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection);
if (serialPort != null) {
Expand Down Expand Up @@ -182,34 +196,34 @@ public void onReceive(Context context, Intent intent) {
private UsbDevice getAttachedArduino() {
HashMap<String, UsbDevice> map = usbManager.getDeviceList();
for (UsbDevice device : map.values()) {
if (hasId(device.getVendorId())) {
if (hasId(String.valueOf(device.getVendorId()))) {
return device;
}
}
return null;
}

private List<Integer> indexOf(byte[] bytes, byte b){
private List<Integer> indexOf(byte[] bytes, byte b) {
List<Integer> idx = new ArrayList<>();
for(int i=0 ; i<bytes.length ; i++){
if(bytes[i] == b){
for (int i = 0; i < bytes.length; i++) {
if (bytes[i] == b) {
idx.add(i);
}
}
return idx;
}

private List<Byte> toByteList(byte[] bytes){
private List<Byte> toByteList(byte[] bytes) {
List<Byte> list = new ArrayList<>();
for(byte b : bytes){
for (byte b : bytes) {
list.add(b);
}
return list;
}

private byte[] toByteArray(List<Byte> bytes){
private byte[] toByteArray(List<Byte> bytes) {
byte[] array = new byte[bytes.size()];
for(int i=0 ; i<bytes.size() ; i++){
for (int i = 0; i < bytes.size(); i++) {
array[i] = bytes.get(i);
}
return array;
Expand All @@ -219,21 +233,21 @@ private byte[] toByteArray(List<Byte> bytes){
public void onReceivedData(byte[] bytes) {
if (bytes.length != 0) {
List<Integer> idx = indexOf(bytes, delimiter);
if(idx.isEmpty()){
if (idx.isEmpty()) {
bytesReceived.addAll(toByteList(bytes));
} else{
} else {
int offset = 0;
for(int index : idx){
for (int index : idx) {
byte[] tmp = Arrays.copyOfRange(bytes, offset, index);
bytesReceived.addAll(toByteList(tmp));
if(listener != null) {
if (listener != null) {
listener.onArduinoMessage(toByteArray(bytesReceived));
}
bytesReceived.clear();
offset = index + 1;
}

if(offset < bytes.length){
if (offset < bytes.length) {
byte[] tmp = Arrays.copyOfRange(bytes, offset, bytes.length);
bytesReceived.addAll(toByteList(tmp));
}
Expand All @@ -245,10 +259,10 @@ public boolean isOpened() {
return isOpened;
}

private boolean hasId(int id) {
Log.i(getClass().getSimpleName(), "Vendor id : "+id);
for(int vendorId : vendorIds){
if(vendorId==id){
private boolean hasId(String id) {
Log.i(getClass().getSimpleName(), "Vendor id : " + id);
for (String vendorId : vendorIds) {
if (Objects.equals(vendorId, id)) {
return true;
}
}
Expand Down