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

Upgrade to SDK 34 #5790

Merged
merged 27 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9db025b
change the overridden method signature as per API 34
rohit9625 Aug 23, 2024
b5b40ac
add version check condition to compare with API 23 before adding flag
rohit9625 Aug 23, 2024
c0a28d0
refactor: add final keywords, fix typo, and remove redundant spaces
rohit9625 Aug 23, 2024
1c9609e
upgrade: migrate to SDK 34 and upgrade APG
rohit9625 Aug 24, 2024
81cc53a
AndroidManifest: add new permission for API 34
rohit9625 Aug 24, 2024
ef18897
refactor: permission should not be check on onCreate for some cases
rohit9625 Aug 24, 2024
bf68861
add method to get correct storage permission and check partial access
rohit9625 Aug 24, 2024
8ec9118
refactor: prevent app from crashing for SDKs >= 34
rohit9625 Aug 24, 2024
9c683aa
add new UI component to allows user to manage partially access photos
rohit9625 Aug 24, 2024
ba573ed
change the overridden method signature as per API 34
rohit9625 Aug 23, 2024
21b2184
add version check condition to compare with API 23 before adding flag
rohit9625 Aug 23, 2024
ee55b59
refactor: add final keywords, fix typo, and remove redundant spaces
rohit9625 Aug 23, 2024
8471928
upgrade: migrate to SDK 34 and upgrade APG
rohit9625 Aug 24, 2024
1995c0a
AndroidManifest: add new permission for API 34
rohit9625 Aug 24, 2024
349b8ef
refactor: permission should not be check on onCreate for some cases
rohit9625 Aug 24, 2024
f8d164b
add method to get correct storage permission and check partial access
rohit9625 Aug 24, 2024
ad1074a
refactor: prevent app from crashing for SDKs >= 34
rohit9625 Aug 24, 2024
bc621a0
add new UI component to allows user to manage partially access photos
rohit9625 Aug 24, 2024
c2c6dc2
Merge branch 'upgrade' of https://github.com/rohit9625/apps-android-c…
rohit9625 Aug 25, 2024
2223e6d
replace deprecated circular progress bar with material progress bar
rohit9625 Aug 25, 2024
75afe05
remove redundant appcompat dependency
rohit9625 Aug 26, 2024
8b58b43
add condition to check for partial access on API >= 34
rohit9625 Aug 28, 2024
d9494ab
Merge branch 'main' into upgrade
rohit9625 Aug 28, 2024
03b5b27
UploadWorker: add foreground service type
rohit9625 Aug 28, 2024
c8e9232
Merge branch 'main' into upgrade
rohit9625 Sep 1, 2024
095f9dd
fix typos in UploadWorker.kt
rohit9625 Sep 1, 2024
543840c
add permission to access media location
rohit9625 Sep 15, 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
29 changes: 25 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,22 @@ dependencies {
implementation 'com.karumi:dexter:5.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

// Jetpack Compose
def composeBom = platform('androidx.compose:compose-bom:2024.08.00')

implementation "androidx.appcompat:appcompat:1.7.0"
implementation "androidx.activity:activity-compose:1.9.1"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.8.4"
implementation (composeBom)
implementation "androidx.compose.runtime:runtime"
implementation "androidx.compose.ui:ui"
implementation "androidx.compose.ui:ui-graphics"
implementation "androidx.compose.ui:ui-tooling"
implementation "androidx.compose.foundation:foundation"
implementation "androidx.compose.foundation:foundation-layout"
implementation "androidx.compose.material3:material3"
androidTestImplementation(composeBom)

implementation "com.hannesdorfmann:adapterdelegates4-kotlin-dsl-viewbinding:$ADAPTER_DELEGATES_VERSION"
implementation "com.hannesdorfmann:adapterdelegates4-pagination:$ADAPTER_DELEGATES_VERSION"
implementation "androidx.paging:paging-runtime-ktx:$PAGING_VERSION"
Expand Down Expand Up @@ -186,7 +202,7 @@ project.gradle.taskGraph.whenReady {
}

android {
compileSdkVersion 33
compileSdkVersion 34

defaultConfig {
//applicationId 'fr.free.nrw.commons'
Expand All @@ -196,7 +212,7 @@ android {
setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName())

minSdkVersion 21
targetSdkVersion 33
targetSdkVersion 34
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: 'true'

Expand Down Expand Up @@ -253,11 +269,12 @@ android {
}
}
debug {
testCoverageEnabled true
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
testProguardFile 'test-proguard-rules.txt'
versionNameSuffix "-debug-" + getBranchName()
enableUnitTestCoverage true
enableAndroidTestCoverage true
}
}

Expand Down Expand Up @@ -354,13 +371,17 @@ android {
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "1.8"
jvmTarget = "11"
}

buildToolsVersion buildToolsVersion

buildFeatures {
viewBinding true
compose true
}
composeOptions {
kotlinCompilerExtensionVersion '1.3.2'
}
namespace 'fr.free.nrw.commons'
lint {
Expand Down
14 changes: 10 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
<uses-permission android:name="android.permission.REORDER_TASKS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"
android:minSdkVersion="33"/>
<uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS" />
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
rohit9625 marked this conversation as resolved.
Show resolved Hide resolved
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED"
android:minSdkVersion="34"/>

<queries>
<!-- Browser -->
Expand Down Expand Up @@ -54,7 +60,7 @@
<activity
android:theme="@style/EditActivityTheme"
android:name=".description.DescriptionEditActivity"
android:exported="true" />
android:exported="false" />

<activity
android:name=".edit.EditActivity"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,17 @@ public void onCreate(Bundle savedInstanceState) {
* so that location in the EXIF metadata of the images shared by the user
* is retained on devices running Android 10 or above
*/
if (VERSION.SDK_INT >= VERSION_CODES.Q) {
PermissionUtils.checkPermissionsAndPerformAction(
this,
() -> {},
R.string.media_location_permission_denied,
R.string.add_location_manually,
permission.ACCESS_MEDIA_LOCATION);
}
// if (VERSION.SDK_INT >= VERSION_CODES.Q) {
rohit9625 marked this conversation as resolved.
Show resolved Hide resolved
// ActivityCompat.requestPermissions(this,
// new String[]{Manifest.permission.ACCESS_MEDIA_LOCATION}, 0);
// PermissionUtils.checkPermissionsAndPerformAction(
// this,
// () -> {},
// R.string.media_location_permission_denied,
// R.string.add_location_manually,
// permission.ACCESS_MEDIA_LOCATION);
// }

checkAndResumeStuckUploads();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ open class OnSwipeTouchListener(context: Context?) : View.OnTouchListener {
* Detects the gestures
*/
override fun onFling(
event1: MotionEvent,
event1: MotionEvent?,
event2: MotionEvent,
velocityX: Float,
velocityY: Float
): Boolean {
try {
val diffY: Float = event2.y - event1.y
val diffX: Float = event2.x - event1.x
val diffY: Float = event2.y - (event1?.y ?: event2.y)
val diffX: Float = event2.x - (event1?.x ?: event2.x)
if (abs(diffX) > abs(diffY)) {
if (abs(diffX) > SWIPE_THRESHOLD_WIDTH && abs(velocityX) >
SWIPE_VELOCITY_THRESHOLD) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,15 @@ class FolderAdapter(
folder.images.removeAll(toBeRemoved)
val count = folder.images.size

if(count == 0) {
if(count == 0 && folders.size > 0) {
// Folder is empty, remove folder from the adapter.
holder.itemView.post{
val updatePosition = folders.indexOf(folder)
folders.removeAt(updatePosition)
notifyItemRemoved(updatePosition)
notifyItemRangeChanged(updatePosition, folders.size)
if(updatePosition != -1) {
folders.removeAt(updatePosition)
notifyItemRemoved(updatePosition)
notifyItemRangeChanged(updatePosition, folders.size)
}
}
} else {
val previewImage = folder.images[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class ImageAdapter(
* Bind View holder, load image, selected view, click listeners.
*/
override fun onBindViewHolder(holder: ImageViewHolder, position: Int) {

if(images.size == 0) { return }
var image=images[position]
holder.image.setImageDrawable (null)
if (context.contentResolver.getType(image.uri) == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,49 @@
package fr.free.nrw.commons.customselector.ui.selector

import android.Manifest
import android.app.Activity
import android.app.Dialog
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.Window
import android.widget.Button
import android.widget.ImageButton
import android.widget.TextView
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModelProvider
import fr.free.nrw.commons.R
import fr.free.nrw.commons.customselector.database.NotForUploadStatus
Expand All @@ -24,10 +57,12 @@ import fr.free.nrw.commons.databinding.ActivityCustomSelectorBinding
import fr.free.nrw.commons.databinding.CustomSelectorBottomLayoutBinding
import fr.free.nrw.commons.databinding.CustomSelectorToolbarBinding
import fr.free.nrw.commons.filepicker.Constants
import fr.free.nrw.commons.filepicker.FilePicker
import fr.free.nrw.commons.media.ZoomableActivity
import fr.free.nrw.commons.theme.BaseActivity
import fr.free.nrw.commons.upload.FileUtilsWrapper
import fr.free.nrw.commons.utils.CustomSelectorUtils
import fr.free.nrw.commons.utils.PermissionUtils
import kotlinx.coroutines.*
import java.io.File
import java.lang.Integer.max
Expand Down Expand Up @@ -114,14 +149,37 @@ class CustomSelectorActivity : BaseActivity(), FolderClickListener, ImageSelectL

private var progressDialogText:String=""

private var showPartialAccessIndicator by mutableStateOf(false)

/**
* onCreate Activity, sets theme, initialises the view model, setup view.
*/
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
ContextCompat.checkSelfPermission(
this, Manifest.permission.READ_MEDIA_IMAGES
) == PackageManager.PERMISSION_DENIED
) {
showPartialAccessIndicator = true
}

binding = ActivityCustomSelectorBinding.inflate(layoutInflater)
toolbarBinding = CustomSelectorToolbarBinding.bind(binding.root)
bottomSheetBinding = CustomSelectorBottomLayoutBinding.bind(binding.root)
binding.partialAccessIndicator.setContent {
PartialStorageAccessIndicator(
isVisible = showPartialAccessIndicator,
onManage = {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
requestPermissions(arrayOf(Manifest.permission.READ_MEDIA_IMAGES), 1)
}
},
modifier = Modifier
.padding(vertical = 8.dp, horizontal = 4.dp)
.fillMaxWidth()
)
}
val view = binding.root
setContentView(view)

Expand All @@ -147,6 +205,24 @@ class CustomSelectorActivity : BaseActivity(), FolderClickListener, ImageSelectL
}
}

override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if(requestCode == 1 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
if(grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
showPartialAccessIndicator = false
}
}
}

override fun onResume() {
super.onResume()
fetchData()
}

/**
* When data will be send from full screen mode, it will be passed to fragment
*/
Expand Down Expand Up @@ -181,7 +257,6 @@ class CustomSelectorActivity : BaseActivity(), FolderClickListener, ImageSelectL
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, FolderFragment.newInstance())
.commit()
fetchData()
setUpToolbar()
setUpBottomLayout()
}
Expand Down Expand Up @@ -498,3 +573,52 @@ class CustomSelectorActivity : BaseActivity(), FolderClickListener, ImageSelectL
const val ITEM_ID: String = "ItemId"
}
}
@Composable
fun PartialStorageAccessIndicator(
isVisible: Boolean,
onManage: ()-> Unit,
modifier: Modifier = Modifier
) {
if(isVisible) {
OutlinedCard(
modifier = modifier,
colors = CardDefaults.cardColors(
containerColor = colorResource(R.color.primarySuperLightColor)
),
border = BorderStroke(0.5.dp, color = colorResource(R.color.primaryColor)),
shape = RoundedCornerShape(8.dp)
) {
Row(modifier = Modifier.padding(16.dp).fillMaxWidth()) {
Text(
text = "You've given access to a select number of photos",
modifier = Modifier.weight(1f)
)
TextButton(
onClick = onManage,
modifier = Modifier.align(Alignment.Bottom),
colors = ButtonDefaults.buttonColors(
containerColor = colorResource(R.color.primaryColor)
),
shape = RoundedCornerShape(8.dp)
) {
Text(
text = "Manage",
style = MaterialTheme.typography.labelMedium,
color = colorResource(R.color.primaryTextColor)
)
}
}
}
}
}

@Preview
@Composable
fun PartialStorageAccessIndicatorPreview() {
Surface {
PartialStorageAccessIndicator(isVisible = true, onManage = {}, modifier = Modifier
.padding(vertical = 8.dp, horizontal = 4.dp)
.fillMaxWidth()
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,14 @@ class FolderFragment : CommonsDaggerSupportFragment() {
private fun handleResult(result: Result) {
if(result.status is CallbackStatus.SUCCESS){
val images = result.images
if(images.isNullOrEmpty())
{
if(images.isEmpty()){
binding?.emptyText?.let {
it.visibility = View.VISIBLE
}
} else {
binding?.emptyText?.let {
it.visibility = View.GONE
}
}
folders = ImageHelper.folderListFromImages(result.images)
folderAdapter.init(folders)
Expand Down
Loading
Loading