mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-09-01 14:45:08 +00:00
Runtime Permissions: optional Permissions
Summary: Added support for optional Permissions. Also provided explanations why the permissions are needed Reviewers: #kde_connect, albertvaka Reviewed By: #kde_connect, albertvaka Subscribers: albertvaka, #kde_connect Tags: #kde_connect Differential Revision: https://phabricator.kde.org/D6094
This commit is contained in:
@@ -26,6 +26,7 @@
|
|||||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" android:required="false" />
|
<uses-permission android:name="android.permission.READ_PHONE_STATE" android:required="false" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_SMS" android:required="false" />
|
<uses-permission android:name="android.permission.RECEIVE_SMS" android:required="false" />
|
||||||
<uses-permission android:name="android.permission.SEND_SMS" android:required="false" />
|
<uses-permission android:name="android.permission.SEND_SMS" android:required="false" />
|
||||||
|
<uses-permission android:name="android.permission.READ_SMS" android:required="false" />
|
||||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
@@ -209,5 +209,12 @@
|
|||||||
<string name="no_permissions_storage">You need to grant permissions to access the storage</string>
|
<string name="no_permissions_storage">You need to grant permissions to access the storage</string>
|
||||||
<string name="plugins_need_permission">Some Plugins need permissions to work (tap for more info):</string>
|
<string name="plugins_need_permission">Some Plugins need permissions to work (tap for more info):</string>
|
||||||
<string name="permission_explanation">This plugin needs permissions to work</string>
|
<string name="permission_explanation">This plugin needs permissions to work</string>
|
||||||
|
<string name="optional_permission_explanation">You need to grant extra permissions to enable all functions</string>
|
||||||
|
<string name="plugins_need_optional_permission">Some plugins have features disabled because of lack of permission (tap for more info):</string>
|
||||||
|
<string name="sftp_permission_explanation">To access your files from your PC the app needs permission to access your phone\'s storage</string>
|
||||||
|
<string name="share_optional_permission_explanation">To share files between your phone and your desktop you need to give access to the phone\'s storage</string>
|
||||||
|
<string name="telepathy_permission_explanation">To read and write SMS from your desktop you need to give permission to SMS</string>
|
||||||
|
<string name="telephony_permission_explanation">To see phone calls and SMS from the desktop you need to give permission to phone calls and SMS</string>
|
||||||
|
<string name="telephony_optional_permission_explanation">To see a contact name instead of a phone number you need to give access to the phone\'s contacts</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -83,6 +83,7 @@ public class Device implements BaseLink.PackageReceiver {
|
|||||||
private final ConcurrentHashMap<String, Plugin> plugins = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<String, Plugin> plugins = new ConcurrentHashMap<>();
|
||||||
private final ConcurrentHashMap<String, Plugin> failedPlugins = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<String, Plugin> failedPlugins = new ConcurrentHashMap<>();
|
||||||
private final ConcurrentHashMap<String, Plugin> pluginsWithoutPermissions = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<String, Plugin> pluginsWithoutPermissions = new ConcurrentHashMap<>();
|
||||||
|
private final ConcurrentHashMap<String, Plugin> pluginsWithoutOptionalPermissions = new ConcurrentHashMap<>();
|
||||||
private Map<String, ArrayList<String>> pluginsByIncomingInterface = new HashMap<>();
|
private Map<String, ArrayList<String>> pluginsByIncomingInterface = new HashMap<>();
|
||||||
|
|
||||||
private final SharedPreferences settings;
|
private final SharedPreferences settings;
|
||||||
@@ -693,6 +694,13 @@ public class Device implements BaseLink.PackageReceiver {
|
|||||||
Plugin existing = plugins.get(pluginKey);
|
Plugin existing = plugins.get(pluginKey);
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
//Log.w("KDE/addPlugin","plugin already present:" + pluginKey);
|
//Log.w("KDE/addPlugin","plugin already present:" + pluginKey);
|
||||||
|
if (existing.checkOptionalPermissions()) {
|
||||||
|
Log.i("KDE/addPlugin", "Optional Permissions OK " + pluginKey);
|
||||||
|
pluginsWithoutOptionalPermissions.remove(pluginKey);
|
||||||
|
} else {
|
||||||
|
Log.e("KDE/addPlugin", "No optional permission " + pluginKey);
|
||||||
|
pluginsWithoutOptionalPermissions.put(pluginKey, existing);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -729,8 +737,16 @@ public class Device implements BaseLink.PackageReceiver {
|
|||||||
pluginsWithoutPermissions.put(pluginKey, plugin);
|
pluginsWithoutPermissions.put(pluginKey, plugin);
|
||||||
success = false;
|
success = false;
|
||||||
} else {
|
} else {
|
||||||
Log.i("KDE/addPlugin", "Permission OK " + pluginKey);
|
Log.i("KDE/addPlugin", "Permissions OK " + pluginKey);
|
||||||
pluginsWithoutPermissions.remove(pluginKey);
|
pluginsWithoutPermissions.remove(pluginKey);
|
||||||
|
|
||||||
|
if (plugin.checkOptionalPermissions()) {
|
||||||
|
Log.i("KDE/addPlugin", "Optional Permissions OK " + pluginKey);
|
||||||
|
pluginsWithoutOptionalPermissions.remove(pluginKey);
|
||||||
|
} else {
|
||||||
|
Log.e("KDE/addPlugin", "No optional permission " + pluginKey);
|
||||||
|
pluginsWithoutOptionalPermissions.put(pluginKey, plugin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
@@ -827,6 +843,10 @@ public class Device implements BaseLink.PackageReceiver {
|
|||||||
return pluginsWithoutPermissions;
|
return pluginsWithoutPermissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ConcurrentHashMap<String,Plugin> getPluginsWithoutOptionalPermissions() {
|
||||||
|
return pluginsWithoutOptionalPermissions;
|
||||||
|
}
|
||||||
|
|
||||||
public void addPluginsChangedListener(PluginsChangedListener listener) {
|
public void addPluginsChangedListener(PluginsChangedListener listener) {
|
||||||
pluginsChangedListeners.add(listener);
|
pluginsChangedListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
@@ -47,6 +47,7 @@ public abstract class Plugin {
|
|||||||
protected Device device;
|
protected Device device;
|
||||||
protected Context context;
|
protected Context context;
|
||||||
protected int permissionExplanation = R.string.permission_explanation;
|
protected int permissionExplanation = R.string.permission_explanation;
|
||||||
|
protected int optionalPermissionExplanation = R.string.optional_permission_explanation;
|
||||||
|
|
||||||
public final void setContext(Context context, Device device) {
|
public final void setContext(Context context, Device device) {
|
||||||
this.device = device;
|
this.device = device;
|
||||||
@@ -266,11 +267,16 @@ public abstract class Plugin {
|
|||||||
return requestPermissionDialog(deviceActivity,getRequiredPermissions(), permissionExplanation);
|
return requestPermissionDialog(deviceActivity,getRequiredPermissions(), permissionExplanation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AlertDialog getOptionalPermissionExplanationDialog(Activity deviceActivity) {
|
||||||
|
return requestPermissionDialog(deviceActivity,getOptionalPermissions(), optionalPermissionExplanation);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean checkRequiredPermissions(){
|
public boolean checkRequiredPermissions(){
|
||||||
if (!arePermissionsGranted(getRequiredPermissions())) {
|
return arePermissionsGranted(getRequiredPermissions());
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
return true;
|
public boolean checkOptionalPermissions(){
|
||||||
|
return arePermissionsGranted(getOptionalPermissions());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -46,8 +46,7 @@ public class SftpPlugin extends Plugin {
|
|||||||
|
|
||||||
private static final SimpleSftpServer server = new SimpleSftpServer();
|
private static final SimpleSftpServer server = new SimpleSftpServer();
|
||||||
|
|
||||||
|
private int sftpPermissionExplanation = R.string.sftp_permission_explanation;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
@@ -62,6 +61,7 @@ public class SftpPlugin extends Plugin {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onCreate() {
|
public boolean onCreate() {
|
||||||
server.init(context, device);
|
server.init(context, device);
|
||||||
|
permissionExplanation = sftpPermissionExplanation;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -64,6 +64,14 @@ public class SharePlugin extends Plugin {
|
|||||||
|
|
||||||
final static boolean openUrlsDirectly = true;
|
final static boolean openUrlsDirectly = true;
|
||||||
|
|
||||||
|
private int sharePermissionExplanation = R.string.share_optional_permission_explanation;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreate() {
|
||||||
|
optionalPermissionExplanation = sharePermissionExplanation;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
return context.getResources().getString(R.string.pref_plugin_sharereceiver);
|
return context.getResources().getString(R.string.pref_plugin_sharereceiver);
|
||||||
@@ -108,7 +116,7 @@ public class SharePlugin extends Plugin {
|
|||||||
if (np.hasPayload()) {
|
if (np.hasPayload()) {
|
||||||
|
|
||||||
Log.i("SharePlugin", "hasPayload");
|
Log.i("SharePlugin", "hasPayload");
|
||||||
|
|
||||||
if (isPermissionGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
if (isPermissionGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||||
receiveFile(np);
|
receiveFile(np);
|
||||||
} else {
|
} else {
|
||||||
@@ -403,9 +411,7 @@ public class SharePlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getRequiredPermissions() {
|
public String[] getOptionalPermissions() {
|
||||||
String[] perms = {Manifest.permission.READ_EXTERNAL_STORAGE};
|
return new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
|
||||||
return perms;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -37,6 +37,14 @@ public class TelepathyPlugin extends Plugin {
|
|||||||
|
|
||||||
public final static String PACKAGE_TYPE_SMS_REQUEST = "kdeconnect.sms.request";
|
public final static String PACKAGE_TYPE_SMS_REQUEST = "kdeconnect.sms.request";
|
||||||
|
|
||||||
|
private int telepathyPermissionExplanation = R.string.telepathy_permission_explanation;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreate() {
|
||||||
|
permissionExplanation = telepathyPermissionExplanation;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
return context.getResources().getString(R.string.pref_plugin_telepathy);
|
return context.getResources().getString(R.string.pref_plugin_telepathy);
|
||||||
@@ -62,17 +70,9 @@ public class TelepathyPlugin extends Plugin {
|
|||||||
String phoneNo = np.getString("phoneNumber");
|
String phoneNo = np.getString("phoneNumber");
|
||||||
String sms = np.getString("messageBody");
|
String sms = np.getString("messageBody");
|
||||||
try {
|
try {
|
||||||
|
SmsManager smsManager = SmsManager.getDefault();
|
||||||
int permissionCheck = ContextCompat.checkSelfPermission(context,
|
smsManager.sendTextMessage(phoneNo, null, sms, null, null);
|
||||||
Manifest.permission.SEND_SMS);
|
Log.d("TelepathyPlugin", "SMS sent");
|
||||||
|
|
||||||
if(permissionCheck == PackageManager.PERMISSION_GRANTED) {
|
|
||||||
SmsManager smsManager = SmsManager.getDefault();
|
|
||||||
smsManager.sendTextMessage(phoneNo, null, sms, null, null);
|
|
||||||
Log.d("TelepathyPlugin", "SMS sent");
|
|
||||||
} else if(permissionCheck == PackageManager.PERMISSION_DENIED){
|
|
||||||
// TODO Request Permission SEND_SMS
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Notify other end
|
//TODO: Notify other end
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@@ -52,6 +52,9 @@ public class TelephonyPlugin extends Plugin {
|
|||||||
private NetworkPackage lastPackage = null;
|
private NetworkPackage lastPackage = null;
|
||||||
private boolean isMuted = false;
|
private boolean isMuted = false;
|
||||||
|
|
||||||
|
private int telephonyPermissionExplanation = R.string.telephony_permission_explanation;
|
||||||
|
private int telephonyOptionalPermissionExplanation = R.string.telephony_optional_permission_explanation;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
return context.getResources().getString(R.string.pref_plugin_telephony);
|
return context.getResources().getString(R.string.pref_plugin_telephony);
|
||||||
@@ -250,6 +253,8 @@ public class TelephonyPlugin extends Plugin {
|
|||||||
filter.setPriority(500);
|
filter.setPriority(500);
|
||||||
filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
|
filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
|
||||||
context.registerReceiver(receiver, filter);
|
context.registerReceiver(receiver, filter);
|
||||||
|
permissionExplanation = telephonyPermissionExplanation;
|
||||||
|
optionalPermissionExplanation = telephonyOptionalPermissionExplanation;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +293,11 @@ public class TelephonyPlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getRequiredPermissions() {
|
public String[] getRequiredPermissions() {
|
||||||
return new String[]{Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_CONTACTS, Manifest.permission.SEND_SMS};
|
return new String[]{Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_SMS};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getOptionalPermissions() {
|
||||||
|
return new String[]{Manifest.permission.READ_CONTACTS};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -67,12 +67,12 @@ public class DeviceFragment extends Fragment {
|
|||||||
static String mDeviceId; //Static because if we get here by using the back button in the action bar, the extra deviceId will not be set.
|
static String mDeviceId; //Static because if we get here by using the back button in the action bar, the extra deviceId will not be set.
|
||||||
Device device;
|
Device device;
|
||||||
|
|
||||||
TextView errorHeader;
|
|
||||||
TextView noPermissionsHeader;
|
|
||||||
|
|
||||||
MaterialActivity mActivity;
|
MaterialActivity mActivity;
|
||||||
|
|
||||||
public DeviceFragment() { }
|
ArrayList<ListAdapter.Item> pluginListItems;
|
||||||
|
|
||||||
|
public DeviceFragment() {
|
||||||
|
}
|
||||||
|
|
||||||
public DeviceFragment(String deviceId) {
|
public DeviceFragment(String deviceId) {
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
@@ -87,7 +87,7 @@ public class DeviceFragment extends Fragment {
|
|||||||
this.setArguments(args);
|
this.setArguments(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceFragment(String deviceId, MaterialActivity activity){
|
public DeviceFragment(String deviceId, MaterialActivity activity) {
|
||||||
this.mActivity = activity;
|
this.mActivity = activity;
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putString(ARG_DEVICE_ID, deviceId);
|
args.putString(ARG_DEVICE_ID, deviceId);
|
||||||
@@ -135,7 +135,7 @@ public class DeviceFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final Button pairButton = (Button)rootView.findViewById(R.id.pair_button);
|
final Button pairButton = (Button) rootView.findViewById(R.id.pair_button);
|
||||||
pairButton.setOnClickListener(new View.OnClickListener() {
|
pairButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
@@ -342,7 +342,7 @@ public class DeviceFragment extends Fragment {
|
|||||||
rootView.findViewById(R.id.on_data_message).setVisibility((paired && !reachable && onData) ? View.VISIBLE : View.GONE);
|
rootView.findViewById(R.id.on_data_message).setVisibility((paired && !reachable && onData) ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ArrayList<ListAdapter.Item> items = new ArrayList<>();
|
pluginListItems = new ArrayList<>();
|
||||||
|
|
||||||
//Plugins button list
|
//Plugins button list
|
||||||
final Collection<Plugin> plugins = device.getLoadedPlugins().values();
|
final Collection<Plugin> plugins = device.getLoadedPlugins().values();
|
||||||
@@ -350,7 +350,7 @@ public class DeviceFragment extends Fragment {
|
|||||||
if (!p.hasMainActivity()) continue;
|
if (!p.hasMainActivity()) continue;
|
||||||
if (p.displayInContextMenu()) continue;
|
if (p.displayInContextMenu()) continue;
|
||||||
|
|
||||||
items.add(new PluginItem(p, new View.OnClickListener() {
|
pluginListItems.add(new PluginItem(p, new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
p.startMainActivity(mActivity);
|
p.startMainActivity(mActivity);
|
||||||
@@ -358,72 +358,27 @@ public class DeviceFragment extends Fragment {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Failed plugins List
|
createPluginsList(device.getFailedPlugins(), R.string.plugins_failed_to_load, new PluginClickListener() {
|
||||||
final ConcurrentHashMap<String, Plugin> failed = device.getFailedPlugins();
|
@Override
|
||||||
if (!failed.isEmpty()) {
|
void action() {
|
||||||
if (errorHeader == null) {
|
plugin.getErrorDialog(mActivity).show();
|
||||||
errorHeader = new TextView(mActivity);
|
|
||||||
errorHeader.setPadding(
|
|
||||||
0,
|
|
||||||
((int) (28 * getResources().getDisplayMetrics().density)),
|
|
||||||
0,
|
|
||||||
((int) (8 * getResources().getDisplayMetrics().density))
|
|
||||||
);
|
|
||||||
errorHeader.setOnClickListener(null);
|
|
||||||
errorHeader.setOnLongClickListener(null);
|
|
||||||
errorHeader.setText(getResources().getString(R.string.plugins_failed_to_load));
|
|
||||||
}
|
}
|
||||||
items.add(new CustomItem(errorHeader));
|
});
|
||||||
for (Map.Entry<String, Plugin> entry : failed.entrySet()) {
|
createPluginsList(device.getPluginsWithoutPermissions(), R.string.plugins_need_permission, new PluginClickListener() {
|
||||||
String pluginKey = entry.getKey();
|
@Override
|
||||||
final Plugin plugin = entry.getValue();
|
void action() {
|
||||||
if (plugin == null) {
|
plugin.getPermissionExplanationDialog(mActivity).show();
|
||||||
items.add(new SmallEntryItem(pluginKey));
|
|
||||||
} else {
|
|
||||||
items.add(new SmallEntryItem(plugin.getDisplayName(), new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
plugin.getErrorDialog(mActivity).show();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
createPluginsList(device.getPluginsWithoutOptionalPermissions(), R.string.plugins_need_optional_permission, new PluginClickListener() {
|
||||||
//Plugins without permissions List
|
@Override
|
||||||
final ConcurrentHashMap<String, Plugin> permissionsNeeded = device.getPluginsWithoutPermissions();
|
void action() {
|
||||||
if (!permissionsNeeded.isEmpty()) {
|
plugin.getOptionalPermissionExplanationDialog(mActivity).show();
|
||||||
if (noPermissionsHeader == null) {
|
|
||||||
noPermissionsHeader = new TextView(mActivity);
|
|
||||||
noPermissionsHeader.setPadding(
|
|
||||||
0,
|
|
||||||
((int) (28 * getResources().getDisplayMetrics().density)),
|
|
||||||
0,
|
|
||||||
((int) (8 * getResources().getDisplayMetrics().density))
|
|
||||||
);
|
|
||||||
noPermissionsHeader.setOnClickListener(null);
|
|
||||||
noPermissionsHeader.setOnLongClickListener(null);
|
|
||||||
noPermissionsHeader.setText(getResources().getString(R.string.plugins_need_permission));
|
|
||||||
}
|
}
|
||||||
items.add(new CustomItem(noPermissionsHeader));
|
});
|
||||||
for (Map.Entry<String, Plugin> entry : permissionsNeeded.entrySet()) {
|
|
||||||
String pluginKey = entry.getKey();
|
|
||||||
final Plugin plugin = entry.getValue();
|
|
||||||
if (plugin == null) {
|
|
||||||
items.add(new SmallEntryItem(pluginKey));
|
|
||||||
} else {
|
|
||||||
items.add(new SmallEntryItem(plugin.getDisplayName(), new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
plugin.getPermissionExplanationDialog(mActivity).show();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ListView buttonsList = (ListView) rootView.findViewById(R.id.buttons_list);
|
ListView buttonsList = (ListView) rootView.findViewById(R.id.buttons_list);
|
||||||
ListAdapter adapter = new ListAdapter(mActivity, items);
|
ListAdapter adapter = new ListAdapter(mActivity, pluginListItems);
|
||||||
buttonsList.setAdapter(adapter);
|
buttonsList.setAdapter(adapter);
|
||||||
|
|
||||||
mActivity.invalidateOptionsMenu();
|
mActivity.invalidateOptionsMenu();
|
||||||
@@ -486,7 +441,7 @@ public class DeviceFragment extends Fragment {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public static void acceptPairing(final String devId, final MaterialActivity activity){
|
public static void acceptPairing(final String devId, final MaterialActivity activity) {
|
||||||
final DeviceFragment frag = new DeviceFragment(devId, activity);
|
final DeviceFragment frag = new DeviceFragment(devId, activity);
|
||||||
BackgroundService.RunCommand(activity, new BackgroundService.InstanceCallback() {
|
BackgroundService.RunCommand(activity, new BackgroundService.InstanceCallback() {
|
||||||
public void onServiceStart(BackgroundService service) {
|
public void onServiceStart(BackgroundService service) {
|
||||||
@@ -505,7 +460,7 @@ public class DeviceFragment extends Fragment {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void rejectPairing(final String devId, final MaterialActivity activity){
|
public static void rejectPairing(final String devId, final MaterialActivity activity) {
|
||||||
final DeviceFragment frag = new DeviceFragment(devId, activity);
|
final DeviceFragment frag = new DeviceFragment(devId, activity);
|
||||||
BackgroundService.RunCommand(activity, new BackgroundService.InstanceCallback() {
|
BackgroundService.RunCommand(activity, new BackgroundService.InstanceCallback() {
|
||||||
public void onServiceStart(BackgroundService service) {
|
public void onServiceStart(BackgroundService service) {
|
||||||
@@ -527,4 +482,58 @@ public class DeviceFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createPluginsList(ConcurrentHashMap<String, Plugin> plugins, int headerText, PluginClickListener onClickListener) {
|
||||||
|
if (!plugins.isEmpty()) {
|
||||||
|
|
||||||
|
TextView header = new TextView(mActivity);
|
||||||
|
header.setPadding(
|
||||||
|
0,
|
||||||
|
((int) (28 * getResources().getDisplayMetrics().density)),
|
||||||
|
0,
|
||||||
|
((int) (8 * getResources().getDisplayMetrics().density))
|
||||||
|
);
|
||||||
|
header.setOnClickListener(null);
|
||||||
|
header.setOnLongClickListener(null);
|
||||||
|
header.setText(headerText);
|
||||||
|
|
||||||
|
pluginListItems.add(new CustomItem(header));
|
||||||
|
for (Map.Entry<String, Plugin> entry : plugins.entrySet()) {
|
||||||
|
String pluginKey = entry.getKey();
|
||||||
|
final Plugin plugin = entry.getValue();
|
||||||
|
if (device.isPluginEnabled(pluginKey)) {
|
||||||
|
if (plugin == null) {
|
||||||
|
pluginListItems.add(new SmallEntryItem(pluginKey));
|
||||||
|
} else {
|
||||||
|
PluginClickListener listener = onClickListener.clone();
|
||||||
|
listener.plugin = plugin;
|
||||||
|
pluginListItems.add(new SmallEntryItem(plugin.getDisplayName(), listener));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private abstract class PluginClickListener implements View.OnClickListener, Cloneable {
|
||||||
|
|
||||||
|
Plugin plugin;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
action();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PluginClickListener clone(){
|
||||||
|
try {
|
||||||
|
return (PluginClickListener) super.clone();
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract void action();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user