Loading app/src/main/java/net/fabiszewski/ulogger/CreateGpxDocument.java 0 → 100644 +29 −0 Original line number Diff line number Diff line /* * Copyright (c) 2021 Bartek Fabiszewski * http://www.fabiszewski.net * * This file is part of μlogger-android. * Licensed under GPL, either version 3, or any later. * See <http://www.gnu.org/licenses/> */ package net.fabiszewski.ulogger; import android.content.Context; import android.content.Intent; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; class CreateGpxDocument extends ActivityResultContracts.CreateDocument { public static final String GPX_MIME = "application/gpx+xml"; @NonNull @Override public Intent createIntent(@NonNull Context context, @NonNull String input) { return super.createIntent(context, input) .setType(GPX_MIME) .addCategory(Intent.CATEGORY_OPENABLE); } } app/src/main/java/net/fabiszewski/ulogger/GpxExportTask.java +0 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,6 @@ public class GpxExportTask implements Runnable { ns_ulogger + " https://raw.githubusercontent.com/bfabiszewski/ulogger-server/master/scripts/gpx_extensions1.xsd"; public static final String GPX_EXTENSION = ".gpx"; public static final String GPX_MIME = "application/gpx+xml"; private DbAccess db; Loading app/src/main/java/net/fabiszewski/ulogger/MainActivity.java +33 −39 Original line number Diff line number Diff line Loading @@ -9,10 +9,10 @@ package net.fabiszewski.ulogger; import static androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult; import static net.fabiszewski.ulogger.Alert.showAlert; import static net.fabiszewski.ulogger.Alert.showConfirm; import static net.fabiszewski.ulogger.GpxExportTask.GPX_EXTENSION; import static net.fabiszewski.ulogger.GpxExportTask.GPX_MIME; import static java.util.concurrent.Executors.newCachedThreadPool; import android.app.Activity; Loading @@ -29,6 +29,7 @@ import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import androidx.activity.result.ActivityResultLauncher; import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; Loading @@ -52,8 +53,6 @@ public class MainActivity extends AppCompatActivity private final String TAG = MainActivity.class.getSimpleName(); private final static int RESULT_PREFS_UPDATED = 1; private final static int RESULT_GPX_EXPORT = 2; public final static String UPDATED_PREFS = "extra_updated_prefs"; public String preferenceHost; Loading Loading @@ -138,8 +137,8 @@ public class MainActivity extends AppCompatActivity public boolean onOptionsItemSelected(@NonNull MenuItem item) { final int id = item.getItemId(); if (id == R.id.menu_settings) { Intent i = new Intent(this, SettingsActivity.class); startActivityForResult(i, RESULT_PREFS_UPDATED); Intent intent = new Intent(this, SettingsActivity.class); settingsLauncher.launch(intent); return true; } else if (id == R.id.menu_about) { showAbout(); Loading Loading @@ -175,45 +174,13 @@ public class MainActivity extends AppCompatActivity showToast(getString(R.string.no_track_warning)); } /** * Callback on activity result. * Called after user updated preferences * * @param requestCode Activity code * @param resultCode Result * @param data Data */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RESULT_PREFS_UPDATED) { // Preferences updated updatePreferences(); if (LoggerService.isRunning()) { // restart logging Intent intent = new Intent(MainActivity.this, LoggerService.class); intent.putExtra(UPDATED_PREFS, true); startService(intent); } } else if (requestCode == RESULT_GPX_EXPORT && resultCode == Activity.RESULT_OK) { if (data != null) { runGpxExportTask(data.getData()); } } } /** * Start export service */ private void startExport() { if (db.countPositions() > 0) { Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType(GPX_MIME); intent.putExtra(Intent.EXTRA_TITLE, DbAccess.getTrackName(this) + GPX_EXTENSION); try { startActivityForResult(intent, RESULT_GPX_EXPORT); getExportUri.launch(DbAccess.getTrackName(this) + GPX_EXTENSION); } catch (ActivityNotFoundException e) { showToast(getString(R.string.cannot_open_picker), Toast.LENGTH_LONG); } Loading Loading @@ -296,6 +263,31 @@ public class MainActivity extends AppCompatActivity } } /** * Open file picker to get exported file URI, then run export task */ final ActivityResultLauncher<String> getExportUri = registerForActivityResult(new CreateGpxDocument(), uri -> { if (uri != null) { runGpxExportTask(uri); } }); /** * Open settings activity, update preferences on return */ final ActivityResultLauncher<Intent> settingsLauncher = registerForActivityResult(new StartActivityForResult(), result -> { if (result.getResultCode() == Activity.RESULT_OK) { // Preferences updated updatePreferences(); if (LoggerService.isRunning()) { // restart logging Intent intent = new Intent(MainActivity.this, LoggerService.class); intent.putExtra(UPDATED_PREFS, true); startService(intent); } } }); /** * Called whenever the contents of the back stack change. */ Loading Loading @@ -323,7 +315,9 @@ public class MainActivity extends AppCompatActivity @Override public void onGpxExportTaskFailure(@NonNull String error) { String message = getString(R.string.export_failed); if (!error.isEmpty()) { message += "\n" + error; } showToast(message); } Loading app/src/main/java/net/fabiszewski/ulogger/MainFragment.java +27 −21 Original line number Diff line number Diff line Loading @@ -18,11 +18,11 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.SystemClock; import android.util.Log; Loading @@ -36,10 +36,11 @@ import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.core.widget.TextViewCompat; import androidx.fragment.app.Fragment; Loading @@ -47,9 +48,12 @@ import androidx.fragment.app.FragmentTransaction; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TimeZone; @SuppressWarnings("WeakerAccess") Loading @@ -61,8 +65,6 @@ public class MainFragment extends Fragment { private final static int LED_RED = 2; private final static int LED_YELLOW = 3; private final static int PERMISSION_LOCATION = 1; private final static double KM_MILE = 0.621371; private final static double KM_NMILE = 0.5399568; Loading Loading @@ -711,32 +713,36 @@ public class MainFragment extends Fragment { case LoggerService.BROADCAST_LOCATION_PERMISSION_DENIED: showToast(getString(R.string.location_permission_denied)); setLocLed(LED_RED); if (activity != null) { ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_LOCATION); List<String> permissions = new ArrayList<>(); permissions.add(Manifest.permission.ACCESS_FINE_LOCATION); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // On Android 12+ coarse location permission must be also requested permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); } requestLocationPermission.launch(permissions.toArray(new String[0])); break; } } }; /** * Callback on permission request result * Called after user granted/rejected location permission * * @param requestCode Permission code * @param permissions Permissions * @param grantResults Result * Request location permission, on granted start logger service */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == PERMISSION_LOCATION) { if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) { final ActivityResultLauncher<String[]> requestLocationPermission = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), results -> { if (Logger.DEBUG) { Log.d(TAG, "[requestLocationPermission: " + results.entrySet() + "]"); } boolean isGranted = false; for (Map.Entry<String, Boolean> result : results.entrySet()) { if (result.getValue()) { isGranted = true; } } if (isGranted) { if (Logger.DEBUG) { Log.d(TAG, "[LocationPermission: granted]"); } Context context = getContext(); if (context != null) { startLogger(context); } } } } }); } app/src/main/java/net/fabiszewski/ulogger/OpenLocalDocument.java 0 → 100644 +34 −0 Original line number Diff line number Diff line /* * Copyright (c) 2021 Bartek Fabiszewski * http://www.fabiszewski.net * * This file is part of μlogger-android. * Licensed under GPL, either version 3, or any later. * See <http://www.gnu.org/licenses/> */ package net.fabiszewski.ulogger; import static android.content.Intent.EXTRA_LOCAL_ONLY; import static android.content.Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION; import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION; import android.content.Context; import android.content.Intent; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; class OpenLocalDocument extends ActivityResultContracts.OpenDocument { @NonNull @Override public Intent createIntent(@NonNull Context context, @NonNull String[] input) { Intent intent = super.createIntent(context, input); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.putExtra(EXTRA_LOCAL_ONLY, true); int flags = FLAG_GRANT_READ_URI_PERMISSION|FLAG_GRANT_PERSISTABLE_URI_PERMISSION; intent.addFlags(flags); return intent; } } Loading
app/src/main/java/net/fabiszewski/ulogger/CreateGpxDocument.java 0 → 100644 +29 −0 Original line number Diff line number Diff line /* * Copyright (c) 2021 Bartek Fabiszewski * http://www.fabiszewski.net * * This file is part of μlogger-android. * Licensed under GPL, either version 3, or any later. * See <http://www.gnu.org/licenses/> */ package net.fabiszewski.ulogger; import android.content.Context; import android.content.Intent; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; class CreateGpxDocument extends ActivityResultContracts.CreateDocument { public static final String GPX_MIME = "application/gpx+xml"; @NonNull @Override public Intent createIntent(@NonNull Context context, @NonNull String input) { return super.createIntent(context, input) .setType(GPX_MIME) .addCategory(Intent.CATEGORY_OPENABLE); } }
app/src/main/java/net/fabiszewski/ulogger/GpxExportTask.java +0 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,6 @@ public class GpxExportTask implements Runnable { ns_ulogger + " https://raw.githubusercontent.com/bfabiszewski/ulogger-server/master/scripts/gpx_extensions1.xsd"; public static final String GPX_EXTENSION = ".gpx"; public static final String GPX_MIME = "application/gpx+xml"; private DbAccess db; Loading
app/src/main/java/net/fabiszewski/ulogger/MainActivity.java +33 −39 Original line number Diff line number Diff line Loading @@ -9,10 +9,10 @@ package net.fabiszewski.ulogger; import static androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult; import static net.fabiszewski.ulogger.Alert.showAlert; import static net.fabiszewski.ulogger.Alert.showConfirm; import static net.fabiszewski.ulogger.GpxExportTask.GPX_EXTENSION; import static net.fabiszewski.ulogger.GpxExportTask.GPX_MIME; import static java.util.concurrent.Executors.newCachedThreadPool; import android.app.Activity; Loading @@ -29,6 +29,7 @@ import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import androidx.activity.result.ActivityResultLauncher; import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; Loading @@ -52,8 +53,6 @@ public class MainActivity extends AppCompatActivity private final String TAG = MainActivity.class.getSimpleName(); private final static int RESULT_PREFS_UPDATED = 1; private final static int RESULT_GPX_EXPORT = 2; public final static String UPDATED_PREFS = "extra_updated_prefs"; public String preferenceHost; Loading Loading @@ -138,8 +137,8 @@ public class MainActivity extends AppCompatActivity public boolean onOptionsItemSelected(@NonNull MenuItem item) { final int id = item.getItemId(); if (id == R.id.menu_settings) { Intent i = new Intent(this, SettingsActivity.class); startActivityForResult(i, RESULT_PREFS_UPDATED); Intent intent = new Intent(this, SettingsActivity.class); settingsLauncher.launch(intent); return true; } else if (id == R.id.menu_about) { showAbout(); Loading Loading @@ -175,45 +174,13 @@ public class MainActivity extends AppCompatActivity showToast(getString(R.string.no_track_warning)); } /** * Callback on activity result. * Called after user updated preferences * * @param requestCode Activity code * @param resultCode Result * @param data Data */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RESULT_PREFS_UPDATED) { // Preferences updated updatePreferences(); if (LoggerService.isRunning()) { // restart logging Intent intent = new Intent(MainActivity.this, LoggerService.class); intent.putExtra(UPDATED_PREFS, true); startService(intent); } } else if (requestCode == RESULT_GPX_EXPORT && resultCode == Activity.RESULT_OK) { if (data != null) { runGpxExportTask(data.getData()); } } } /** * Start export service */ private void startExport() { if (db.countPositions() > 0) { Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType(GPX_MIME); intent.putExtra(Intent.EXTRA_TITLE, DbAccess.getTrackName(this) + GPX_EXTENSION); try { startActivityForResult(intent, RESULT_GPX_EXPORT); getExportUri.launch(DbAccess.getTrackName(this) + GPX_EXTENSION); } catch (ActivityNotFoundException e) { showToast(getString(R.string.cannot_open_picker), Toast.LENGTH_LONG); } Loading Loading @@ -296,6 +263,31 @@ public class MainActivity extends AppCompatActivity } } /** * Open file picker to get exported file URI, then run export task */ final ActivityResultLauncher<String> getExportUri = registerForActivityResult(new CreateGpxDocument(), uri -> { if (uri != null) { runGpxExportTask(uri); } }); /** * Open settings activity, update preferences on return */ final ActivityResultLauncher<Intent> settingsLauncher = registerForActivityResult(new StartActivityForResult(), result -> { if (result.getResultCode() == Activity.RESULT_OK) { // Preferences updated updatePreferences(); if (LoggerService.isRunning()) { // restart logging Intent intent = new Intent(MainActivity.this, LoggerService.class); intent.putExtra(UPDATED_PREFS, true); startService(intent); } } }); /** * Called whenever the contents of the back stack change. */ Loading Loading @@ -323,7 +315,9 @@ public class MainActivity extends AppCompatActivity @Override public void onGpxExportTaskFailure(@NonNull String error) { String message = getString(R.string.export_failed); if (!error.isEmpty()) { message += "\n" + error; } showToast(message); } Loading
app/src/main/java/net/fabiszewski/ulogger/MainFragment.java +27 −21 Original line number Diff line number Diff line Loading @@ -18,11 +18,11 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.SystemClock; import android.util.Log; Loading @@ -36,10 +36,11 @@ import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.core.widget.TextViewCompat; import androidx.fragment.app.Fragment; Loading @@ -47,9 +48,12 @@ import androidx.fragment.app.FragmentTransaction; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TimeZone; @SuppressWarnings("WeakerAccess") Loading @@ -61,8 +65,6 @@ public class MainFragment extends Fragment { private final static int LED_RED = 2; private final static int LED_YELLOW = 3; private final static int PERMISSION_LOCATION = 1; private final static double KM_MILE = 0.621371; private final static double KM_NMILE = 0.5399568; Loading Loading @@ -711,32 +713,36 @@ public class MainFragment extends Fragment { case LoggerService.BROADCAST_LOCATION_PERMISSION_DENIED: showToast(getString(R.string.location_permission_denied)); setLocLed(LED_RED); if (activity != null) { ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_LOCATION); List<String> permissions = new ArrayList<>(); permissions.add(Manifest.permission.ACCESS_FINE_LOCATION); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // On Android 12+ coarse location permission must be also requested permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); } requestLocationPermission.launch(permissions.toArray(new String[0])); break; } } }; /** * Callback on permission request result * Called after user granted/rejected location permission * * @param requestCode Permission code * @param permissions Permissions * @param grantResults Result * Request location permission, on granted start logger service */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == PERMISSION_LOCATION) { if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) { final ActivityResultLauncher<String[]> requestLocationPermission = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), results -> { if (Logger.DEBUG) { Log.d(TAG, "[requestLocationPermission: " + results.entrySet() + "]"); } boolean isGranted = false; for (Map.Entry<String, Boolean> result : results.entrySet()) { if (result.getValue()) { isGranted = true; } } if (isGranted) { if (Logger.DEBUG) { Log.d(TAG, "[LocationPermission: granted]"); } Context context = getContext(); if (context != null) { startLogger(context); } } } } }); }
app/src/main/java/net/fabiszewski/ulogger/OpenLocalDocument.java 0 → 100644 +34 −0 Original line number Diff line number Diff line /* * Copyright (c) 2021 Bartek Fabiszewski * http://www.fabiszewski.net * * This file is part of μlogger-android. * Licensed under GPL, either version 3, or any later. * See <http://www.gnu.org/licenses/> */ package net.fabiszewski.ulogger; import static android.content.Intent.EXTRA_LOCAL_ONLY; import static android.content.Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION; import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION; import android.content.Context; import android.content.Intent; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; class OpenLocalDocument extends ActivityResultContracts.OpenDocument { @NonNull @Override public Intent createIntent(@NonNull Context context, @NonNull String[] input) { Intent intent = super.createIntent(context, input); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.putExtra(EXTRA_LOCAL_ONLY, true); int flags = FLAG_GRANT_READ_URI_PERMISSION|FLAG_GRANT_PERSISTABLE_URI_PERMISSION; intent.addFlags(flags); return intent; } }