diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 78d920f..1510e0a 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -12,13 +12,14 @@ jobs: uses: actions/setup-java@v4 with: distribution: temurin - java-version: 8 + java-version: 11 cache: gradle - name: Setup Android SDK uses: android-actions/setup-android@v3 with: cmdline-tools-version: 8512546 + # packages: 'tools platform-tools' # this is the default - name: Build with Gradle run: ./gradlew --no-daemon build diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 82c87e5..0000000 --- a/.travis.yml +++ /dev/null @@ -1,32 +0,0 @@ -language: android - -before_install: - - chmod +x gradlew - -# override the default "./gradlew build connectedCheck" as it requires passphrase for keystore -script: - - ./gradlew assembleDebug - -android: - components: - # Uncomment the lines below if you want to - # use the latest revision of Android SDK Tools - - platform-tools - - tools - - # The BuildTools version used by your project - - build-tools-21.1.2 - - # The SDK version used to compile your project - - android-21 - - # Additional components - - extra-google-google_play_services - - extra-google-m2repository - - extra-android-m2repository - - addon-google_apis-google-19 - - # Specify at least one system image, - # if you need to run emulator(s) during your tests - #- sys-img-armeabi-v7a-android-19 - #- sys-img-x86-android-17 diff --git a/app/build.gradle b/app/build.gradle index 29ec593..9b370b7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,28 @@ apply plugin: 'com.android.application' +java { + toolchain { + languageVersion = JavaLanguageVersion.of(11) + } +} + android { - compileSdkVersion 21 - buildToolsVersion "21.1.2" + compileSdk 33 + //buildTools '33.0.2' + namespace 'me.samael.android.calllocation' defaultConfig { applicationId "me.samael.android.calllocation" - minSdkVersion 15 - targetSdkVersion 21 + minSdk 32 + targetSdkVersion 33 versionCode 1 versionName "1.0" } + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } lintOptions { abortOnError false htmlReport true @@ -37,48 +48,50 @@ android { } dependencies { - // compile fileTree(dir: 'libs', include: '*.jar') - //compile 'com.android.support:support-v4:18.+' - //compile 'com.android.support:appcompat-v7:18.+' + // implementation fileTree(dir: 'libs', include: '*.jar') + //implementation 'com.android.support:support-v4:18.+' + //implementation 'com.android.support:appcompat-v7:18.+' + implementation 'androidx.core:core:1.12.0' - compile 'com.google.android.gms:play-services-maps:8.4.0' + implementation 'com.google.android.gms:play-services-location:21.0.1' + implementation 'com.google.android.gms:play-services-maps:18.1.0' } -import groovy.swing.SwingBuilder - -gradle.taskGraph.whenReady { taskGraph -> - if (taskGraph.hasTask(':app:assembleRelease')) { - def storePass = '' - def keyPass = '' - if (System.console() == null) { - new SwingBuilder().edt { - dialog(modal: true, title: 'Enter password', alwaysOnTop: true, resizable: false, locationRelativeTo: null, pack: true, show: true) { - vbox { // Put everything below each other - label(text: "Please enter store passphrase:") - def input1 = passwordField() - label(text: "Please enter key passphrase:") - def input2 = passwordField() - button(defaultButton: true, text: 'OK', actionPerformed: { - storePass = input1.password; - keyPass = input2.password; - dispose(); - }) - } - } - } - } else { - storePass = System.console().readPassword("\nPlease enter store passphrase: ") - keyPass = System.console().readPassword("\nPlease enter key passphrase: ") - } +//import groovy.swing.SwingBuilder - if (storePass.size() <= 0 || keyPass.size() <= 0) { - throw new InvalidUserDataException("You must enter the passwords to proceed.") - } - - storePass = new String(storePass) - keyPass = new String(keyPass) - - android.signingConfigs.release.storePassword = storePass - android.signingConfigs.release.keyPassword = keyPass - } -} +//gradle.taskGraph.whenReady { taskGraph -> +// if (taskGraph.hasTask(':app:assembleRelease')) { +// def storePass = '' +// def keyPass = '' +// if (System.console() == null) { +// new SwingBuilder().edt { +// dialog(modal: true, title: 'Enter password', alwaysOnTop: true, resizable: false, locationRelativeTo: null, pack: true, show: true) { +// vbox { // Put everything below each other +// label(text: "Please enter store passphrase:") +// def input1 = passwordField() +// label(text: "Please enter key passphrase:") +// def input2 = passwordField() +// button(defaultButton: true, text: 'OK', actionPerformed: { +// storePass = input1.password; +// keyPass = input2.password; +// dispose(); +// }) +// } +// } +// } +// } else { +// storePass = System.console().readPassword("\nPlease enter store passphrase: ") +// keyPass = System.console().readPassword("\nPlease enter key passphrase: ") +// } +// +// if (storePass.size() <= 0 || keyPass.size() <= 0) { +// throw new InvalidUserDataException("You must enter the passwords to proceed.") +// } +// +// storePass = new String(storePass) +// keyPass = new String(keyPass) +// +// android.signingConfigs.release.storePassword = storePass +// android.signingConfigs.release.keyPassword = keyPass +// } +//} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f02afed..96fc43e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,17 +10,22 @@ android:glEsVersion="0x00020000" android:required="true" /> + + + - + + android:screenOrientation="portrait" + android:exported="true"> @@ -65,7 +71,8 @@ + android:screenOrientation="portrait" + android:exported="false"> diff --git a/app/src/main/java/me/samael/android/calllocation/CallLocationService.java b/app/src/main/java/me/samael/android/calllocation/CallLocationService.java index 1d56674..f3eeb1c 100644 --- a/app/src/main/java/me/samael/android/calllocation/CallLocationService.java +++ b/app/src/main/java/me/samael/android/calllocation/CallLocationService.java @@ -12,6 +12,7 @@ import android.app.Service; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.location.Criteria; import android.location.Location; import android.location.LocationListener; @@ -24,10 +25,13 @@ import android.util.Log; import android.widget.Toast; +import androidx.core.app.ActivityCompat; + public class CallLocationService extends Service { private static final String TAG = CallLocationService.class.getSimpleName(); - + private static final String CHANNEL_ID = "3984275"; + private static final int LOCATION_REQUEST_CODE = 45367452; private static final boolean DEBUG_MODE = true; private static LocationManager locationManager = null; @@ -79,7 +83,9 @@ CallLocationService getService() { @Override public IBinder onBind(Intent intent) { - if(DEBUG_MODE) Log.d(TAG, "[SERVICE] onBind"); + if(DEBUG_MODE) { + Log.d(TAG, "[SERVICE] onBind"); + } return serviceBinder; } @@ -116,7 +122,20 @@ public void onCreate() { if(DEBUG_MODE) Log.d(TAG, "Inner Location Listener instantiated"); settings = SharedPrefs.getCallLocationPrefs(this); - + + if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, settings.getGpsTimeInterval(), settings.getGpsDistance(), locationListener); + + //ActivityCompat.requestPermissions(this, new String[] { android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}, 111); + // TODO: Consider calling + // ActivityCompat#requestPermissions + // here to request the missing permissions, and then overriding + // public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) + // to handle the case where the user grants the permission. See the documentation + // for ActivityCompat#requestPermissions for more details. + return; + } locationManager.requestLocationUpdates(provider, settings.getGpsTimeInterval(), settings.getGpsDistance(), locationListener); // exceptions will be thrown if provider is not permitted. @@ -247,7 +266,7 @@ public void onCallStateChanged(int state, String incomingNumber) { break; case TelephonyManager.CALL_STATE_RINGING: //phone is ringing - Log.d("CallLocationService PhoneStateListener", "Phone Call from: " + incomingNumber); + Log.d("PhoneStateListener", "Phone Call from: " + incomingNumber); addCallToDatabase(incomingNumber, getCurrentLocation()); break; default: @@ -262,7 +281,10 @@ private Location getCurrentLocation() { criteria.setAccuracy(Criteria.ACCURACY_FINE); String provider = locationManager.getBestProvider(criteria, true); Log.d(TAG, "Best Provider: " + provider); - + + if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED){ + return new Location(provider); // todo: fix this + } Location location = locationManager.getLastKnownLocation(provider); return (location != null) ? location : new Location(provider); } @@ -279,16 +301,21 @@ public void onLocationUpdated(Location location) { * Shows a notification in the status bar while service is running. */ private void showNotification() { - CharSequence appName = getText(R.string.app_name); - CharSequence notificationSubText = getText(R.string.service_subtext); - - Notification notification = new Notification(R.drawable.icon_launcher, appName, System.currentTimeMillis()); + final Notification notification = new Notification.Builder(getApplicationContext(), CHANNEL_ID) + .setSmallIcon(R.drawable.icon_launcher) + .setTicker(getText(R.string.app_name)) + .setSubText(getText(R.string.service_subtext)) + .setWhen(System.currentTimeMillis()) + .build(); + notification.flags = Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT; //Context context = getApplicationContext(); - Intent mainActivityIntent = new Intent(this, MainActivity.class); - PendingIntent contentIntent = PendingIntent.getActivity(this, 0, mainActivityIntent, 0); - notification.setLatestEventInfo(this, appName, notificationSubText, contentIntent); +// Intent mainActivityIntent = new Intent(this, MainActivity.class); +// PendingIntent contentIntent = PendingIntent.getActivity(this, 0, mainActivityIntent, 0); + + // todo: fix this: + //notification.setLatestEventInfo(this, appName, notificationSubText, contentIntent); notificationManager.notify(R.string.app_name, notification); } diff --git a/app/src/main/java/me/samael/android/calllocation/MainActivity.java b/app/src/main/java/me/samael/android/calllocation/MainActivity.java index a4aad29..e9d1a9b 100644 --- a/app/src/main/java/me/samael/android/calllocation/MainActivity.java +++ b/app/src/main/java/me/samael/android/calllocation/MainActivity.java @@ -3,6 +3,12 @@ import me.samael.android.calllocation.CallLocationService.LocalBinder; import me.samael.android.calllocation.data.SharedPrefs; import android.app.Activity; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.pm.PackageManager; +import android.os.Build; +import androidx.annotation.NonNull; +import androidx.core.app.ActivityCompat; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; @@ -23,9 +29,15 @@ import android.os.IBinder; import android.widget.TextView; +//import com.google.android.gms.location.FusedLocationProviderClient; +import com.google.android.gms.location.LocationRequest; + public class MainActivity extends Activity implements OnClickListener { private static final String TAG = MainActivity.class.getSimpleName(); + private static final String CHANNEL_ID = "3984275"; + private static final int LOCATION_REQUEST_CODE = 45367452; + Button buttonStart, buttonStop; TextView tempfeedback; Intent callLocationServiceIntent; @@ -101,18 +113,43 @@ public void onDestroy() { super.onDestroy(); } - //@Override + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + if(LOCATION_REQUEST_CODE == requestCode) { + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + Log.d(TAG, "permission granted"); + //_fusedLocationClient.getLastLocation().addOnSuccessListener() + } + } + } + + @Override public void onClick(View view) { switch (view.getId()) { case R.id.buttonStart: if (!serviceBound) { Log.d(TAG, "onClick: starting service"); tempfeedback.setText("starting service"); + + if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + + ActivityCompat.requestPermissions(this, new String[] { + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.ACCESS_COARSE_LOCATION + }, LOCATION_REQUEST_CODE); + } + + final LocationRequest locationRequest = new LocationRequest(); + locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); + locationRequest.setInterval(20 * 1000); + startService(callLocationServiceIntent); bindService(callLocationServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE); // todo - problem here if exit app with service running } else { - Location loc = callLocationService.getLocation(); - tempfeedback.setText(loc.getLatitude() + " " + loc.getLongitude()); + final Location loc = callLocationService.getLocation(); + tempfeedback.setText(loc != null ? loc.getLatitude() + " " + loc.getLongitude() : "Unknown"); } buttonStart.setClickable(false); buttonStop.setClickable(true); @@ -177,6 +214,30 @@ public void onServiceDisconnected(ComponentName arg0) { } }; + private void createNotificationChannel() { + // Create the NotificationChannel, but only on API 26+ because + // the NotificationChannel class is new and not in the support library + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + + final NotificationChannel channel = new NotificationChannel( + CHANNEL_ID, + getString(R.string.channel_name), + NotificationManager.IMPORTANCE_DEFAULT + ); + + channel.setDescription(getString(R.string.channel_description)); + + // Register the channel with the system; you can't change the importance + // or other notification behaviors after this + final NotificationManager notificationManager = getSystemService(NotificationManager.class); + if(notificationManager != null) { + notificationManager.createNotificationChannel(channel); + } else { + Log.w(TAG, "unable to create notification channel"); + } + } + } + // The BroadcastReceiver that listens for updates from the // CallLocationService private final BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() { diff --git a/app/src/main/java/me/samael/android/calllocation/NewsFeedActivity.java b/app/src/main/java/me/samael/android/calllocation/NewsFeedActivity.java index af532d2..3a79e4d 100644 --- a/app/src/main/java/me/samael/android/calllocation/NewsFeedActivity.java +++ b/app/src/main/java/me/samael/android/calllocation/NewsFeedActivity.java @@ -13,6 +13,7 @@ import android.app.Activity; import android.app.ListActivity; import android.app.ProgressDialog; +import android.content.DialogInterface; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; @@ -27,6 +28,8 @@ public class NewsFeedActivity extends ListActivity { private static final String TAG = NewsFeedActivity.class.getName(); private ProgressDialog progressBar; + private DownLoadNewsFeed _downLoadNewsFeedTask; + private RssFeed rssFeed = null; private ArrayList rssItems; @@ -35,12 +38,16 @@ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.callhistory); - new DownLoadNewsFeed().execute("http://feeds.bbci.co.uk/news/technology/rss.xml"); // todo replace URL with the projects RSS feed + _downLoadNewsFeedTask = new DownLoadNewsFeed(); + _downLoadNewsFeedTask.execute("https://feeds.bbci.co.uk/news/technology/rss.xml"); // todo replace URL with the projects RSS feed } @Override public void onDestroy() { Log.d(TAG, "onDestroy"); + if(AsyncTask.Status.RUNNING.equals(_downLoadNewsFeedTask.getStatus())) { + _downLoadNewsFeedTask.cancel(true); + } super.onDestroy(); } @@ -128,7 +135,13 @@ protected void onPostExecute(RssFeed _feed) { private void showProgressBar() { progressBar = new ProgressDialog(NewsFeedActivity.this); progressBar.setMessage(getText(R.string.newsfeedactivity_wait)); - progressBar.setCancelable(false); + progressBar.setCancelable(true); + progressBar.setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + _downLoadNewsFeedTask.cancel(true); + } + }); progressBar.show(); } diff --git a/app/src/main/java/me/samael/android/calllocation/RecentLocation.java b/app/src/main/java/me/samael/android/calllocation/RecentLocation.java index 9d47071..62536a8 100644 --- a/app/src/main/java/me/samael/android/calllocation/RecentLocation.java +++ b/app/src/main/java/me/samael/android/calllocation/RecentLocation.java @@ -2,11 +2,15 @@ import java.util.Timer; import java.util.TimerTask; -import android.content.Context; -import android.location.Location; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; +import androidx.core.app.ActivityCompat; /** * @@ -21,25 +25,37 @@ public class RecentLocation { boolean gps_enabled=false; boolean network_enabled=false; - public boolean getLocation(Context context, LocationResult result) - { + public boolean getLocation(Context ctx, LocationResult result) { //I use LocationResult callback class to pass location value from MyLocation to user code. locationResult=result; if(lm==null) - lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + lm = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE); - //exceptions will be thrown if provider is not permitted. - try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){} - try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){} +// //exceptions will be thrown if provider is not permitted. +// try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){} +// try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){} +// +// //don't start listeners if no provider is enabled +// if(!gps_enabled && !network_enabled) +// return false; +// +// if(gps_enabled) +// lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps); +// if(network_enabled) +// lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork); - //don't start listeners if no provider is enabled - if(!gps_enabled && !network_enabled) - return false; + if(ActivityCompat.checkSelfPermission(ctx, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { + if(lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) { + lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps); + } + } else if(ActivityCompat.checkSelfPermission(ctx, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { + if(lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { + lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork); + } + } else { + return false; + } - if(gps_enabled) - lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps); - if(network_enabled) - lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork); timer1=new Timer(); timer1.schedule(new GetLastLocation(), 20000); return true; @@ -75,34 +91,49 @@ public void run() { lm.removeUpdates(locationListenerGps); lm.removeUpdates(locationListenerNetwork); - Location net_loc=null, gps_loc=null; - if(gps_enabled) - gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); - if(network_enabled) - net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); - - //if there are both values use the latest one - if(gps_loc!=null && net_loc!=null){ - if(gps_loc.getTime()>net_loc.getTime()) - locationResult.onLocationUpdated(gps_loc); - else - locationResult.onLocationUpdated(net_loc); - return; - } - - if(gps_loc!=null){ - locationResult.onLocationUpdated(gps_loc); - return; - } - if(net_loc!=null){ - locationResult.onLocationUpdated(net_loc); - return; - } - locationResult.onLocationUpdated(null); +// Location net_loc=null, gps_loc=null; +// +// if(gps_enabled) +// gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); +// if(network_enabled) +// net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); +// +// //if there are both values use the latest one +// if(gps_loc!=null && net_loc!=null){ +// if(gps_loc.getTime()>net_loc.getTime()) +// locationResult.onLocationUpdated(gps_loc); +// else +// locationResult.onLocationUpdated(net_loc); +// return; +// } +// +// if(gps_loc!=null){ +// locationResult.onLocationUpdated(gps_loc); +// return; +// } +// if(net_loc!=null){ +// locationResult.onLocationUpdated(net_loc); +// return; +// } +// locationResult.onLocationUpdated(null); + + Location loc = null; + + try { + if(lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) { + loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); + } else if(lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { + loc = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); + } + } catch (final SecurityException e) { + return; + } + + locationResult.onLocationUpdated(loc); } } - public static abstract class LocationResult{ + public static abstract class LocationResult { public abstract void onLocationUpdated(Location location); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bd9a454..6264b16 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -41,4 +41,7 @@ Delete Entry Are you sure? + Channel Name + Channel Description + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 5d09b73..12fa501 100644 --- a/build.gradle +++ b/build.gradle @@ -2,9 +2,17 @@ buildscript { repositories { + google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:1.5.0' + classpath 'com.android.tools.build:gradle:8.2.2' } } + +allprojects { + repositories { + google() + mavenCentral() + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..5465fec --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +android.enableJetifier=true +android.useAndroidX=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4ca2b88..03c3551 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip diff --git a/gradlew b/gradlew old mode 100755 new mode 100644 diff --git a/gradlew.bat b/gradlew.bat old mode 100755 new mode 100644