2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-08-28 12:47:43 +00:00

Use DialogFragment instead of an AlertDialog for runtime permissions

This commit is contained in:
Erik Duisters 2019-02-02 11:38:13 +00:00
parent fc11951532
commit d364401ea9
4 changed files with 285 additions and 19 deletions

View File

@ -29,12 +29,13 @@ import android.widget.Button;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.UserInterface.AlertDialogFragment;
import org.kde.kdeconnect.UserInterface.PermissionsAlertDialogFragment;
import org.kde.kdeconnect.UserInterface.PluginSettingsFragment;
import org.kde.kdeconnect_tp.R;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
public abstract class Plugin {
@ -223,18 +224,14 @@ public abstract class Plugin {
return true;
}
protected AlertDialog requestPermissionDialog(Activity activity, String permissions, @StringRes int reason) {
return requestPermissionDialog(activity, new String[]{permissions}, reason);
}
private AlertDialog requestPermissionDialog(final Activity activity, final String[] permissions, @StringRes int reason) {
return new AlertDialog.Builder(activity)
private PermissionsAlertDialogFragment requestPermissionDialog(final String[] permissions, @StringRes int reason, int requestCode) {
return new PermissionsAlertDialogFragment.Builder()
.setTitle(getDisplayName())
.setMessage(reason)
.setPositiveButton(R.string.ok, (dialogInterface, i) -> ActivityCompat.requestPermissions(activity, permissions, 0))
.setNegativeButton(R.string.cancel, (dialogInterface, i) -> {
//Do nothing
})
.setPositiveButton(R.string.ok)
.setNegativeButton(R.string.cancel)
.setPermissions(permissions)
.setRequestCode(requestCode)
.create();
}
@ -247,12 +244,12 @@ public abstract class Plugin {
return null;
}
public AlertDialog getPermissionExplanationDialog(Activity deviceActivity) {
return requestPermissionDialog(deviceActivity, getRequiredPermissions(), permissionExplanation);
public AlertDialogFragment getPermissionExplanationDialog(int requestCode) {
return requestPermissionDialog(getRequiredPermissions(), permissionExplanation, requestCode);
}
public AlertDialog getOptionalPermissionExplanationDialog(Activity deviceActivity) {
return requestPermissionDialog(deviceActivity, getOptionalPermissions(), optionalPermissionExplanation);
public AlertDialogFragment getOptionalPermissionExplanationDialog(int requestCode) {
return requestPermissionDialog(getOptionalPermissions(), optionalPermissionExplanation, requestCode);
}
public boolean checkRequiredPermissions() {

View File

@ -0,0 +1,185 @@
/*
* Copyright 2019 Erik Duisters <e.duisters1@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.UserInterface;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
public class AlertDialogFragment extends DialogFragment implements DialogInterface.OnClickListener {
private static final String KEY_TITLE_RES_ID = "TitleResId";
private static final String KEY_TITLE = "Title";
private static final String KEY_MESSAGE_RES_ID = "MessageResId";
private static final String KEY_POSITIVE_BUTTON_TEXT_RES_ID = "PositiveButtonResId";
private static final String KEY_NEGATIVE_BUTTON_TEXT_RES_ID = "NegativeButtonResId";
@StringRes private int titleResId;
@Nullable private String title;
@StringRes private int messageResId;
@StringRes private int positiveButtonResId;
@StringRes private int negativeButtonResId;
@Nullable private Callback callback;
public AlertDialogFragment() {
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
if (args == null) {
throw new RuntimeException("You need to instantiate a new AlertDialogFragment using AlertDialogFragment.Builder");
}
titleResId = args.getInt(KEY_TITLE_RES_ID);
title = args.getString(KEY_TITLE);
messageResId = args.getInt(KEY_MESSAGE_RES_ID);
positiveButtonResId = args.getInt(KEY_POSITIVE_BUTTON_TEXT_RES_ID);
negativeButtonResId = args.getInt(KEY_NEGATIVE_BUTTON_TEXT_RES_ID);
}
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
@SuppressLint("ResourceType")
String titleString = titleResId > 0 ? getString(titleResId) : title;
return new AlertDialog.Builder(requireContext())
.setTitle(titleString)
.setMessage(messageResId)
.setPositiveButton(positiveButtonResId, this)
.setNegativeButton(negativeButtonResId, this)
.create();
}
public void setCallback(@Nullable Callback callback) {
this.callback = callback;
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (callback == null) {
return;
}
switch (which) {
case AlertDialog.BUTTON_POSITIVE:
callback.onPositiveButtonClicked();
break;
case AlertDialog.BUTTON_NEGATIVE:
callback.onNegativeButtonClicked();
break;
default:
break;
}
}
@Override
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
if (callback != null) {
callback.onCancel();
}
}
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
if (callback != null) {
callback.onDismiss();
}
}
public static abstract class AbstractBuilder<B extends AbstractBuilder<B, F>, F extends DialogFragment> {
Bundle args;
AbstractBuilder() {
args = new Bundle();
}
public abstract B getThis();
public B setTitle(@StringRes int titleResId) {
args.putInt(KEY_TITLE_RES_ID, titleResId);
return getThis();
}
public B setTitle(@NonNull String title) {
args.putString(KEY_TITLE, title);
return getThis();
}
public B setMessage(@StringRes int messageResId) {
args.putInt(KEY_MESSAGE_RES_ID, messageResId);
return getThis();
}
public B setPositiveButton(@StringRes int positiveButtonResId) {
args.putInt(KEY_POSITIVE_BUTTON_TEXT_RES_ID, positiveButtonResId);
return getThis();
}
public B setNegativeButton(@StringRes int negativeButtonResId) {
args.putInt(KEY_NEGATIVE_BUTTON_TEXT_RES_ID, negativeButtonResId);
return getThis();
}
protected abstract F createFragment();
public F create() {
F fragment = createFragment();
fragment.setArguments(args);
return fragment;
}
}
public static class Builder extends AbstractBuilder<Builder, AlertDialogFragment> {
@Override
public Builder getThis() {
return this;
}
@Override
protected AlertDialogFragment createFragment() {
return new AlertDialogFragment();
}
}
public static abstract class Callback {
public void onPositiveButtonClicked() {}
public void onNegativeButtonClicked() {}
public void onDismiss() {}
public void onCancel() {}
}
}

View File

@ -338,15 +338,17 @@ public class DeviceFragment extends Fragment {
}
});
DeviceFragment.this.createPluginsList(device.getPluginsWithoutPermissions(), R.string.plugins_need_permission, (plugin) -> {
AlertDialog dialog = plugin.getPermissionExplanationDialog(mActivity);
AlertDialogFragment dialog = plugin.getPermissionExplanationDialog(0);
if (dialog != null) {
dialog.show();
dialog.show(getChildFragmentManager(), null);
}
});
DeviceFragment.this.createPluginsList(device.getPluginsWithoutOptionalPermissions(), R.string.plugins_need_optional_permission, (plugin) -> {
AlertDialog dialog = plugin.getOptionalPermissionExplanationDialog(mActivity);
AlertDialogFragment dialog = plugin.getOptionalPermissionExplanationDialog(0);
if (dialog != null) {
dialog.show();
dialog.show(getChildFragmentManager(), null);
}
});
}

View File

@ -0,0 +1,82 @@
/*
* Copyright 2019 Erik Duisters <e.duisters1@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.UserInterface;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
public class PermissionsAlertDialogFragment extends AlertDialogFragment {
private static final String KEY_PERMISSIONS = "Permissions";
private static final String KEY_REQUEST_CODE = "RequestCode";
private String[] permissions;
private int requestCode;
public PermissionsAlertDialogFragment() {
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
if (args == null || !args.containsKey(KEY_PERMISSIONS)) {
throw new RuntimeException("You must call Builder.setPermission() to set the array of needed permissions");
}
permissions = args.getStringArray(KEY_PERMISSIONS);
requestCode = args.getInt(KEY_REQUEST_CODE, 0);
setCallback(new Callback() {
@Override
public void onPositiveButtonClicked() {
ActivityCompat.requestPermissions(requireActivity(), permissions, requestCode);
}
});
}
public static class Builder extends AlertDialogFragment.AbstractBuilder<Builder, PermissionsAlertDialogFragment> {
@Override
public Builder getThis() {
return this;
}
public Builder setPermissions(String[] permissions) {
args.putStringArray(KEY_PERMISSIONS, permissions);
return getThis();
}
public Builder setRequestCode(int requestCode) {
args.putInt(KEY_REQUEST_CODE, requestCode);
return getThis();
}
@Override
protected PermissionsAlertDialogFragment createFragment() {
return new PermissionsAlertDialogFragment();
}
}
}