mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-28 20:57:42 +00:00
Use DialogFragment instead of an AlertDialog for runtime permissions
This commit is contained in:
parent
fc11951532
commit
d364401ea9
@ -29,12 +29,13 @@ import android.widget.Button;
|
|||||||
|
|
||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
import org.kde.kdeconnect.NetworkPacket;
|
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.UserInterface.PluginSettingsFragment;
|
||||||
import org.kde.kdeconnect_tp.R;
|
import org.kde.kdeconnect_tp.R;
|
||||||
|
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.core.app.ActivityCompat;
|
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
public abstract class Plugin {
|
public abstract class Plugin {
|
||||||
@ -223,18 +224,14 @@ public abstract class Plugin {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AlertDialog requestPermissionDialog(Activity activity, String permissions, @StringRes int reason) {
|
private PermissionsAlertDialogFragment requestPermissionDialog(final String[] permissions, @StringRes int reason, int requestCode) {
|
||||||
return requestPermissionDialog(activity, new String[]{permissions}, reason);
|
return new PermissionsAlertDialogFragment.Builder()
|
||||||
}
|
|
||||||
|
|
||||||
private AlertDialog requestPermissionDialog(final Activity activity, final String[] permissions, @StringRes int reason) {
|
|
||||||
return new AlertDialog.Builder(activity)
|
|
||||||
.setTitle(getDisplayName())
|
.setTitle(getDisplayName())
|
||||||
.setMessage(reason)
|
.setMessage(reason)
|
||||||
.setPositiveButton(R.string.ok, (dialogInterface, i) -> ActivityCompat.requestPermissions(activity, permissions, 0))
|
.setPositiveButton(R.string.ok)
|
||||||
.setNegativeButton(R.string.cancel, (dialogInterface, i) -> {
|
.setNegativeButton(R.string.cancel)
|
||||||
//Do nothing
|
.setPermissions(permissions)
|
||||||
})
|
.setRequestCode(requestCode)
|
||||||
.create();
|
.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,12 +244,12 @@ public abstract class Plugin {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlertDialog getPermissionExplanationDialog(Activity deviceActivity) {
|
public AlertDialogFragment getPermissionExplanationDialog(int requestCode) {
|
||||||
return requestPermissionDialog(deviceActivity, getRequiredPermissions(), permissionExplanation);
|
return requestPermissionDialog(getRequiredPermissions(), permissionExplanation, requestCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlertDialog getOptionalPermissionExplanationDialog(Activity deviceActivity) {
|
public AlertDialogFragment getOptionalPermissionExplanationDialog(int requestCode) {
|
||||||
return requestPermissionDialog(deviceActivity, getOptionalPermissions(), optionalPermissionExplanation);
|
return requestPermissionDialog(getOptionalPermissions(), optionalPermissionExplanation, requestCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean checkRequiredPermissions() {
|
public boolean checkRequiredPermissions() {
|
||||||
|
185
src/org/kde/kdeconnect/UserInterface/AlertDialogFragment.java
Normal file
185
src/org/kde/kdeconnect/UserInterface/AlertDialogFragment.java
Normal 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() {}
|
||||||
|
}
|
||||||
|
}
|
@ -338,15 +338,17 @@ public class DeviceFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
DeviceFragment.this.createPluginsList(device.getPluginsWithoutPermissions(), R.string.plugins_need_permission, (plugin) -> {
|
DeviceFragment.this.createPluginsList(device.getPluginsWithoutPermissions(), R.string.plugins_need_permission, (plugin) -> {
|
||||||
AlertDialog dialog = plugin.getPermissionExplanationDialog(mActivity);
|
AlertDialogFragment dialog = plugin.getPermissionExplanationDialog(0);
|
||||||
|
|
||||||
if (dialog != null) {
|
if (dialog != null) {
|
||||||
dialog.show();
|
dialog.show(getChildFragmentManager(), null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
DeviceFragment.this.createPluginsList(device.getPluginsWithoutOptionalPermissions(), R.string.plugins_need_optional_permission, (plugin) -> {
|
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) {
|
if (dialog != null) {
|
||||||
dialog.show();
|
dialog.show(getChildFragmentManager(), null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user