From a657a516dd77d3dbe1858243321df02cc9fd09c5 Mon Sep 17 00:00:00 2001 From: Mariusz Date: Fri, 12 Jan 2018 11:34:33 +0100 Subject: [PATCH 1/3] - prevent rationale dialog from showing twice - app settings dialog created base on dialog fragment - now you have possibility to check app setting dialog is showing - sample how prevent call EasyPermission.requestPermission(...) when android permission dialog is showing (too works after rotation changed) - including kotlin --- app/build.gradle | 3 + app/src/main/AndroidManifest.xml | 5 + .../easypermissions/sample/MainActivity.java | 151 ----------------- .../easypermissions/sample/MainActivity.kt | 155 ++++++++++++++++++ .../sample/MyMainActivity.java | 111 +++++++++++++ app/src/main/res/layout/activity_main.xml | 12 +- app/src/main/res/layout/activity_my_main.xml | 7 + build.gradle | 4 +- easypermissions/build.gradle | 3 + .../easypermissions/AbstractDialogFragment.kt | 58 +++++++ .../AppSettingDialogFragment.kt | 85 ++++++++++ .../easypermissions/DialogFragmentCallback.kt | 12 ++ .../RationaleDialogClickListener.java | 6 + .../BaseFrameworkPermissionsHelper.java | 6 +- .../helper/BaseSupportPermissionsHelper.java | 4 + .../helper/PermissionHelper.java | 6 + 16 files changed, 472 insertions(+), 156 deletions(-) delete mode 100644 app/src/main/java/pub/devrel/easypermissions/sample/MainActivity.java create mode 100644 app/src/main/java/pub/devrel/easypermissions/sample/MainActivity.kt create mode 100644 app/src/main/java/pub/devrel/easypermissions/sample/MyMainActivity.java create mode 100644 app/src/main/res/layout/activity_my_main.xml create mode 100644 easypermissions/src/main/java/pub/devrel/easypermissions/AbstractDialogFragment.kt create mode 100644 easypermissions/src/main/java/pub/devrel/easypermissions/AppSettingDialogFragment.kt create mode 100644 easypermissions/src/main/java/pub/devrel/easypermissions/DialogFragmentCallback.kt diff --git a/app/build.gradle b/app/build.gradle index 3901b18..685d671 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,4 +1,6 @@ apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' android { compileSdkVersion compileSdk @@ -21,6 +23,7 @@ android { dependencies { implementation "com.android.support:appcompat-v7:$support_library_version" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" implementation project(':easypermissions') } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1a3388f..ac2f13f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,6 +11,9 @@ + + + + + diff --git a/app/src/main/java/pub/devrel/easypermissions/sample/MainActivity.java b/app/src/main/java/pub/devrel/easypermissions/sample/MainActivity.java deleted file mode 100644 index 94eaf9d..0000000 --- a/app/src/main/java/pub/devrel/easypermissions/sample/MainActivity.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package pub.devrel.easypermissions.sample; - -import android.Manifest; -import android.content.Intent; -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v7.app.AppCompatActivity; -import android.util.Log; -import android.view.View; -import android.widget.Toast; - -import java.util.List; - -import pub.devrel.easypermissions.AfterPermissionGranted; -import pub.devrel.easypermissions.AppSettingsDialog; -import pub.devrel.easypermissions.EasyPermissions; - -public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { - - private static final String TAG = "MainActivity"; - private static final String[] LOCATION_AND_CONTACTS = - {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_CONTACTS}; - - private static final int RC_CAMERA_PERM = 123; - private static final int RC_LOCATION_CONTACTS_PERM = 124; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - // Button click listener that will request one permission. - findViewById(R.id.button_camera).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - cameraTask(); - } - }); - - // Button click listener that will request two permissions. - findViewById(R.id.button_location_and_contacts).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - locationAndContactsTask(); - } - }); - } - - private boolean hasCameraPermission() { - return EasyPermissions.hasPermissions(this, Manifest.permission.CAMERA); - } - - private boolean hasLocationAndContactsPermissions() { - return EasyPermissions.hasPermissions(this, LOCATION_AND_CONTACTS); - } - - private boolean hasSmsPermission() { - return EasyPermissions.hasPermissions(this, Manifest.permission.READ_SMS); - } - - @AfterPermissionGranted(RC_CAMERA_PERM) - public void cameraTask() { - if (hasCameraPermission()) { - // Have permission, do the thing! - Toast.makeText(this, "TODO: Camera things", Toast.LENGTH_LONG).show(); - } else { - // Ask for one permission - EasyPermissions.requestPermissions( - this, - getString(R.string.rationale_camera), - RC_CAMERA_PERM, - Manifest.permission.CAMERA); - } - } - - @AfterPermissionGranted(RC_LOCATION_CONTACTS_PERM) - public void locationAndContactsTask() { - if (hasLocationAndContactsPermissions()) { - // Have permissions, do the thing! - Toast.makeText(this, "TODO: Location and Contacts things", Toast.LENGTH_LONG).show(); - } else { - // Ask for both permissions - EasyPermissions.requestPermissions( - this, - getString(R.string.rationale_location_contacts), - RC_LOCATION_CONTACTS_PERM, - LOCATION_AND_CONTACTS); - } - } - - @Override - public void onRequestPermissionsResult(int requestCode, - @NonNull String[] permissions, - @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - - // EasyPermissions handles the request result. - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); - } - - @Override - public void onPermissionsGranted(int requestCode, @NonNull List perms) { - Log.d(TAG, "onPermissionsGranted:" + requestCode + ":" + perms.size()); - } - - @Override - public void onPermissionsDenied(int requestCode, @NonNull List perms) { - Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size()); - - // (Optional) Check whether the user denied any permissions and checked "NEVER ASK AGAIN." - // This will display a dialog directing them to enable the permission in app settings. - if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { - new AppSettingsDialog.Builder(this).build().show(); - } - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - - if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) { - String yes = getString(R.string.yes); - String no = getString(R.string.no); - - // Do something after user returned from app settings screen, like showing a Toast. - Toast.makeText( - this, - getString(R.string.returned_from_app_settings_to_activity, - hasCameraPermission() ? yes : no, - hasLocationAndContactsPermissions() ? yes : no, - hasSmsPermission() ? yes : no), - Toast.LENGTH_LONG) - .show(); - } - } -} diff --git a/app/src/main/java/pub/devrel/easypermissions/sample/MainActivity.kt b/app/src/main/java/pub/devrel/easypermissions/sample/MainActivity.kt new file mode 100644 index 0000000..d20ea1e --- /dev/null +++ b/app/src/main/java/pub/devrel/easypermissions/sample/MainActivity.kt @@ -0,0 +1,155 @@ +/* + * Copyright Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pub.devrel.easypermissions.sample + +import android.Manifest +import android.content.Intent +import android.os.Bundle +import android.support.v7.app.AppCompatActivity +import android.util.Log +import android.view.View +import android.widget.Toast +import com.mgsoftware.kotlinapp.DialogFragmentCallback +import kotlinx.android.synthetic.main.activity_main.* + +import pub.devrel.easypermissions.AfterPermissionGranted +import pub.devrel.easypermissions.AppSettingDialogFragment +import pub.devrel.easypermissions.AppSettingsDialog +import pub.devrel.easypermissions.EasyPermissions + +class MainActivity : AppCompatActivity(), EasyPermissions.PermissionCallbacks, DialogFragmentCallback { + val RC_APP_SETTING_DIALOG = 125 + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + button_test.setOnClickListener({ + val config = Bundle() + config.putInt(AppSettingDialogFragment.KEY_THEME_RED_ID, android.R.style.Theme_DeviceDefault_Light_Dialog_NoActionBar_MinWidth) + config.putString(AppSettingDialogFragment.KEY_POSITIVE_BUTTON_TEXT, "settings") + AppSettingDialogFragment.newInstance(RC_APP_SETTING_DIALOG, config).show(supportFragmentManager, AppSettingDialogFragment::class.java.name) + }) + + // Button click listener that will request one permission. + findViewById(R.id.button_camera).setOnClickListener { cameraTask() } + + // Button click listener that will request two permissions. + findViewById(R.id.button_location_and_contacts).setOnClickListener { locationAndContactsTask() } + } + + private fun hasCameraPermission(): Boolean { + return EasyPermissions.hasPermissions(this, Manifest.permission.CAMERA) + } + + private fun hasLocationAndContactsPermissions(): Boolean { + return EasyPermissions.hasPermissions(this, *LOCATION_AND_CONTACTS) + } + + private fun hasSmsPermission(): Boolean { + return EasyPermissions.hasPermissions(this, Manifest.permission.READ_SMS) + } + + @AfterPermissionGranted(RC_CAMERA_PERM) + fun cameraTask() { + if (hasCameraPermission()) { + // Have permission, do the thing! + Toast.makeText(this, "TODO: Camera things", Toast.LENGTH_LONG).show() + } else { + // Ask for one permission + EasyPermissions.requestPermissions( + this, + getString(R.string.rationale_camera), + RC_CAMERA_PERM, + Manifest.permission.CAMERA) + } + } + + @AfterPermissionGranted(RC_LOCATION_CONTACTS_PERM) + fun locationAndContactsTask() { + if (hasLocationAndContactsPermissions()) { + // Have permissions, do the thing! + Toast.makeText(this, "TODO: Location and Contacts things", Toast.LENGTH_LONG).show() + } else { + // Ask for both permissions + EasyPermissions.requestPermissions( + this, + getString(R.string.rationale_location_contacts), + RC_LOCATION_CONTACTS_PERM, + *LOCATION_AND_CONTACTS) + } + } + + override fun onRequestPermissionsResult(requestCode: Int, + permissions: Array, + grantResults: IntArray) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + + // EasyPermissions handles the request result. + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + Log.d(TAG, "onPermissionsGranted:" + requestCode + ":" + perms.size) + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size) + + // (Optional) Check whether the user denied any permissions and checked "NEVER ASK AGAIN." + // This will display a dialog directing them to enable the permission in app settings. + if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { + AppSettingsDialog.Builder(this).build().show() + } + } + + public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + + if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) { + val yes = getString(R.string.yes) + val no = getString(R.string.no) + + // Do something after user returned from app settings screen, like showing a Toast. + Toast.makeText( + this, + getString(R.string.returned_from_app_settings_to_activity, + if (hasCameraPermission()) yes else no, + if (hasLocationAndContactsPermissions()) yes else no, + if (hasSmsPermission()) yes else no), + Toast.LENGTH_LONG) + .show() + } + } + + override fun onDialogResult(requestCode: Int, resultCode: Int, data: Bundle?) { + when(requestCode) { + RC_APP_SETTING_DIALOG -> { + + } + } + + } + + companion object { + + private val TAG = "MainActivity" + private val LOCATION_AND_CONTACTS = arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_CONTACTS) + + private const val RC_CAMERA_PERM = 123 + private const val RC_LOCATION_CONTACTS_PERM = 124 + } +} diff --git a/app/src/main/java/pub/devrel/easypermissions/sample/MyMainActivity.java b/app/src/main/java/pub/devrel/easypermissions/sample/MyMainActivity.java new file mode 100644 index 0000000..92423cc --- /dev/null +++ b/app/src/main/java/pub/devrel/easypermissions/sample/MyMainActivity.java @@ -0,0 +1,111 @@ +package pub.devrel.easypermissions.sample; + +import android.Manifest; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; + +import com.mgsoftware.kotlinapp.DialogFragmentCallback; + +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +import pub.devrel.easypermissions.AppSettingDialogFragment; +import pub.devrel.easypermissions.EasyPermissions; +import pub.devrel.easypermissions.PermissionRequest; +import pub.devrel.easypermissions.helper.PermissionHelper; + +public class MyMainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks, DialogFragmentCallback, PermissionHelper.Callback { + private static final String TAG = "MainActivity"; + + private static final String[] REQUESTED_PERMISSIONS_ON_START = { + Manifest.permission.CAMERA, + Manifest.permission.RECORD_AUDIO, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.ACCESS_FINE_LOCATION + }; + + private static final int RC_REQUIRED_PERM = 125; + private static final int RC_APP_SETTING_DIALOG = 126; + + // In this case prevent showing dialogs under android permission dialog + private boolean waiting = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_my_main); + Log.d(TAG, "onCreate() called with: savedInstanceState = [" + savedInstanceState + "]"); + + waiting = hasCurrentPermissionsRequest(savedInstanceState); + } + + @Override + protected void onStart() { + super.onStart(); + if (!EasyPermissions.hasPermissions(this, REQUESTED_PERMISSIONS_ON_START)) { + if (!waiting) { + if (!isShowing(getSupportFragmentManager(), AppSettingDialogFragment.Companion.getTAG())) { + PermissionRequest request = new PermissionRequest.Builder(this, + RC_REQUIRED_PERM, + REQUESTED_PERMISSIONS_ON_START) + .setRationale("my_rationale") + .build(); + EasyPermissions.requestPermissions(request); + } + } + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + waiting = false; + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + if (!EasyPermissions.hasPermissions(this, REQUESTED_PERMISSIONS_ON_START)) { + if (!isShowing(getSupportFragmentManager(), AppSettingDialogFragment.Companion.getTAG())) { + Bundle config = new Bundle(); + config.putInt(AppSettingDialogFragment.Companion.getKEY_THEME_RED_ID(), android.R.style.Theme_DeviceDefault_Light_Dialog_NoActionBar_MinWidth); + config.putString(AppSettingDialogFragment.Companion.getKEY_POSITIVE_BUTTON_TEXT(), "my_settings"); + AppSettingDialogFragment.Companion.newInstance(RC_APP_SETTING_DIALOG, config).show(getSupportFragmentManager(), AppSettingDialogFragment.Companion.getTAG()); + } + } + } + + @Override + public void onDialogResult(int requestCode, int resultCode, @Nullable Bundle data) { + if(requestCode == AppSettingDialogFragment.Companion.getDEFAULT_SETTINGS_REQ_CODE()) { + if(resultCode == DialogFragmentCallback.Companion.getRESULT_CANCEL()) { + // TODO + } + } + } + + @Override + public void onAndroidRequestPermissionsCalled() { + waiting = true; + } + + private boolean hasCurrentPermissionsRequest(Bundle savedInstanceState) { + return savedInstanceState != null && savedInstanceState.getBoolean("android:hasCurrentPermissionsRequest", false); + } + + private boolean isShowing(FragmentManager fragmentManager, String tag) { + Fragment fragment = fragmentManager.findFragmentByTag(tag); + return fragment != null; + + } +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index b93dcf2..a496ab8 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -10,23 +10,29 @@ android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin"> +