Use dexter for requesting storage permissions (#2258)

* Use dexter for requesting storage permissions

* minor changes

* Fix minor issue
This commit is contained in:
Vivek Maskara 2019-01-02 21:41:19 +05:30 committed by neslihanturan
parent 2ea6bd7f65
commit a48a09a785
13 changed files with 149 additions and 408 deletions

View file

@ -1,5 +1,6 @@
package fr.free.nrw.commons;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;

View file

@ -47,6 +47,7 @@ public class BookmarkLocationsFragment extends DaggerFragment {
@Inject
BookmarkLocationsController controller;
@Inject @Named("direct_nearby_upload_prefs") SharedPreferences directPrefs;
@Inject @Named("default_preferences") SharedPreferences defaultPrefs;
private NearbyAdapterFactory adapterFactory;
private ContributionController contributionController;
@ -66,7 +67,7 @@ public class BookmarkLocationsFragment extends DaggerFragment {
) {
View v = inflater.inflate(R.layout.fragment_bookmarks_locations, container, false);
ButterKnife.bind(this, v);
contributionController = new ContributionController(this);
contributionController = new ContributionController(this, defaultPrefs);
adapterFactory = new NearbyAdapterFactory(this, contributionController);
return v;
}
@ -100,30 +101,6 @@ public class BookmarkLocationsFragment extends DaggerFragment {
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Timber.d("onRequestPermissionsResult: req code = " + " perm = " + permissions + " grant =" + grantResults);
switch (requestCode) {
// 4 = "Read external storage" allowed when gallery selected
case 4: {
if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
Timber.d("Call controller.startGalleryPick()");
contributionController.startGalleryPick();
}
}
break;
// 5 = "Write external storage" allowed when camera selected
case 5: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Timber.d("Call controller.startCameraCapture()");
contributionController.startCameraCapture();
}
}
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

View file

@ -1,7 +1,10 @@
package fr.free.nrw.commons.contributions;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
@ -14,12 +17,24 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.FileProvider;
import com.karumi.dexter.Dexter;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.BasePermissionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.upload.UploadActivity;
import fr.free.nrw.commons.utils.DialogUtil;
import fr.free.nrw.commons.utils.PermissionUtils;
import fr.free.nrw.commons.utils.ViewUtil;
import timber.log.Timber;
import static android.content.Intent.ACTION_GET_CONTENT;
@ -34,14 +49,16 @@ import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ITEM_LOCAT
public class ContributionController {
public static final int SELECT_FROM_GALLERY = 1;
static final int SELECT_FROM_GALLERY = 1;
public static final int SELECT_FROM_CAMERA = 2;
public static final int PICK_IMAGE_MULTIPLE = 3;
static final int PICK_IMAGE_MULTIPLE = 3;
private Fragment fragment;
private SharedPreferences defaultPrefs;
public ContributionController(Fragment fragment) {
public ContributionController(Fragment fragment, SharedPreferences defaultSharedPrefs) {
this.fragment = fragment;
this.defaultPrefs = defaultSharedPrefs;
}
// See http://stackoverflow.com/a/5054673/17865 for why this is done
@ -58,6 +75,85 @@ public class ContributionController {
photoFile);
}
public void initiateCameraPick(Activity activity) {
boolean useExtStorage = defaultPrefs.getBoolean("useExternalStorage", true);
if (!useExtStorage) {
startCameraCapture();
return;
}
Dexter.withActivity(activity)
.withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(new BasePermissionListener() {
@Override
public void onPermissionGranted(PermissionGrantedResponse response) {
startCameraCapture();
}
@Override
public void onPermissionDenied(PermissionDeniedResponse response) {
if (response.isPermanentlyDenied()) {
DialogUtil.showAlertDialog(activity,
activity.getString(R.string.storage_permission_title),
activity.getString(R.string.write_storage_permission_rationale),
activity.getString(R.string.navigation_item_settings),
null,
() -> PermissionUtils.askUserToManuallyEnablePermissionFromSettings(activity),
null);
}
}
@Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
DialogUtil.showAlertDialog(activity,
activity.getString(R.string.storage_permission_title),
activity.getString(R.string.write_storage_permission_rationale),
activity.getString(android.R.string.ok),
activity.getString(android.R.string.cancel),
token::continuePermissionRequest,
token::cancelPermissionRequest);
}
}).check();
}
public void initiateGalleryPick(Activity activity) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
startGalleryPick();
} else {
Dexter.withActivity(activity)
.withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
.withListener(new BasePermissionListener() {
@Override
public void onPermissionGranted(PermissionGrantedResponse response) {
startCameraCapture();
}
@Override
public void onPermissionDenied(PermissionDeniedResponse response) {
if (response.isPermanentlyDenied()) {
DialogUtil.showAlertDialog(activity,
activity.getString(R.string.storage_permission_title),
activity.getString(R.string.read_storage_permission_rationale),
activity.getString(R.string.navigation_item_settings),
null,
() -> PermissionUtils.askUserToManuallyEnablePermissionFromSettings(activity),
null);
}
}
@Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
DialogUtil.showAlertDialog(activity,
activity.getString(R.string.storage_permission_title),
activity.getString(R.string.read_storage_permission_rationale),
activity.getString(android.R.string.ok),
activity.getString(android.R.string.cancel),
token::continuePermissionRequest,
token::cancelPermissionRequest);
}
}).check();
}
}
private static void requestWritePermission(Context context, Intent intent, Uri uri) {
List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent,
@ -69,7 +165,7 @@ public class ContributionController {
}
}
public void startCameraCapture() {
private void startCameraCapture() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
lastGeneratedCaptureUri = reGenerateImageCaptureUriInCache();
@ -84,7 +180,7 @@ public class ContributionController {
fragment.startActivityForResult(takePictureIntent, SELECT_FROM_CAMERA);
}
public void startGalleryPick() {
private void startGalleryPick() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
startMultipleGalleryPick();
} else {
@ -92,7 +188,7 @@ public class ContributionController {
}
}
public void startSingleGalleryPick() {
private void startSingleGalleryPick() {
//FIXME: Starts gallery (opens Google Photos)
Intent pickImageIntent = new Intent(ACTION_GET_CONTENT);
pickImageIntent.setType("image/*");
@ -107,7 +203,7 @@ public class ContributionController {
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public void startMultipleGalleryPick() {
private void startMultipleGalleryPick() {
Intent pickImageIntent = new Intent(ACTION_GET_CONTENT);
pickImageIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
pickImageIntent.setType("image/*");
@ -120,7 +216,7 @@ public class ContributionController {
fragment.startActivityForResult(pickImageIntent, PICK_IMAGE_MULTIPLE);
}
public void handleImagesPicked(int requestCode, @Nullable ArrayList<Uri> uri) {
void handleImagesPicked(int requestCode, @Nullable ArrayList<Uri> uri) {
FragmentActivity activity = fragment.getActivity();
Intent shareIntent = new Intent(activity, UploadActivity.class);
shareIntent.setAction(ACTION_SEND_MULTIPLE);

View file

@ -4,15 +4,12 @@ import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@ -26,7 +23,6 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Arrays;
import javax.inject.Inject;
import javax.inject.Named;
@ -36,11 +32,8 @@ import butterknife.ButterKnife;
import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.utils.PermissionUtils;
import timber.log.Timber;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.app.Activity.RESULT_OK;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.view.View.*;
@ -96,7 +89,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment {
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (controller == null) {
controller = new ContributionController(this);
controller = new ContributionController(this, defaultPrefs);
}
controller.loadState(savedInstanceState);
}
@ -107,7 +100,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment {
if (controller != null) {
controller.saveState(outState);
} else {
controller = new ContributionController(this);
controller = new ContributionController(this, defaultPrefs);
}
}
@ -130,88 +123,11 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment {
}
private void setListeners() {
fabPlus.setOnClickListener(view -> animateFAB(isFabOpen));
fabCamera.setOnClickListener(view -> {
boolean useExtStorage = defaultPrefs.getBoolean("useExternalStorage", true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && useExtStorage) {
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(getActivity(), WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
if (shouldShowRequestPermissionRationale(WRITE_EXTERNAL_STORAGE)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
new AlertDialog.Builder(getParentFragment().getActivity())
.setMessage(getString(R.string.write_storage_permission_rationale))
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
getActivity().requestPermissions
(new String[]{WRITE_EXTERNAL_STORAGE}, PermissionUtils.CAMERA_PERMISSION_FROM_CONTRIBUTION_LIST);
dialog.dismiss();
})
.setNegativeButton(android.R.string.cancel, null)
.create()
.show();
} else {
// No explanation needed, we can request the permission.
requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE},
3);
// MY_PERMISSIONS_WRITE_EXTERNAL_STORAGE is an
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
controller.startCameraCapture();
}
} else {
controller.startCameraCapture();
}
});
fabGallery.setOnClickListener(view -> {
// Gallery crashes before reach ShareActivity screen so must implement permissions check here
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(getActivity(), READ_EXTERNAL_STORAGE)
!= PERMISSION_GRANTED) {
// Should we show an explanation?
if (shouldShowRequestPermissionRationale(READ_EXTERNAL_STORAGE)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
new AlertDialog.Builder(getParentFragment().getActivity())
.setMessage(getString(R.string.read_storage_permission_rationale))
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
getActivity().requestPermissions
(new String[]{READ_EXTERNAL_STORAGE}, PermissionUtils.GALLERY_PERMISSION_FROM_CONTRIBUTION_LIST);
dialog.dismiss();
})
.setNegativeButton(android.R.string.cancel, null)
.create()
.show();
} else {
// No explanation needed, we can request the permission.
requestPermissions(new String[]{READ_EXTERNAL_STORAGE}, 1);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
controller.startGalleryPick();
}
} else {
controller.startGalleryPick();
}
controller.initiateCameraPick(getActivity());
});
fabGallery.setOnClickListener(view -> controller.initiateGalleryPick(getActivity()));
}
private void animateFAB(boolean isFabOpen) {
@ -260,40 +176,6 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment {
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Timber.d("onRequestPermissionsResult: req code = " + " perm = "
+ Arrays.toString(permissions) + " grant =" + Arrays.toString(grantResults));
switch (requestCode) {
// 1 = Storage allowed when gallery selected
case 1: {
if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
Timber.d("Call controller.startGalleryPick()");
controller.startGalleryPick();
}
}
break;
// 2 = Location allowed when 'nearby places' selected
case 2: {
// TODO: understand and fix
/*if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
Timber.d("Location permission granted");
Intent nearbyIntent = new Intent(getActivity(), MainActivity.class);
startActivity(nearbyIntent);
}*/
}
break;
case 3: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Timber.d("Call controller.startCameraCapture()");
controller.startCameraCapture();
}
}
}
}
private void handleMultipleImages(int requestCode, Intent data) {
if (getContext() == null) {
return;

View file

@ -477,60 +477,6 @@ public class MainActivity extends AuthenticatedActivity implements FragmentManag
}
return;
}
// Storage permission for gallery
case PermissionUtils.GALLERY_PERMISSION_FROM_CONTRIBUTION_LIST: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Storage permission given
ContributionsListFragment contributionsListFragment =
(ContributionsListFragment) contributionsActivityPagerAdapter
.getItem(0).getChildFragmentManager()
.findFragmentByTag(ContributionsFragment.CONTRIBUTION_LIST_FRAGMENT_TAG);
contributionsListFragment.controller.startGalleryPick();
}
return;
}
case PermissionUtils.CAMERA_PERMISSION_FROM_CONTRIBUTION_LIST: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Storage permission given
ContributionsListFragment contributionsListFragment =
(ContributionsListFragment) contributionsActivityPagerAdapter
.getItem(0).getChildFragmentManager()
.findFragmentByTag(ContributionsFragment.CONTRIBUTION_LIST_FRAGMENT_TAG);
contributionsListFragment.controller.startCameraCapture();
}
return;
}
case PermissionUtils.CAMERA_PERMISSION_FROM_NEARBY_MAP: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Storage permission given
NearbyMapFragment nearbyMapFragment =
((NearbyFragment) contributionsActivityPagerAdapter
.getItem(1)).nearbyMapFragment;
nearbyMapFragment.controller.startCameraCapture();
}
return;
}
case PermissionUtils.GALLERY_PERMISSION_FROM_NEARBY_MAP: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Storage permission given
NearbyMapFragment nearbyMapFragment =
((NearbyFragment) contributionsActivityPagerAdapter
.getItem(1)).nearbyMapFragment;
nearbyMapFragment.controller.startGalleryPick();
}
return;
}
default:
return;

View file

@ -1,111 +0,0 @@
package fr.free.nrw.commons.nearby;
import android.app.Activity;
import android.os.Build;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.contributions.ContributionController;
import fr.free.nrw.commons.utils.PermissionUtils;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
/**
* Initiates the uploads made from a Nearby Place, in both the list and map views.
*/
class DirectUpload {
private ContributionController controller;
private Fragment fragment;
DirectUpload(Fragment fragment, ContributionController controller) {
this.fragment = fragment;
this.controller = controller;
}
/**
* Initiates the upload if user selects the Gallery FAB.
* The permission requests will be handled by the Fragments.
* Do not use requestCode 1 as it will conflict with NearbyFragment's requestCodes.
*/
void initiateGalleryUpload() {
// Only need to handle permissions for Marshmallow and above
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return;
}
Activity parentActivity = fragment.getActivity();
if (parentActivity == null) {
controller.startSingleGalleryPick();
return;
}
// If we have permission, go ahead
if (ContextCompat.checkSelfPermission(parentActivity, READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED) {
controller.startSingleGalleryPick();
return;
}
// If we don't have permission, and we need to show the rationale, show the rationale
if (fragment.shouldShowRequestPermissionRationale(READ_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(parentActivity)
.setMessage(parentActivity.getString(R.string.read_storage_permission_rationale))
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
parentActivity.requestPermissions(new String[]{READ_EXTERNAL_STORAGE}, PermissionUtils.GALLERY_PERMISSION_FROM_NEARBY_MAP);
dialog.dismiss();
})
.setNegativeButton(android.R.string.cancel, null)
.create()
.show();
return;
}
// If we don't have permission, and we don't need to show rationale just request permission
parentActivity.requestPermissions(new String[]{READ_EXTERNAL_STORAGE}, PermissionUtils.GALLERY_PERMISSION_FROM_NEARBY_MAP);
}
/**
* Initiates the upload if user selects the Camera FAB.
* The permission requests will be handled by the Fragments.
* Do not use requestCode 1 as it will conflict with NearbyFragment's requestCodes.
*/
void initiateCameraUpload() {
// Only need to handle permissions for Marshmallow and above
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return;
}
Activity parentActivity = fragment.getActivity();
if (parentActivity == null) {
controller.startCameraCapture();
return;
}
// If we have permission, go ahead
if (ContextCompat.checkSelfPermission(parentActivity, WRITE_EXTERNAL_STORAGE) == PERMISSION_GRANTED) {
controller.startCameraCapture();
return;
}
// If we don't have permission, and we need to show the rationale, show the rationale
if (fragment.shouldShowRequestPermissionRationale(WRITE_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(parentActivity)
.setMessage(parentActivity.getString(R.string.write_storage_permission_rationale))
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
parentActivity.requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE}, PermissionUtils.CAMERA_PERMISSION_FROM_NEARBY_MAP);
dialog.dismiss();
})
.setNegativeButton(android.R.string.cancel, null)
.create()
.show();
return;
}
// If we don't have permission, and we don't need to show rationale just request permission
parentActivity.requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE}, PermissionUtils.CAMERA_PERMISSION_FROM_NEARBY_MAP);
}
}

View file

@ -54,9 +54,8 @@ public class NearbyListFragment extends DaggerFragment {
private ContributionController controller;
@Inject
@Named("direct_nearby_upload_prefs")
SharedPreferences directPrefs;
@Inject @Named("direct_nearby_upload_prefs") SharedPreferences directPrefs;
@Inject @Named("default_preferences") SharedPreferences defaultPrefs;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -79,7 +78,7 @@ public class NearbyListFragment extends DaggerFragment {
recyclerView = view.findViewById(R.id.listView);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
controller = new ContributionController(this);
controller = new ContributionController(this, defaultPrefs);
adapterFactory = new NearbyAdapterFactory(this, controller);
return view;
}
@ -139,31 +138,6 @@ public class NearbyListFragment extends DaggerFragment {
return placeList;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Timber.d("onRequestPermissionsResult: req code = " + " perm = " + permissions + " grant =" + grantResults);
switch (requestCode) {
// 4 = "Read external storage" allowed when gallery selected
case 4: {
if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
Timber.d("Call controller.startGalleryPick()");
controller.startGalleryPick();
}
}
break;
// 5 = "Write external storage" allowed when camera selected
case 5: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Timber.d("Call controller.startCameraCapture()");
controller.startCameraCapture();
}
}
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

View file

@ -112,7 +112,6 @@ public class NearbyMapFragment extends DaggerFragment {
private Animation fab_open;
private Animation rotate_forward;
public ContributionController controller;
private DirectUpload directUpload;
private Place place;
private Marker selected;
@ -137,6 +136,9 @@ public class NearbyMapFragment extends DaggerFragment {
@Named("prefs")
SharedPreferences prefs;
@Inject
@Named("default_preferences")
SharedPreferences defaultPrefs;
@Inject
@Named("direct_nearby_upload_prefs")
SharedPreferences directPrefs;
@Inject
@ -152,9 +154,7 @@ public class NearbyMapFragment extends DaggerFragment {
super.onCreate(savedInstanceState);
Timber.d("Nearby map fragment created");
controller = new ContributionController(this);
directUpload = new DirectUpload(this, controller);
controller = new ContributionController(this, defaultPrefs);
Bundle bundle = this.getArguments();
Gson gson = new GsonBuilder()
.registerTypeAdapter(Uri.class, new UriDeserializer())
@ -862,7 +862,7 @@ public class NearbyMapFragment extends DaggerFragment {
if (fabCamera.isShown()) {
Timber.d("Camera button tapped. Place: %s", place.toString());
storeSharedPrefs();
directUpload.initiateCameraUpload();
controller.initiateCameraPick(getActivity());
}
});
@ -870,7 +870,7 @@ public class NearbyMapFragment extends DaggerFragment {
if (fabGallery.isShown()) {
Timber.d("Gallery button tapped. Place: %s", place.toString());
storeSharedPrefs();
directUpload.initiateGalleryUpload();
controller.initiateGalleryPick(getActivity());
}
});
}
@ -885,31 +885,6 @@ public class NearbyMapFragment extends DaggerFragment {
editor.apply();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Timber.d("onRequestPermissionsResult: req code = " + " perm = " + permissions + " grant =" + grantResults);
// Do not use requestCode 1 as it will conflict with NearbyFragment's requestCodes
switch (requestCode) {
// 4 = "Read external storage" allowed when gallery selected
case 4: {
if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
Timber.d("Call controller.startGalleryPick()");
controller.startGalleryPick();
}
}
break;
// 5 = "Write external storage" allowed when camera selected
case 5: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Timber.d("Call controller.startCameraCapture()");
controller.startCameraCapture();
}
}
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

View file

@ -72,6 +72,9 @@ public class PlaceRenderer extends Renderer<Place> {
BookmarkLocationsDao bookmarkLocationDao;
@Inject @Named("prefs") SharedPreferences prefs;
@Inject @Named("direct_nearby_upload_prefs") SharedPreferences directPrefs;
@Inject
@Named("default_preferences")
SharedPreferences defaultPrefs;
public PlaceRenderer(){
openedItems = new ArrayList<>();
@ -138,9 +141,8 @@ public class PlaceRenderer extends Renderer<Place> {
.show();
} else {
Timber.d("Camera button tapped. Image title: " + place.getName() + "Image desc: " + place.getLongDescription());
DirectUpload directUpload = new DirectUpload(fragment, controller);
storeSharedPrefs();
directUpload.initiateCameraUpload();
controller.initiateCameraPick(fragment.getActivity());
}
});
@ -159,9 +161,8 @@ public class PlaceRenderer extends Renderer<Place> {
.show();
}else {
Timber.d("Gallery button tapped. Image title: " + place.getName() + "Image desc: " + place.getLongDescription());
DirectUpload directUpload = new DirectUpload(fragment, controller);
storeSharedPrefs();
directUpload.initiateGalleryUpload();
controller.initiateGalleryPick(fragment.getActivity());
}
});

View file

@ -143,19 +143,23 @@ public class DialogUtil {
builder.setTitle(title);
builder.setMessage(message);
builder.setPositiveButton(positiveButtonText, (dialogInterface, i) -> {
dialogInterface.dismiss();
if (onPositiveBtnClick != null) {
onPositiveBtnClick.run();
}
});
if (!StringUtils.isNullOrWhiteSpace(positiveButtonText)) {
builder.setPositiveButton(positiveButtonText, (dialogInterface, i) -> {
dialogInterface.dismiss();
if (onPositiveBtnClick != null) {
onPositiveBtnClick.run();
}
});
}
builder.setNegativeButton(negativeButtonText, (DialogInterface dialogInterface, int i) -> {
dialogInterface.dismiss();
if (onNegativeBtnClick != null) {
onNegativeBtnClick.run();
}
});
if (!StringUtils.isNullOrWhiteSpace(negativeButtonText)) {
builder.setNegativeButton(negativeButtonText, (DialogInterface dialogInterface, int i) -> {
dialogInterface.dismiss();
if (onNegativeBtnClick != null) {
onNegativeBtnClick.run();
}
});
}
AlertDialog dialog = builder.create();
showSafely(activity, dialog);
@ -179,13 +183,13 @@ public class DialogUtil {
onPositiveBtnClick,
onNegativeBtnClick,
customView,
false);
cancelable);
}
/*
Shows alert dialog with custom view
*/
private static void showAlertDialog(Activity activity,
public static void showAlertDialog(Activity activity,
String title,
String message,
String positiveButtonText,

View file

@ -12,11 +12,6 @@ import fr.free.nrw.commons.CommonsApplication;
public class PermissionUtils {
public static final int CAMERA_PERMISSION_FROM_CONTRIBUTION_LIST = 100;
public static final int GALLERY_PERMISSION_FROM_CONTRIBUTION_LIST = 101;
public static final int CAMERA_PERMISSION_FROM_NEARBY_MAP = 102;
public static final int GALLERY_PERMISSION_FROM_NEARBY_MAP = 103;
/**
* This method can be used by any activity which requires a permission which has been blocked(marked never ask again by the user)
It open the app settings from where the user can manually give us the required permission.

View file

@ -6,9 +6,7 @@ import android.support.annotation.StringRes;
import android.support.design.widget.Snackbar;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.PopupWindow;
import android.widget.Toast;
public class ViewUtil {
@ -85,14 +83,16 @@ public class ViewUtil {
* A snack bar which has an action button which on click dismisses the snackbar and invokes the
* listener passed
*/
public static void showDismissibleSnackBar(View view, int messageResourceId,
int actionButtonResourceId, View.OnClickListener onClickListener) {
public static void showDismissibleSnackBar(View view,
int messageResourceId,
int actionButtonResourceId,
View.OnClickListener onClickListener) {
if (view.getContext() == null) {
return;
}
ExecutorUtils.uiExecutor().execute(() -> {
Snackbar snackbar = Snackbar.make(view, view.getContext().getString(messageResourceId),
Snackbar.LENGTH_INDEFINITE);
Snackbar.LENGTH_INDEFINITE);
snackbar.setAction(view.getContext().getString(actionButtonResourceId), v -> {
snackbar.dismiss();
onClickListener.onClick(v);

View file

@ -163,6 +163,7 @@
<string name="detail_description_empty">No description</string>
<string name="detail_license_empty">Unknown license</string>
<string name="menu_refresh">Refresh</string>
<string name="storage_permission_title">Requesting Storage Permission</string>
<string name="read_storage_permission_rationale">Required permission: Read external storage. App cannot access your gallery without this.</string>
<string name="write_storage_permission_rationale">Required permission: Write external storage. App cannot access your camera without this.</string>
<string name="location_permission_rationale">Optional permission: Get current location for category suggestions</string>