mirror of
				https://github.com/commons-app/apps-android-commons.git
				synced 2025-10-31 06:43:56 +01:00 
			
		
		
		
	Merge 2.10 with master & Fixed merge conflicts (#2844)
This commit is contained in:
		
							parent
							
								
									02ad3b2dc8
								
							
						
					
					
						commit
						08a555c095
					
				
					 18 changed files with 172 additions and 113 deletions
				
			
		|  | @ -63,12 +63,8 @@ public class Utils { | |||
|                 return R.string.license_name_cc_by_sa_four; | ||||
|             case Prefs.Licenses.CC0: | ||||
|                 return R.string.license_name_cc0; | ||||
|             case Prefs.Licenses.CC_BY:  // for backward compatibility to v2.1 | ||||
|                 return R.string.license_name_cc_by_3_0; | ||||
|             case Prefs.Licenses.CC_BY_SA:  // for backward compatibility to v2.1 | ||||
|                 return R.string.license_name_cc_by_sa_3_0; | ||||
|         } | ||||
|         throw new RuntimeException("Unrecognized license value: " + license); | ||||
|         throw new IllegalStateException("Unrecognized license value: " + license); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -92,7 +88,7 @@ public class Utils { | |||
|             case Prefs.Licenses.CC0: | ||||
|                 return "https://creativecommons.org/publicdomain/zero/1.0/"; | ||||
|             default: | ||||
|                 throw new RuntimeException("Unrecognized license value: " + license); | ||||
|                 throw new IllegalStateException("Unrecognized license value: " + license); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -6,17 +6,15 @@ import android.database.Cursor; | |||
| import android.database.sqlite.SQLiteDatabase; | ||||
| import android.os.RemoteException; | ||||
| import androidx.annotation.NonNull; | ||||
| import fr.free.nrw.commons.bookmarks.Bookmark; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
| import javax.inject.Provider; | ||||
| import javax.inject.Singleton; | ||||
| 
 | ||||
| import fr.free.nrw.commons.bookmarks.Bookmark; | ||||
| 
 | ||||
| import static fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesContentProvider.BASE_URI; | ||||
| 
 | ||||
| @Singleton | ||||
|  | @ -121,6 +119,10 @@ public class BookmarkPicturesDao { | |||
|      * @return boolean : is bookmark in database ? | ||||
|      */ | ||||
|     public boolean findBookmark(Bookmark bookmark) { | ||||
|         if (bookmark == null) {//Avoiding NPE's | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         Cursor cursor = null; | ||||
|         ContentProviderClient db = clientProvider.get(); | ||||
|         try { | ||||
|  |  | |||
|  | @ -259,10 +259,6 @@ public class  Contribution extends Media { | |||
|                 return "{{self|cc-by-sa-4.0}}"; | ||||
|             case Prefs.Licenses.CC0: | ||||
|                 return "{{self|cc-zero}}"; | ||||
|             case Prefs.Licenses.CC_BY: | ||||
|                 return "{{self|cc-by-3.0}}"; | ||||
|             case Prefs.Licenses.CC_BY_SA: | ||||
|                 return "{{self|cc-by-sa-3.0}}"; | ||||
|         } | ||||
| 
 | ||||
|         throw new RuntimeException("Unrecognized license value: " + license); | ||||
|  |  | |||
|  | @ -9,10 +9,9 @@ import android.net.Uri; | |||
| import android.os.RemoteException; | ||||
| import androidx.annotation.Nullable; | ||||
| import android.text.TextUtils; | ||||
| import fr.free.nrw.commons.settings.Prefs; | ||||
| 
 | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| 
 | ||||
| import fr.free.nrw.commons.settings.Prefs; | ||||
| import java.util.Date; | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
|  | @ -320,7 +319,7 @@ public class ContributionDao { | |||
|             try { | ||||
|                 db.execSQL(query); | ||||
|             } catch (SQLiteException e) { | ||||
|                 Timber.e(e, "Exception performing query: " + query); | ||||
|                 Timber.e("Exception performing query: " + query + " message: " + e.getMessage()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,26 +2,20 @@ package fr.free.nrw.commons.explore; | |||
| 
 | ||||
| import android.database.DataSetObserver; | ||||
| import android.os.Bundle; | ||||
| import com.google.android.material.tabs.TabLayout; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentManager; | ||||
| import androidx.fragment.app.FragmentTransaction; | ||||
| import androidx.viewpager.widget.ViewPager; | ||||
| import androidx.appcompat.widget.Toolbar; | ||||
| import android.text.TextUtils; | ||||
| import android.view.View; | ||||
| import android.widget.FrameLayout; | ||||
| import android.widget.SearchView; | ||||
| 
 | ||||
| import com.jakewharton.rxbinding2.view.RxView; | ||||
| import com.jakewharton.rxbinding2.widget.RxSearchView; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| import androidx.appcompat.widget.Toolbar; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentManager; | ||||
| import androidx.fragment.app.FragmentTransaction; | ||||
| import androidx.viewpager.widget.ViewPager; | ||||
| import butterknife.BindView; | ||||
| import butterknife.ButterKnife; | ||||
| import com.google.android.material.tabs.TabLayout; | ||||
| import com.jakewharton.rxbinding2.view.RxView; | ||||
| import com.jakewharton.rxbinding2.widget.RxSearchView; | ||||
| import fr.free.nrw.commons.Media; | ||||
| import fr.free.nrw.commons.R; | ||||
| import fr.free.nrw.commons.explore.categories.SearchCategoryFragment; | ||||
|  | @ -29,8 +23,12 @@ import fr.free.nrw.commons.explore.images.SearchImageFragment; | |||
| import fr.free.nrw.commons.explore.recentsearches.RecentSearchesFragment; | ||||
| import fr.free.nrw.commons.media.MediaDetailPagerFragment; | ||||
| import fr.free.nrw.commons.theme.NavigationBaseActivity; | ||||
| import fr.free.nrw.commons.utils.FragmentUtils; | ||||
| import fr.free.nrw.commons.utils.ViewUtil; | ||||
| import io.reactivex.android.schedulers.AndroidSchedulers; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| /** | ||||
|  * Represents search screen of this app | ||||
|  | @ -109,8 +107,13 @@ public class SearchActivity extends NavigationBaseActivity implements MediaDetai | |||
|                                 viewPager.setVisibility(View.VISIBLE); | ||||
|                                 tabLayout.setVisibility(View.VISIBLE); | ||||
|                                 searchHistoryContainer.setVisibility(View.GONE); | ||||
|                                 searchImageFragment.updateImageList(query.toString()); | ||||
|                                 searchCategoryFragment.updateCategoryList(query.toString()); | ||||
|                                 if (FragmentUtils.isFragmentUIActive(searchImageFragment)) { | ||||
|                                     searchImageFragment.updateImageList(query.toString()); | ||||
|                                 } | ||||
| 
 | ||||
|                                 if (FragmentUtils.isFragmentUIActive(searchCategoryFragment)) { | ||||
|                                     searchCategoryFragment.updateCategoryList(query.toString()); | ||||
|                                 } | ||||
|                             }else { | ||||
|                                 //Open RecentSearchesFragment | ||||
|                                 recentSearchesFragment.updateRecentSearches(); | ||||
|  | @ -261,4 +264,10 @@ public class SearchActivity extends NavigationBaseActivity implements MediaDetai | |||
|             searchImageFragment.addImagesToList(query); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override protected void onDestroy() { | ||||
|         super.onDestroy(); | ||||
|         //Dispose the disposables when the activity is destroyed | ||||
|         compositeDisposable.dispose(); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,5 @@ | |||
| package fr.free.nrw.commons.explore.images; | ||||
| 
 | ||||
| 
 | ||||
| import android.annotation.SuppressLint; | ||||
| import android.content.res.Configuration; | ||||
| import android.os.Bundle; | ||||
|  | @ -228,8 +227,15 @@ public class SearchImageFragment extends CommonsDaggerSupportFragment { | |||
|      * Handles the UI updates for no internet scenario | ||||
|      */ | ||||
|     private void handleNoInternet() { | ||||
|         progressBar.setVisibility(GONE); | ||||
|         ViewUtil.showShortSnackbar(imagesRecyclerView, R.string.no_internet); | ||||
|         if (null | ||||
|             != getView()) {//We have exposed public methods to update our ui, we will have to add null checks until we make this lifecycle aware | ||||
|             if (null != progressBar) { | ||||
|                 progressBar.setVisibility(GONE); | ||||
|             } | ||||
|             ViewUtil.showShortSnackbar(imagesRecyclerView, R.string.no_internet); | ||||
|         } else { | ||||
|             Timber.d("Attempt to update fragment ui after its view was destroyed"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -257,4 +263,9 @@ public class SearchImageFragment extends CommonsDaggerSupportFragment { | |||
|             return imagesAdapter.getItem(i); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override public void onDestroyView() { | ||||
|         super.onDestroyView(); | ||||
|         compositeDisposable.clear(); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -52,6 +52,12 @@ import io.reactivex.Single; | |||
| import io.reactivex.android.schedulers.AndroidSchedulers; | ||||
| import io.reactivex.disposables.Disposable; | ||||
| import io.reactivex.schedulers.Schedulers; | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Date; | ||||
| import java.util.Locale; | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Provider; | ||||
| import timber.log.Timber; | ||||
| 
 | ||||
| import static android.view.View.GONE; | ||||
|  | @ -285,6 +291,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment { | |||
|             detailProvider.unregisterDataSetObserver(dataObserver); | ||||
|             dataObserver = null; | ||||
|         } | ||||
|         compositeDisposable.clear(); | ||||
|         super.onDestroyView(); | ||||
|     } | ||||
| 
 | ||||
|  | @ -414,9 +421,12 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment { | |||
|                 .subscribeOn(Schedulers.io()) | ||||
|                 .observeOn(AndroidSchedulers.mainThread()) | ||||
|                 .subscribe(s -> { | ||||
|                     isDeleted = true; | ||||
|                     enableDeleteButton(false); | ||||
|                     if (getActivity() != null) { | ||||
|                         isDeleted = true; | ||||
|                         enableDeleteButton(false); | ||||
|                     } | ||||
|                 })); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @OnClick(R.id.seeMore) | ||||
|  | @ -540,4 +550,5 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment { | |||
|             nominatedForDeletion.setVisibility(GONE); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -5,7 +5,6 @@ import android.app.DownloadManager; | |||
| import android.content.Intent; | ||||
| import android.database.DataSetObserver; | ||||
| import android.net.Uri; | ||||
| import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| import android.os.Environment; | ||||
| import android.os.Handler; | ||||
|  | @ -15,14 +14,12 @@ import android.view.MenuInflater; | |||
| import android.view.MenuItem; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.Toast; | ||||
| 
 | ||||
| import com.google.android.material.snackbar.Snackbar; | ||||
| 
 | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
| 
 | ||||
| import androidx.core.app.ActivityCompat; | ||||
| import androidx.core.content.ContextCompat; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentManager; | ||||
| import androidx.fragment.app.FragmentStatePagerAdapter; | ||||
|  | @ -44,12 +41,12 @@ import fr.free.nrw.commons.kvstore.JsonKvStore; | |||
| import fr.free.nrw.commons.mwapi.MediaWikiApi; | ||||
| 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 timber.log.Timber; | ||||
| 
 | ||||
| import static android.Manifest.permission.READ_EXTERNAL_STORAGE; | ||||
| import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; | ||||
| import static android.content.Context.DOWNLOAD_SERVICE; | ||||
| import static android.content.pm.PackageManager.PERMISSION_GRANTED; | ||||
| import static fr.free.nrw.commons.Utils.handleWebUrl; | ||||
| 
 | ||||
| public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment implements ViewPager.OnPageChangeListener { | ||||
|  | @ -227,20 +224,19 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple | |||
|         // 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); | ||||
| 
 | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && | ||||
|                 ContextCompat.checkSelfPermission(getContext(), READ_EXTERNAL_STORAGE) | ||||
|                         != PERMISSION_GRANTED | ||||
|                 && getView() != null) { | ||||
|             Snackbar.make(getView(), R.string.read_storage_permission_rationale, | ||||
|                     Snackbar.LENGTH_INDEFINITE).setAction(R.string.ok, | ||||
|                     view -> ActivityCompat.requestPermissions(getActivity(), | ||||
|                             new String[]{READ_EXTERNAL_STORAGE}, 1)).show(); | ||||
|         } else { | ||||
|             DownloadManager systemService = (DownloadManager) getActivity().getSystemService(DOWNLOAD_SERVICE); | ||||
|             if (systemService != null) { | ||||
|                 systemService.enqueue(req); | ||||
|             } | ||||
|     } | ||||
| 
 | ||||
|     private void enqueueRequest(DownloadManager.Request req) { | ||||
|         DownloadManager systemService = | ||||
|             (DownloadManager) getActivity().getSystemService(DOWNLOAD_SERVICE); | ||||
|         if (systemService != null) { | ||||
|             systemService.enqueue(req); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -69,6 +69,10 @@ public class CustomMwApi { | |||
|     } | ||||
| 
 | ||||
|     public void setAuthCookie(String authCookie) { | ||||
|         if (authCookie == null) {//If the authCookie is null, no need to proceed | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         this.authCookie = authCookie; | ||||
|         this.isLoggedIn = true; | ||||
|         String[] cookies = authCookie.split(";"); | ||||
|  |  | |||
|  | @ -319,10 +319,13 @@ public class OkHttpJsonApiClient { | |||
|             if (response.body() != null && response.isSuccessful()) { | ||||
|                 String json = response.body().string(); | ||||
|                 MwQueryResponse mwQueryResponse = gson.fromJson(json, MwQueryResponse.class); | ||||
|                 putContinueValues(keyword, mwQueryResponse.continuation()); | ||||
|                 if (mwQueryResponse.query() == null) { | ||||
|                 if (null == mwQueryResponse | ||||
|                     || null == mwQueryResponse.query() | ||||
|                     || null == mwQueryResponse.query().pages()) { | ||||
|                     return mediaList; | ||||
|                 } | ||||
|                 putContinueValues(keyword, mwQueryResponse.continuation()); | ||||
| 
 | ||||
|                 List<MwQueryPage> pages = mwQueryResponse.query().pages(); | ||||
|                 for (MwQueryPage page : pages) { | ||||
|                     Media media = Media.from(page); | ||||
|  |  | |||
|  | @ -14,9 +14,5 @@ public class Prefs { | |||
|         public static final String CC_BY_SA_4 = "CC BY-SA 4.0"; | ||||
|         public static final String CC_BY_4 = "CC BY 4.0"; | ||||
|         public static final String CC0 = "CC0"; | ||||
| 
 | ||||
|         // kept for backward compatibility to v2.1 | ||||
|         @Deprecated public static final String CC_BY = "CC BY"; | ||||
|         @Deprecated public static final String CC_BY_SA = "CC BY-SA"; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -2,18 +2,8 @@ package fr.free.nrw.commons.upload; | |||
| 
 | ||||
| import android.annotation.SuppressLint; | ||||
| import android.content.Context; | ||||
| 
 | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| 
 | ||||
| import java.lang.reflect.Proxy; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
| import javax.inject.Singleton; | ||||
| 
 | ||||
| import fr.free.nrw.commons.R; | ||||
| import fr.free.nrw.commons.Utils; | ||||
| import fr.free.nrw.commons.category.CategoriesModel; | ||||
| import fr.free.nrw.commons.contributions.Contribution; | ||||
| import fr.free.nrw.commons.filepicker.UploadableFile; | ||||
|  | @ -31,6 +21,7 @@ import java.util.List; | |||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
| import javax.inject.Singleton; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| import timber.log.Timber; | ||||
| 
 | ||||
| import static fr.free.nrw.commons.upload.UploadModel.UploadItem; | ||||
|  | @ -334,7 +325,15 @@ public class UploadPresenter { | |||
|      * Sets the list of licences and the default license. | ||||
|      */ | ||||
|     private void updateLicenses() { | ||||
|         String selectedLicense = directKvStore.getString(Prefs.DEFAULT_LICENSE, Prefs.Licenses.CC_BY_SA_3); | ||||
|         String selectedLicense = directKvStore.getString(Prefs.DEFAULT_LICENSE, | ||||
|             Prefs.Licenses.CC_BY_SA_4);//CC_BY_SA_4 is the default one used by the commons web app | ||||
|         try {//I have to make sure that the stored default license was not one of the deprecated one's | ||||
|             Utils.licenseNameFor(selectedLicense); | ||||
|         } catch (IllegalStateException exception) { | ||||
|             Timber.e(exception.getMessage()); | ||||
|             selectedLicense = Prefs.Licenses.CC_BY_SA_4; | ||||
|             directKvStore.putString(Prefs.DEFAULT_LICENSE, Prefs.Licenses.CC_BY_SA_4); | ||||
|         } | ||||
|         view.updateLicenses(uploadModel.getLicenses(), selectedLicense); | ||||
|         view.updateLicenseSummary(selectedLicense, uploadModel.getCount()); | ||||
|     } | ||||
|  |  | |||
|  | @ -10,6 +10,6 @@ public class FragmentUtils { | |||
|      * @return | ||||
|      */ | ||||
|     public static boolean isFragmentUIActive(Fragment fragment) { | ||||
|         return fragment.getActivity() != null && fragment.isAdded() && !fragment.isDetached() && !fragment.isRemoving(); | ||||
|         return fragment!=null && fragment.getActivity() != null && fragment.isAdded() && !fragment.isDetached() && !fragment.isRemoving(); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -14,7 +14,6 @@ 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 fr.free.nrw.commons.CommonsApplication; | ||||
| import fr.free.nrw.commons.R; | ||||
| 
 | ||||
|  | @ -64,42 +63,68 @@ public class PermissionUtils { | |||
|      * @param rationaleTitle rationale title to be displayed when permission was denied | ||||
|      * @param rationaleMessage rationale message to be displayed when permission was denied | ||||
|      */ | ||||
|     public static void checkPermissionsAndPerformAction(Activity activity, | ||||
|                                                   String permission, | ||||
|                                                   Runnable onPermissionGranted, | ||||
|                                                   @StringRes int rationaleTitle, | ||||
|                                                   @StringRes int rationaleMessage) { | ||||
|         Dexter.withActivity(activity) | ||||
|                 .withPermission(permission) | ||||
|                 .withListener(new BasePermissionListener() { | ||||
|                     @Override | ||||
|                     public void onPermissionGranted(PermissionGrantedResponse response) { | ||||
|                         onPermissionGranted.run(); | ||||
|                     } | ||||
|     public static void checkPermissionsAndPerformAction(Activity activity, String permission, | ||||
|         Runnable onPermissionGranted, @StringRes int rationaleTitle, | ||||
|         @StringRes int rationaleMessage) { | ||||
|         checkPermissionsAndPerformAction(activity, permission, onPermissionGranted, null, | ||||
|             rationaleTitle, rationaleMessage); | ||||
|     } | ||||
| 
 | ||||
|                     @Override | ||||
|                     public void onPermissionDenied(PermissionDeniedResponse response) { | ||||
|                         if (response.isPermanentlyDenied()) { | ||||
|                             DialogUtil.showAlertDialog(activity, | ||||
|                                     activity.getString(rationaleTitle), | ||||
|                                     activity.getString(rationaleMessage), | ||||
|                                     activity.getString(R.string.navigation_item_settings), | ||||
|                                     null, | ||||
|                                     () -> askUserToManuallyEnablePermissionFromSettings(activity), | ||||
|                                     null); | ||||
|     /** | ||||
|      * Checks for a particular permission and runs the corresponding runnables to perform an action when the permission is granted/denied | ||||
|      * Also, it shows a rationale if needed | ||||
|      * | ||||
|      * Sample usage: | ||||
|      * | ||||
|      * PermissionUtils.checkPermissionsAndPerformAction(activity, | ||||
|      *                 Manifest.permission.WRITE_EXTERNAL_STORAGE, | ||||
|      *                 () -> initiateCameraUpload(activity), | ||||
|      *                 () -> showMessage(), | ||||
|      *                 R.string.storage_permission_title, | ||||
|      *                 R.string.write_storage_permission_rationale); | ||||
|      * | ||||
|      * | ||||
|      * @param activity activity requesting permissions | ||||
|      * @param permission the permission being requests | ||||
|      * @param onPermissionGranted the runnable to be executed when the permission is granted | ||||
|      * @param onPermissionDenied the runnable to be executed when the permission is denied(but not permanently) | ||||
|      * @param rationaleTitle rationale title to be displayed when permission was denied | ||||
|      * @param rationaleMessage rationale message to be displayed when permission was denied | ||||
|      */ | ||||
| 
 | ||||
|     public static void checkPermissionsAndPerformAction(Activity activity, String permission, | ||||
|         Runnable onPermissionGranted, Runnable onPermissionDenied, @StringRes int rationaleTitle, | ||||
|         @StringRes int rationaleMessage) { | ||||
|         Dexter.withActivity(activity) | ||||
|             .withPermission(permission) | ||||
|             .withListener(new BasePermissionListener() { | ||||
|                 @Override public void onPermissionGranted(PermissionGrantedResponse response) { | ||||
|                     onPermissionGranted.run(); | ||||
|                 } | ||||
| 
 | ||||
|                 @Override public void onPermissionDenied(PermissionDeniedResponse response) { | ||||
|                     if (response.isPermanentlyDenied()) { | ||||
|                         DialogUtil.showAlertDialog(activity, activity.getString(rationaleTitle), | ||||
|                             activity.getString(rationaleMessage), | ||||
|                             activity.getString(R.string.navigation_item_settings), null, | ||||
|                             () -> askUserToManuallyEnablePermissionFromSettings(activity), null); | ||||
|                     } else { | ||||
|                         if (null != onPermissionDenied) { | ||||
|                             onPermissionDenied.run(); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                     @Override | ||||
|                     public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) { | ||||
|                         DialogUtil.showAlertDialog(activity, | ||||
|                                 activity.getString(rationaleTitle), | ||||
|                                 activity.getString(rationaleMessage), | ||||
|                                 activity.getString(android.R.string.ok), | ||||
|                                 activity.getString(android.R.string.cancel), | ||||
|                                 token::continuePermissionRequest, | ||||
|                                 token::cancelPermissionRequest); | ||||
|                     } | ||||
|                 }).check(); | ||||
|                 @Override | ||||
|                 public void onPermissionRationaleShouldBeShown(PermissionRequest permission, | ||||
|                     PermissionToken token) { | ||||
|                     DialogUtil.showAlertDialog(activity, activity.getString(rationaleTitle), | ||||
|                         activity.getString(rationaleMessage), | ||||
|                         activity.getString(android.R.string.ok), | ||||
|                         activity.getString(android.R.string.cancel), | ||||
|                         token::continuePermissionRequest, token::cancelPermissionRequest); | ||||
|                 } | ||||
|             }) | ||||
|             .check(); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ import android.view.Display; | |||
| import android.view.View; | ||||
| import android.view.inputmethod.InputMethodManager; | ||||
| import android.widget.Toast; | ||||
| import timber.log.Timber; | ||||
| 
 | ||||
| import com.google.android.material.snackbar.Snackbar; | ||||
| 
 | ||||
|  | @ -22,7 +23,13 @@ public class ViewUtil { | |||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         ExecutorUtils.uiExecutor().execute(() -> Snackbar.make(view, messageResourceId, Snackbar.LENGTH_SHORT).show()); | ||||
|         ExecutorUtils.uiExecutor().execute(() -> { | ||||
|             try { | ||||
|                 Snackbar.make(view, messageResourceId, Snackbar.LENGTH_SHORT).show(); | ||||
|             }catch (IllegalStateException e){ | ||||
|                 Timber.e(e.getMessage()); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     public static void showLongToast(Context context, String text) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ashish Kumar
						Ashish Kumar