drop min sup versions

Signed-off-by: alperozturk <alper_ozturk@proton.me>
This commit is contained in:
alperozturk 2025-06-12 11:06:11 +02:00 committed by Alper Öztürk
parent 50eb848926
commit dba17a8778
13 changed files with 30 additions and 112 deletions

View File

@ -105,7 +105,7 @@ android {
defaultConfig {
applicationId "com.nextcloud.client"
minSdkVersion 25
minSdkVersion 26
targetSdkVersion 35
compileSdk 35

View File

@ -127,9 +127,7 @@ class EditImageActivity :
}
menu?.findItem(R.id.custom_menu_placeholder_item)?.apply {
icon = saveIcon
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
contentDescription = getString(R.string.common_save)
}
contentDescription = getString(R.string.common_save)
}
return true
}

View File

@ -11,7 +11,6 @@ import android.app.Notification
import android.app.NotificationManager
import android.content.Context
import android.graphics.BitmapFactory
import android.os.Build
import android.os.Handler
import android.os.Looper
import androidx.core.app.NotificationCompat
@ -40,10 +39,7 @@ open class WorkerNotificationManager(
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.notification_icon))
setStyle(NotificationCompat.BigTextStyle())
priority = NotificationCompat.PRIORITY_LOW
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_DOWNLOAD)
}
setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_DOWNLOAD)
}
fun showNotification() {

View File

@ -8,7 +8,6 @@ package com.nextcloud.client.media
import android.media.AudioFocusRequest
import android.media.AudioManager
import android.os.Build
/**
* Wrapper around audio manager exposing simplified audio focus API and
@ -39,12 +38,10 @@ internal class AudioFocusManager(
private var focusRequest: AudioFocusRequest? = null
init {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
focusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).run {
setWillPauseWhenDucked(true)
setOnAudioFocusChangeListener(focusListener)
}.build()
}
focusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).run {
setWillPauseWhenDucked(true)
setOnAudioFocusChangeListener(focusListener)
}.build()
}
/**
@ -52,12 +49,8 @@ internal class AudioFocusManager(
* If focus cannot be gained, lost of focus is reported.
*/
fun requestFocus() {
val requestResult = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val requestResult =
focusRequest?.let { audioManger.requestAudioFocus(it) }
} else {
audioManger.requestAudioFocus(focusListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN)
}
if (requestResult == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
focusListener.onAudioFocusChange(AudioManager.AUDIOFOCUS_GAIN)
} else {
@ -69,13 +62,9 @@ internal class AudioFocusManager(
* Release audio focus. Loss of focus is reported via callback.
*/
fun releaseFocus() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
focusRequest?.let {
audioManger.abandonAudioFocusRequest(it)
} ?: AudioManager.AUDIOFOCUS_REQUEST_FAILED
} else {
audioManger.abandonAudioFocus(focusListener)
}
focusRequest?.let {
audioManger.abandonAudioFocusRequest(it)
} ?: AudioManager.AUDIOFOCUS_REQUEST_FAILED
focusListener.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS)
}
}

View File

@ -10,7 +10,6 @@ import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.media.AudioManager
import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.widget.MediaController
@ -184,10 +183,7 @@ class PlayerService : Service() {
setOngoing(true)
setContentTitle(ticker)
setContentText(content)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_MEDIA)
}
setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_MEDIA)
}
ForegroundServiceHelper.startService(

View File

@ -10,9 +10,9 @@ import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Build
import android.os.IBinder
import android.widget.MediaController
import androidx.core.content.ContextCompat
import com.nextcloud.client.account.User
import com.owncloud.android.datamodel.OCFile
@ -133,10 +133,6 @@ class PlayerServiceConnection(private val context: Context) : MediaController.Me
// endregion
private fun startForegroundService(i: Intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(i)
} else {
context.startService(i)
}
ContextCompat.startForegroundService(context, i)
}
}

View File

@ -13,7 +13,6 @@ import android.content.Context
import android.content.Intent
import android.content.res.Resources
import android.graphics.BitmapFactory
import android.os.Build
import androidx.core.app.NotificationCompat
import com.nextcloud.client.account.User
import com.owncloud.android.R
@ -38,11 +37,8 @@ class AppNotificationManagerImpl @Inject constructor(
}
private fun builder(channelId: String): NotificationCompat.Builder {
val builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val builder =
NotificationCompat.Builder(context, channelId)
} else {
NotificationCompat.Builder(context)
}
viewThemeUtils.androidx.themeNotificationCompatBuilder(context, builder)
return builder
}

View File

@ -129,7 +129,7 @@ import static com.owncloud.android.ui.activity.ContactsPreferenceActivity.PREFER
* Contains methods to build the "static" strings. These strings were before constants in different classes.
*/
public class MainApp extends Application implements HasAndroidInjector, NetworkChangeListener {
public static final OwnCloudVersion OUTDATED_SERVER_VERSION = NextcloudVersion.nextcloud_28;
public static final OwnCloudVersion OUTDATED_SERVER_VERSION = NextcloudVersion.nextcloud_29;
public static final OwnCloudVersion MINIMUM_SUPPORTED_SERVER_VERSION = OwnCloudVersion.nextcloud_18;
private static final String TAG = MainApp.class.getSimpleName();
@ -667,7 +667,7 @@ public class MainApp extends Application implements HasAndroidInjector, NetworkC
}
public static void notificationChannels() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O && getAppContext() != null) {
if (getAppContext() != null) {
Context context = getAppContext();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
@ -718,8 +718,7 @@ public class MainApp extends Application implements HasAndroidInjector, NetworkC
private static void createChannel(NotificationManager notificationManager,
String channelId, int channelName,
int channelDescription, Context context, int importance) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O
&& getAppContext() != null) {
if (getAppContext() != null) {
CharSequence name = context.getString(channelName);
String description = context.getString(channelDescription);
NotificationChannel channel = new NotificationChannel(channelId, name, importance);

View File

@ -523,11 +523,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
private void showNotification(int id, NotificationCompat.Builder builder) {
NotificationManager notificationManager = (NotificationManager) getContext().
getSystemService(Context.NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
builder.setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_FILE_SYNC);
}
builder.setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_FILE_SYNC);
notificationManager.notify(id, builder.build());
}
/**

View File

@ -50,11 +50,7 @@ public class LoadContactsTask extends AsyncTask<Void, Void, Boolean> {
if (!isCancelled()) {
File file = new File(ocFile.getStoragePath());
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vCards.addAll(Ezvcard.parse(new BufferedInputStream(Files.newInputStream(file.toPath()))).all());
} else {
vCards.addAll(Ezvcard.parse(new BufferedInputStream(new FileInputStream((file)))).all());
}
vCards.addAll(Ezvcard.parse(new BufferedInputStream(Files.newInputStream(file.toPath()))).all());
Collections.sort(vCards, new VCardComparator());
} catch (IOException e) {
Log_OC.e(this, "IO Exception: " + file.getAbsolutePath());

View File

@ -6,7 +6,6 @@
*/
package com.owncloud.android.utils;
import android.os.Build;
import android.text.TextUtils;
import com.owncloud.android.lib.common.utils.Log_OC;
@ -49,10 +48,6 @@ public final class FileUtil {
public static @Nullable
Long getCreationTimestamp(File file) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
return null;
}
try {
return Files.readAttributes(file.toPath(), BasicFileAttributes.class)
.creationTime()

View File

@ -4,20 +4,18 @@
*/
package third_parties.ezvcard_android;
import android.annotation.SuppressLint;
import android.content.ContentProviderOperation;
import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.RemoteException;
import android.provider.ContactsContract;
import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.utils.DisplayUtils;
import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;
@ -454,8 +452,6 @@ public class ContactOperations {
}
private void convertBirthdays(List<NonEmptyContentValues> contentValues, VCard vcard) {
final var df = new BirthdayDateFormatter();
for (Birthday birthday : vcard.getBirthdays()) {
Temporal date = birthday.getDate();
if (date == null) {
@ -465,55 +461,20 @@ public class ContactOperations {
NonEmptyContentValues cv = new NonEmptyContentValues(ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE);
cv.put(ContactsContract.CommonDataKinds.Event.TYPE, ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY);
cv.put(ContactsContract.CommonDataKinds.Event.START_DATE, df.format(date));
cv.put(ContactsContract.CommonDataKinds.Event.START_DATE, formatBirthday(date));
contentValues.add(cv);
}
}
/**
* A formatter class to handle the formatting of birthday dates across different Android versions.
* This class ensures that:
* - For API levels below 26, SimpleDateFormat is used to format dates.
* - For API levels 26 and above, DateTimeFormatter is used.
* <p>
* It also handles the issue where a `java.lang.IllegalArgumentException: Cannot format given Object as a Date`
* can be thrown when trying to format a `Temporal` object (e.g., `LocalDate`) directly using `SimpleDateFormat`.
* <p>
* In the future (post-Android O), this class can be removed entirely, and only DateTimeFormatter should be used.
*/
private static class BirthdayDateFormatter {
private final Object formatter = getDateFormatter();
@SuppressLint("SimpleDateFormat")
private Object getDateFormatter() {
String pattern = "yyyy-MM-dd";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return DateTimeFormatter.ofPattern(pattern)
.withZone(ZoneId.systemDefault());
} else {
return new SimpleDateFormat(pattern);
}
}
public String format(Temporal date) {
if (date == null) {
return "";
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && formatter instanceof DateTimeFormatter dateTimeFormatter) {
return dateTimeFormatter.format(date);
} else if (formatter instanceof SimpleDateFormat simpleDateFormat) {
try {
return simpleDateFormat.format(date);
} catch (Throwable t) {
Log_OC.d("BirthdayDateFormatter","Exception convertBirthdays: " + t);
return date.toString();
}
}
private String formatBirthday(Temporal date) {
if (date == null) {
return "";
}
final String pattern = "yyyy-MM-dd";
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern).withZone(ZoneId.systemDefault());
return formatter.format(date);
}
private void convertWebsites(List<NonEmptyContentValues> contentValues, VCard vcard) {

View File

@ -21,7 +21,7 @@ android {
namespace "com.nextcloud.appscan"
defaultConfig {
minSdk 25
minSdk 26
targetSdk 35
compileSdk 35