diff --git a/Android-Simple-Bluetooth-Example.zip b/Android-Simple-Bluetooth-Example.zip
new file mode 100644
index 0000000..f5308c0
Binary files /dev/null and b/Android-Simple-Bluetooth-Example.zip differ
diff --git a/app/build.gradle b/app/build.gradle
index 56e822b..66310f6 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,14 +1,13 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 23
- buildToolsVersion "23.0.3"
+ compileSdk 32
defaultConfig {
applicationId "com.mcuhq.simplebluetooth"
minSdkVersion 15
targetSdkVersion 23
- versionCode 1
+ versionCode 29
versionName "1.0"
}
buildTypes {
@@ -17,13 +16,19 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
- lintOptions {
- abortOnError false
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_11
+ targetCompatibility JavaVersion.VERSION_11
}
+ dependenciesInfo {
+ includeInApk true
+ includeInBundle true
+ }
+ buildToolsVersion '31.0.0 rc3'
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- testImplementation 'junit:junit:4.12'
- implementation 'com.android.support:appcompat-v7:23.3.0'
+ testImplementation 'junit:junit:4.13.2'
+ implementation 'androidx.appcompat:appcompat:1.5.1'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b29f7e7..a1500ca 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -4,21 +4,27 @@
+
+
+
+
+
-
+
diff --git a/app/src/main/java/com/mcuhq/simplebluetooth/MainActivity.java b/app/src/main/java/com/mcuhq/simplebluetooth/MainActivity.java
index 17635b5..37756e6 100644
--- a/app/src/main/java/com/mcuhq/simplebluetooth/MainActivity.java
+++ b/app/src/main/java/com/mcuhq/simplebluetooth/MainActivity.java
@@ -13,9 +13,13 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.content.ContextCompat;
-import android.support.v7.app.AppCompatActivity;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+//import android.support.v4.app.ActivityCompat;
+//import android.support.v4.content.ContextCompat;
+//import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
@@ -29,6 +33,7 @@
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
+import java.nio.charset.StandardCharsets;
import java.util.Set;
import java.util.UUID;
@@ -66,59 +71,55 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
- mBluetoothStatus = (TextView)findViewById(R.id.bluetooth_status);
+ mBluetoothStatus = (TextView) findViewById(R.id.bluetooth_status);
mReadBuffer = (TextView) findViewById(R.id.read_buffer);
- mScanBtn = (Button)findViewById(R.id.scan);
- mOffBtn = (Button)findViewById(R.id.off);
- mDiscoverBtn = (Button)findViewById(R.id.discover);
- mListPairedDevicesBtn = (Button)findViewById(R.id.paired_btn);
- mLED1 = (CheckBox)findViewById(R.id.checkbox_led_1);
+ mScanBtn = (Button) findViewById(R.id.scan);
+ mOffBtn = (Button) findViewById(R.id.off);
+ mDiscoverBtn = (Button) findViewById(R.id.discover);
+ mListPairedDevicesBtn = (Button) findViewById(R.id.paired_btn);
+ mLED1 = (CheckBox) findViewById(R.id.checkbox_led_1);
mBTArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
mBTAdapter = BluetoothAdapter.getDefaultAdapter(); // get a handle on the bluetooth radio
- mDevicesListView = (ListView)findViewById(R.id.devices_list_view);
+ mDevicesListView = (ListView) findViewById(R.id.devices_list_view);
mDevicesListView.setAdapter(mBTArrayAdapter); // assign model to view
mDevicesListView.setOnItemClickListener(mDeviceClickListener);
// Ask for location permission if not already allowed
- if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
- mHandler = new Handler(Looper.getMainLooper()){
+ mHandler = new Handler(Looper.getMainLooper()) {
@Override
- public void handleMessage(Message msg){
- if(msg.what == MESSAGE_READ){
+ public void handleMessage(Message msg) {
+ if (msg.what == MESSAGE_READ) {
String readMessage = null;
- try {
- readMessage = new String((byte[]) msg.obj, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- }
+ readMessage = new String((byte[]) msg.obj, StandardCharsets.UTF_8);
mReadBuffer.setText(readMessage);
}
- if(msg.what == CONNECTING_STATUS){
- if(msg.arg1 == 1)
- mBluetoothStatus.setText("Connected to Device: " + msg.obj);
+ if (msg.what == CONNECTING_STATUS) {
+ char[] sConnected;
+ if (msg.arg1 == 1)
+ mBluetoothStatus.setText(getString(R.string.BTConnected) + msg.obj);
else
- mBluetoothStatus.setText("Connection Failed");
+ mBluetoothStatus.setText(getString(R.string.BTconnFail));
}
}
};
if (mBTArrayAdapter == null) {
// Device does not support Bluetooth
- mBluetoothStatus.setText("Status: Bluetooth not found");
- Toast.makeText(getApplicationContext(),"Bluetooth device not found!",Toast.LENGTH_SHORT).show();
- }
- else {
+ mBluetoothStatus.setText(getString(R.string.sBTstaNF));
+ Toast.makeText(getApplicationContext(), getString(R.string.sBTdevNF), Toast.LENGTH_SHORT).show();
+ } else {
- mLED1.setOnClickListener(new View.OnClickListener(){
+ mLED1.setOnClickListener(new View.OnClickListener() {
@Override
- public void onClick(View v){
- if(mConnectedThread != null) //First check to make sure thread created
+ public void onClick(View v) {
+ if (mConnectedThread != null) //First check to make sure thread created
mConnectedThread.write("1");
}
});
@@ -131,79 +132,87 @@ public void onClick(View v) {
}
});
- mOffBtn.setOnClickListener(new View.OnClickListener(){
+ mOffBtn.setOnClickListener(new View.OnClickListener() {
@Override
- public void onClick(View v){
+ public void onClick(View v) {
bluetoothOff();
}
});
mListPairedDevicesBtn.setOnClickListener(new View.OnClickListener() {
@Override
- public void onClick(View v){
+ public void onClick(View v) {
listPairedDevices();
}
});
- mDiscoverBtn.setOnClickListener(new View.OnClickListener(){
+ mDiscoverBtn.setOnClickListener(new View.OnClickListener() {
@Override
- public void onClick(View v){
+ public void onClick(View v) {
discover();
}
});
}
}
- private void bluetoothOn(){
+ private void bluetoothOn() {
if (!mBTAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
- mBluetoothStatus.setText("Bluetooth enabled");
- Toast.makeText(getApplicationContext(),"Bluetooth turned on",Toast.LENGTH_SHORT).show();
+ mBluetoothStatus.setText(getString(R.string.BTEnable));
+ Toast.makeText(getApplicationContext(), getString(R.string.sBTturON), Toast.LENGTH_SHORT).show();
- }
- else{
- Toast.makeText(getApplicationContext(),"Bluetooth is already on", Toast.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(getApplicationContext(), getString(R.string.BTisON), Toast.LENGTH_SHORT).show();
}
}
// Enter here after user selects "yes" or "no" to enabling radio
@Override
- protected void onActivityResult(int requestCode, int resultCode, Intent Data){
+ protected void onActivityResult(int requestCode, int resultCode, Intent Data) {
// Check which request we're responding to
if (requestCode == REQUEST_ENABLE_BT) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a contact.
// The Intent's data Uri identifies which contact was selected.
- mBluetoothStatus.setText("Enabled");
- }
- else
- mBluetoothStatus.setText("Disabled");
+ mBluetoothStatus.setText(getString(R.string.sEnabled));
+ } else
+ mBluetoothStatus.setText(getString(R.string.sDisabled));
}
}
- private void bluetoothOff(){
+ private void bluetoothOff() {
mBTAdapter.disable(); // turn off
- mBluetoothStatus.setText("Bluetooth disabled");
- Toast.makeText(getApplicationContext(),"Bluetooth turned Off", Toast.LENGTH_SHORT).show();
+ mBluetoothStatus.setText(getString(R.string.sBTdisabl));
+ Toast.makeText(getApplicationContext(), "Bluetooth turned Off", Toast.LENGTH_SHORT).show();
}
- private void discover(){
+ private void discover() {
// Check if the device is already discovering
- if(mBTAdapter.isDiscovering()){
- mBTAdapter.cancelDiscovery();
- Toast.makeText(getApplicationContext(),"Discovery stopped",Toast.LENGTH_SHORT).show();
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
+ // TODO: Consider calling
+ // ActivityCompat#requestPermissions
+ // here to request the missing permissions, and then overriding
+ // public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ // int[] grantResults)
+ // to handle the case where the user grants the permission. See the documentation
+ // for ActivityCompat#requestPermissions for more details.
+ Toast.makeText(getBaseContext(), "Bluetooth Scan Permission denied", Toast.LENGTH_SHORT).show();
+ return;
}
- else{
- if(mBTAdapter.isEnabled()) {
+ if (mBTAdapter.isDiscovering()) {
+ mBTAdapter.cancelDiscovery();
+
+ Toast.makeText(getApplicationContext(), getString(R.string.DisStop), Toast.LENGTH_SHORT).show();
+ } else {
+ if (mBTAdapter.isEnabled()) {
mBTArrayAdapter.clear(); // clear items
mBTAdapter.startDiscovery();
- Toast.makeText(getApplicationContext(), "Discovery started", Toast.LENGTH_SHORT).show();
+ Toast.makeText(getApplicationContext(), getString(R.string.DisStart), Toast.LENGTH_SHORT).show();
registerReceiver(blReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
- }
- else{
- Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(getApplicationContext(), getString(R.string.BTnotOn), Toast.LENGTH_SHORT).show();
}
}
}
@@ -212,47 +221,56 @@ private void discover(){
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- if(BluetoothDevice.ACTION_FOUND.equals(action)){
+ if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// add the name to the list
+ if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
+ // TODO: Consider calling
+ // ActivityCompat#requestPermissions
+ // here to request the missing permissions, and then overriding
+ // public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ // int[] grantResults)
+ // to handle the case where the user grants the permission. See the documentation
+ // for ActivityCompat#requestPermissions for more details.
+ Toast.makeText(getBaseContext(), "Socket Connection Permission denied", Toast.LENGTH_SHORT).show();
+ return;
+ }
mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
mBTArrayAdapter.notifyDataSetChanged();
}
}
};
- private void listPairedDevices(){
+ private void listPairedDevices() {
mBTArrayAdapter.clear();
mPairedDevices = mBTAdapter.getBondedDevices();
- if(mBTAdapter.isEnabled()) {
+ if (mBTAdapter.isEnabled()) {
// put it's one to the adapter
for (BluetoothDevice device : mPairedDevices)
mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
- Toast.makeText(getApplicationContext(), "Show Paired Devices", Toast.LENGTH_SHORT).show();
- }
- else
- Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
+ Toast.makeText(getApplicationContext(), getString(R.string.show_paired_devices), Toast.LENGTH_SHORT).show();
+ } else
+ Toast.makeText(getApplicationContext(), getString(R.string.BTnotOn), Toast.LENGTH_SHORT).show();
}
private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
- if(!mBTAdapter.isEnabled()) {
- Toast.makeText(getBaseContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
+ if (!mBTAdapter.isEnabled()) {
+ Toast.makeText(getBaseContext(), getString(R.string.BTnotOn), Toast.LENGTH_SHORT).show();
return;
}
- mBluetoothStatus.setText("Connecting...");
+ mBluetoothStatus.setText(getString(R.string.cConnet));
// Get the device MAC address, which is the last 17 chars in the View
String info = ((TextView) view).getText().toString();
final String address = info.substring(info.length() - 17);
- final String name = info.substring(0,info.length() - 17);
+ final String name = info.substring(0, info.length() - 17);
// Spawn a new thread to avoid blocking the GUI one
- new Thread()
- {
+ new Thread() {
@Override
public void run() {
boolean fail = false;
@@ -263,10 +281,21 @@ public void run() {
mBTSocket = createBluetoothSocket(device);
} catch (IOException e) {
fail = true;
- Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_SHORT).show();
+ Toast.makeText(getBaseContext(), getString(R.string.ErrSockCrea), Toast.LENGTH_SHORT).show();
}
// Establish the Bluetooth socket connection.
try {
+ if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
+ // TODO: Consider calling
+ // ActivityCompat#requestPermissions
+ // here to request the missing permissions, and then overriding
+ // public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ // int[] grantResults)
+ // to handle the case where the user grants the permission. See the documentation
+ // for ActivityCompat#requestPermissions for more details.
+ Toast.makeText(getBaseContext(), "Socket creation Permission denied", Toast.LENGTH_SHORT).show();
+ return;
+ }
mBTSocket.connect();
} catch (IOException e) {
try {
@@ -276,10 +305,10 @@ public void run() {
.sendToTarget();
} catch (IOException e2) {
//insert code to deal with this
- Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_SHORT).show();
+ Toast.makeText(getBaseContext(), getString(R.string.ErrSockCrea), Toast.LENGTH_SHORT).show();
}
}
- if(!fail) {
+ if (!fail) {
mConnectedThread = new ConnectedThread(mBTSocket, mHandler);
mConnectedThread.start();
@@ -296,8 +325,18 @@ private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOE
final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", UUID.class);
return (BluetoothSocket) m.invoke(device, BT_MODULE_UUID);
} catch (Exception e) {
- Log.e(TAG, "Could not create Insecure RFComm Connection",e);
+ Log.e(TAG, "Could not create Insecure RFComm Connection", e);
+ }
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
+ // TODO: Consider calling
+ // ActivityCompat#requestPermissions
+ // here to request the missing permissions, and then overriding
+ // public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ // int[] grantResults)
+ // to handle the case where the user grants the permission. See the documentation
+ // for ActivityCompat#requestPermissions for more details.
+ return null;
}
- return device.createRfcommSocketToServiceRecord(BT_MODULE_UUID);
+ return device.createRfcommSocketToServiceRecord(BT_MODULE_UUID);
}
}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 545e63e..a8a86a1 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -19,7 +19,7 @@
android:checked="false"
android:scaleX="1.7"
android:scaleY="1.7"
- android:text="Toggle LED"
+ android:text="@string/toggle_led"
android:textStyle="bold" />
+ android:text="@string/lt_read_buffer" />
+ android:text="@string/lt_bluetooth_status" />
+ android:text="@string/bluetooth_on" />
+ android:text="@string/bluetooth_off" />
+ android:text="@string/show_paired_devices" />
+ android:text="@string/discover_new_devices" />
+
+ Bluetooth abilitato
+ Stato: Bluetooth non trovato
+ Dispositivo Bluetooth non trovato!
+ Richiesta Accensione Bluetooth
+ Il bluetooth è già acceso
+ Abilitato
+ Disabilitato
+ "Connesso al dispositivo: "
+ Il bluetooth è disabilitato
+ Il bluetooth è stato spento
+ Ricerca in corso…
+ Il bluetooth non è acceso
+ Connessione in corso…
+ Creazione del Socket non riuscita
+ Commuta LED
+ <Buffer di lettura>
+ <Stato del Bluetooth
+ "Stato: "
+ Bluetooth ON
+ Bluetooth OFF
+ Dispositivi associati
+ Ricerca dispositivi disponibili
+ Connessione %s non riuscita
+ Ricerca annullata
+ Bluetooth è già spento
+ Connessione non riuscita
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index dffe5cf..0e2db2d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,28 @@
- Simple Bluetooth
+ Simple Bluetooth
+ Connection Failed
+ Connected to Device:
+ "Bluetooth device not found!"
+ Status: Bluetooth not found
+ Bluetooth enabled
+ Bluetooth turned on
+ Bluetooth is already on
+ Enabled
+ Disabled
+ Bluetooth disabled
+ Bluetooth not on
+ Bluetooth status
+ Bluetooth turned off
+ Connecting…
+ Socket creation failed
+ Discovery started
+ Show Paired Devices
+ Discovery stopped
+ "Status:"
+ Discover new device
+ Toggle LED
+ RX:
+ <Read Buffer>
+ Bluetooth ON
+ Bluetooth OFF
diff --git a/build.gradle b/build.gradle
index 922ec4d..755a59a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,13 +2,15 @@
buildscript {
repositories {
- jcenter()
+ mavenCentral()
maven {
url "https://maven.google.com"
+ name 'Google'
}
+ google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.6.3'
+ classpath 'com.android.tools.build:gradle:7.2.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -17,9 +19,10 @@ buildscript {
allprojects {
repositories {
- jcenter()
+ mavenCentral()
maven {
url "https://maven.google.com"
+ name 'Google'
}
}
}
diff --git a/gradle.properties b/gradle.properties
index 1d3591c..915f0e6 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.enableJetifier=true
+android.useAndroidX=true
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index ff58779..d437d65 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed May 20 11:09:54 BST 2020
+#Mon Sep 26 15:21:11 CEST 2022
distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-milestone-1-bin.zip
distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
+zipStoreBase=GRADLE_USER_HOME