diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 886e27cd..a15a529e 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -88,6 +88,17 @@ android:value="org.kde.kdeconnect.UserInterface.DeviceActivity" /> + + + + + + () { @Override protected Void doInBackground(Void... voids) { - - try { - NetworkPackage identity = NetworkPackage.createIdentityPackage(context); - identity.set("tcpPort",finalTcpPort); - byte[] b = identity.serialize().getBytes("UTF-8"); - DatagramPacket packet = new DatagramPacket(b, b.length, InetAddress.getByAddress(new byte[]{-1,-1,-1,-1}), port); - DatagramSocket socket = new DatagramSocket(); - socket.setReuseAddress(true); - socket.setBroadcast(true); - socket.send(packet); - //Log.e("LanLinkProvider","Udp identity package sent"); - } catch(Exception e) { - e.printStackTrace(); - Log.e("LanLinkProvider","Sending udp identity package failed"); + String deviceListPrefs = PreferenceManager.getDefaultSharedPreferences(context).getString( + KEY_CUSTOM_DEVLIST_PREFERENCE, ""); + ArrayList iplist = new ArrayList(); + if (!deviceListPrefs.isEmpty()) { + iplist = CustomDevicesActivity.deserializeIpList(deviceListPrefs); + } + iplist.add("255.255.255.255"); + for (String ipstr : iplist) { + try { + InetAddress client = InetAddress.getByName(ipstr); + NetworkPackage identity = NetworkPackage.createIdentityPackage(context); + identity.set("tcpPort", finalTcpPort); + byte[] b = identity.serialize().getBytes("UTF-8"); + DatagramPacket packet = new DatagramPacket(b, b.length, client, port); + DatagramSocket socket = new DatagramSocket(); + socket.setReuseAddress(true); + socket.setBroadcast(true); + socket.send(packet); + //Log.i("LanLinkProvider","Udp identity package sent to address "+packet.getAddress()); + } catch(Exception e) { + e.printStackTrace(); + Log.e("LanLinkProvider","Sending udp identity package failed. Invalid address? ("+ipstr+")"); + } } return null; diff --git a/src/main/java/org/kde/kdeconnect/UserInterface/CustomDevicesActivity.java b/src/main/java/org/kde/kdeconnect/UserInterface/CustomDevicesActivity.java new file mode 100644 index 00000000..98f0f73d --- /dev/null +++ b/src/main/java/org/kde/kdeconnect/UserInterface/CustomDevicesActivity.java @@ -0,0 +1,142 @@ +package org.kde.kdeconnect.UserInterface; + +import android.app.AlertDialog; +import android.app.ListActivity; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.ListView; +import android.widget.TextView; + +import org.kde.kdeconnect_tp.R; + +import java.util.ArrayList; + +public class CustomDevicesActivity extends ListActivity { + + private static final String LOG_ID = "CustomDevicesActivity"; + public static final String KEY_CUSTOM_DEVLIST_PREFERENCE = "device_list_preference"; + private static final String IP_DELIM = ","; + + ArrayList ipAddressList = new ArrayList(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + initializeDeviceList(this); + setContentView(R.layout.custom_ip_list); + setListAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, ipAddressList)); + + + EditText ipEntryBox = (EditText)findViewById(R.id.ip_edittext); + ipEntryBox.setOnEditorActionListener(new TextView.OnEditorActionListener() { + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_SEND) { + addNewIp(v); + return true; + } + return false; + } + }); + } + + @Override + public void onListItemClick(ListView l, View v, final int position, final long id) { + Log.i(LOG_ID, "Item clicked pos: "+position+" id: "+id); + // remove touched item after confirmation + DialogInterface.OnClickListener confirmationListener = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + switch (which) { + case DialogInterface.BUTTON_POSITIVE: + ipAddressList.remove(position); + Log.i(LOG_ID, "Removed item pos: "+position+" id: "+id); + saveList(); + break; + case DialogInterface.BUTTON_NEGATIVE: + break; + } + } + }; + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setMessage("Delete "+ipAddressList.get(position)+" ?"); + builder.setPositiveButton("Yes", confirmationListener); + builder.setNegativeButton("No", confirmationListener); + builder.show(); + ((ArrayAdapter)getListAdapter()).notifyDataSetChanged(); + } + + public void addNewIp(View v) { + EditText ipEntryBox = (EditText)findViewById(R.id.ip_edittext); + String enteredText = ipEntryBox.getText().toString().trim(); + if (!enteredText.equals("")) { + // don't add empty string (after trimming) + ipAddressList.add(enteredText); + } + + saveList(); + // clear entry box + ipEntryBox.setText(""); + InputMethodManager inputManager = (InputMethodManager) + getSystemService(Context.INPUT_METHOD_SERVICE); + + inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), + InputMethodManager.HIDE_NOT_ALWAYS); + } + + void saveList() { + // add entry to list and save to preferences (unless empty) + String serialized = ""; + if (!ipAddressList.isEmpty()) { + serialized = serializeIpList(ipAddressList); + } + PreferenceManager.getDefaultSharedPreferences(this).edit().putString( + KEY_CUSTOM_DEVLIST_PREFERENCE, serialized).commit(); + ((ArrayAdapter)getListAdapter()).notifyDataSetChanged(); + + } + + static String serializeIpList(ArrayList iplist) { + String serialized = ""; + for (String ipaddr : iplist) { + serialized += IP_DELIM+ipaddr; + } + // remove first delimiter + serialized = serialized.substring(IP_DELIM.length()); + Log.d(LOG_ID, serialized); + return serialized; + } + + public static ArrayList deserializeIpList(String serialized) { + ArrayList iplist = new ArrayList(); + Log.d(LOG_ID, serialized); + for (String ipaddr : serialized.split(IP_DELIM)) { + iplist.add(ipaddr); + Log.d(LOG_ID, ipaddr); + } + return iplist; + } + + void initializeDeviceList(Context context){ + String deviceListPrefs = PreferenceManager.getDefaultSharedPreferences(context).getString( + KEY_CUSTOM_DEVLIST_PREFERENCE, + ""); + if(deviceListPrefs.isEmpty()){ + Log.i(LOG_ID, "Initialising empty custom device list"); + PreferenceManager.getDefaultSharedPreferences(context).edit().putString( + KEY_CUSTOM_DEVLIST_PREFERENCE, + deviceListPrefs).commit(); + } else { + Log.i(LOG_ID, "Populating device list"); + ipAddressList = deserializeIpList(deviceListPrefs); + } + } +} diff --git a/src/main/java/org/kde/kdeconnect/UserInterface/MainActivity.java b/src/main/java/org/kde/kdeconnect/UserInterface/MainActivity.java index a2c6c6d7..99fcddc3 100644 --- a/src/main/java/org/kde/kdeconnect/UserInterface/MainActivity.java +++ b/src/main/java/org/kde/kdeconnect/UserInterface/MainActivity.java @@ -89,6 +89,9 @@ public class MainActivity extends ActionBarActivity { case R.id.menu_settings: startActivity(new Intent(this,MainSettingsActivity.class)); break; + case R.id.menu_custom_device_list: + startActivity(new Intent(this, CustomDevicesActivity.class)); + break; default: break; } diff --git a/src/main/res/layout/custom_ip_list.xml b/src/main/res/layout/custom_ip_list.xml new file mode 100644 index 00000000..65162eb1 --- /dev/null +++ b/src/main/res/layout/custom_ip_list.xml @@ -0,0 +1,36 @@ + + + + + + + + +