Skip to content

Commit 7afaea2

Browse files
Merge pull request #14401 from nextcloud/backport/14247/stable-3.30
[stable-3.30] request media_location
2 parents 3f3a90f + 50e910c commit 7afaea2

File tree

12 files changed

+168
-9
lines changed

12 files changed

+168
-9
lines changed

Diff for: app/src/gplay/AndroidManifest.xml

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
tools:node="remove"
1919
tools:ignore="ScopedStorage" />
2020

21+
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
22+
2123
<application
2224
android:name=".MainApp"
2325
android:icon="@mipmap/ic_launcher"

Diff for: app/src/main/AndroidManifest.xml

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
<uses-permission
4949
android:name="com.android.launcher.permission.INSTALL_SHORTCUT"
5050
android:maxSdkVersion="25" />
51+
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
5152
<!--
5253
Apps that target Android 9 (API level 28) or higher and use foreground services
5354
must request the FOREGROUND_SERVICE permission

Diff for: app/src/main/java/com/nextcloud/client/jobs/MediaFoldersDetectionWork.kt

+44
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import com.nextcloud.client.account.UserAccountManager
3232
import com.nextcloud.client.core.Clock
3333
import com.nextcloud.client.preferences.AppPreferences
3434
import com.nextcloud.client.preferences.AppPreferencesImpl
35+
import com.nextcloud.utils.BuildHelper
3536
import com.owncloud.android.MainApp
3637
import com.owncloud.android.R
3738
import com.owncloud.android.datamodel.ArbitraryDataProvider
@@ -41,6 +42,7 @@ import com.owncloud.android.datamodel.MediaFoldersModel
4142
import com.owncloud.android.datamodel.MediaProvider
4243
import com.owncloud.android.datamodel.SyncedFolderProvider
4344
import com.owncloud.android.lib.common.utils.Log_OC
45+
import com.owncloud.android.ui.activity.FileDisplayActivity
4446
import com.owncloud.android.ui.activity.ManageAccountsActivity.PENDING_FOR_REMOVAL
4547
import com.owncloud.android.ui.activity.SyncedFoldersActivity
4648
import com.owncloud.android.ui.notifications.NotificationUtils
@@ -190,9 +192,51 @@ class MediaFoldersDetectionWork constructor(
190192
gson.toJson(mediaFoldersModel)
191193
)
192194
}
195+
196+
// only send notification when synced folder is setup, gplay flavor and not branded client
197+
@Suppress("ComplexMethod")
198+
if (syncedFolderProvider.syncedFolders.isNotEmpty() &&
199+
BuildHelper.isFlavourGPlay() &&
200+
!preferences.isAutoUploadGPlayNotificationShown &&
201+
!MainApp.isClientBranded()
202+
) {
203+
sendAutoUploadNotification()
204+
}
205+
193206
return Result.success()
194207
}
195208

209+
private fun sendAutoUploadNotification() {
210+
val notificationId = randomIdGenerator.nextInt()
211+
val intent = Intent().apply {
212+
setClassName(context, FileDisplayActivity::class.java.name)
213+
setAction(FileDisplayActivity.AUTO_UPLOAD_NOTIFICATION)
214+
}
215+
val pendingIntent = PendingIntent.getActivity(
216+
context,
217+
0,
218+
intent,
219+
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
220+
)
221+
222+
val notificationBuilder = NotificationCompat.Builder(
223+
context,
224+
NotificationUtils.NOTIFICATION_CHANNEL_GENERAL
225+
)
226+
.setSmallIcon(R.drawable.notification_icon)
227+
.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.notification_icon))
228+
.setContentTitle(context.getString(R.string.re_enable_auto_upload))
229+
.setContentText(context.getString(R.string.click_to_learn_how_to_re_enable_auto_uploads))
230+
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
231+
.setAutoCancel(true)
232+
.setContentIntent(pendingIntent)
233+
234+
viewThemeUtils.androidx.themeNotificationCompatBuilder(context, notificationBuilder)
235+
236+
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
237+
notificationManager.notify(notificationId, notificationBuilder.build())
238+
}
239+
196240
@Suppress("LongMethod")
197241
private fun sendNotification(contentTitle: String, subtitle: String, user: User, path: String, type: Int) {
198242
val notificationId = randomIdGenerator.nextInt()

Diff for: app/src/main/java/com/nextcloud/client/preferences/AppPreferences.java

+6
Original file line numberDiff line numberDiff line change
@@ -403,4 +403,10 @@ default void onDarkThemeModeChanged(DarkMode mode) {
403403

404404
boolean isAutoUploadGPlayWarningShown();
405405
void setAutoUploadGPlayWarningShown(boolean value);
406+
407+
boolean isAutoUploadGPlayWarning2Shown();
408+
void setAutoUploadGPlayWarning2Shown(boolean value);
409+
410+
boolean isAutoUploadGPlayNotificationShown();
411+
void setAutoUploadGPlayNotificationShown(boolean value);
406412
}

Diff for: app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java

+22
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ public final class AppPreferencesImpl implements AppPreferences {
108108
private static final String PREF__STOP_DOWNLOAD_JOBS_ON_START = "stop_download_jobs_on_start";
109109

110110
private static final String PREF__AUTO_UPLOAD_GPLAY_WARNING_SHOWN = "auto_upload_gplay_warning_shown";
111+
private static final String PREF__AUTO_UPLOAD_GPLAY_WARNING2_SHOWN = "auto_upload_gplay_warning2_shown";
112+
private static final String PREF__AUTO_UPLOAD_GPLAY_NOTIFICATION_SHOWN = "auto_upload_gplay_notification_shown";
111113

112114
private static final String LOG_ENTRY = "log_entry";
113115

@@ -836,4 +838,24 @@ public boolean isAutoUploadGPlayWarningShown() {
836838
public void setAutoUploadGPlayWarningShown(boolean value) {
837839
preferences.edit().putBoolean(PREF__AUTO_UPLOAD_GPLAY_WARNING_SHOWN, value).apply();
838840
}
841+
842+
@Override
843+
public boolean isAutoUploadGPlayWarning2Shown() {
844+
return preferences.getBoolean(PREF__AUTO_UPLOAD_GPLAY_WARNING2_SHOWN, false);
845+
}
846+
847+
@Override
848+
public void setAutoUploadGPlayWarning2Shown(boolean value) {
849+
preferences.edit().putBoolean(PREF__AUTO_UPLOAD_GPLAY_WARNING2_SHOWN, value).apply();
850+
}
851+
852+
@Override
853+
public boolean isAutoUploadGPlayNotificationShown() {
854+
return preferences.getBoolean(PREF__AUTO_UPLOAD_GPLAY_NOTIFICATION_SHOWN, false);
855+
}
856+
857+
@Override
858+
public void setAutoUploadGPlayNotificationShown(boolean value) {
859+
preferences.edit().putBoolean(PREF__AUTO_UPLOAD_GPLAY_NOTIFICATION_SHOWN, value).apply();
860+
}
839861
}

Diff for: app/src/main/java/com/owncloud/android/MainApp.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -403,9 +403,13 @@ private void setProxyForNonBrandedPlusClients() {
403403
Log_OC.d(TAG, "Error caught at setProxyForNonBrandedPlusClients: " + e);
404404
}
405405
}
406+
407+
public static boolean isClientBranded() {
408+
return getAppContext().getResources().getBoolean(R.bool.is_branded_client);
409+
}
406410

407411
public static boolean isClientBrandedPlus() {
408-
return (getAppContext().getResources().getBoolean(R.bool.is_branded_plus_client));
412+
return getAppContext().getResources().getBoolean(R.bool.is_branded_plus_client);
409413
}
410414

411415
private final IntentFilter restrictionsFilter = new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);

Diff for: app/src/main/java/com/owncloud/android/datamodel/OCFile.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import android.text.TextUtils;
2222

2323
import com.nextcloud.utils.BuildHelper;
24-
import com.owncloud.android.BuildConfig;
2524
import com.owncloud.android.R;
2625
import com.owncloud.android.lib.common.network.WebdavEntry;
2726
import com.owncloud.android.lib.common.network.WebdavUtils;
@@ -1085,7 +1084,7 @@ public void setInternalFolderSyncResult(String internalFolderSyncResult) {
10851084
}
10861085

10871086
public boolean isAPKorAAB() {
1088-
if (BuildHelper.GPLAY.equals(BuildConfig.FLAVOR)) {
1087+
if (BuildHelper.INSTANCE.isFlavourGPlay()) {
10891088
return getFileName().endsWith(".apk") || getFileName().endsWith(".aab");
10901089
} else {
10911090
return false;

Diff for: app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java

+56-4
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@
7373
import com.nextcloud.utils.extensions.IntentExtensionsKt;
7474
import com.nextcloud.utils.fileNameValidator.FileNameValidator;
7575
import com.nextcloud.utils.view.FastScrollUtils;
76-
import com.owncloud.android.BuildConfig;
7776
import com.owncloud.android.MainApp;
7877
import com.owncloud.android.R;
7978
import com.owncloud.android.databinding.FilesBinding;
8079
import com.owncloud.android.datamodel.FileDataStorageManager;
80+
import com.owncloud.android.datamodel.MediaFolderType;
8181
import com.owncloud.android.datamodel.OCFile;
8282
import com.owncloud.android.datamodel.SyncedFolder;
8383
import com.owncloud.android.datamodel.SyncedFolderProvider;
@@ -176,6 +176,7 @@ public class FileDisplayActivity extends FileActivity
176176
public static final String RESTART = "RESTART";
177177
public static final String ALL_FILES = "ALL_FILES";
178178
public static final String LIST_GROUPFOLDERS = "LIST_GROUPFOLDERS";
179+
public static final String AUTO_UPLOAD_NOTIFICATION = "AUTO_UPLOAD_NOTIFICATION";
179180
public static final int SINGLE_USER_SIZE = 1;
180181
public static final String OPEN_FILE = "NC_OPEN_FILE";
181182

@@ -283,15 +284,16 @@ protected void onCreate(Bundle savedInstanceState) {
283284
mPlayerConnection = new PlayerServiceConnection(this);
284285

285286
checkStoragePath();
286-
checkAutoUploadOnGPlay();
287+
notifyGPlayPermissionChanges();
288+
showAutoUploadWarningForGPlayFlavour();
287289

288290
initSyncBroadcastReceiver();
289291
observeWorkerState();
290292
registerRefreshFolderEventReceiver();
291293
}
292294

293-
private void checkAutoUploadOnGPlay() {
294-
if (!BuildHelper.GPLAY.equals(BuildConfig.FLAVOR)) {
295+
private void notifyGPlayPermissionChanges() {
296+
if (!BuildHelper.INSTANCE.isFlavourGPlay() || MainApp.isClientBranded()) {
295297
return;
296298
}
297299

@@ -333,6 +335,41 @@ private void checkAutoUploadOnGPlay() {
333335
preferences.setAutoUploadGPlayWarningShown(true);
334336
}
335337

338+
private void showAutoUploadWarningForGPlayFlavour() {
339+
if (!BuildHelper.INSTANCE.isFlavourGPlay() || MainApp.isClientBranded()) {
340+
return;
341+
}
342+
343+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
344+
return;
345+
}
346+
347+
boolean showAutoUploadDialog = false;
348+
for (SyncedFolder syncedFolder : syncedFolderProvider.getSyncedFolders()) {
349+
if (syncedFolder.getType() == MediaFolderType.CUSTOM) {
350+
showAutoUploadDialog = true;
351+
break;
352+
}
353+
}
354+
355+
if (!preferences.isAutoUploadGPlayWarning2Shown()) {
356+
String title = showAutoUploadDialog ? getString(R.string.auto_upload_gplay) : getString(R.string.upload_gplay);
357+
String message = showAutoUploadDialog ? getString(R.string.auto_upload_gplay_desc2) : getString(R.string.upload_gplay_desc);
358+
359+
new MaterialAlertDialogBuilder(this, R.style.Theme_ownCloud_Dialog)
360+
.setTitle(title)
361+
.setMessage(message)
362+
.setNegativeButton(R.string.dialog_close, (dialog, which) -> {
363+
PermissionUtil.requestMediaLocationPermission(this);
364+
preferences.setAutoUploadGPlayWarning2Shown(true);
365+
dialog.dismiss();
366+
})
367+
.setIcon(R.drawable.nav_synced_folders)
368+
.create()
369+
.show();
370+
}
371+
}
372+
336373
@SuppressWarnings("unchecked")
337374
private void loadSavedInstanceState(Bundle savedInstanceState) {
338375
if (savedInstanceState != null) {
@@ -617,9 +654,24 @@ protected void onNewIntent(Intent intent) {
617654

618655
setLeftFragment(new GroupfolderListFragment());
619656
getSupportFragmentManager().executePendingTransactions();
657+
} else if (AUTO_UPLOAD_NOTIFICATION.equals(intent.getAction())) {
658+
handleAutoUploadNotification();
620659
}
621660
}
622661
}
662+
663+
private void handleAutoUploadNotification() {
664+
new MaterialAlertDialogBuilder(this, R.style.Theme_ownCloud_Dialog)
665+
.setTitle(R.string.re_enable_auto_upload)
666+
.setMessage(R.string.re_enable_auto_upload_desc)
667+
.setNegativeButton(R.string.dialog_close, (dialog, which) -> {
668+
dialog.dismiss();
669+
preferences.setAutoUploadGPlayNotificationShown(true);
670+
})
671+
.setIcon(R.drawable.nav_synced_folders)
672+
.create()
673+
.show();
674+
}
623675

624676
private void onOpenFileIntent(Intent intent) {
625677
String extra = intent.getStringExtra(EXTRA_FILE);

Diff for: app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java

+2
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,8 @@ public void registerFabListener() {
486486
// is not available in FolderPickerActivity
487487
viewThemeUtils.material.themeFAB(mFabMain);
488488
mFabMain.setOnClickListener(v -> {
489+
PermissionUtil.requestMediaLocationPermission(activity);
490+
489491
final OCFileListBottomSheetDialog dialog =
490492
new OCFileListBottomSheetDialog(activity,
491493
this,

Diff for: app/src/main/java/com/owncloud/android/utils/PermissionUtil.kt

+22-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ object PermissionUtil {
3939
const val PERMISSIONS_READ_CALENDAR_AUTOMATIC = 6
4040
const val PERMISSIONS_WRITE_CALENDAR = 7
4141
const val PERMISSIONS_POST_NOTIFICATIONS = 8
42+
const val PERMISSIONS_MEDIA_LOCATION = 9
4243

4344
const val REQUEST_CODE_MANAGE_ALL_FILES = 19203
4445

@@ -151,7 +152,8 @@ object PermissionUtil {
151152
// use granular media permissions
152153
arrayOf(
153154
Manifest.permission.READ_MEDIA_IMAGES,
154-
Manifest.permission.READ_MEDIA_VIDEO
155+
Manifest.permission.READ_MEDIA_VIDEO,
156+
Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED
155157
)
156158
} else {
157159
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)
@@ -302,4 +304,23 @@ object PermissionUtil {
302304
}
303305
}
304306
}
307+
308+
/**
309+
* Request media location permission. Required on API level >= 34.
310+
* Does not have any effect on API level < 34.
311+
*
312+
* @param activity target activity
313+
*/
314+
@JvmStatic
315+
fun requestMediaLocationPermission(activity: Activity) {
316+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
317+
if (!checkSelfPermission(activity, Manifest.permission.ACCESS_MEDIA_LOCATION)) {
318+
ActivityCompat.requestPermissions(
319+
activity,
320+
arrayOf(Manifest.permission.ACCESS_MEDIA_LOCATION),
321+
PERMISSIONS_MEDIA_LOCATION
322+
)
323+
}
324+
}
325+
}
305326
}

Diff for: app/src/main/res/values/strings.xml

+6
Original file line numberDiff line numberDiff line change
@@ -1255,4 +1255,10 @@
12551255
<string name="two_way_sync_activity_disable_all_button_title">Disable for all folders</string>
12561256
<string name="auto_upload_gplay">Auto upload behaviour changed</string>
12571257
<string name="auto_upload_gplay_desc">Due to new restrictions imposed by Google, the auto upload feature will no longer be able to automatically remove uploaded files.</string>
1258+
<string name="auto_upload_gplay_desc2">Due to new restrictions imposed by Google, we have been forced to remove an important permission. As a result, auto upload will only be able to upload image and video files.\nAdditionally, a new permission is required to access location information for uploaded images.\nMake sure that media access is set to \"Always allow all\".</string>
1259+
<string name="upload_gplay">Permission changes</string>
1260+
<string name="upload_gplay_desc">A new permission is required to access location information for uploaded images.\nMake sure that media access is set to \"Always allow all\".</string>
1261+
<string name="re_enable_auto_upload">Changes to auto upload</string>
1262+
<string name="re_enable_auto_upload_desc">Due to new restrictions imposed by Google, we have been forced to remove an important permission. We are currently working with Google to resolve this issue and restore full functionality.\n\nTo re-enable auto upload for new photos and videos:\nSelect \"Allow all\" in the following dialogue or the system settings.\nAllow Nextcloud to use location when prompted, as this allows us to store location when uploading images.\n\nAuto upload will no longer be able to upload any other files when using the Google Play version of the Nextcloud app.\n\nPlease check for any files that may not have been uploaded since December 2024.</string>
1263+
<string name="click_to_learn_how_to_re_enable_auto_uploads">Manual intervention required to re-enable auto-upload</string>
12581264
</resources>

Diff for: scripts/analysis/lint-results.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
DO NOT TOUCH; GENERATED BY DRONE
2-
<span class="mdl-layout-title">Lint Report: 3 errors and 60 warnings</span>
2+
<span class="mdl-layout-title">Lint Report: 3 errors and 59 warnings</span>

0 commit comments

Comments
 (0)