Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -1,52 +1,43 @@
package fr.free.nrw.commons.media;

import static fr.free.nrw.commons.Utils.handleWebUrl;

import android.annotation.SuppressLint;
import android.app.DownloadManager;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;

import com.google.android.material.snackbar.Snackbar;

import javax.inject.Inject;
import javax.inject.Named;

import butterknife.BindView;
import butterknife.ButterKnife;
import com.google.android.material.snackbar.Snackbar;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.category.CategoryImagesCallback;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.bookmarks.Bookmark;
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesContentProvider;
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao;
import fr.free.nrw.commons.category.CategoryImagesCallback;
import fr.free.nrw.commons.contributions.Contribution;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.utils.DownloadUtils;
import fr.free.nrw.commons.utils.ImageUtils;
import fr.free.nrw.commons.utils.NetworkUtils;
import fr.free.nrw.commons.utils.PermissionUtils;
import fr.free.nrw.commons.utils.ViewUtil;
import javax.inject.Inject;
import javax.inject.Named;
import timber.log.Timber;

import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.Context.DOWNLOAD_SERVICE;
import static fr.free.nrw.commons.Utils.handleWebUrl;

public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment implements ViewPager.OnPageChangeListener {

@Inject SessionManager sessionManager;
Expand Down Expand Up @@ -168,7 +159,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
ViewUtil.showShortSnackbar(getView(), R.string.no_internet);
return false;
}
downloadMedia(m);
DownloadUtils.downloadMedia(getActivity(), m);
return true;
case R.id.menu_set_as_wallpaper:
// Set wallpaper
Expand All @@ -192,53 +183,6 @@ private void setWallpaper(Media media) {
ImageUtils.setWallpaperFromImageUrl(getActivity(), Uri.parse(media.getImageUrl()));
}

/**
* Start the media file downloading to the local SD card/storage.
* The file can then be opened in Gallery or other apps.
*
* @param m Media file to download
*/
private void downloadMedia(Media m) {
String imageUrl = m.getImageUrl(), fileName = m.getFilename();

if (imageUrl == null
|| fileName == null
|| getContext() == null
|| getActivity() == null) {
Timber.d("Skipping download media as either imageUrl %s or filename %s activity is null", imageUrl, fileName);
return;
}

// Strip 'File:' from beginning of filename, we really shouldn't store it
fileName = fileName.replaceFirst("^File:", "");

Uri imageUri = Uri.parse(imageUrl);

DownloadManager.Request req = new DownloadManager.Request(imageUri);
//These are not the image title and description fields, they are download descs for notifications
req.setDescription(getString(R.string.app_name));
req.setTitle(m.getDisplayTitle());
req.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);

// Modern Android updates the gallery automatically. Yay!
req.allowScanningByMediaScanner();
req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
PermissionUtils.checkPermissionsAndPerformAction(getActivity(), WRITE_EXTERNAL_STORAGE,
() -> enqueueRequest(req), () -> Toast.makeText(getContext(),
R.string.download_failed_we_cannot_download_the_file_without_storage_permission,
Toast.LENGTH_SHORT).show(), R.string.storage_permission,
R.string.write_storage_permission_rationale);

}

private void enqueueRequest(DownloadManager.Request req) {
DownloadManager systemService =
(DownloadManager) getActivity().getSystemService(DOWNLOAD_SERVICE);
if (systemService != null) {
systemService.enqueue(req);
}
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (!editable) { // Disable menu options for editable views
Expand Down
65 changes: 65 additions & 0 deletions app/src/main/java/fr/free/nrw/commons/utils/DownloadUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package fr.free.nrw.commons.utils

import android.Manifest.permission
import android.app.Activity
import android.app.DownloadManager
import android.content.Context
import android.net.Uri
import android.os.Environment
import android.widget.Toast
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.R
import timber.log.Timber

object DownloadUtils {
/**
* Start the media file downloading to the local SD card/storage. The file can then be opened in
* Gallery or other apps.
*
* @param m Media file to download
*/
@JvmStatic
fun downloadMedia(activity: Activity?, m: Media) {
val imageUrl = m.getImageUrl()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't the IDE be suggesting using propertyAccess syntax?

var fileName = m.getFilename()
if (imageUrl == null || fileName == null || activity == null
) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird place for a parentheses

Timber.d(
"Skipping download media as either imageUrl %s or filename %s activity is null",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use kotlin string interpolation here

imageUrl, fileName
)
return
}
// Strip 'File:' from beginning of filename, we really shouldn't store it
fileName = fileName.replaceFirst("^File:".toRegex(), "")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.substringAfter will express this a bit nicer

val imageUri = Uri.parse(imageUrl)
val req = DownloadManager.Request(imageUri)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can use .apply to make building this Request look nicer

//These are not the image title and description fields, they are download descs for notifications
req.setDescription(activity.getString(R.string.app_name))
req.setTitle(m.displayTitle)
req.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
// Modern Android updates the gallery automatically. Yay!
req.allowScanningByMediaScanner()
req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
PermissionUtils.checkPermissionsAndPerformAction(
activity,
permission.WRITE_EXTERNAL_STORAGE,
{ enqueueRequest(activity, req) },
{
Toast.makeText(
activity,
R.string.download_failed_we_cannot_download_the_file_without_storage_permission,
Toast.LENGTH_SHORT
).show()
},
R.string.storage_permission,
R.string.write_storage_permission_rationale
)
}

private fun enqueueRequest(activity: Activity, req: DownloadManager.Request) {
val systemService =
activity.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
systemService?.enqueue(req)
}
}