diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml
new file mode 100644
index 0000000..4a53bee
--- /dev/null
+++ b/.idea/AndroidProjectSystem.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index d45a919..b86273d 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,23 +1,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..b268ef3
--- /dev/null
+++ b/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index ee635a3..639c779 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -1,21 +1,18 @@
+
diff --git a/.idea/migrations.xml b/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 0f4ea11..42537b8 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -42,7 +42,7 @@
-
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 818daef..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
index 7f68460..72f00ed 100644
--- a/.idea/runConfigurations.xml
+++ b/.idea/runConfigurations.xml
@@ -3,6 +3,14 @@
+
+
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 94a25f7..35eb1dd 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index a4a67f7..9ba2cb9 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,11 +1,12 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 28
- buildToolsVersion '23.0.3'
+ namespace "org.rockettrack"
+
+ compileSdkVersion 33
defaultConfig {
applicationId "org.rockettrack"
- minSdkVersion 17
+ minSdkVersion 31
targetSdkVersion 28
versionCode 2
versionName "1.0"
@@ -21,9 +22,18 @@ android {
}
dependencies {
- implementation 'com.android.support:appcompat-v7:28.0.0'
+ // AndroidX AppCompat
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+
+ // AndroidX Legacy Support Libraries
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation 'androidx.legacy:legacy-support-v13:1.0.0'
+
+ // Latest Play Services Maps library (update to latest stable version)
+ implementation 'com.google.android.gms:play-services-maps:19.2.0'
+ // For developers using AndroidX in their applications
+ implementation 'pub.devrel:easypermissions:3.0.0'
- implementation 'com.android.support:support-v4:28.0.0'
- implementation 'com.android.support:support-v13:28.0.0'
- implementation 'com.google.android.gms:play-services-maps:9.2.0'
+ // For developers using the Android Support Library
+ implementation 'pub.devrel:easypermissions:2.0.1'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 02bf742..0f00ef8 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,12 +1,17 @@
- android:targetSdkVersion="17" />
+
+
+
+
+
+
-
+
+ android:exported="true">
@@ -68,6 +76,9 @@
android:label="@string/select_device"
android:theme="@android:style/Theme.Dialog" />
+
+
mPairedDevicesArrayAdapter;
private ArrayAdapter mNewDevicesArrayAdapter;
@Override
- protected void onCreate(Bundle savedInstanceState) {
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Setup the window
@@ -73,6 +82,39 @@ protected void onCreate(Bundle savedInstanceState) {
// Set result CANCELED incase the user backs out
setResult(Activity.RESULT_CANCELED);
+ // Check and request Bluetooth permission
+ boolean hasPermissions = EasyPermissions.hasPermissions(this,
+ Manifest.permission.BLUETOOTH_CONNECT,
+ Manifest.permission.BLUETOOTH_SCAN);
+ if (hasPermissions) {
+ // Permission already granted, proceed with Bluetooth functionality
+ getBondedDevices();
+ } else {
+ // Request Bluetooth permission
+ EasyPermissions.requestPermissions(
+ this,
+ "Bluetooth permission is required to access bonded devices.",
+ REQUEST_BLUETOOTH_CONNECT,
+ Manifest.permission.BLUETOOTH_SCAN
+ );
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
+ }
+
+ @AfterPermissionGranted(REQUEST_BLUETOOTH_CONNECT)
+ private void getBondedDevices() {
+ // This method will be called when Bluetooth permission is granted
+ // Proceed with accessing Bluetooth functionality, e.g., get paired devices
+ // TODO
+ // Set pairedDevices = BluetoothAdapter.getDefaultAdapter().getBondedDevices();
+ // Handle paired devices as needed
+
+
// Initialize the button to perform device discovery
Button scanButton = (Button) findViewById(R.id.button_scan);
scanButton.setOnClickListener(new OnClickListener() {
@@ -111,6 +153,10 @@ public void onClick(View v) {
// Get a set of currently paired devices
Set pairedDevices = mBtAdapter.getBondedDevices();
+ extracted(pairedDevices);
+ }
+
+ private void extracted(Set pairedDevices) {
// If there are paired devices, add each one to the ArrayAdapter
if (pairedDevices.size() > 0) {
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
@@ -124,7 +170,7 @@ public void onClick(View v) {
mPairedDevicesArrayAdapter.add(noDevices);
}
}
-
+
private boolean isSPPDevice( BluetoothDevice device ) {
ParcelUuid[] supportedFunctions = device.getUuids();
diff --git a/app/src/main/java/org/rockettrack/LogActivity.java b/app/src/main/java/org/rockettrack/LogActivity.java
new file mode 100644
index 0000000..daa09d6
--- /dev/null
+++ b/app/src/main/java/org/rockettrack/LogActivity.java
@@ -0,0 +1,60 @@
+package org.rockettrack;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.widget.Button;
+import android.widget.TextView;
+import androidx.appcompat.app.AppCompatActivity;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+public class LogActivity extends AppCompatActivity {
+
+ private TextView logTextView;
+ private final StringBuilder logContent = new StringBuilder();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_log);
+
+ logTextView = findViewById(R.id.log_output);
+ Button emailButton = findViewById(R.id.email_button);
+
+ loadLogcat();
+
+ emailButton.setOnClickListener(v -> emailLog());
+ }
+
+ private void loadLogcat() {
+ try {
+ Process process = Runtime.getRuntime().exec("logcat -d");
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(process.getInputStream()));
+
+ String line;
+ while ((line = reader.readLine()) != null) {
+ logContent.append(line).append('\n');
+ }
+
+ logTextView.setText(logContent.toString());
+
+ } catch (Exception e) {
+ logTextView.setText("Failed to load logcat: " + e.getMessage());
+ }
+ }
+
+ private void emailLog() {
+ Intent intent = new Intent(Intent.ACTION_SEND);
+ intent.setType("message/rfc822");
+ intent.putExtra(Intent.EXTRA_SUBJECT, "Logcat Output");
+ intent.putExtra(Intent.EXTRA_TEXT, logContent.toString());
+
+ try {
+ startActivity(Intent.createChooser(intent, "Send Email"));
+ } catch (android.content.ActivityNotFoundException ex) {
+ logTextView.setText("No email clients installed.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/rockettrack/Main.java b/app/src/main/java/org/rockettrack/Main.java
index 663eb8b..7b775e2 100644
--- a/app/src/main/java/org/rockettrack/Main.java
+++ b/app/src/main/java/org/rockettrack/Main.java
@@ -20,9 +20,9 @@
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentTabHost;
-import android.support.v4.content.LocalBroadcastManager;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentTabHost;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
@@ -153,24 +153,32 @@ public boolean onCreateOptionsMenu(Menu menu) {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.connect_scan:
+ int itemId = item.getItemId();
+ if (itemId == R.id.connect_scan) {
// Launch the DeviceListActivity to see devices and do scan
- selectDevice();
+ selectDevice();
+ return true;
+ } else if (itemId == R.id.save_recording) {
+ // Save the raw recording
+ saveRawRecording();
+ return true;
+ } else if (itemId == R.id.menu_preferences) {
+ // Open the Preferences activity
+ Intent preferencesIntent = new Intent(this, Preferences.class);
+ startActivity(preferencesIntent);
+ return true;
+ } else if (itemId == R.id.stop_service) {
+ // Stop the service
+ onDoStop();
+ return true;
+ } else if (itemId == R.id.menu_log){
+ Intent intent = new Intent(this, LogActivity.class);
+ startActivity(intent);
return true;
- case R.id.save_recording:
- saveRawRecording();
- return true;
- case R.id.menu_preferences:
- Intent i = new Intent(this,Preferences.class);
- startActivity(i);
- break;
- case R.id.stop_service:
- onDoStop();
- break;
+ // Handle other menu item selections here if needed
}
- return false;
- }
+ return super.onOptionsItemSelected(item);
+ }
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
diff --git a/app/src/main/java/org/rockettrack/MapFragment.java b/app/src/main/java/org/rockettrack/MapFragment.java
index b0ece4b..50a34a0 100644
--- a/app/src/main/java/org/rockettrack/MapFragment.java
+++ b/app/src/main/java/org/rockettrack/MapFragment.java
@@ -21,39 +21,29 @@
import java.util.ArrayList;
import java.util.List;
-import android.app.Activity;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.Toast;
import android.widget.ToggleButton;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.OnMapReadyCallback;
-import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
-import com.google.android.gms.maps.CameraUpdateFactory;
-import com.google.android.gms.maps.GoogleMap;
-import com.google.android.gms.maps.OnMapReadyCallback;
-import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.UiSettings;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.Circle;
import com.google.android.gms.maps.model.CircleOptions;
-import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
diff --git a/app/src/main/java/org/rockettrack/RocketTrackBaseFragment.java b/app/src/main/java/org/rockettrack/RocketTrackBaseFragment.java
index 8ffe37d..2d812bf 100644
--- a/app/src/main/java/org/rockettrack/RocketTrackBaseFragment.java
+++ b/app/src/main/java/org/rockettrack/RocketTrackBaseFragment.java
@@ -27,7 +27,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
-import android.support.v4.app.Fragment;
+import androidx.fragment.app.Fragment;
import android.view.Surface;
import android.view.View;
import android.view.WindowManager;
diff --git a/app/src/main/java/org/rockettrack/Utils.java b/app/src/main/java/org/rockettrack/Utils.java
index 399a178..006b566 100644
--- a/app/src/main/java/org/rockettrack/Utils.java
+++ b/app/src/main/java/org/rockettrack/Utils.java
@@ -33,5 +33,4 @@ public static void createFolder(String folderName) {
}
}
-
}
diff --git a/app/src/main/java/org/rockettrack/service/AppService.java b/app/src/main/java/org/rockettrack/service/AppService.java
index 101c7b5..f0d5102 100644
--- a/app/src/main/java/org/rockettrack/service/AppService.java
+++ b/app/src/main/java/org/rockettrack/service/AppService.java
@@ -20,8 +20,8 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
-import android.support.v4.app.NotificationCompat;
-import android.support.v4.content.LocalBroadcastManager;
+import androidx.core.app.NotificationCompat;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.Toast;
@@ -151,12 +151,12 @@ public void onDestroy() {
}
/**
- *
+ *
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// The PendingIntent to launch our activity if the user selects this notification
- PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, Main.class), 0);
+ PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, Main.class), PendingIntent.FLAG_IMMUTABLE);
CharSequence text = getText(R.string.telemetry_service_started);
@@ -168,11 +168,27 @@ public int onStartCommand(Intent intent, int flags, int startId) {
notificationBuilder.setContentText(text);
notificationBuilder.setOngoing(true);
notificationBuilder.setContentIntent(contentIntent);
-
+
Notification notification = notificationBuilder.build();
+ /* TODO
+ org.rockettrack E FATAL EXCEPTION: main
+ Process: org.rockettrack, PID: 26339
+ android.app.RemoteServiceException$CannotPostForegroundServiceNotificationException: Bad notification for startForeground
+ at android.app.ActivityThread.throwRemoteServiceException(ActivityThread.java:2192)
+ at android.app.ActivityThread.-$$Nest$mthrowRemoteServiceException(Unknown Source:0)
+ at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2493)
+ at android.os.Handler.dispatchMessage(Handler.java:111)
+ at android.os.Looper.loopOnce(Looper.java:242)
+ at android.os.Looper.loop(Looper.java:362)
+ at android.app.ActivityThread.main(ActivityThread.java:8448)
+ at java.lang.reflect.Method.invoke(Native Method)
+ at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
+ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:992)
+
+ */
// Move us into the foreground.
- startForeground(NOTIFICATION, notification);
+ //startForeground(NOTIFICATION, notification);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
@@ -221,7 +237,7 @@ public void connectToRocketTracker( BluetoothDevice device ) {
mAltosBluetooth = new RocketTrackBluetooth(device, mHandler);
setState(STATE_CONNECTING);
}
-
+
}
public void stopService() {
@@ -266,10 +282,10 @@ private void connected() {
notificationBuilder.setContentText(text);
notificationBuilder.setProgress(0, 0, false);
updateNotification();
-
+
setState(STATE_CONNECTED);
- // Send setup commands:
+ // Send setup commands:
String cmd;
// this should increase the run time of the tx.
cmd = "$PMTK314,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n";
@@ -340,5 +356,5 @@ private void updateNotification() {
NotificationManager mgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mgr.notify(NOTIFICATION, notificationBuilder.build());
}
-
+
}
diff --git a/app/src/main/res/layout/activity_log.xml b/app/src/main/res/layout/activity_log.xml
new file mode 100644
index 0000000..62edce6
--- /dev/null
+++ b/app/src/main/res/layout/activity_log.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index d70b7cf..05341ab 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,4 +1,4 @@
-
-
+
diff --git a/app/src/main/res/menu/option_menu.xml b/app/src/main/res/menu/option_menu.xml
index 7403537..7f56452 100644
--- a/app/src/main/res/menu/option_menu.xml
+++ b/app/src/main/res/menu/option_menu.xml
@@ -29,7 +29,9 @@
-
-
-
+ android:title="@string/menu_preferences"/>
+
\ No newline at end of file
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index e30403d..c1c2515 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -23,6 +23,7 @@
+ Journal de l\'app
RocketTrack Telemetry Service
Connection à
Connecté à
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c6ed5df..4e02e05 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -20,6 +20,7 @@
Stop Service
Save Recording
Preferences
+ App Log
@@ -38,8 +39,4 @@
Units
AGL
Display altitude as AGL
-
-
- Hello blank fragment
-
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index ae98c53..04c389e 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -1,23 +1,8 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/xml/prefered_device.xml b/app/src/main/res/xml/prefered_device.xml
deleted file mode 100644
index 363b6ee..0000000
--- a/app/src/main/res/xml/prefered_device.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
diff --git a/build.gradle b/build.gradle
index 0cc143e..8ffd811 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ buildscript {
google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.5.3'
+ classpath 'com.android.tools.build:gradle:8.9.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/gradle.properties b/gradle.properties
index 1d3591c..ccb748f 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -15,4 +15,7 @@
# 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
+android.enableJetifier=true
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index babdf56..bbad5e2 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Fri Dec 27 08:58:46 CET 2019
+#Sun Apr 27 22:43:41 PDT 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
diff --git a/gradlew b/gradlew
old mode 100644
new mode 100755