ui+search+conn
This commit is contained in:
parent
b982711339
commit
a4e6d4ba17
1
.idea/gradle.xml
generated
1
.idea/gradle.xml
generated
@ -13,7 +13,6 @@
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
|
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -4,7 +4,7 @@
|
||||
<option name="filePathToZoomLevelMap">
|
||||
<map>
|
||||
<entry key="../../../../layout/custom_preview.xml" value="0.203125" />
|
||||
<entry key="app/src/main/res/layout/activity_main.xml" value="0.2" />
|
||||
<entry key="app/src/main/res/layout/activity_main.xml" value="0.33" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
|
@ -3,12 +3,12 @@ plugins {
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk 31
|
||||
compileSdk 33
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.example.co2sense_app"
|
||||
minSdk 26
|
||||
targetSdk 31
|
||||
targetSdk 33
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
@ -25,14 +25,18 @@ android {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
namespace 'com.example.co2sense_app'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
implementation 'com.google.android.material:material:1.6.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.5.1'
|
||||
implementation 'com.google.android.material:material:1.7.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.activity:activity:1.7.0-alpha02'
|
||||
implementation 'androidx.fragment:fragment:1.6.0-alpha04'
|
||||
implementation 'androidx.core:core:1.9.0'
|
||||
//testImplementation 'junit:junit:4.13.2'
|
||||
//androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
//androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
}
|
@ -1,10 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.co2sense_app">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-feature android:name="android.software.companion_device_setup" />
|
||||
|
||||
<uses-feature android:name="android.software.companion_device_setup"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:usesPermissionFlags="neverForLocation"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
@ -12,6 +18,15 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.CO2Sense_app">
|
||||
<!--android:theme="@style/Theme.AppCompat.NoActionBar"-->
|
||||
<!--android:theme="@style/Theme.CO2Sense_app"-->
|
||||
<activity
|
||||
android:name=".search_ble_devices_activity"
|
||||
android:exported="false">
|
||||
<meta-data
|
||||
android:name="android.app.lib_name"
|
||||
android:value="" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true">
|
||||
@ -22,4 +37,5 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -10,12 +10,11 @@ import android.bluetooth.BluetoothGattCallback;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothManager;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.companion.AssociationRequest;
|
||||
import android.companion.BluetoothDeviceFilter;
|
||||
import android.bluetooth.le.BluetoothLeScanner;
|
||||
import android.bluetooth.le.ScanCallback;
|
||||
import android.companion.CompanionDeviceManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentSender;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
@ -31,36 +30,45 @@ import java.nio.ByteBuffer;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public abstract class BLEDevice {
|
||||
private enum ConnectionState {NONE, STARTING_BT, CONNECTING, CONNECTED};
|
||||
private ConnectionState state = ConnectionState.NONE;
|
||||
|
||||
private static final int REQUEST_BT_PERMISSION = 16535;
|
||||
private static final int REQUEST_ENABLE_BT = 16536;
|
||||
private static final int SELECT_DEVICE_REQUEST_CODE = 16537;
|
||||
private static final int REQUEST_BT_CONNECT_PERMISSION = 16538;
|
||||
private static final int REQUEST_BT_SCAN_PERMISSION = 16539;
|
||||
private static final int REQUEST_FINE_LOC_PERMISSION = 16540;
|
||||
|
||||
private final Activity activity;
|
||||
private boolean startPairingOnBTStart;
|
||||
private boolean startConnectOnBTStart;
|
||||
|
||||
protected BluetoothGatt bluetoothGatt;
|
||||
private BluetoothDevice device;
|
||||
private final ActivityResultLauncher<String> requestPermissionLauncher;
|
||||
private BluetoothAdapter bluetoothAdapter;
|
||||
|
||||
private ScanCallback scanCallback;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.S)
|
||||
BLEDevice(Activity activity) {
|
||||
this.activity = activity;
|
||||
requestPermissionLauncher = ((ActivityResultCaller) activity).registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> connect());
|
||||
}
|
||||
ActivityResultLauncher<String> requestPermissionLauncher = ((ActivityResultCaller) activity).registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> connect());
|
||||
|
||||
public void startBT() {
|
||||
Log.d("bt", "startBT");
|
||||
Context context = activity.getApplicationContext();
|
||||
BluetoothManager bluetoothManager = ContextCompat.getSystemService(context, BluetoothManager.class);
|
||||
if (bluetoothManager == null)
|
||||
throw new NoSuchElementException("No Bluetooth manager found");
|
||||
BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
|
||||
bluetoothAdapter = bluetoothManager.getAdapter();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.S)
|
||||
public void startBT() {
|
||||
Log.d("bt", "startBT");
|
||||
if (bluetoothAdapter == null)
|
||||
throw new NoSuchElementException("No Bluetooth adapter found");
|
||||
|
||||
if (bluetoothAdapter.isEnabled()) {
|
||||
if (startPairingOnBTStart) pair();
|
||||
if (startConnectOnBTStart) connect();
|
||||
} else {
|
||||
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
|
||||
if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED) {
|
||||
@ -71,36 +79,6 @@ public abstract class BLEDevice {
|
||||
}
|
||||
}
|
||||
|
||||
protected void pair() {
|
||||
Log.d("bt", "pair");
|
||||
BluetoothDeviceFilter deviceFilter = new BluetoothDeviceFilter.Builder()
|
||||
//.setNamePattern(Pattern.compile("My device"))
|
||||
//.addServiceUuid(new ParcelUuid(new UUID(0x123abcL, -1L)), null)
|
||||
.build();
|
||||
AssociationRequest pairingRequest = new AssociationRequest.Builder()
|
||||
.addDeviceFilter(deviceFilter)
|
||||
//.setSingleDevice(true)
|
||||
.build();
|
||||
|
||||
CompanionDeviceManager deviceManager = (CompanionDeviceManager) activity.getSystemService(Context.COMPANION_DEVICE_SERVICE);
|
||||
deviceManager.associate(pairingRequest, new CompanionDeviceManager.Callback() {
|
||||
@Override
|
||||
public void onDeviceFound(IntentSender chooserLauncher) {
|
||||
try {
|
||||
activity.startIntentSenderForResult(chooserLauncher, SELECT_DEVICE_REQUEST_CODE, null, 0, 0, 0
|
||||
);
|
||||
} catch (IntentSender.SendIntentException e) {
|
||||
Log.e("MainActivity", "Failed to send intent");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(CharSequence error) {
|
||||
Log.e("pair", (String) error);
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
@RequiresApi(api = Build.VERSION_CODES.S)
|
||||
protected void connect() {
|
||||
@ -119,6 +97,7 @@ public abstract class BLEDevice {
|
||||
bluetoothGatt.discoverServices();
|
||||
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
|
||||
Log.d("bt", "disconnected");
|
||||
connect();
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,7 +129,7 @@ public abstract class BLEDevice {
|
||||
switch (requestCode) {
|
||||
case REQUEST_ENABLE_BT:
|
||||
if(resultCode != Activity.RESULT_OK) startBT();
|
||||
else if(startPairingOnBTStart) pair();
|
||||
else if(startConnectOnBTStart) connect();
|
||||
break;
|
||||
case SELECT_DEVICE_REQUEST_CODE:
|
||||
Log.d("bt", "device selected");
|
||||
@ -166,11 +145,55 @@ public abstract class BLEDevice {
|
||||
}
|
||||
}
|
||||
|
||||
public void startPairingOnBTStart(boolean status) {
|
||||
startPairingOnBTStart = status;
|
||||
@RequiresApi(api = Build.VERSION_CODES.S)
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){
|
||||
switch (requestCode){
|
||||
case REQUEST_BT_SCAN_PERMISSION:
|
||||
//startScan(scanCallback);
|
||||
break;
|
||||
case REQUEST_FINE_LOC_PERMISSION:
|
||||
startScan(scanCallback);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void startConnectOnBTStart(boolean status) {
|
||||
startConnectOnBTStart = status;
|
||||
}
|
||||
|
||||
protected void onServicesDiscovered(){
|
||||
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.S)
|
||||
public void startScan(ScanCallback callback){
|
||||
scanCallback = callback;
|
||||
Log.d("BLE_device", "startScan: startBT");
|
||||
startBT();
|
||||
Log.d("BLE_device", "startScan: getPerm");
|
||||
|
||||
if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
activity.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_FINE_LOC_PERMISSION);
|
||||
Log.d("BLE_device", "startScan: asking perms");
|
||||
return;
|
||||
}
|
||||
if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
activity.requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_FINE_LOC_PERMISSION);
|
||||
Log.d("BLE_device", "startScan: asking perms");
|
||||
return;
|
||||
}
|
||||
if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
|
||||
activity.requestPermissions(new String[]{Manifest.permission.BLUETOOTH_SCAN}, REQUEST_BT_SCAN_PERMISSION);
|
||||
Log.d("BLE device", "startScan: asking perms");
|
||||
//return;
|
||||
}
|
||||
Log.d("BLE_device", "startScan: ");
|
||||
BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
|
||||
bluetoothLeScanner.startScan(callback);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.S)
|
||||
public void setDeviceFromMAC(String targetDeviceMAC) {
|
||||
device = bluetoothAdapter.getRemoteDevice(targetDeviceMAC);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,21 @@
|
||||
package com.example.co2sense_app;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.Layout;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
@ -19,14 +27,31 @@ public class MainActivity extends AppCompatActivity {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
Toolbar myToolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
myToolbar.showContextMenu();
|
||||
myToolbar.showOverflowMenu();
|
||||
setSupportActionBar(myToolbar);
|
||||
getSupportActionBar().setDisplayShowTitleEnabled(false);
|
||||
|
||||
SharedPreferences sharedPref = getSharedPreferences(
|
||||
getString(R.string.main_shared_pref),Context.MODE_PRIVATE);
|
||||
String targetDeviceMAC = sharedPref.getString("target_device_mac", null);
|
||||
Log.d("MAIN", "onCreate: "+targetDeviceMAC);
|
||||
Log.d("MAIN", "onCreate: "+sharedPref.hashCode());
|
||||
|
||||
sensor = new CO2Sensor(this);
|
||||
sensor.startPairingOnBTStart(true);
|
||||
if(targetDeviceMAC != null) {
|
||||
sensor.setDeviceFromMAC(targetDeviceMAC);
|
||||
sensor.startConnectOnBTStart(true);
|
||||
sensor.startBT();
|
||||
}
|
||||
|
||||
ConstraintLayout mainLayout = findViewById(R.id.mainLayout);
|
||||
OMeter CO2Meter = findViewById(R.id.CO2OMeter);
|
||||
mainLayout.setOnClickListener(v -> {
|
||||
// sensor.startBT();
|
||||
// sensor.pair();
|
||||
|
||||
ConstraintLayout CO2_widget = findViewById(R.id.CO2_ES);
|
||||
OMeter CO2Meter = CO2_widget.findViewById(R.id.OMeter);
|
||||
CO2_widget.setOnClickListener(v -> {
|
||||
Log.d("MAIN", "onCreate: click");
|
||||
CO2Meter.setValue(CO2Meter.getValue() + 100);
|
||||
});
|
||||
}
|
||||
@ -43,4 +68,33 @@ public class MainActivity extends AppCompatActivity {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
sensor.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.S)
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
sensor.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.toolbar, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.select_target:
|
||||
Intent myIntent = new Intent(this, search_ble_devices_activity.class);
|
||||
startActivity(myIntent);
|
||||
return true;
|
||||
|
||||
default:
|
||||
// If we got here, the user's action was not recognized.
|
||||
// Invoke the superclass to handle it.
|
||||
return super.onOptionsItemSelected(item);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -17,13 +17,14 @@ import android.view.View;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class OMeter extends View {
|
||||
private float min, max, value;
|
||||
private float min, max, value = 100;
|
||||
private float angle;
|
||||
private int minColor, maxColor;
|
||||
private int bandRad;
|
||||
private int strokeWidth;
|
||||
private RectF rectf;
|
||||
private String dispValue = "NaN";
|
||||
private int textColor;
|
||||
|
||||
private final Paint bandPaint;
|
||||
private final Paint textPaint;
|
||||
@ -48,7 +49,7 @@ public class OMeter extends View {
|
||||
bandPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
|
||||
textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
textPaint.setColor(0xFFFFFFFF); //TODO : get from theme
|
||||
textPaint.setColor(textColor);
|
||||
textPaint.setTextAlign(Paint.Align.CENTER);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,74 @@
|
||||
package com.example.co2sense_app;
|
||||
|
||||
|
||||
import android.bluetooth.le.ScanResult;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ble_devices_adapter extends RecyclerView.Adapter<ble_devices_adapter.ViewHolder> {
|
||||
ArrayList<ScanResult> data;
|
||||
View.OnClickListener itemSelectListener;
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
private final TextView textView;
|
||||
private final Button selectButton;
|
||||
|
||||
public ViewHolder(View view) {
|
||||
super(view);
|
||||
textView = view.findViewById(R.id.name);
|
||||
selectButton = view.findViewById(R.id.select_ble_device);
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
textView.setText(name);
|
||||
}
|
||||
|
||||
public void setSelectOnClickListener(View.OnClickListener l){
|
||||
selectButton.setOnClickListener(l);
|
||||
}
|
||||
}
|
||||
|
||||
public ble_devices_adapter(){
|
||||
data = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addDevice(ScanResult result){
|
||||
if(data.stream().anyMatch(r -> r.getDevice().getAddress().equals(result.getDevice().getAddress()))) return;
|
||||
data.add(result);
|
||||
}
|
||||
|
||||
public void setSelectOnClickListener(View.OnClickListener l){
|
||||
itemSelectListener = l;
|
||||
}
|
||||
|
||||
public ScanResult getDataByIndex(int viewIndex) {
|
||||
return data.get(viewIndex);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.ble_device_scan_item, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
holder.setName(data.get(position).getScanRecord().getDeviceName());
|
||||
holder.setSelectOnClickListener(itemSelectListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return data.size();
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package com.example.co2sense_app;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.bluetooth.le.ScanCallback;
|
||||
import android.bluetooth.le.ScanResult;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
|
||||
public class search_ble_devices_activity extends AppCompatActivity {
|
||||
|
||||
CO2Sensor sensor;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.S)
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_search_ble_devices);
|
||||
|
||||
RecyclerView resultsView = findViewById(R.id.devicesFoundList);
|
||||
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
|
||||
resultsView.setLayoutManager(layoutManager);
|
||||
|
||||
ble_devices_adapter resultsAdapter = new ble_devices_adapter();
|
||||
|
||||
Activity thisActivity=this;
|
||||
|
||||
resultsAdapter.setSelectOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
SharedPreferences sharedPref = thisActivity.getSharedPreferences(
|
||||
getString(R.string.main_shared_pref),Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor edit = sharedPref.edit();
|
||||
int viewIndex = resultsView.getChildAdapterPosition((View)view.getParent());
|
||||
ScanResult device = resultsAdapter.getDataByIndex(viewIndex);
|
||||
String address = device.getDevice().getAddress();
|
||||
Log.d("search_ble", "onClick: "+address);
|
||||
edit.putString("target_device_mac", address);
|
||||
edit.apply();
|
||||
thisActivity.finish();
|
||||
}
|
||||
});
|
||||
resultsView.setAdapter(resultsAdapter);
|
||||
|
||||
sensor = new CO2Sensor(this);
|
||||
Log.d("search_ble", "onCreate: ");
|
||||
sensor.startScan(new ScanCallback() {
|
||||
@Override
|
||||
public void onScanResult(int callbackType, ScanResult result) {
|
||||
super.onScanResult(callbackType, result);
|
||||
resultsAdapter.addDevice(result);
|
||||
resultsAdapter.notifyDataSetChanged();
|
||||
Log.d("search_ble", "onScanResult: "+result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.S)
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
sensor.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.S)
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
sensor.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
}
|
9
app/src/main/res/drawable/battery_icon.xml
Normal file
9
app/src/main/res/drawable/battery_icon.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="200dp"
|
||||
android:height="200dp"
|
||||
android:viewportWidth="1000"
|
||||
android:viewportHeight="1000">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M964.8,374.6h-34.6v-39.2c0,-27.9 -22.6,-50.5 -50.5,-50.5H60.5c-27.9,0 -50.5,22.6 -50.5,50.5v329.3c0,27.9 22.6,50.5 50.5,50.5h819.1c27.9,0 50.5,-22.6 50.5,-50.5v-39.2h34.6c14,0 25.2,-11.3 25.2,-25.2V399.9C990.1,385.9 978.7,374.6 964.8,374.6zM868.2,635.6c0,14 -11.3,25.2 -25.2,25.2H97.4c-14,0 -25.3,-11.3 -25.3,-25.2V364.3c0,-14 11.3,-25.2 25.3,-25.2H843c14,0 25.2,11.3 25.2,25.2V635.6L868.2,635.6z"/>
|
||||
</vector>
|
32
app/src/main/res/drawable/battery_progressbar.xml
Normal file
32
app/src/main/res/drawable/battery_progressbar.xml
Normal file
@ -0,0 +1,32 @@
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@android:id/background">
|
||||
<shape android:shape="rectangle"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<corners android:radius="8dp"/>
|
||||
<size android:width="100dp" android:height="40dp" />
|
||||
<solid android:color="#00000000" />
|
||||
<stroke android:width="1dp" android:color="@color/black" />
|
||||
</shape>
|
||||
<shape android:shape="rectangle"
|
||||
android:tint="?attr/colorControlNormal" >
|
||||
<corners android:radius="1dp"/>
|
||||
<size android:width="10dp" android:height="20dp" />
|
||||
<solid android:color="@color/black" />
|
||||
<stroke android:width="1dp" android:color="@color/black" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:id="@android:id/progress">
|
||||
<clip>
|
||||
<shape>
|
||||
<gradient
|
||||
android:startColor="#FF0000"
|
||||
android:centerColor="#007A00"
|
||||
android:centerY="1.0"
|
||||
android:endColor="#06101d"
|
||||
android:angle="0"
|
||||
/>
|
||||
</shape>
|
||||
</clip>
|
||||
</item>
|
||||
</layer-list>
|
9
app/src/main/res/drawable/bluetooth_icon.xml
Normal file
9
app/src/main/res/drawable/bluetooth_icon.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="217.5dp"
|
||||
android:height="217.5dp"
|
||||
android:viewportWidth="217.5"
|
||||
android:viewportHeight="217.5">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M123.26,108.75l45.6,-44.49c1.74,-1.69 2.71,-4.02 2.71,-6.44s-0.98,-4.75 -2.71,-6.44l-50.04,-48.82c-2.59,-2.53 -6.44,-3.26 -9.78,-1.85c-3.34,1.41 -5.51,4.67 -5.51,8.29v80.5l-42.33,-41.3c-3.56,-3.47 -9.26,-3.4 -12.73,0.16c-3.47,3.56 -3.4,9.26 0.16,12.73l48.85,47.66l-48.85,47.66c-3.56,3.47 -3.63,9.17 -0.16,12.73s9.17,3.63 12.73,0.16l42.33,-41.3v80.5c0,3.62 2.17,6.89 5.51,8.29c1.13,0.48 2.32,0.71 3.49,0.71c2.31,0 4.57,-0.89 6.29,-2.56l50.04,-48.82c1.74,-1.69 2.71,-4.02 2.71,-6.44s-0.98,-4.75 -2.71,-6.44L123.26,108.75zM121.54,30.35l28.15,27.47l-28.15,27.47V30.35zM121.54,187.14v-54.93l28.15,27.47L121.54,187.14z"/>
|
||||
</vector>
|
10
app/src/main/res/drawable/rounded_rectangle.xml
Normal file
10
app/src/main/res/drawable/rounded_rectangle.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="rectangle" android:tint="?attr/colorAccent">
|
||||
<corners android:radius="8dp"/>
|
||||
<size android:width="100dp" android:height="40dp" />
|
||||
<stroke android:width="1dp" android:color="?attr/colorOnBackground"/>
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
@ -7,22 +7,65 @@
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/metersLayout"
|
||||
android:layout_width="0dp"
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:theme="?attr/actionBarTheme"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:menu="@menu/toolbar">
|
||||
|
||||
<com.example.co2sense_app.OMeter
|
||||
android:id="@+id/CO2OMeter"
|
||||
<TextView
|
||||
android:id="@+id/status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:max="1700"
|
||||
app:min="0">
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/status_erreur"
|
||||
tools:layout_editor_absoluteX="16dp"
|
||||
tools:layout_editor_absoluteY="28dp" />
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/ES_widgets_sv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/toolbar">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/CO2_ES"
|
||||
layout="@layout/es_widget"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<include
|
||||
android:id="@+id/TEMP_ES"
|
||||
layout="@layout/es_widget"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<include
|
||||
android:id="@+id/HUM_ES"
|
||||
layout="@layout/es_widget"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<include
|
||||
android:id="@+id/BATT_ES"
|
||||
layout="@layout/es_widget"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
</com.example.co2sense_app.OMeter>
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
14
app/src/main/res/layout/activity_search_ble_devices.xml
Normal file
14
app/src/main/res/layout/activity_search_ble_devices.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".search_ble_devices_activity">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/devicesFoundList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
26
app/src/main/res/layout/ble_device_scan_item.xml
Normal file
26
app/src/main/res/layout/ble_device_scan_item.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="@string/status_erreur"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/select_ble_device"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/select_ble_device"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
45
app/src/main/res/layout/es_widget.xml
Normal file
45
app/src/main/res/layout/es_widget.xml
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@drawable/rounded_rectangle"
|
||||
android:gravity="center"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.example.co2sense_app.OMeter
|
||||
android:id="@+id/OMeter"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:layout_marginVertical="8dp"
|
||||
android:layout_weight="1"
|
||||
app:textColor="?android:attr/textColorPrimaryNoDisable" />
|
||||
|
||||
<Space
|
||||
android:layout_width="8dp"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/value"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="sans-serif-condensed"
|
||||
android:text="@string/no_data"
|
||||
android:textColor="?android:attr/textColorPrimaryNoDisable"
|
||||
android:textSize="60sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
10
app/src/main/res/menu/toolbar.xml
Normal file
10
app/src/main/res/menu/toolbar.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/select_target"
|
||||
android:icon="@drawable/bluetooth_icon"
|
||||
android:iconTint="?attr/actionMenuTextColor"
|
||||
android:title="Target"
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
@ -1,6 +1,6 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.CO2Sense_app" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<style name="Theme.CO2Sense_app" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_200</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
|
@ -5,5 +5,6 @@
|
||||
<attr name="max" format="float"/>
|
||||
<attr name="minColor" format="color"/>
|
||||
<attr name="maxColor" format="color"/>
|
||||
<attr name="textColor" format="color"/>
|
||||
</declare-styleable>
|
||||
</resources>
|
@ -1,3 +1,8 @@
|
||||
<resources>
|
||||
<string name="app_name">CO2Sense_app</string>
|
||||
<string name="no_data">N/A</string>
|
||||
<string name="no_devices">No Device</string>
|
||||
<string name="status_erreur">erreur</string>
|
||||
<string name="select_ble_device">select</string>
|
||||
<string name="main_shared_pref">com.example.co2sense_app.SHARED_PREF_MAIN</string>
|
||||
</resources>
|
@ -1,6 +1,6 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.CO2Sense_app" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<style name="Theme.CO2Sense_app" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_500</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
@ -10,7 +10,9 @@
|
||||
<item name="colorSecondaryVariant">@color/teal_700</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
<item name = "android:windowActionBar">false</item>
|
||||
<item name = "android:windowNoTitle">true</item>
|
||||
</style>
|
||||
</resources>
|
7
battery_icon.svg
Normal file
7
battery_icon.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
|
||||
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
|
||||
<g><path d="M964.8,374.6h-34.6v-39.2c0-27.9-22.6-50.5-50.5-50.5H60.5c-27.9,0-50.5,22.6-50.5,50.5v329.3c0,27.9,22.6,50.5,50.5,50.5h819.1c27.9,0,50.5-22.6,50.5-50.5v-39.2h34.6c14,0,25.2-11.3,25.2-25.2V399.9C990.1,385.9,978.7,374.6,964.8,374.6z M868.2,635.6c0,14-11.3,25.2-25.2,25.2H97.4c-14,0-25.3-11.3-25.3-25.2V364.3c0-14,11.3-25.2,25.3-25.2H843c14,0,25.2,11.3,25.2,25.2V635.6L868.2,635.6z"/></g>
|
||||
</svg>
|
After Width: | Height: | Size: 878 B |
45
bluetooth-svgrepo-com.svg
Normal file
45
bluetooth-svgrepo-com.svg
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 217.499 217.499" style="enable-background:new 0 0 217.499 217.499;" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M123.264,108.749l45.597-44.488c1.736-1.693,2.715-4.016,2.715-6.441s-0.979-4.748-2.715-6.441l-50.038-48.82
|
||||
c-2.591-2.528-6.444-3.255-9.78-1.853c-3.336,1.406-5.505,4.674-5.505,8.294v80.504l-42.331-41.3
|
||||
c-3.558-3.471-9.255-3.402-12.727,0.156c-3.471,3.558-3.401,9.256,0.157,12.727l48.851,47.663l-48.851,47.663
|
||||
c-3.558,3.471-3.628,9.169-0.157,12.727s9.17,3.628,12.727,0.156l42.331-41.3v80.504c0,3.62,2.169,6.888,5.505,8.294
|
||||
c1.128,0.476,2.315,0.706,3.493,0.706c2.305,0,4.572-0.886,6.287-2.559l50.038-48.82c1.736-1.693,2.715-4.016,2.715-6.441
|
||||
s-0.979-4.748-2.715-6.441L123.264,108.749z M121.539,30.354l28.15,27.465l-28.15,27.465V30.354z M121.539,187.143v-54.93
|
||||
l28.15,27.465L121.539,187.143z"/>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
@ -1,7 +1,7 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
id 'com.android.application' version '7.1.3' apply false
|
||||
id 'com.android.library' version '7.1.3' apply false
|
||||
id 'com.android.application' version '7.3.1' apply false
|
||||
id 'com.android.library' version '7.3.1' apply false
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
||||
#Wed Apr 20 17:58:30 CEST 2022
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
Loading…
x
Reference in New Issue
Block a user