Skip to content

Commit

Permalink
Upgrade to Android 13, Sdk Version 33 (#985)
Browse files Browse the repository at this point in the history
- Add notification permission to manifest, though it is not strickly needed as all notifications are attached to a MediaSession and those are exempt from Android's 13 new requirements on notification permissions
  https://developer.android.com/develop/ui/views/notifications/notification-permission
- Use granular media permissions, switching from READ_EXTERNAL_STORAGE to READ_MEDIA_{IMAGES|VIDEO|AUDIO}
  https://developer.android.com/about/versions/13/behavior-changes-13#granular-media-permissions
  • Loading branch information
SyncedSynapse committed Nov 16, 2023
1 parent 51cc8a8 commit b77fc22
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 31 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ android {
defaultConfig {
applicationId "org.xbmc.kore"
minSdkVersion 24
targetSdkVersion 32
targetSdkVersion 33
versionCode 31
versionName = getVersionName()
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
Expand Down
12 changes: 11 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,19 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!--
Added notification permission so that code in MediaSessionService doesn't show errors.
This is not really necessary, given that notifications are sent via MediaService, and those
are exempt from being explicitly requested but it doesn't hurt
-->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- Dangerous permissions -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@
import org.xbmc.kore.jsonrpc.type.PlayerType;
import org.xbmc.kore.jsonrpc.type.PlaylistType;
import org.xbmc.kore.ui.AbstractListFragment;
import org.xbmc.kore.ui.viewgroups.GridRecyclerView;
import org.xbmc.kore.utils.CharacterDrawable;
import org.xbmc.kore.utils.LogUtils;
import org.xbmc.kore.utils.UIUtils;
import org.xbmc.kore.utils.Utils;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -82,13 +82,10 @@ public class LocalMediaFileListFragment extends AbstractListFragment {
private LocalFileLocation currentDirLocation = null;

// Permission check callback
private final ActivityResultLauncher<String> filesPermissionLauncher =
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
if (isGranted) {
browseDirectory(currentDirLocation);
} else {
showStatusMessage(null, getString(R.string.read_storage_permission_denied));
}
private final ActivityResultLauncher<String[]> filesPermissionLauncher =
registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), permissionsGranted -> {
// Call on refresh, which checks if premissions were granted and shows results
onRefresh();
});

@Override
Expand All @@ -107,7 +104,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
rootPath = (args != null)?
args.getString(ROOT_PATH) :
(savedInstanceState != null) ?
savedInstanceState.getParcelable(ROOT_PATH) :
savedInstanceState.getString(ROOT_PATH) :
Environment.getExternalStorageDirectory().getAbsolutePath();
if (rootPath != null && !rootPath.endsWith("/")) rootPath += "/";
currentDirLocation = (savedInstanceState != null) ?
Expand All @@ -123,7 +120,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
@Override
public void onStart() {
super.onStart();
if (checkReadStoragePermission())
if (checkReadStoragePermission(true))
browseDirectory(currentDirLocation);
}

Expand All @@ -136,7 +133,11 @@ public void onSaveInstanceState(@NonNull Bundle outState) {

@Override
public void onRefresh() {
browseDirectory(currentDirLocation);
if (checkReadStoragePermission(false)){
browseDirectory(currentDirLocation);
} else {
showStatusMessage(null, getString(R.string.read_storage_permission_denied));
}
hideRefreshAnimation();
}

Expand Down Expand Up @@ -167,12 +168,18 @@ public void onConnectionStatusSuccess() {}
@Override
public void onConnectionStatusNoResultsYet() {}

private boolean checkReadStoragePermission() {
boolean hasStoragePermission =
ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
private boolean checkReadStoragePermission(boolean askIfNotGranted) {
String[] permissions = Utils.isTiramisuOrLater() ?
new String[]{Manifest.permission.READ_MEDIA_AUDIO,
Manifest.permission.READ_MEDIA_VIDEO,
Manifest.permission.READ_MEDIA_IMAGES} :
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE};

if (!hasStoragePermission) {
filesPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE);
boolean hasStoragePermission = Arrays.stream(permissions)
.allMatch(p -> ContextCompat.checkSelfPermission(requireContext(), p) == PackageManager.PERMISSION_GRANTED);

if (!hasStoragePermission && askIfNotGranted) {
filesPermissionLauncher.launch(permissions);
}
return hasStoragePermission;
}
Expand Down Expand Up @@ -200,7 +207,7 @@ public boolean navigateToParentDir() {
}

public boolean isRootDirectory(LocalFileLocation dir) {
return dir.fullPath.equals(rootPath);
return (dir.fullPath != null) && (dir.fullPath.equals(rootPath));
}

/**
Expand Down Expand Up @@ -333,10 +340,8 @@ public void onError(int errorCode, String description) {
*/
public static String getParentDirectory(final String path) {
String p = path;
String pathSymbol = "/"; // unix style
if (path.contains("\\")) {
pathSymbol = "\\"; // windows style
}
// windows / unix style
String pathSymbol = (path.contains("\\")) ? "\\" : "/";

// if path ends with /, remove it before removing the directory name
if (path.endsWith(pathSymbol)) {
Expand All @@ -357,10 +362,8 @@ public static String getParentDirectory(final String path) {
*/
public static String getFilenameFromPath(final String path) {
String p = path;
String pathSymbol = "/"; // unix style
if (path.contains("\\")) {
pathSymbol = "\\"; // windows style
}
// windows / unix style
String pathSymbol = (path.contains("\\")) ? "\\" : "/";
// if path ends with /, remove it
if (path.endsWith(pathSymbol)) {
p = path.substring(0, path.length() - 1);
Expand Down
8 changes: 4 additions & 4 deletions app/src/main/java/org/xbmc/kore/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@
import android.os.Build;
import android.text.TextUtils;

import androidx.preference.PreferenceManager;

import org.xbmc.kore.Settings;

import java.util.List;
import java.util.Locale;

Expand All @@ -52,6 +48,10 @@ public static boolean isSOrLater() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
}

public static boolean isTiramisuOrLater() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU;
}

/**
* Concats a list of strings
* @param list List to concatenate
Expand Down

0 comments on commit b77fc22

Please sign in to comment.