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

add an activity check for the permission check #5900

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
62 changes: 44 additions & 18 deletions app/src/main/java/fr/free/nrw/commons/utils/DownloadUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,20 @@ import fr.free.nrw.commons.Media
import fr.free.nrw.commons.R
import timber.log.Timber

/**
* Utility class for managing media file downloads.
* This class provides a function to start downloading media files to the local SD card/storage.
* The downloaded file can then be opened in the Gallery or other apps.
*/
object DownloadUtils {

/**
* Start the media file downloading to the local SD card/storage. The file can then be opened in
* Gallery or other apps.
* Initiates the downloading of a media file to the device's external storage.
* This method will check for storage permissions before attempting to download the file.
* If permissions are granted, the file will be saved to the device's Downloads folder.
*
* @param m Media file to download
* @param activity Activity context to perform permission checks and display messages
* @param m Media object representing the file to download
*/
@JvmStatic
fun downloadMedia(
Expand All @@ -25,43 +33,61 @@ object DownloadUtils {
val imageUrl = m.imageUrl
var fileName = m.filename
if (imageUrl == null || fileName == null || activity == null) {
Timber.d("Skipping download media as either imageUrl $imageUrl or filename $fileName activity is null")
// Log if any required parameter is null and exit
Timber.d("Skipping download media as either imageUrl $imageUrl or filename $fileName or activity is null")
return
}
// Strip 'File:' from beginning of filename, we really shouldn't store it

// Strip 'File:' from beginning of filename to ensure it is stored correctly
fileName = fileName.substringAfter("File:")
val imageUri = Uri.parse(imageUrl)
val req =

// Prepare a DownloadManager.Request object with the media's URI and other configurations
val req = try {
DownloadManager.Request(imageUri).apply {
setTitle(m.displayTitle)
setDescription(activity.getString(R.string.app_name))
setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
allowScanningByMediaScanner()
setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
}
} catch (e: SecurityException) {
// Catch SecurityException if storage permission is missing, show a message, and exit
Toast.makeText(activity, "no permission", Toast.LENGTH_SHORT).show()
return
}

// Check for storage permissions and perform the download action if granted
PermissionUtils.checkPermissionsAndPerformAction(
activity,
{ enqueueRequest(activity, req) },
{
Toast
.makeText(
activity,
R.string.download_failed_we_cannot_download_the_file_without_storage_permission,
Toast.LENGTH_SHORT,
).show()
if (activity != null) enqueueRequest(activity, req) // Ensure activity is not null before proceeding
},
R.string.storage_permission,
R.string.write_storage_permission_rationale,
*PermissionUtils.PERMISSIONS_STORAGE,
{
// Show a message if permissions are denied and download cannot proceed
Toast.makeText(
activity,
R.string.download_failed_we_cannot_download_the_file_without_storage_permission,
Toast.LENGTH_SHORT,
).show()
},
R.string.storage_permission, // Title for permission rationale
R.string.write_storage_permission_rationale, // Message for permission rationale
*PermissionUtils.PERMISSIONS_STORAGE, // Permissions to request
)
}

/**
* Enqueues the download request with the system's DownloadManager.
*
* @param activity Activity context for accessing the system's DownloadManager
* @param req DownloadManager.Request configured with the download details
*/
private fun enqueueRequest(
activity: Activity,
req: DownloadManager.Request,
) {
val systemService =
activity.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val systemService = activity.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
systemService?.enqueue(req)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,23 @@ private static double calculateSimilarity(String str1, String str2) {
* @return Number of characters the strings differ by
*/
private static int levenshteinDistance(String str1, String str2) {
if (str1.equals(str2)) return 0;
if (str1.length() == 0) return str2.length();
if (str2.length() == 0) return str1.length();
if (str1.equals(str2)) {
return 0;
}
if (str1.length() == 0) {
return str2.length();
}
if (str2.length() == 0) {
return str1.length();
}

int[] cost = new int[str1.length() + 1];
int[] newcost = new int[str1.length() + 1];

// initial cost of skipping prefix in str1
for (int i = 0; i < cost.length; i++) cost[i] = i;
for (int i = 0; i < cost.length; i++) {
cost[i] = i;
}

// transformation cost for each letter in str2
for (int j = 1; j <= str2.length(); j++) {
Expand Down