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 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/res/menu/main.xml b/src/main/res/menu/main.xml
index 189b0360..b377ca5a 100644
--- a/src/main/res/menu/main.xml
+++ b/src/main/res/menu/main.xml
@@ -24,4 +24,13 @@
android:title="@string/settings"
kdeconnect:showAsAction="never"
/>
+
+
+
\ No newline at end of file
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 5801b31c..62a6dfb6 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -98,6 +98,9 @@
%s
Invalid device name
Received text, saved to clipboard
+ Custom device list
+ Custom device list
+ Custom device list
Noisy notifications
Vibrate and play a sound when receiving a file
Internal storage
@@ -106,6 +109,8 @@
SD card
(read only)
Camera pictures
+ Add host/IP
+ Use this option only if your device is not automatically detected. Enter IP address or hostname below and touch the button to add it to the list. Touch an existing item to remove it from the list.
- 10 seconds