Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Milestone 132 - update SDK versions #1168

Draft
wants to merge 19 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
65d2eae
Use compileSdk instead of compileSdkVersion
mendhak Sep 28, 2024
f750ff7
The Post notification permission may not be needed as part of initial…
mendhak Sep 28, 2024
7c3292f
Set exported true on various activities and receivers
mendhak Sep 28, 2024
f1237fa
Pending intents with mutable or immutable
mendhak Sep 28, 2024
b9a3568
Upgrade logger version, I still don't understand slf4j and logback
mendhak Sep 29, 2024
976ca60
Use GnssStatus for target SDK version 31 because GpsStatus is deprecated
mendhak Sep 29, 2024
af2662f
Bump the minSdkVersion for jetpack compose april 2024 requirements
mendhak Sep 29, 2024
1dd785c
Update to latest version of androidx and junit packages
mendhak Sep 29, 2024
c809f0c
Adding text file to media database should not be needed, unnecessary …
mendhak Sep 29, 2024
59a9f9a
Rejection handler should indicate which task it's rejecting. Increase…
mendhak Sep 29, 2024
a507d60
Include notification permission. Refactor permission list to be in si…
mendhak Sep 29, 2024
221c7e1
Adjust alarm manager to use inexact alarm if background running/unopt…
mendhak Sep 30, 2024
df2ed4a
Update to target sdk 33
mendhak Sep 30, 2024
a57b5d4
Updating target sdk to 34, with exported activities and exported flag…
mendhak Oct 1, 2024
8972b9a
Target SDK 35
mendhak Oct 1, 2024
1747b53
132-test1
mendhak Oct 2, 2024
50ab4d3
go back to target 34, because 35 requires major UI changes probably
mendhak Oct 4, 2024
74b9497
Note about battery optimization or background work
mendhak Oct 5, 2024
c417c4a
Target SDK 35 and push the preference activity down to allow insets a…
mendhak Oct 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions assets/text/faq/faq03-no-point-logged.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ Sometimes your specified time interval will have passed, but no point was logged

* On Android 6+ (Marshmallow), a new feature called *[doze mode](http://lifehacker.com/how-android-doze-works-and-how-to-tweak-it-to-save-you-1785921957)* was introduced, which severely restricts activity on the device after certain periods of inactivity. Be sure to grant the app permission to run in the background by disabling battery optimization. If you aren't sure, or if you've denied this permission you can [disable battery optimization for GPSLogger manually](https://android.stackexchange.com/a/129075/14996) which does not bypass doze mode but occasionally provides logging windows in which to work. It will not make a great difference though, doze mode is quite aggressive.

* Background permission or battery un-optimization wasn't granted to the app, and this can prevent the periodic alarm scheduling the app needs to get a new point.

* This can also happen if the app isn't used for a long time, the OS starts to remove permissions from the app.

* Many vendors are also known to introduce their own _additional_ poorly written but aggressive battery optimization mechanisms. App developers don't have a way of detecting or working around these, and unfortunately the apps receive all the blame. You can see some partial workarounds on the [Don't Kill My App site](https://dontkillmyapp.com/?app=GPSLogger)

* The GPS system will have attempted to find its location and given up after a while. This in turn means that Android OS will not have given a location to GPSLogger
Expand Down
34 changes: 15 additions & 19 deletions gpslogger/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ repositories {
}

android {
compileSdkVersion 34
compileSdk 35

defaultConfig {
applicationId "com.mendhak.gpslogger"
minSdkVersion 16
//noinspection ExpiredTargetSdkVersion
targetSdkVersion 30
minSdkVersion 21

targetSdkVersion 35
compileSdk 34
versionCode 131
versionName "131-rc2"
versionCode 132
versionName "132-test1"

// Used by AppAuth-Android
manifestPlaceholders = [
Expand Down Expand Up @@ -121,8 +121,8 @@ android {
dependencies {

// implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation "androidx.activity:activity:1.8.2"
implementation "androidx.fragment:fragment:1.6.2"
implementation "androidx.activity:activity:1.9.2"
implementation "androidx.fragment:fragment:1.8.3"
implementation "androidx.preference:preference:1.2.1"
implementation "androidx.constraintlayout:constraintlayout:2.1.4"

Expand All @@ -136,16 +136,12 @@ dependencies {


//Debug Logging
implementation('org.slf4j:slf4j-api:1.7.30')
implementation('com.github.tony19:logback-android-classic:1.1.1-2'){
exclude group: 'com.google.android', module: 'android'
}

implementation('com.github.tony19:logback-android-core:1.1.1-2')
implementation 'org.slf4j:slf4j-api:2.0.7'
implementation 'com.github.tony19:logback-android:3.0.0'


//Android lollipop/material features including the Toolbar
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.appcompat:appcompat:1.7.0'


//Cardviews
Expand All @@ -164,7 +160,7 @@ dependencies {
implementation 'com.github.dmytrodanylyk.android-process-button:library:1.0.4'

//Android's WorkManager
implementation 'androidx.work:work-runtime:2.9.0'
implementation 'androidx.work:work-runtime:2.9.1'
// We need to use Gson to help with WorkManager limitations
implementation 'com.google.code.gson:gson:2.10.1'

Expand Down Expand Up @@ -212,11 +208,11 @@ dependencies {
implementation('org.apache.commons:commons-csv:1.9.0')

//Libraries required for unit testing
testImplementation 'junit:junit:4.12'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:3.10.0'
testImplementation 'org.json:json:20180813'
testImplementation 'androidx.test:runner:1.5.2'
testImplementation 'androidx.test:rules:1.5.0'
testImplementation 'androidx.test:runner:1.6.2'
testImplementation 'androidx.test:rules:1.6.1'
}


Expand Down
27 changes: 21 additions & 6 deletions gpslogger/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@
android:resource="@xml/shortcuts" />
</activity>

<activity android:name="net.openid.appauth.RedirectUriReceiverActivity">
<activity android:name="net.openid.appauth.RedirectUriReceiverActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
Expand All @@ -94,7 +95,9 @@
<activity
android:name=".MainPreferenceActivity"
android:label="@string/settings_screen_name"
android:parentActivityName=".GpsMainActivity" >
android:parentActivityName=".GpsMainActivity"
android:exported="true"
>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.mendhak.gpslogger.GpsMainActivity" />
Expand All @@ -105,7 +108,9 @@
android:name=".Faqtivity"
android:label="@string/faq_screen_title"
android:launchMode="singleTask"
android:parentActivityName=".GpsMainActivity" >
android:parentActivityName=".GpsMainActivity"
android:exported="true"
>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.mendhak.gpslogger.GpsMainActivity" />
Expand All @@ -114,6 +119,7 @@
<activity
android:name="com.dropbox.core.android.AuthActivity"
android:configChanges="orientation|keyboard"
android:exported="true"
android:launchMode="singleTask"
android:parentActivityName=".GpsMainActivity" >
<meta-data
Expand All @@ -134,6 +140,7 @@

<activity
android:name=".shortcuts.ShortcutCreate"
android:exported="true"
android:theme="@style/Theme.AppCompat.Translucent" >
<intent-filter>
<action android:name="android.intent.action.CREATE_SHORTCUT" />
Expand All @@ -143,13 +150,15 @@
</activity>
<activity
android:name=".shortcuts.ShortcutStart"
android:exported="true"
android:theme="@style/Theme.AppCompat.Translucent" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
</intent-filter>
</activity>
<activity
android:name=".shortcuts.ShortcutStop"
android:exported="true"
android:theme="@style/Theme.AppCompat.Translucent" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
Expand All @@ -159,6 +168,7 @@
<receiver
android:name=".StartupReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
Expand All @@ -168,13 +178,15 @@
</receiver>
<receiver android:name=".senders.AlarmReceiver" />

<receiver android:name=".MyPackageUpgradeReceiver">
<receiver android:name=".MyPackageUpgradeReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>

<receiver android:name=".TaskerReceiver">
<receiver android:name=".TaskerReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.mendhak.gpslogger.TASKER_COMMAND" />
</intent-filter>
Expand All @@ -185,6 +197,7 @@
<!--android:theme="@style/Theme.AppCompat.Translucent"-->
<activity
android:name=".NotificationAnnotationActivity"
android:exported="true"
android:label=""
android:theme="@style/Theme.AppCompat.Translucent"
android:excludeFromRecents="true"
Expand All @@ -209,7 +222,9 @@
</provider>


<activity android:name=".ProfileLinkReceiverActivity" android:theme="@style/Theme.AppCompat.Translucent" >
<activity android:name=".ProfileLinkReceiverActivity"
android:exported="true"
android:theme="@style/Theme.AppCompat.Translucent" >
<intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.graphics.BitmapFactory;
import android.location.GnssStatus;
import android.location.Location;
import android.location.LocationManager;
import android.os.*;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.AlarmManagerCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.app.TaskStackBuilder;
import android.text.Html;
Expand Down Expand Up @@ -70,6 +74,7 @@ public class GpsLoggingService extends Service {
private LocationManager passiveLocationManager;
private LocationManager towerLocationManager;
private GeneralLocationListener gpsLocationListener;
private GnssStatus.Callback gnssStatusCallback;
private GeneralLocationListener towerLocationListener;
private GeneralLocationListener passiveLocationListener;
private NmeaLocationListener nmeaLocationListener;
Expand Down Expand Up @@ -166,7 +171,7 @@ public void onLowMemory() {
LOG.error("Android is low on memory!");
Intent i = new Intent(this, GpsLoggingService.class);
i.putExtra(IntentConstants.GET_NEXT_POINT, true);
PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
PendingIntent pi = PendingIntent.getService(this, 0, i, PendingIntent.FLAG_IMMUTABLE);
nextPointAlarmManager.cancel(pi);
nextPointAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 300000, pi);
super.onLowMemory();
Expand Down Expand Up @@ -319,7 +324,11 @@ public void setupAutoSendTimers() {
alarmIntent = new Intent(this, AlarmReceiver.class);
cancelAlarm();

PendingIntent sender = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
int flags = PendingIntent.FLAG_UPDATE_CURRENT;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
flags |= PendingIntent.FLAG_MUTABLE;
}
PendingIntent sender = PendingIntent.getBroadcast(this, 0, alarmIntent, flags);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
am.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerTime, sender);
Expand Down Expand Up @@ -351,7 +360,8 @@ public void logOnce() {
private void cancelAlarm() {
if (alarmIntent != null) {
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent sender = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent sender = PendingIntent.getBroadcast(this, 0, alarmIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
am.cancel(sender);
}
}
Expand Down Expand Up @@ -497,19 +507,23 @@ private Notification getNotification() {
Intent stopLoggingIntent = new Intent(this, GpsLoggingService.class);
stopLoggingIntent.setAction("NotificationButton_STOP");
stopLoggingIntent.putExtra(IntentConstants.IMMEDIATE_STOP, true);
PendingIntent piStop = PendingIntent.getService(this, 0, stopLoggingIntent, 0);
PendingIntent piStop = PendingIntent.getService(this, 0, stopLoggingIntent, PendingIntent.FLAG_IMMUTABLE);

Intent annotateIntent = new Intent(this, NotificationAnnotationActivity.class);
annotateIntent.setAction("com.mendhak.gpslogger.NOTIFICATION_BUTTON");
PendingIntent piAnnotate = PendingIntent.getActivity(this,0, annotateIntent,0);
PendingIntent piAnnotate = PendingIntent.getActivity(this,0, annotateIntent, PendingIntent.FLAG_IMMUTABLE);

// What happens when the notification item is clicked
Intent contentIntent = new Intent(this, GpsMainActivity.class);

TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntent(contentIntent);

PendingIntent pending = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
int flags = PendingIntent.FLAG_UPDATE_CURRENT;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
flags |= PendingIntent.FLAG_IMMUTABLE;
}
PendingIntent pending = stackBuilder.getPendingIntent(0, flags);

CharSequence contentTitle = getString(R.string.gpslogger_still_running);
CharSequence contentText = getString(R.string.app_name);
Expand Down Expand Up @@ -581,6 +595,7 @@ private void startPassiveManager() {
}
}


/**
* Starts the location manager. There are two location managers - GPS and
* Cell Tower. This code determines which manager to request updates from
Expand All @@ -607,6 +622,32 @@ private void startGpsManager() {
towerLocationListener = new GeneralLocationListener(this, "CELL");
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
gnssStatusCallback = new GnssStatus.Callback() {
@Override
public void onStarted() {
super.onStarted();
}

@Override
public void onStopped() {
super.onStopped();
}

@Override
public void onFirstFix(int ttffMillis) {
super.onFirstFix(ttffMillis);
LOG.info("Time to first fix: {}ms", ttffMillis);
}

@Override
public void onSatelliteStatusChanged(@NonNull GnssStatus status) {
super.onSatelliteStatusChanged(status);
setSatelliteInfo(status.getSatelliteCount());
gpsLocationListener.satellitesUsedInFix = status.getSatelliteCount();
}
};
}


gpsLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Expand All @@ -618,7 +659,13 @@ private void startGpsManager() {
LOG.info("Requesting GPS location updates");
// gps satellite based
gpsLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, gpsLocationListener);
gpsLocationManager.addGpsStatusListener(gpsLocationListener);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
gpsLocationManager.registerGnssStatusCallback(gnssStatusCallback);
}
else {
gpsLocationManager.addGpsStatusListener(gpsLocationListener);
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (nmeaLocationListener == null){
Expand Down Expand Up @@ -715,6 +762,12 @@ private void stopGpsManager() {
if (gpsLocationListener != null) {
LOG.debug("Removing gpsLocationManager updates");
gpsLocationManager.removeUpdates(gpsLocationListener);
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && gnssStatusCallback != null) {
gpsLocationManager.unregisterGnssStatusCallback(gnssStatusCallback);
}
else {
gpsLocationManager.removeGpsStatusListener(gpsLocationListener);
}

Expand Down Expand Up @@ -1035,26 +1088,26 @@ protected void stopManagerAndResetAlarm() {
private void stopAlarm() {
Intent i = new Intent(this, GpsLoggingService.class);
i.putExtra(IntentConstants.GET_NEXT_POINT, true);
PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
PendingIntent pi = PendingIntent.getService(this, 0, i, PendingIntent.FLAG_MUTABLE);
nextPointAlarmManager.cancel(pi);
}

private void setAlarmForNextPoint() {
LOG.debug("Set alarm for " + preferenceHelper.getMinimumLoggingInterval() + " seconds");

Intent i = new Intent(this, GpsLoggingService.class);
i.putExtra(IntentConstants.GET_NEXT_POINT, true);
PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
PendingIntent pi = PendingIntent.getService(this, 0, i, PendingIntent.FLAG_MUTABLE);
nextPointAlarmManager.cancel(pi);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
nextPointAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + preferenceHelper.getMinimumLoggingInterval() * 1000, pi);

if(AlarmManagerCompat.canScheduleExactAlarms(nextPointAlarmManager)){
LOG.debug("Setting exact alarm for {}s", preferenceHelper.getMinimumLoggingInterval());
AlarmManagerCompat.setExactAndAllowWhileIdle(nextPointAlarmManager, AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + preferenceHelper.getMinimumLoggingInterval() * 1000L, pi);
}
else {
nextPointAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + preferenceHelper.getMinimumLoggingInterval() * 1000, pi);
LOG.debug("Setting inexact alarm for {}s (exact alarm disallowed/not available)", preferenceHelper.getMinimumLoggingInterval());
AlarmManagerCompat.setAndAllowWhileIdle(nextPointAlarmManager, AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + preferenceHelper.getMinimumLoggingInterval() * 1000L, pi);
}

}


Expand Down
Loading