Skip to content

Commit fbf7cd5

Browse files
ashishkumar468neslihanturan
authored andcommitted
Bug Fix issue #2648 (#2678)
* Bug Fix issue #2648 * Handled external storage permission before file download * * Removed redudant check for permission in MediaDetailPagerFragment (Dexter already does that) * Removed duplicate code in PermissionUtil$checkPermissionsAndPerformAction, used the existing function with conditional extra parameters * string name typo correction
1 parent 468f0b7 commit fbf7cd5

File tree

3 files changed

+76
-58
lines changed

3 files changed

+76
-58
lines changed

app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java

+16-23
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,12 @@
55
import android.content.Intent;
66
import android.database.DataSetObserver;
77
import android.net.Uri;
8-
import android.os.Build;
98
import android.os.Bundle;
109
import android.os.Environment;
1110
import android.os.Handler;
12-
import android.support.design.widget.Snackbar;
13-
import android.support.v4.app.ActivityCompat;
1411
import android.support.v4.app.Fragment;
1512
import android.support.v4.app.FragmentManager;
1613
import android.support.v4.app.FragmentStatePagerAdapter;
17-
import android.support.v4.content.ContextCompat;
1814
import android.support.v4.view.ViewPager;
1915
import android.view.LayoutInflater;
2016
import android.view.Menu;
@@ -23,10 +19,6 @@
2319
import android.view.View;
2420
import android.view.ViewGroup;
2521
import android.widget.Toast;
26-
27-
import javax.inject.Inject;
28-
import javax.inject.Named;
29-
3022
import butterknife.BindView;
3123
import butterknife.ButterKnife;
3224
import fr.free.nrw.commons.Media;
@@ -43,13 +35,15 @@
4335
import fr.free.nrw.commons.mwapi.MediaWikiApi;
4436
import fr.free.nrw.commons.utils.ImageUtils;
4537
import fr.free.nrw.commons.utils.NetworkUtils;
38+
import fr.free.nrw.commons.utils.PermissionUtils;
4639
import fr.free.nrw.commons.utils.ViewUtil;
40+
import javax.inject.Inject;
41+
import javax.inject.Named;
4742
import timber.log.Timber;
4843

49-
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
44+
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
5045
import static android.content.Context.DOWNLOAD_SERVICE;
5146
import static android.content.Intent.ACTION_VIEW;
52-
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
5347
import static android.widget.Toast.LENGTH_SHORT;
5448

5549
public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment implements ViewPager.OnPageChangeListener {
@@ -237,20 +231,19 @@ private void downloadMedia(Media m) {
237231
// Modern Android updates the gallery automatically. Yay!
238232
req.allowScanningByMediaScanner();
239233
req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
234+
PermissionUtils.checkPermissionsAndPerformAction(getActivity(), WRITE_EXTERNAL_STORAGE,
235+
() -> enqueueRequest(req), () -> Toast.makeText(getContext(),
236+
R.string.download_failed_we_cannot_download_the_file_without_storage_permission,
237+
Toast.LENGTH_SHORT).show(), R.string.storage_permission,
238+
R.string.write_storage_permission_rationale);
240239

241-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
242-
ContextCompat.checkSelfPermission(getContext(), READ_EXTERNAL_STORAGE)
243-
!= PERMISSION_GRANTED
244-
&& getView() != null) {
245-
Snackbar.make(getView(), R.string.read_storage_permission_rationale,
246-
Snackbar.LENGTH_INDEFINITE).setAction(R.string.ok,
247-
view -> ActivityCompat.requestPermissions(getActivity(),
248-
new String[]{READ_EXTERNAL_STORAGE}, 1)).show();
249-
} else {
250-
DownloadManager systemService = (DownloadManager) getActivity().getSystemService(DOWNLOAD_SERVICE);
251-
if (systemService != null) {
252-
systemService.enqueue(req);
253-
}
240+
}
241+
242+
private void enqueueRequest(DownloadManager.Request req) {
243+
DownloadManager systemService =
244+
(DownloadManager) getActivity().getSystemService(DOWNLOAD_SERVICE);
245+
if (systemService != null) {
246+
systemService.enqueue(req);
254247
}
255248
}
256249

app/src/main/java/fr/free/nrw/commons/utils/PermissionUtils.java

+58-34
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,12 @@
77
import android.provider.Settings;
88
import android.support.annotation.StringRes;
99
import android.support.v4.content.ContextCompat;
10-
1110
import com.karumi.dexter.Dexter;
1211
import com.karumi.dexter.PermissionToken;
1312
import com.karumi.dexter.listener.PermissionDeniedResponse;
1413
import com.karumi.dexter.listener.PermissionGrantedResponse;
1514
import com.karumi.dexter.listener.PermissionRequest;
1615
import com.karumi.dexter.listener.single.BasePermissionListener;
17-
1816
import fr.free.nrw.commons.CommonsApplication;
1917
import fr.free.nrw.commons.R;
2018

@@ -64,42 +62,68 @@ public static boolean hasPermission(Activity activity, String permission) {
6462
* @param rationaleTitle rationale title to be displayed when permission was denied
6563
* @param rationaleMessage rationale message to be displayed when permission was denied
6664
*/
67-
public static void checkPermissionsAndPerformAction(Activity activity,
68-
String permission,
69-
Runnable onPermissionGranted,
70-
@StringRes int rationaleTitle,
71-
@StringRes int rationaleMessage) {
65+
public static void checkPermissionsAndPerformAction(Activity activity, String permission,
66+
Runnable onPermissionGranted, @StringRes int rationaleTitle,
67+
@StringRes int rationaleMessage) {
68+
checkPermissionsAndPerformAction(activity, permission, onPermissionGranted, null,
69+
rationaleTitle, rationaleMessage);
70+
}
71+
72+
/**
73+
* Checks for a particular permission and runs the corresponding runnables to perform an action when the permission is granted/denied
74+
* Also, it shows a rationale if needed
75+
*
76+
* Sample usage:
77+
*
78+
* PermissionUtils.checkPermissionsAndPerformAction(activity,
79+
* Manifest.permission.WRITE_EXTERNAL_STORAGE,
80+
* () -> initiateCameraUpload(activity),
81+
* () -> showMessage(),
82+
* R.string.storage_permission_title,
83+
* R.string.write_storage_permission_rationale);
84+
*
85+
*
86+
* @param activity activity requesting permissions
87+
* @param permission the permission being requests
88+
* @param onPermissionGranted the runnable to be executed when the permission is granted
89+
* @param onPermissionDenied the runnable to be executed when the permission is denied(but not permanently)
90+
* @param rationaleTitle rationale title to be displayed when permission was denied
91+
* @param rationaleMessage rationale message to be displayed when permission was denied
92+
*/
93+
94+
public static void checkPermissionsAndPerformAction(Activity activity, String permission,
95+
Runnable onPermissionGranted, Runnable onPermissionDenied, @StringRes int rationaleTitle,
96+
@StringRes int rationaleMessage) {
7297
Dexter.withActivity(activity)
73-
.withPermission(permission)
74-
.withListener(new BasePermissionListener() {
75-
@Override
76-
public void onPermissionGranted(PermissionGrantedResponse response) {
77-
onPermissionGranted.run();
78-
}
98+
.withPermission(permission)
99+
.withListener(new BasePermissionListener() {
100+
@Override public void onPermissionGranted(PermissionGrantedResponse response) {
101+
onPermissionGranted.run();
102+
}
79103

80-
@Override
81-
public void onPermissionDenied(PermissionDeniedResponse response) {
82-
if (response.isPermanentlyDenied()) {
83-
DialogUtil.showAlertDialog(activity,
84-
activity.getString(rationaleTitle),
85-
activity.getString(rationaleMessage),
86-
activity.getString(R.string.navigation_item_settings),
87-
null,
88-
() -> askUserToManuallyEnablePermissionFromSettings(activity),
89-
null);
104+
@Override public void onPermissionDenied(PermissionDeniedResponse response) {
105+
if (response.isPermanentlyDenied()) {
106+
DialogUtil.showAlertDialog(activity, activity.getString(rationaleTitle),
107+
activity.getString(rationaleMessage),
108+
activity.getString(R.string.navigation_item_settings), null,
109+
() -> askUserToManuallyEnablePermissionFromSettings(activity), null);
110+
} else {
111+
if (null != onPermissionDenied) {
112+
onPermissionDenied.run();
90113
}
91114
}
115+
}
92116

93-
@Override
94-
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
95-
DialogUtil.showAlertDialog(activity,
96-
activity.getString(rationaleTitle),
97-
activity.getString(rationaleMessage),
98-
activity.getString(android.R.string.ok),
99-
activity.getString(android.R.string.cancel),
100-
token::continuePermissionRequest,
101-
token::cancelPermissionRequest);
102-
}
103-
}).check();
117+
@Override
118+
public void onPermissionRationaleShouldBeShown(PermissionRequest permission,
119+
PermissionToken token) {
120+
DialogUtil.showAlertDialog(activity, activity.getString(rationaleTitle),
121+
activity.getString(rationaleMessage),
122+
activity.getString(android.R.string.ok),
123+
activity.getString(android.R.string.cancel),
124+
token::continuePermissionRequest, token::cancelPermissionRequest);
125+
}
126+
})
127+
.check();
104128
}
105129
}

app/src/main/res/values/strings.xml

+2-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@
165165
<string name="menu_refresh">Refresh</string>
166166
<string name="storage_permission_title">Requesting Storage Permission</string>
167167
<string name="read_storage_permission_rationale">Required permission: Read external storage. App cannot access your gallery without this.</string>
168-
<string name="write_storage_permission_rationale">Required permission: Write external storage. App cannot access your camera without this.</string>
168+
<string name="write_storage_permission_rationale">Required permission: Write external storage. App cannot access your camera/gallery without this.</string>
169169
<string name="location_permission_rationale">Optional permission: Get current location for category suggestions</string>
170170
<string name="ok">OK</string>
171171
<string name="title_activity_nearby">Nearby Places</string>
@@ -472,4 +472,5 @@ Upload your first media by touching the camera or gallery icon above.</string>
472472
<string name="image_chooser_title">Choose Images to upload</string>
473473

474474
<string name="please_wait">Please wait…</string>
475+
<string name="download_failed_we_cannot_download_the_file_without_storage_permission">Download Failed!!. We cannot download the file without external storage permission.</string>
475476
</resources>

0 commit comments

Comments
 (0)