2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-09-02 07:05:09 +00:00

Compare commits

...

19 Commits
v0.8d ... v0.8f

Author SHA1 Message Date
Albert Vaca
86236169d1 Increase version to release 2015-04-04 18:20:57 -07:00
Albert Vaca
32d9f199ff Let's flush this socket just in case 2015-04-04 18:08:53 -07:00
Albert Vaca
1d51c8792d Do not disconnect the devices when refreshing the listeners
This caused the devices to flicker in the main activity
2015-04-04 17:09:38 -07:00
Albert Vaca
6124b9a206 Minor changes trying to debug discovery issue reported by Aleix on the list 2015-04-04 17:08:26 -07:00
Albert Vaca
c3ad265490 Fixed crash 2015-04-04 14:41:22 -07:00
Albert Vaca
9cf9f43118 Fixes some potential null pointer exceptions reported by Coverity 2015-04-04 14:29:20 -07:00
Albert Vaca
11012e21e5 Added a different notification message for failed file transfers 2015-04-04 14:29:16 -07:00
Albert Vaca
b7faa97292 Handle closing some resources that we were missing to close 2015-04-04 14:29:11 -07:00
Albert Vaca
cc17402609 Fixed NioSocketConnector being kept open after every connection received
And other fixes in the LanLinkProvider
2015-04-04 12:55:52 -07:00
Albert Vaca
a0b82d17b4 Added some logging to help debugging an issue, now commented for future use
Also we prepend KDE/ to these logs to ease filtering them
2015-04-04 11:37:12 -07:00
Albert Vaca
8550de5e7f Coding style 2015-04-04 10:43:49 -07:00
Albert Vaca
46c70639ac Only unpair when receiving unknown packages if I'm not requesting pairing
In case the other device thinks we are paired and answers my identity
packet with unexpected stuff.
2015-03-30 23:26:57 -07:00
l10n daemon script
fb2b1232fb SVN_SILENT made messages (after extraction) 2015-03-31 02:22:21 +00:00
l10n daemon script
c2011831a9 SVN_SILENT made messages (after extraction) 2015-03-30 02:06:46 +00:00
l10n daemon script
ac3ab375ab SVN_SILENT made messages (after extraction) 2015-03-21 02:14:46 +00:00
Albert Vaca
ab4a1079cc Increased version number to release 2015-03-15 17:52:25 -07:00
Albert Vaca
57871802d8 Only try to mount the root of the phone if we have read access to it
BUG: 336043
2015-03-15 17:52:25 -07:00
Albert Vaca
838be381c3 Establishing connection only worked one way (bug introduced in 459fe40) 2015-03-15 16:58:28 -07:00
l10n daemon script
53ad94ef32 SVN_SILENT made messages (after extraction) 2015-03-14 02:09:03 +00:00
19 changed files with 378 additions and 258 deletions

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.kde.kdeconnect_tp" package="org.kde.kdeconnect_tp"
android:versionCode="804" android:versionCode="806"
android:versionName="0.8d"> android:versionName="0.8f">
<uses-sdk android:minSdkVersion="9" <uses-sdk android:minSdkVersion="9"
android:targetSdkVersion="21" /> android:targetSdkVersion="21" />

View File

@@ -3,7 +3,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:1.0.+' classpath 'com.android.tools.build:gradle:1.1.0'
} }
} }

View File

@@ -8,6 +8,7 @@
<string name="pref_plugin_sftp_desc">Erlaubt das Browsen des Dateisystems auf dem entfernten Handy</string> <string name="pref_plugin_sftp_desc">Erlaubt das Browsen des Dateisystems auf dem entfernten Handy</string>
<string name="pref_plugin_clipboard">Abgleich der Zwischenablage</string> <string name="pref_plugin_clipboard">Abgleich der Zwischenablage</string>
<string name="pref_plugin_clipboard_desc">Inhalt der Zwischenablage freigeben</string> <string name="pref_plugin_clipboard_desc">Inhalt der Zwischenablage freigeben</string>
<string name="pref_plugin_mousepad_desc">Verwendet Ihr Handy als Maus und Tastatur</string>
<string name="pref_plugin_mpris">Multimedia-Fernbedienungen</string> <string name="pref_plugin_mpris">Multimedia-Fernbedienungen</string>
<string name="pref_plugin_mpris_desc">Audio und Video mit Ihrem Telefon steuern</string> <string name="pref_plugin_mpris_desc">Audio und Video mit Ihrem Telefon steuern</string>
<string name="pref_plugin_ping">Ping</string> <string name="pref_plugin_ping">Ping</string>
@@ -52,7 +53,13 @@
<string name="received_url_title">Verknüpfung von %1s erhalten</string> <string name="received_url_title">Verknüpfung von %1s erhalten</string>
<string name="incoming_file_title">Eingehende Datei von %1s</string> <string name="incoming_file_title">Eingehende Datei von %1s</string>
<string name="incoming_file_text">%1s</string> <string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Datei wird an %1s gesendet</string>
<string name="outgoing_file_text">%1s</string>
<string name="received_file_title">Datei von %1s erhalten</string> <string name="received_file_title">Datei von %1s erhalten</string>
<string name="sent_file_title">Datei an %1s gesendet</string>
<string name="sent_file_text">%1s</string>
<string name="sent_file_failed_title">Das Senden der Datei an %1s ist fehlgeschlagen</string>
<string name="sent_file_failed_text">%1s</string>
<string name="tap_to_answer">Tippen zum Antworten</string> <string name="tap_to_answer">Tippen zum Antworten</string>
<string name="reconnect">Erneut verbinden</string> <string name="reconnect">Erneut verbinden</string>
<string name="right_click">Rechtsklick senden</string> <string name="right_click">Rechtsklick senden</string>
@@ -91,7 +98,9 @@
<string name="invalid_device_name">Ungültiger Gerätename</string> <string name="invalid_device_name">Ungültiger Gerätename</string>
<string name="shareplugin_text_saved">Text empfangen und in der Zwischenablage gespeichert</string> <string name="shareplugin_text_saved">Text empfangen und in der Zwischenablage gespeichert</string>
<string name="custom_devices_settings">Benutzerdefinierte Geräteliste</string> <string name="custom_devices_settings">Benutzerdefinierte Geräteliste</string>
<string name="custom_device_list">Geräte nach IP hinzufügen</string>
<string name="share_notification_preference_summary">Beim Empfang einer Datei vibrieren und einen Sound abspielen</string> <string name="share_notification_preference_summary">Beim Empfang einer Datei vibrieren und einen Sound abspielen</string>
<string name="title_activity_notification_filter">Benachrichtigungs-Filter</string>
<string name="sftp_internal_storage">Interner Speicher</string> <string name="sftp_internal_storage">Interner Speicher</string>
<string name="sftp_all_files">Alle Dateien</string> <string name="sftp_all_files">Alle Dateien</string>
<string name="sftp_sdcard_num">SD-Karte %d</string> <string name="sftp_sdcard_num">SD-Karte %d</string>
@@ -99,5 +108,6 @@
<string name="sftp_readonly">(Nur lesen)</string> <string name="sftp_readonly">(Nur lesen)</string>
<string name="sftp_camera">Kamerabilder</string> <string name="sftp_camera">Kamerabilder</string>
<string name="add_host">Rechner/IP hinzufügen</string> <string name="add_host">Rechner/IP hinzufügen</string>
<string name="add_host_hint">Rechnername oder IP</string>
<string name="mpris_player_on_device">%1$s auf %2$s</string> <string name="mpris_player_on_device">%1$s auf %2$s</string>
</resources> </resources>

View File

@@ -27,6 +27,7 @@
<string name="send_ping">Poslať ping</string> <string name="send_ping">Poslať ping</string>
<string name="open_mpris_controls">Otvoriť diaľkové ovládanie</string> <string name="open_mpris_controls">Otvoriť diaľkové ovládanie</string>
<string name="open_mousepad">Otvoriť ovládanie touchpadu</string> <string name="open_mousepad">Otvoriť ovládanie touchpadu</string>
<string name="mousepad_info">Posúvajte prst na obrazovke na posun kurzora. Ťuknutie vyvolá klik a použite dva/tri prsty pre pravé a stredné tlačidlo. Použite dlhé stlačenie pre drag and drop.</string>
<string name="mousepad_double_tap_settings_title">Nastaviť akciu dvoch prstov</string> <string name="mousepad_double_tap_settings_title">Nastaviť akciu dvoch prstov</string>
<string name="mousepad_triple_tap_settings_title">Nastaviť akciu troch prstov</string> <string name="mousepad_triple_tap_settings_title">Nastaviť akciu troch prstov</string>
<string-array name="mousepad_tap_entries"> <string-array name="mousepad_tap_entries">
@@ -58,10 +59,13 @@
<string name="received_url_text">Ťuknite na otvorenie \'%1s\'</string> <string name="received_url_text">Ťuknite na otvorenie \'%1s\'</string>
<string name="incoming_file_title">Prichádzajúci súbor od %s</string> <string name="incoming_file_title">Prichádzajúci súbor od %s</string>
<string name="incoming_file_text">%1s</string> <string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Posielam súbor pre %1s</string>
<string name="outgoing_file_text">%1s</string> <string name="outgoing_file_text">%1s</string>
<string name="received_file_title">Prijatý súbor od %1s</string> <string name="received_file_title">Prijatý súbor od %1s</string>
<string name="received_file_text">Ťuknite na otvorenie \'%1s\'</string> <string name="received_file_text">Ťuknite na otvorenie \'%1s\'</string>
<string name="sent_file_title">Poslať súbor pre %1s</string>
<string name="sent_file_text">%1s</string> <string name="sent_file_text">%1s</string>
<string name="sent_file_failed_title">Zlyhalo poslanie súboru %1s</string>
<string name="sent_file_failed_text">%1s</string> <string name="sent_file_failed_text">%1s</string>
<string name="tap_to_answer">Tapnite na odpoveď</string> <string name="tap_to_answer">Tapnite na odpoveď</string>
<string name="reconnect">Znovu pripojiť</string> <string name="reconnect">Znovu pripojiť</string>
@@ -83,6 +87,8 @@
<string name="mpris_next">Nasledovné</string> <string name="mpris_next">Nasledovné</string>
<string name="mpris_volume">Hlasitosť</string> <string name="mpris_volume">Hlasitosť</string>
<string name="mpris_settings">Multimediálne nastavenia</string> <string name="mpris_settings">Multimediálne nastavenia</string>
<string name="mpris_time_settings_title">Tlačidlá dopredu/pretočiť</string>
<string name="mpris_time_settings_summary">Prispôsobiť čas na pretáčanie dopredu alebo dozadu pri stlačení.</string>
<string-array name="mpris_time_entries"> <string-array name="mpris_time_entries">
<item>10 sekúnd</item> <item>10 sekúnd</item>
<item>20 sekúnd</item> <item>20 sekúnd</item>
@@ -104,6 +110,8 @@
<string name="custom_device_list">Pridať zariadenia podľa IP</string> <string name="custom_device_list">Pridať zariadenia podľa IP</string>
<string name="share_notification_preference">Hlučné pripomienky</string> <string name="share_notification_preference">Hlučné pripomienky</string>
<string name="share_notification_preference_summary">Vibrovať a prehrať zvuk pri prijatí súboru</string> <string name="share_notification_preference_summary">Vibrovať a prehrať zvuk pri prijatí súboru</string>
<string name="title_activity_notification_filter">Filter upozornení</string>
<string name="filter_apps_info">Upozornenia budú synchronizované pre vybrané aplikácie.</string>
<string name="sftp_internal_storage">Interné úložisko</string> <string name="sftp_internal_storage">Interné úložisko</string>
<string name="sftp_all_files">Všetky súbory</string> <string name="sftp_all_files">Všetky súbory</string>
<string name="sftp_sdcard_num">SD karta %d</string> <string name="sftp_sdcard_num">SD karta %d</string>
@@ -111,6 +119,7 @@
<string name="sftp_readonly">(iba na čítanie)</string> <string name="sftp_readonly">(iba na čítanie)</string>
<string name="sftp_camera">Obrázky fotoaparátu</string> <string name="sftp_camera">Obrázky fotoaparátu</string>
<string name="add_host">Pridať hostiteľa/IP</string> <string name="add_host">Pridať hostiteľa/IP</string>
<string name="add_host_hint">Názov hostiteľa alebo IP</string>
<string name="no_players_connected">Nenašli sa žiadne prehrávače</string> <string name="no_players_connected">Nenašli sa žiadne prehrávače</string>
<string name="custom_dev_list_help">Túto voľbu použite iba vtedy, ak vaše zariadenie nie je automaticky detekované. Zadajte IP adresu alebo názov hostiteľa nižšie a kliknite na tlačidlo na pridanie do zoznamu. Kliknite na existujúcu položku na odstránenie jej zo zoznamu.</string> <string name="custom_dev_list_help">Túto voľbu použite iba vtedy, ak vaše zariadenie nie je automaticky detekované. Zadajte IP adresu alebo názov hostiteľa nižšie a kliknite na tlačidlo na pridanie do zoznamu. Kliknite na existujúcu položku na odstránenie jej zo zoznamu.</string>
<string name="mpris_player_on_device">%1$s na %2$s</string> <string name="mpris_player_on_device">%1$s na %2$s</string>

View File

@@ -70,6 +70,7 @@
<string name="outgoing_file_title">Sending file to %1s</string> <string name="outgoing_file_title">Sending file to %1s</string>
<string name="outgoing_file_text">%1s</string> <string name="outgoing_file_text">%1s</string>
<string name="received_file_title">Received file from %1s</string> <string name="received_file_title">Received file from %1s</string>
<string name="received_file_fail_title">Failed receiving file from %1s</string>
<string name="received_file_text">Tap to open \'%1s\'</string> <string name="received_file_text">Tap to open \'%1s\'</string>
<string name="sent_file_title">Sent file to %1s</string> <string name="sent_file_title">Sent file to %1s</string>
<string name="sent_file_text">%1s</string> <string name="sent_file_text">%1s</string>

View File

@@ -46,13 +46,13 @@ public abstract class BaseLinkProvider {
//These two should be called when the provider links to a new computer //These two should be called when the provider links to a new computer
protected void connectionAccepted(NetworkPackage identityPackage, BaseLink link) { protected void connectionAccepted(NetworkPackage identityPackage, BaseLink link) {
Log.i("LinkProvider", "connectionAccepted"); //Log.i("KDE/LinkProvider", "connectionAccepted");
for(ConnectionReceiver cr : connectionReceivers) { for(ConnectionReceiver cr : connectionReceivers) {
cr.onConnectionReceived(identityPackage, link); cr.onConnectionReceived(identityPackage, link);
} }
} }
protected void connectionLost(BaseLink link) { protected void connectionLost(BaseLink link) {
Log.i("LinkProvider", "connectionLost"); //Log.i("KDE/LinkProvider", "connectionLost");
for(ConnectionReceiver cr : connectionReceivers) { for(ConnectionReceiver cr : connectionReceivers) {
cr.onConnectionLost(link); cr.onConnectionLost(link);
} }

View File

@@ -47,8 +47,10 @@ public class LanLink extends BaseLink {
private IoSession session = null; private IoSession session = null;
public void disconnect() { public void disconnect() {
if (session == null) return; if (session == null) {
//Log.i("LanLink", "Disconnect: "+session.getRemoteAddress().toString()); Log.e("KDE/LanLink", "Not yet connected");
return;
}
session.close(true); session.close(true);
} }
@@ -60,7 +62,7 @@ public class LanLink extends BaseLink {
//Blocking, do not call from main thread //Blocking, do not call from main thread
private void sendPackageInternal(NetworkPackage np, final Device.SendPackageStatusCallback callback, PublicKey key) { private void sendPackageInternal(NetworkPackage np, final Device.SendPackageStatusCallback callback, PublicKey key) {
if (session == null) { if (session == null) {
Log.e("sendPackage", "Not yet connected"); Log.e("KDE/sendPackage", "Not yet connected");
callback.sendFailure(new NotYetConnectedException()); callback.sendFailure(new NotYetConnectedException());
return; return;
} }
@@ -87,7 +89,7 @@ public class LanLink extends BaseLink {
WriteFuture future = session.write(np.serialize()); WriteFuture future = session.write(np.serialize());
future.awaitUninterruptibly(); future.awaitUninterruptibly();
if (!future.isWritten()) { if (!future.isWritten()) {
Log.e("sendPackage", "!future.isWritten()"); Log.e("KDE/sendPackage", "!future.isWritten()");
callback.sendFailure(future.getException()); callback.sendFailure(future.getException());
return; return;
} }
@@ -101,7 +103,7 @@ public class LanLink extends BaseLink {
timeout.schedule(new TimerTask() { timeout.schedule(new TimerTask() {
@Override @Override
public void run() { public void run() {
Log.e("sendPackage","Timeout"); Log.e("KDE/sendPackage","Timeout");
try { server.close(); } catch (Exception e) { } try { server.close(); } catch (Exception e) { }
callback.sendFailure(new TimeoutException("Timed out waiting for other end to establish a connection to receive the payload.")); callback.sendFailure(new TimeoutException("Timed out waiting for other end to establish a connection to receive the payload."));
} }
@@ -109,7 +111,7 @@ public class LanLink extends BaseLink {
socket = server.accept().getOutputStream(); socket = server.accept().getOutputStream();
timeout.cancel(); timeout.cancel();
Log.i("LanLink", "Beginning to send payload"); Log.i("KDE/LanLink", "Beginning to send payload");
byte[] buffer = new byte[4096]; byte[] buffer = new byte[4096];
int bytesRead; int bytesRead;
@@ -123,9 +125,11 @@ public class LanLink extends BaseLink {
callback.sendProgress((int)(progress / np.getPayloadSize())); callback.sendProgress((int)(progress / np.getPayloadSize()));
} }
} }
Log.i("LanLink", "Finished sending payload"); socket.flush();
stream.close();
Log.i("KDE/LanLink", "Finished sending payload");
} catch (Exception e) { } catch (Exception e) {
Log.e("sendPackage", "Exception: "+e); Log.e("KDE/sendPackage", "Exception: "+e);
callback.sendFailure(e); callback.sendFailure(e);
return; return;
} finally { } finally {
@@ -167,22 +171,24 @@ public class LanLink extends BaseLink {
np = np.decrypt(privateKey); np = np.decrypt(privateKey);
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
Log.e("onPackageReceived","Exception reading the key needed to decrypt the package"); Log.e("KDE/onPackageReceived","Exception reading the key needed to decrypt the package");
} }
} }
if (np.hasPayloadTransferInfo()) { if (np.hasPayloadTransferInfo()) {
Socket socket = null;
try { try {
Socket socket = new Socket(); socket = new Socket();
int tcpPort = np.getPayloadTransferInfo().getInt("port"); int tcpPort = np.getPayloadTransferInfo().getInt("port");
InetSocketAddress address = (InetSocketAddress)session.getRemoteAddress(); InetSocketAddress address = (InetSocketAddress)session.getRemoteAddress();
socket.connect(new InetSocketAddress(address.getAddress(), tcpPort)); socket.connect(new InetSocketAddress(address.getAddress(), tcpPort));
np.setPayload(socket.getInputStream(), np.getPayloadSize()); np.setPayload(socket.getInputStream(), np.getPayloadSize());
} catch (Exception e) { } catch (Exception e) {
try { socket.close(); } catch(Exception ignored) { }
e.printStackTrace(); e.printStackTrace();
Log.e("LanLink", "Exception connecting to payload remote socket"); Log.e("KDE/LanLink", "Exception connecting to payload remote socket");
} }
} }
@@ -200,12 +206,12 @@ public class LanLink extends BaseLink {
candidateServer = new ServerSocket(); candidateServer = new ServerSocket();
candidateServer.bind(new InetSocketAddress(tcpPort)); candidateServer.bind(new InetSocketAddress(tcpPort));
success = true; success = true;
Log.i("LanLink", "Using port "+tcpPort); Log.i("KDE/LanLink", "Using port "+tcpPort);
} catch(IOException e) { } catch(IOException e) {
//Log.e("LanLink", "Exception openning serversocket: "+e); //Log.e("LanLink", "Exception openning serversocket: "+e);
tcpPort++; tcpPort++;
if (tcpPort >= 1764) { if (tcpPort >= 1764) {
Log.e("LanLink", "No more ports available"); Log.e("KDE/LanLink", "No more ports available");
throw e; throw e;
} }
} }

View File

@@ -21,7 +21,6 @@
package org.kde.kdeconnect.Backends.LanBackend; package org.kde.kdeconnect.Backends.LanBackend;
import android.content.Context; import android.content.Context;
import android.os.AsyncTask;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v4.util.LongSparseArray; import android.support.v4.util.LongSparseArray;
import android.util.Log; import android.util.Log;
@@ -47,9 +46,11 @@ import java.net.DatagramPacket;
import java.net.DatagramSocket; import java.net.DatagramSocket;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Set;
public class LanLinkProvider extends BaseLinkProvider { public class LanLinkProvider extends BaseLinkProvider {
@@ -59,6 +60,7 @@ public class LanLinkProvider extends BaseLinkProvider {
private final Context context; private final Context context;
private final HashMap<String, LanLink> visibleComputers = new HashMap<String, LanLink>(); private final HashMap<String, LanLink> visibleComputers = new HashMap<String, LanLink>();
private final LongSparseArray<LanLink> nioSessions = new LongSparseArray<LanLink>(); private final LongSparseArray<LanLink> nioSessions = new LongSparseArray<LanLink>();
private final LongSparseArray<NioSocketConnector> nioConnectors = new LongSparseArray<NioSocketConnector>();
private NioSocketAcceptor tcpAcceptor = null; private NioSocketAcceptor tcpAcceptor = null;
private NioDatagramAcceptor udpAcceptor = null; private NioDatagramAcceptor udpAcceptor = null;
@@ -66,29 +68,46 @@ public class LanLinkProvider extends BaseLinkProvider {
private final IoHandler tcpHandler = new IoHandlerAdapter() { private final IoHandler tcpHandler = new IoHandlerAdapter() {
@Override @Override
public void sessionClosed(IoSession session) throws Exception { public void sessionClosed(IoSession session) throws Exception {
try {
final LanLink brokenLink = nioSessions.get(session.getId()); long id = session.getId();
if (brokenLink != null) { final LanLink brokenLink = nioSessions.get(id);
nioSessions.remove(session.getId()); NioSocketConnector connector = nioConnectors.get(id);
brokenLink.disconnect(); if (connector != null) {
String deviceId = brokenLink.getDeviceId(); connector.dispose();
if (visibleComputers.get(deviceId) == brokenLink) { nioConnectors.remove(id);
visibleComputers.remove(deviceId);
} }
new Thread(new Runnable() { if (brokenLink != null) {
@Override nioSessions.remove(id);
public void run() { //Log.i("KDE/LanLinkProvider", "nioSessions.size(): " + nioSessions.size() + " (-)");
//Wait a bit before emiting connectionLost, in case the same device re-appears try {
try { brokenLink.disconnect();
Thread.sleep(200); } catch (Exception e) {
} catch (InterruptedException e) { } e.printStackTrace();
connectionLost(brokenLink); Log.e("KDE/LanLinkProvider", "Exception. Already disconnected?");
} }
}).start(); //Log.i("KDE/LanLinkProvider", "Disconnected!");
String deviceId = brokenLink.getDeviceId();
if (visibleComputers.get(deviceId) == brokenLink) {
visibleComputers.remove(deviceId);
}
new Thread(new Runnable() {
@Override
public void run() {
//Wait a bit before emiting connectionLost, in case the same device re-appears
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
connectionLost(brokenLink);
}
}).start();
}
} catch (Exception e) { //If we don't catch it here, Mina will swallow it :/
e.printStackTrace();
Log.e("KDE/LanLinkProvider", "sessionClosed exception");
} }
} }
@Override @Override
@@ -100,7 +119,7 @@ public class LanLinkProvider extends BaseLinkProvider {
String theMessage = (String) message; String theMessage = (String) message;
if (theMessage.isEmpty()) { if (theMessage.isEmpty()) {
Log.e("LanLinkProvider","Empty package received"); Log.e("KDE/LanLinkProvider","Empty package received");
return; return;
} }
@@ -113,15 +132,16 @@ public class LanLinkProvider extends BaseLinkProvider {
return; return;
} }
//Log.e("LanLinkProvider", "Identity package received from "+np.getString("deviceName")); //Log.i("KDE/LanLinkProvider", "Identity package received from " + np.getString("deviceName"));
LanLink link = new LanLink(session, np.getString("deviceId"), LanLinkProvider.this); LanLink link = new LanLink(session, np.getString("deviceId"), LanLinkProvider.this);
nioSessions.put(session.getId(),link); nioSessions.put(session.getId(),link);
//Log.e("KDE/LanLinkProvider","nioSessions.size(): " + nioSessions.size());
addLink(np, link); addLink(np, link);
} else { } else {
LanLink prevLink = nioSessions.get(session.getId()); LanLink prevLink = nioSessions.get(session.getId());
if (prevLink == null) { if (prevLink == null) {
Log.e("LanLinkProvider","2 Expecting an identity package"); Log.e("KDE/LanLinkProvider","Expecting an identity package (A)");
} else { } else {
prevLink.injectNetworkPackage(np); prevLink.injectNetworkPackage(np);
} }
@@ -143,7 +163,7 @@ public class LanLinkProvider extends BaseLinkProvider {
final NetworkPackage identityPackage = NetworkPackage.unserialize(theMessage); final NetworkPackage identityPackage = NetworkPackage.unserialize(theMessage);
if (!identityPackage.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) { if (!identityPackage.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
Log.e("LanLinkProvider", "1 Expecting an identity package"); Log.e("KDE/LanLinkProvider", "Expecting an identity package (B)");
return; return;
} else { } else {
String myId = NetworkPackage.createIdentityPackage(context).getString("deviceId"); String myId = NetworkPackage.createIdentityPackage(context).getString("deviceId");
@@ -152,7 +172,7 @@ public class LanLinkProvider extends BaseLinkProvider {
} }
} }
Log.i("LanLinkProvider", "Identity package received, creating link"); //Log.i("KDE/LanLinkProvider", "Identity package received, creating link");
final InetSocketAddress address = (InetSocketAddress) udpSession.getRemoteAddress(); final InetSocketAddress address = (InetSocketAddress) udpSession.getRemoteAddress();
@@ -162,44 +182,50 @@ public class LanLinkProvider extends BaseLinkProvider {
//TextLineCodecFactory will buffer incoming data and emit a message very time it finds a \n //TextLineCodecFactory will buffer incoming data and emit a message very time it finds a \n
TextLineCodecFactory textLineFactory = new TextLineCodecFactory(Charset.defaultCharset(), LineDelimiter.UNIX, LineDelimiter.UNIX); TextLineCodecFactory textLineFactory = new TextLineCodecFactory(Charset.defaultCharset(), LineDelimiter.UNIX, LineDelimiter.UNIX);
textLineFactory.setDecoderMaxLineLength(512*1024); //Allow to receive up to 512kb of data textLineFactory.setDecoderMaxLineLength(512*1024); //Allow to receive up to 512kb of data
tcpAcceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(textLineFactory)); connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(textLineFactory));
int tcpPort = identityPackage.getInt("tcpPort",port); int tcpPort = identityPackage.getInt("tcpPort", port);
ConnectFuture future = connector.connect(new InetSocketAddress(address.getAddress(), tcpPort)); final ConnectFuture future = connector.connect(new InetSocketAddress(address.getAddress(), tcpPort));
future.addListener(new IoFutureListener<IoFuture>() { future.addListener(new IoFutureListener<IoFuture>() {
@Override @Override
public void operationComplete(IoFuture ioFuture) { public void operationComplete(IoFuture ioFuture) {
final IoSession session = ioFuture.getSession(); try {
future.removeListener(this);
final IoSession session = ioFuture.getSession();
Log.i("KDE/LanLinkProvider", "Connection successful: " + session.isConnected());
final LanLink link = new LanLink(session, identityPackage.getString("deviceId"), LanLinkProvider.this); final LanLink link = new LanLink(session, identityPackage.getString("deviceId"), LanLinkProvider.this);
new Thread(new Runnable() {
@Override
public void run() {
NetworkPackage np2 = NetworkPackage.createIdentityPackage(context);
link.sendPackage(np2,new Device.SendPackageStatusCallback() {
@Override
protected void onSuccess() {
nioSessions.put(session.getId(), link);
nioConnectors.put(session.getId(), connector);
//Log.e("KDE/LanLinkProvider","nioSessions.size(): " + nioSessions.size());
addLink(identityPackage, link);
}
Log.i("LanLinkProvider", "Connection successful: " + session.isConnected()); @Override
protected void onFailure(Throwable e) {
new Thread(new Runnable() { Log.e("KDE/LanLinkProvider", "Connection failed: could not send identity package back");
@Override }
public void run() { });
NetworkPackage np2 = NetworkPackage.createIdentityPackage(context);
link.sendPackage(np2,new Device.SendPackageStatusCallback() {
@Override
protected void onSuccess() {
nioSessions.put(session.getId(), link);
addLink(identityPackage, link);
}
@Override
protected void onFailure(Throwable e) {
}
});
}
}).start();
}
}).start();
} catch (Exception e) { //If we don't catch it here, Mina will swallow it :/
e.printStackTrace();
Log.e("KDE/LanLinkProvider", "sessionClosed exception");
}
} }
}); });
} catch (Exception e) { } catch (Exception e) {
Log.e("LanLinkProvider","Exception receiving udp package!!"); Log.e("KDE/LanLinkProvider","Exception receiving udp package!!");
e.printStackTrace(); e.printStackTrace();
} }
@@ -208,16 +234,16 @@ public class LanLinkProvider extends BaseLinkProvider {
private void addLink(NetworkPackage identityPackage, LanLink link) { private void addLink(NetworkPackage identityPackage, LanLink link) {
String deviceId = identityPackage.getString("deviceId"); String deviceId = identityPackage.getString("deviceId");
Log.i("LanLinkProvider","addLink to "+deviceId); Log.i("KDE/LanLinkProvider","addLink to "+deviceId);
LanLink oldLink = visibleComputers.get(deviceId); LanLink oldLink = visibleComputers.get(deviceId);
if (oldLink == link) { if (oldLink == link) {
Log.e("KDEConnect", "LanLinkProvider: oldLink == link. This should not happen!"); Log.e("KDE/LanLinkProvider", "oldLink == link. This should not happen!");
return; return;
} }
visibleComputers.put(deviceId, link); visibleComputers.put(deviceId, link);
connectionAccepted(identityPackage, link); connectionAccepted(identityPackage, link);
if (oldLink != null) { if (oldLink != null) {
Log.i("LanLinkProvider","Removing old connection to same device"); Log.i("KDE/LanLinkProvider","Removing old connection to same device");
oldLink.disconnect(); oldLink.disconnect();
connectionLost(oldLink); connectionLost(oldLink);
} }
@@ -232,13 +258,11 @@ public class LanLinkProvider extends BaseLinkProvider {
tcpAcceptor.setHandler(tcpHandler); tcpAcceptor.setHandler(tcpHandler);
tcpAcceptor.getSessionConfig().setKeepAlive(true); tcpAcceptor.getSessionConfig().setKeepAlive(true);
tcpAcceptor.getSessionConfig().setReuseAddress(true); tcpAcceptor.getSessionConfig().setReuseAddress(true);
tcpAcceptor.setCloseOnDeactivation(false);
//TextLineCodecFactory will buffer incoming data and emit a message very time it finds a \n //TextLineCodecFactory will buffer incoming data and emit a message very time it finds a \n
TextLineCodecFactory textLineFactory = new TextLineCodecFactory(Charset.defaultCharset(), LineDelimiter.UNIX, LineDelimiter.UNIX); TextLineCodecFactory textLineFactory = new TextLineCodecFactory(Charset.defaultCharset(), LineDelimiter.UNIX, LineDelimiter.UNIX);
textLineFactory.setDecoderMaxLineLength(512*1024); //Allow to receive up to 512kb of data textLineFactory.setDecoderMaxLineLength(512*1024); //Allow to receive up to 512kb of data
tcpAcceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(textLineFactory)); tcpAcceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(textLineFactory));
udpAcceptor = new NioDatagramAcceptor(); udpAcceptor = new NioDatagramAcceptor();
udpAcceptor.getSessionConfig().setReuseAddress(true); //Share port if existing udpAcceptor.getSessionConfig().setReuseAddress(true); //Share port if existing
//TextLineCodecFactory will buffer incoming data and emit a message very time it finds a \n //TextLineCodecFactory will buffer incoming data and emit a message very time it finds a \n
@@ -256,12 +280,19 @@ public class LanLinkProvider extends BaseLinkProvider {
//This handles the case when I'm the existing device in the network and receive a "hello" UDP package //This handles the case when I'm the existing device in the network and receive a "hello" UDP package
Set<SocketAddress> addresses = udpAcceptor.getLocalAddresses();
for (SocketAddress address : addresses) {
Log.i("KDE/LanLinkProvider", "UDP unbind old address");
udpAcceptor.unbind(address);
}
//Log.i("KDE/LanLinkProvider", "UDP Bind.");
udpAcceptor.setHandler(udpHandler); udpAcceptor.setHandler(udpHandler);
try { try {
udpAcceptor.bind(new InetSocketAddress(port)); udpAcceptor.bind(new InetSocketAddress(port));
} catch(Exception e) { } catch(Exception e) {
Log.e("LanLinkProvider", "Error: Could not bind udp socket"); Log.e("KDE/LanLinkProvider", "Error: Could not bind udp socket");
e.printStackTrace(); e.printStackTrace();
} }
@@ -276,50 +307,73 @@ public class LanLinkProvider extends BaseLinkProvider {
} }
} }
Log.i("LanLinkProvider","Using tcpPort "+tcpPort); Log.i("KDE/LanLinkProvider","Using tcpPort "+tcpPort);
//I'm on a new network, let's be polite and introduce myself //I'm on a new network, let's be polite and introduce myself
final int finalTcpPort = tcpPort; final int finalTcpPort = tcpPort;
new AsyncTask<Void,Void,Void>() { new Thread(new Runnable() {
@Override @Override
protected Void doInBackground(Void... voids) { public void run() {
String deviceListPrefs = PreferenceManager.getDefaultSharedPreferences(context).getString( String deviceListPrefs = PreferenceManager.getDefaultSharedPreferences(context).getString(
KEY_CUSTOM_DEVLIST_PREFERENCE, ""); KEY_CUSTOM_DEVLIST_PREFERENCE, "");
ArrayList<String> iplist = new ArrayList<String>(); ArrayList<String> iplist = new ArrayList<String>();
if (!deviceListPrefs.isEmpty()) { if (!deviceListPrefs.isEmpty()) {
iplist = CustomDevicesActivity.deserializeIpList(deviceListPrefs); iplist = CustomDevicesActivity.deserializeIpList(deviceListPrefs);
} }
iplist.add("255.255.255.255"); iplist.add("255.255.255.255"); //Default: broadcast.
for (String ipstr : iplist) {
try { NetworkPackage identity = NetworkPackage.createIdentityPackage(context);
InetAddress client = InetAddress.getByName(ipstr); identity.set("tcpPort", finalTcpPort);
NetworkPackage identity = NetworkPackage.createIdentityPackage(context); DatagramSocket socket = null;
identity.set("tcpPort", finalTcpPort); byte[] bytes = null;
byte[] b = identity.serialize().getBytes("UTF-8"); try {
DatagramPacket packet = new DatagramPacket(b, b.length, client, port); socket = new DatagramSocket();
DatagramSocket socket = new DatagramSocket(); socket.setReuseAddress(true);
socket.setReuseAddress(true); socket.setBroadcast(true);
socket.setBroadcast(true); bytes = identity.serialize().getBytes("UTF-8");
socket.send(packet); } catch (Exception e) {
//Log.i("LanLinkProvider","Udp identity package sent to address "+packet.getAddress()); e.printStackTrace();
} catch(Exception e) { Log.e("KDE/LanLinkProvider","Failed to create DatagramSocket");
e.printStackTrace(); }
Log.e("LanLinkProvider","Sending udp identity package failed. Invalid address? ("+ipstr+")");
if (bytes != null) {
//Log.e("KDE/LanLinkProvider","Sending packet to "+iplist.size()+" ips");
for (String ipstr : iplist) {
try {
InetAddress client = InetAddress.getByName(ipstr);
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, client, port);
socket.send(packet);
//Log.i("KDE/LanLinkProvider","Udp identity package sent to address "+packet.getAddress());
} catch (Exception e) {
e.printStackTrace();
Log.e("KDE/LanLinkProvider", "Sending udp identity package failed. Invalid address? (" + ipstr + ")");
}
} }
} }
return null; socket.close();
} }
}).start();
}.execute();
} }
@Override @Override
public void onNetworkChange() { public void onNetworkChange() {
//Log.e("KDE/LanLinkProvider","onNetworkChange");
//FilesHelper.LogOpenFileCount();
//Keep existing connections open while unbinding the socket
tcpAcceptor.setCloseOnDeactivation(false);
onStop(); onStop();
tcpAcceptor.setCloseOnDeactivation(true);
//FilesHelper.LogOpenFileCount();
onStart(); onStart();
//FilesHelper.LogOpenFileCount();
} }
@Override @Override
@@ -327,14 +381,12 @@ public class LanLinkProvider extends BaseLinkProvider {
udpAcceptor.unbind(); udpAcceptor.unbind();
tcpAcceptor.unbind(); tcpAcceptor.unbind();
} }
/*
@Override
public int getPriority() {
return 1000;
}
*/
@Override @Override
public String getName() { public String getName() {
return "LanLinkProvider"; return "LanLinkProvider";
} }
} }

View File

@@ -105,17 +105,17 @@ public class BackgroundService extends Service {
@Override @Override
public void onConnectionReceived(final NetworkPackage identityPackage, final BaseLink link) { public void onConnectionReceived(final NetworkPackage identityPackage, final BaseLink link) {
Log.i("BackgroundService", "Connection accepted!"); Log.i("KDE/BackgroundService", "Connection accepted!");
String deviceId = identityPackage.getString("deviceId"); String deviceId = identityPackage.getString("deviceId");
Device device = devices.get(deviceId); Device device = devices.get(deviceId);
if (device != null) { if (device != null) {
Log.i("BackgroundService", "addLink, known device: " + deviceId); Log.i("KDE/BackgroundService", "addLink, known device: " + deviceId);
device.addLink(identityPackage, link); device.addLink(identityPackage, link);
} else { } else {
Log.i("BackgroundService", "addLink,unknown device: " + deviceId); Log.i("KDE/BackgroundService", "addLink,unknown device: " + deviceId);
device = new Device(BackgroundService.this, identityPackage, link); device = new Device(BackgroundService.this, identityPackage, link);
devices.put(deviceId, device); devices.put(deviceId, device);
device.addPairingCallback(devicePairingCallback); device.addPairingCallback(devicePairingCallback);
@@ -127,7 +127,7 @@ public class BackgroundService extends Service {
@Override @Override
public void onConnectionLost(BaseLink link) { public void onConnectionLost(BaseLink link) {
Device d = devices.get(link.getDeviceId()); Device d = devices.get(link.getDeviceId());
Log.i("onConnectionLost", "removeLink, deviceId: " + link.getDeviceId()); Log.i("KDE/onConnectionLost", "removeLink, deviceId: " + link.getDeviceId());
if (d != null) { if (d != null) {
d.removeLink(link); d.removeLink(link);
if (!d.isReachable() && !d.isPaired()) { if (!d.isReachable() && !d.isPaired()) {
@@ -136,7 +136,7 @@ public class BackgroundService extends Service {
d.removePairingCallback(devicePairingCallback); d.removePairingCallback(devicePairingCallback);
} }
} else { } else {
Log.e("onConnectionLost","Removing connection to unknown device, this should not happen"); Log.e("KDE/onConnectionLost","Removing connection to unknown device, this should not happen");
} }
if (deviceListChangedCallback != null) deviceListChangedCallback.onDeviceListChanged(); if (deviceListChangedCallback != null) deviceListChangedCallback.onDeviceListChanged();
} }
@@ -147,34 +147,35 @@ public class BackgroundService extends Service {
} }
public void startDiscovery() { public void startDiscovery() {
Log.i("BackgroundService","StartDiscovery"); Log.i("KDE/BackgroundService","StartDiscovery");
for (BaseLinkProvider a : linkProviders) { for (BaseLinkProvider a : linkProviders) {
a.onStart(); a.onStart();
} }
} }
public void stopDiscovery() { public void stopDiscovery() {
Log.i("BackgroundService","StopDiscovery"); Log.i("KDE/BackgroundService","StopDiscovery");
for (BaseLinkProvider a : linkProviders) { for (BaseLinkProvider a : linkProviders) {
a.onStop(); a.onStop();
} }
} }
public void onNetworkChange() { public void onNetworkChange() {
Log.i("BackgroundService","OnNetworkChange"); Log.i("KDE/BackgroundService","OnNetworkChange");
for (BaseLinkProvider a : linkProviders) { for (BaseLinkProvider a : linkProviders) {
a.onNetworkChange(); a.onNetworkChange();
} }
} }
public void addConnectionListener(BaseLinkProvider.ConnectionReceiver cr) { public void addConnectionListener(BaseLinkProvider.ConnectionReceiver cr) {
Log.i("BackgroundService","Registering connection listener"); Log.i("KDE/BackgroundService","Registering connection listener");
for (BaseLinkProvider a : linkProviders) { for (BaseLinkProvider a : linkProviders) {
a.addConnectionReceiver(cr); a.addConnectionReceiver(cr);
} }
} }
public void removeConnectionListener(BaseLinkProvider.ConnectionReceiver cr) { public void removeConnectionListener(BaseLinkProvider.ConnectionReceiver cr) {
Log.i("KDE/BackgroundService","Removing connection listener");
for (BaseLinkProvider a : linkProviders) { for (BaseLinkProvider a : linkProviders) {
a.removeConnectionReceiver(cr); a.removeConnectionReceiver(cr);
} }
@@ -198,7 +199,7 @@ public class BackgroundService extends Service {
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
registerReceiver(new KdeConnectBroadcastReceiver(), filter); registerReceiver(new KdeConnectBroadcastReceiver(), filter);
Log.i("BackgroundService","Service not started yet, initializing..."); Log.i("KDE/BackgroundService","Service not started yet, initializing...");
initializeRsaKeys(); initializeRsaKeys();
MainSettingsActivity.initializeDeviceName(this); MainSettingsActivity.initializeDeviceName(this);
@@ -223,7 +224,7 @@ public class BackgroundService extends Service {
keyPair = keyGen.genKeyPair(); keyPair = keyGen.genKeyPair();
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
Log.e("initializeRsaKeys","Exception"); Log.e("KDE/initializeRsaKeys","Exception");
return; return;
} }
@@ -268,7 +269,7 @@ public class BackgroundService extends Service {
@Override @Override
public void onDestroy() { public void onDestroy() {
Log.i("BackgroundService", "Destroying"); Log.i("KDE/BackgroundService", "Destroying");
stopDiscovery(); stopDiscovery();
super.onDestroy(); super.onDestroy();
} }

View File

@@ -102,7 +102,7 @@ public class Device implements BaseLink.PackageReceiver {
publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes)); publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Log.e("Device","Exception"); Log.e("KDE/Device","Exception");
} }
reloadPluginsFromSettings(); reloadPluginsFromSettings();
@@ -200,7 +200,7 @@ public class Device implements BaseLink.PackageReceiver {
for (PairingCallback cb : pairingCallback) { for (PairingCallback cb : pairingCallback) {
cb.pairingFailed(context.getString(R.string.error_timed_out)); cb.pairingFailed(context.getString(R.string.error_timed_out));
} }
Log.e("Device","Unpairing (timeout A)"); Log.e("KDE/Device","Unpairing (timeout A)");
pairStatus = PairStatus.NotPaired; pairStatus = PairStatus.NotPaired;
} }
}, 30*1000); //Time to wait for the other to accept }, 30*1000); //Time to wait for the other to accept
@@ -212,7 +212,7 @@ public class Device implements BaseLink.PackageReceiver {
for (PairingCallback cb : pairingCallback) { for (PairingCallback cb : pairingCallback) {
cb.pairingFailed(context.getString(R.string.error_could_not_send_package)); cb.pairingFailed(context.getString(R.string.error_could_not_send_package));
} }
Log.e("Device","Unpairing (sendFailed A)"); Log.e("KDE/Device","Unpairing (sendFailed A)");
pairStatus = PairStatus.NotPaired; pairStatus = PairStatus.NotPaired;
} }
@@ -271,7 +271,7 @@ public class Device implements BaseLink.PackageReceiver {
public void acceptPairing() { public void acceptPairing() {
Log.i("Device","Accepted pair request started by the other device"); Log.i("KDE/Device","Accepted pair request started by the other device");
//Send our own public key //Send our own public key
NetworkPackage np = NetworkPackage.createPublicKeyPackage(context); NetworkPackage np = NetworkPackage.createPublicKeyPackage(context);
@@ -294,7 +294,7 @@ public class Device implements BaseLink.PackageReceiver {
public void rejectPairing() { public void rejectPairing() {
Log.i("Device","Rejected pair request started by the other device"); Log.i("KDE/Device","Rejected pair request started by the other device");
//Log.e("Device","Unpairing (rejectPairing)"); //Log.e("Device","Unpairing (rejectPairing)");
pairStatus = PairStatus.NotPaired; pairStatus = PairStatus.NotPaired;
@@ -321,6 +321,7 @@ public class Device implements BaseLink.PackageReceiver {
} }
public void addLink(NetworkPackage identityPackage, BaseLink link) { public void addLink(NetworkPackage identityPackage, BaseLink link) {
//FilesHelper.LogOpenFileCount();
this.protocolVersion = identityPackage.getInt("protocolVersion"); this.protocolVersion = identityPackage.getInt("protocolVersion");
@@ -341,10 +342,10 @@ public class Device implements BaseLink.PackageReceiver {
link.setPrivateKey(privateKey); link.setPrivateKey(privateKey);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Log.e("Device", "Exception reading our own private key"); //Should not happen Log.e("KDE/Device", "Exception reading our own private key"); //Should not happen
} }
Log.i("Device","addLink "+link.getLinkProvider().getName()+" -> "+getName() + " active links: "+ links.size()); Log.i("KDE/Device","addLink "+link.getLinkProvider().getName()+" -> "+getName() + " active links: "+ links.size());
/* /*
Collections.sort(links, new Comparator<BaseLink>() { Collections.sort(links, new Comparator<BaseLink>() {
@@ -363,9 +364,11 @@ public class Device implements BaseLink.PackageReceiver {
} }
public void removeLink(BaseLink link) { public void removeLink(BaseLink link) {
//FilesHelper.LogOpenFileCount();
link.removePackageReceiver(this); link.removePackageReceiver(this);
links.remove(link); links.remove(link);
Log.i("Device","removeLink: "+link.getLinkProvider().getName() + " -> "+getName() + " active links: "+ links.size()); Log.i("KDE/Device","removeLink: "+link.getLinkProvider().getName() + " -> "+getName() + " active links: "+ links.size());
if (links.isEmpty()) { if (links.isEmpty()) {
reloadPluginsFromSettings(); reloadPluginsFromSettings();
} }
@@ -376,7 +379,7 @@ public class Device implements BaseLink.PackageReceiver {
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_PAIR)) { if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_PAIR)) {
Log.i("Device","Pair package"); Log.i("KDE/Device","Pair package");
boolean wantsPair = np.getBoolean("pair"); boolean wantsPair = np.getBoolean("pair");
@@ -401,7 +404,7 @@ public class Device implements BaseLink.PackageReceiver {
publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes)); publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
Log.e("Device","Pairing exception: Received incorrect key"); Log.e("KDE/Device","Pairing exception: Received incorrect key");
for (PairingCallback cb : pairingCallback) { for (PairingCallback cb : pairingCallback) {
cb.pairingFailed(context.getString(R.string.error_invalid_key)); cb.pairingFailed(context.getString(R.string.error_invalid_key));
} }
@@ -410,7 +413,7 @@ public class Device implements BaseLink.PackageReceiver {
if (pairStatus == PairStatus.Requested) { //We started pairing if (pairStatus == PairStatus.Requested) { //We started pairing
Log.i("Pairing","Pair answer"); Log.i("KDE/Pairing","Pair answer");
if (pairingTimer != null) pairingTimer.cancel(); if (pairingTimer != null) pairingTimer.cancel();
@@ -418,7 +421,7 @@ public class Device implements BaseLink.PackageReceiver {
} else { } else {
Log.i("Pairing","Pair request"); Log.i("KDE/Pairing","Pair request");
Intent intent = new Intent(context, PairActivity.class); Intent intent = new Intent(context, PairActivity.class);
intent.putExtra("deviceId", deviceId); intent.putExtra("deviceId", deviceId);
@@ -447,7 +450,7 @@ public class Device implements BaseLink.PackageReceiver {
pairingTimer.schedule(new TimerTask() { pairingTimer.schedule(new TimerTask() {
@Override @Override
public void run() { public void run() {
Log.e("Device","Unpairing (timeout B)"); Log.e("KDE/Device","Unpairing (timeout B)");
pairStatus = PairStatus.NotPaired; pairStatus = PairStatus.NotPaired;
notificationManager.cancel(notificationId); notificationManager.cancel(notificationId);
} }
@@ -457,7 +460,7 @@ public class Device implements BaseLink.PackageReceiver {
} }
} else { } else {
Log.i("Pairing","Unpair request"); Log.i("KDE/Pairing","Unpair request");
if (pairStatus == PairStatus.Requested) { if (pairStatus == PairStatus.Requested) {
pairingTimer.cancel(); pairingTimer.cancel();
@@ -470,27 +473,30 @@ public class Device implements BaseLink.PackageReceiver {
reloadPluginsFromSettings(); reloadPluginsFromSettings();
} }
//Log.e("Device","Unpairing (unpair request)");
pairStatus = PairStatus.NotPaired; pairStatus = PairStatus.NotPaired;
for (PairingCallback cb : pairingCallback) cb.unpaired(); for (PairingCallback cb : pairingCallback) cb.unpaired();
} }
} else if (!isPaired()) { } else if (isPaired()) {
unpair();
Log.e("onPackageReceived","Device not paired, ignoring package!");
} else {
for (Plugin plugin : plugins.values()) { for (Plugin plugin : plugins.values()) {
try { try {
plugin.onPackageReceived(np); plugin.onPackageReceived(np);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Log.e("Device", "Exception in "+plugin.getDisplayName()+"'s onPackageReceived()"); Log.e("KDE/Device", "Exception in "+plugin.getDisplayName()+"'s onPackageReceived()");
} }
} }
} else {
Log.e("KDE/onPackageReceived","Device not paired, ignoring package!");
if (pairStatus != PairStatus.Requested) {
unpair();
}
} }
} }
@@ -508,9 +514,9 @@ public class Device implements BaseLink.PackageReceiver {
public void sendFailure(Throwable e) { public void sendFailure(Throwable e) {
if (e != null) { if (e != null) {
e.printStackTrace(); e.printStackTrace();
Log.e("sendPackage", "Exception: " + e.getMessage()); Log.e("KDE/sendPackage", "Exception: " + e.getMessage());
} else { } else {
Log.e("sendPackage", "Unknown (null) exception"); Log.e("KDE/sendPackage", "Unknown (null) exception");
} }
onFailure(e); onFailure(e);
} }
@@ -543,6 +549,7 @@ public class Device implements BaseLink.PackageReceiver {
//Make a copy to avoid concurrent modification exception if the original list changes //Make a copy to avoid concurrent modification exception if the original list changes
ArrayList<BaseLink> mLinks = new ArrayList<BaseLink>(links); ArrayList<BaseLink> mLinks = new ArrayList<BaseLink>(links);
for (final BaseLink link : mLinks) { for (final BaseLink link : mLinks) {
if (link == null) continue; //Since we made a copy, maybe somebody destroyed the link in the meanwhile
if (useEncryption) { if (useEncryption) {
link.sendPackageEncrypted(np, callback, publicKey); link.sendPackageEncrypted(np, callback, publicKey);
} else { } else {
@@ -552,7 +559,7 @@ public class Device implements BaseLink.PackageReceiver {
} }
if (!callback.success) { if (!callback.success) {
Log.e("sendPackage", "No device link (of "+mLinks.size()+" available) could send the package. Package lost!"); Log.e("KDE/sendPackage", "No device link (of "+mLinks.size()+" available) could send the package. Package lost!");
backtrace.printStackTrace(); backtrace.printStackTrace();
} }
@@ -580,13 +587,13 @@ public class Device implements BaseLink.PackageReceiver {
private synchronized void addPlugin(final String name) { private synchronized void addPlugin(final String name) {
Plugin existing = plugins.get(name); Plugin existing = plugins.get(name);
if (existing != null) { if (existing != null) {
Log.w("addPlugin","plugin already present:" + name); Log.w("KDE/addPlugin","plugin already present:" + name);
return; return;
} }
final Plugin plugin = PluginFactory.instantiatePluginForDevice(context, name, this); final Plugin plugin = PluginFactory.instantiatePluginForDevice(context, name, this);
if (plugin == null) { if (plugin == null) {
Log.e("addPlugin","could not instantiate plugin: "+name); Log.e("KDE/addPlugin","could not instantiate plugin: "+name);
failedPlugins.put(name, plugin); failedPlugins.put(name, plugin);
return; return;
} }
@@ -601,7 +608,7 @@ public class Device implements BaseLink.PackageReceiver {
} catch (Exception e) { } catch (Exception e) {
success = false; success = false;
e.printStackTrace(); e.printStackTrace();
Log.e("addPlugin", "Exception loading plugin " + name); Log.e("KDE/addPlugin", "Exception loading plugin " + name);
} }
if (success) { if (success) {
@@ -609,7 +616,7 @@ public class Device implements BaseLink.PackageReceiver {
failedPlugins.remove(name); failedPlugins.remove(name);
plugins.put(name, plugin); plugins.put(name, plugin);
} else { } else {
Log.e("addPlugin", "plugin failed to load " + name); Log.e("KDE/addPlugin", "plugin failed to load " + name);
plugins.remove(name); plugins.remove(name);
failedPlugins.put(name, plugin); failedPlugins.put(name, plugin);
} }
@@ -641,7 +648,7 @@ public class Device implements BaseLink.PackageReceiver {
//Log.e("removePlugin","removed " + name); //Log.e("removePlugin","removed " + name);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Log.e("removePlugin","Exception calling onDestroy for plugin "+name); Log.e("KDE/removePlugin","Exception calling onDestroy for plugin "+name);
} }
for (PluginsChangedListener listener : pluginsChangedListeners) { for (PluginsChangedListener listener : pluginsChangedListeners) {

View File

@@ -20,8 +20,11 @@
package org.kde.kdeconnect.Helpers; package org.kde.kdeconnect.Helpers;
import android.util.Log;
import android.webkit.MimeTypeMap; import android.webkit.MimeTypeMap;
import java.io.File;
public class FilesHelper { public class FilesHelper {
public static String getFileExt(String fileName) { public static String getFileExt(String fileName) {
@@ -73,4 +76,11 @@ public class FilesHelper {
return toFileSystemSafeName(name, true, 255); return toFileSystemSafeName(name, true, 255);
} }
public static int GetOpenFileCount() {
return new File("/proc/self/fd").listFiles().length;
}
public static void LogOpenFileCount() {
Log.e("KDE/FileCount",""+GetOpenFileCount());
}
} }

View File

@@ -81,7 +81,9 @@ public class StorageHelper {
if (storage.exists() && storage.isDirectory()) { if (storage.exists() && storage.isDirectory()) {
String mounts = null; String mounts = null;
try { try {
mounts = new Scanner( new File("/proc/mounts") ).useDelimiter("\\A").next(); Scanner scanner = new Scanner( new File("/proc/mounts") );
mounts = scanner.useDelimiter("\\A").next();
scanner.close();
//Log.e("Mounts",mounts); //Log.e("Mounts",mounts);
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
@@ -90,7 +92,7 @@ public class StorageHelper {
File dirs[] = storage.listFiles(); File dirs[] = storage.listFiles();
for (File dir : dirs) { for (File dir : dirs) {
//Log.e("getStorageList", "path: "+dir.getAbsolutePath()); //Log.e("getStorageList", "path: "+dir.getAbsolutePath());
if (dir.isDirectory()) { if (dir.isDirectory() && dir.canRead() && dir.canExecute()) {
String path, path2; String path, path2;
path2 = dir.getAbsolutePath(); path2 = dir.getAbsolutePath();
try { try {
@@ -101,9 +103,10 @@ public class StorageHelper {
} }
if (!path.startsWith("/storage/emulated") || dirs.length == 1) { if (!path.startsWith("/storage/emulated") || dirs.length == 1) {
if (!paths.contains(path) && !paths.contains(path2)) { if (!paths.contains(path) && !paths.contains(path2)) {
if (mounts == null || mounts.contains(path) || mounts.contains(path2)) if (mounts == null || mounts.contains(path) || mounts.contains(path2)) {
list.add(0, new StorageInfo(path, false, true, cur_removable_number++)); list.add(0, new StorageInfo(path, false, true, cur_removable_number++));
paths.add(path); paths.add(path);
}
} }
} }
} }

View File

@@ -64,13 +64,14 @@ public class NotificationFilterActivity extends ActionBarActivity {
res.moveToNext(); res.moveToNext();
i++; i++;
} }
res.close();
appDatabase.close(); appDatabase.close();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_multiple_choice,android.R.id.text1, appName); android.R.layout.simple_list_item_multiple_choice,android.R.id.text1, appName);
listView.setAdapter(adapter); listView.setAdapter(adapter);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
for (i = 0 ; i < res.getCount(); i++){ for (i = 0 ; i < isFiltered.length; i++){
if (isFiltered[i]) { if (isFiltered[i]) {
listView.setItemChecked(i, true); listView.setItemChecked(i, true);
} }
@@ -85,6 +86,7 @@ public class NotificationFilterActivity extends ActionBarActivity {
appDatabase.close(); appDatabase.close();
} }
}); });
} }
// Delete apps from database which are uninstalled // Delete apps from database which are uninstalled
@@ -101,6 +103,7 @@ public class NotificationFilterActivity extends ActionBarActivity {
} }
res.moveToNext(); res.moveToNext();
} }
res.close();
} }
appDatabase.close(); appDatabase.close();

View File

@@ -90,51 +90,55 @@ public class SftpPlugin extends Plugin {
np2.set("user", server.passwordAuth.getUser()); np2.set("user", server.passwordAuth.getUser());
np2.set("password", server.passwordAuth.getPassword()); np2.set("password", server.passwordAuth.getPassword());
//Kept for compatibility, but new desktop clients will read "multiPaths" instead, //Kept for compatibility, in case "multiPaths" is not possible or the other end does not support it
// that supports devices with more than one external storage
np2.set("path", Environment.getExternalStorageDirectory().getAbsolutePath()); np2.set("path", Environment.getExternalStorageDirectory().getAbsolutePath());
List<StorageHelper.StorageInfo> storageList = StorageHelper.getStorageList(); File root = new File("/");
ArrayList<String> paths = new ArrayList<String>(); if (root.canExecute() && root.canRead()) {
ArrayList<String> pathNames = new ArrayList<String>(); List<StorageHelper.StorageInfo> storageList = StorageHelper.getStorageList();
ArrayList<String> paths = new ArrayList<String>();
ArrayList<String> pathNames = new ArrayList<String>();
for (StorageHelper.StorageInfo storage : storageList) { for (StorageHelper.StorageInfo storage : storageList) {
paths.add(storage.path); paths.add(storage.path);
StringBuilder res = new StringBuilder(); StringBuilder res = new StringBuilder();
if (storageList.size() > 1) {
if (!storage.removable) {
res.append(context.getString(R.string.sftp_internal_storage));
} else if (storage.number > 1) {
res.append(context.getString(R.string.sftp_sdcard_num, storage.number));
} else {
res.append(context.getString(R.string.sftp_sdcard));
}
} else {
res.append(context.getString(R.string.sftp_all_files));
}
String pathName = res.toString();
if (storage.readonly) {
res.append(" ");
res.append(context.getString(R.string.sftp_readonly));
}
pathNames.add(res.toString());
//Shortcut for users that only want to browse camera pictures
String dcim = storage.path + "/DCIM/Camera";
if (new File(dcim).exists()) {
paths.add(dcim);
if (storageList.size() > 1) { if (storageList.size() > 1) {
pathNames.add(context.getString(R.string.sftp_camera) + "(" + pathName + ")"); if (!storage.removable) {
res.append(context.getString(R.string.sftp_internal_storage));
} else if (storage.number > 1) {
res.append(context.getString(R.string.sftp_sdcard_num, storage.number));
} else {
res.append(context.getString(R.string.sftp_sdcard));
}
} else { } else {
pathNames.add(context.getString(R.string.sftp_camera)); res.append(context.getString(R.string.sftp_all_files));
} }
String pathName = res.toString();
if (storage.readonly) {
res.append(" ");
res.append(context.getString(R.string.sftp_readonly));
}
pathNames.add(res.toString());
//Shortcut for users that only want to browse camera pictures
String dcim = storage.path + "/DCIM/Camera";
if (new File(dcim).exists()) {
paths.add(dcim);
if (storageList.size() > 1) {
pathNames.add(context.getString(R.string.sftp_camera) + "(" + pathName + ")");
} else {
pathNames.add(context.getString(R.string.sftp_camera));
}
}
}
if (paths.size() > 0) {
np2.set("multiPaths", paths);
np2.set("pathNames", pathNames);
} }
} }
np2.set("multiPaths", paths);
np2.set("pathNames", pathNames);
device.sendPackage(np2); device.sendPackage(np2);
return true; return true;

View File

@@ -144,56 +144,56 @@ public class ShareActivity extends ActionBarActivity {
Device device = devicesList.get(i-1); //NOTE: -1 because of the title! Device device = devicesList.get(i-1); //NOTE: -1 because of the title!
Bundle extras = intent.getExtras(); Bundle extras = intent.getExtras();
if (extras.containsKey(Intent.EXTRA_STREAM)) { if (extras != null) {
if (extras.containsKey(Intent.EXTRA_STREAM)) {
try { try {
ArrayList<Uri> uriList; ArrayList<Uri> uriList;
if (!Intent.ACTION_SEND.equals(intent.getAction())) { if (!Intent.ACTION_SEND.equals(intent.getAction())) {
uriList = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); uriList = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
} else {
Uri uri = extras.getParcelable(Intent.EXTRA_STREAM);
uriList = new ArrayList<Uri>();
uriList.add(uri);
}
queuedSendUriList(device, uriList);
} catch (Exception e) {
Log.e("ShareActivity", "Exception");
e.printStackTrace();
}
} else if (extras.containsKey(Intent.EXTRA_TEXT)) {
String text = extras.getString(Intent.EXTRA_TEXT);
String subject = extras.getString(Intent.EXTRA_SUBJECT);
//Hack: Detect shared youtube videos, so we can open them in the browser instead of as text
if (subject != null && subject.endsWith("YouTube")) {
int index = text.indexOf(": http://youtu.be/");
if (index > 0) {
text = text.substring(index + 2); //Skip ": "
}
}
boolean isUrl;
try {
new URL(text);
isUrl = true;
} catch (Exception e) {
isUrl = false;
}
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_SHARE);
if (isUrl) {
np.set("url", text);
} else { } else {
Uri uri = extras.getParcelable(Intent.EXTRA_STREAM); np.set("text", text);
uriList = new ArrayList<Uri>();
uriList.add(uri);
} }
device.sendPackage(np);
queuedSendUriList(device, uriList);
} catch (Exception e) {
Log.e("ShareActivity", "Exception");
e.printStackTrace();
} }
} else if (extras.containsKey(Intent.EXTRA_TEXT)) {
String text = extras.getString(Intent.EXTRA_TEXT);
String subject = extras.getString(Intent.EXTRA_SUBJECT);
//Hack: Detect shared youtube videos, so we can open them in the browser instead of as text
if (subject != null && subject.endsWith("YouTube")) {
int index = text.indexOf(": http://youtu.be/");
if (index > 0) {
text = text.substring(index+2); //Skip ": "
}
}
boolean isUrl;
try {
new URL(text);
isUrl = true;
} catch(Exception e) {
isUrl = false;
}
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_SHARE);
if (isUrl) {
np.set("url", text);
} else {
np.set("text", text);
}
device.sendPackage(np);
} }
finish(); finish();
} }
}); });
@@ -235,12 +235,13 @@ public class ShareActivity extends ActionBarActivity {
try { try {
size = new File(uri.getPath()).length(); size = new File(uri.getPath()).length();
np.setPayload(inputStream, size);
} catch(Exception e) { } catch(Exception e) {
Log.e("ShareActivity", "Could not obtain file size"); Log.e("ShareActivity", "Could not obtain file size");
e.printStackTrace(); e.printStackTrace();
} }
np.setPayload(inputStream, size);
}else{ }else{
// Probably a content:// uri, so we query the Media content provider // Probably a content:// uri, so we query the Media content provider

View File

@@ -141,8 +141,10 @@ public class SharePlugin extends Plugin {
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
OutputStream output = null;
boolean successul = true;
try { try {
OutputStream output = new FileOutputStream(destinationFullPath.getPath()); output = new FileOutputStream(destinationFullPath.getPath());
byte data[] = new byte[1024]; byte data[] = new byte[1024];
long progress = 0, prevProgressPercentage = 0; long progress = 0, prevProgressPercentage = 0;
int count; int count;
@@ -162,9 +164,17 @@ public class SharePlugin extends Plugin {
} }
output.flush(); output.flush();
output.close();
input.close();
} catch (Exception e) {
successul = false;
Log.e("SharePlugin", "Receiver thread exception");
e.printStackTrace();
} finally {
try { output.close(); } catch (Exception e) {}
try { input.close(); } catch (Exception e) {}
}
try {
Log.i("SharePlugin", "Transfer finished"); Log.i("SharePlugin", "Transfer finished");
//Make sure it is added to the Android Gallery //Make sure it is added to the Android Gallery
@@ -185,23 +195,25 @@ public class SharePlugin extends Plugin {
Resources res = context.getResources(); Resources res = context.getResources();
String message = successul? res.getString(R.string.received_file_title, device.getName()) : res.getString(R.string.received_file_fail_title, device.getName());
NotificationCompat.Builder builder = new NotificationCompat.Builder(context) NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setContentTitle(res.getString(R.string.received_file_title, device.getName())) .setContentTitle(message)
.setContentText(res.getString(R.string.received_file_text, filename)) .setTicker(message)
.setContentIntent(resultPendingIntent)
.setTicker(res.getString(R.string.received_file_title, device.getName()))
.setSmallIcon(android.R.drawable.stat_sys_download_done) .setSmallIcon(android.R.drawable.stat_sys_download_done)
.setAutoCancel(true); .setAutoCancel(true);
if (successul) {
builder.setContentText(res.getString(R.string.received_file_text, filename))
.setContentIntent(resultPendingIntent);
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
if (prefs.getBoolean("share_notification_preference", true)) { if (prefs.getBoolean("share_notification_preference", true)) {
builder.setDefaults(Notification.DEFAULT_ALL); builder.setDefaults(Notification.DEFAULT_ALL);
} }
Notification noti = builder.build(); Notification notification = builder.build();
notificationManager.notify(notificationId, notification);
notificationManager.notify(notificationId, noti);
} catch (Exception e) { } catch (Exception e) {
Log.e("SharePlugin", "Receiver thread exception"); Log.e("SharePlugin", "Receiver thread exception");

View File

@@ -108,8 +108,11 @@ public class CustomDevicesActivity extends ListActivity {
InputMethodManager inputManager = (InputMethodManager) InputMethodManager inputManager = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE); getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), View focus = getCurrentFocus();
InputMethodManager.HIDE_NOT_ALWAYS); if (focus != null) {
inputManager.hideSoftInputFromWindow(focus.getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
} }
void saveList() { void saveList() {

View File

@@ -46,10 +46,12 @@ public class SmallEntryItem implements ListAdapter.Item {
View v = layoutInflater.inflate(android.R.layout.simple_list_item_1, null); View v = layoutInflater.inflate(android.R.layout.simple_list_item_1, null);
TextView titleView = (TextView)v.findViewById(android.R.id.text1); TextView titleView = (TextView)v.findViewById(android.R.id.text1);
if (titleView != null) titleView.setText(title); if (titleView != null) {
if (clickListener != null) { titleView.setText(title);
titleView.setOnClickListener(clickListener); if (clickListener != null) {
v.setBackgroundDrawable(layoutInflater.getContext().getResources().getDrawable(R.drawable.abc_list_selector_holo_dark)); titleView.setOnClickListener(clickListener);
v.setBackgroundDrawable(layoutInflater.getContext().getResources().getDrawable(R.drawable.abc_list_selector_holo_dark));
}
} }
return v; return v;

View File

@@ -61,7 +61,7 @@ public class MainSettingsActivity extends PreferenceActivity {
} }
private void initPreferences(final EditTextPreference deviceNamePref) { private void initPreferences(final EditTextPreference deviceNamePref) {
final SharedPreferences sharedPreferences=PreferenceManager.getDefaultSharedPreferences(this); final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
deviceNamePref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { deviceNamePref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override @Override
public boolean onPreferenceChange(Preference preference, Object newDeviceName) { public boolean onPreferenceChange(Preference preference, Object newDeviceName) {
@@ -99,16 +99,12 @@ public class MainSettingsActivity extends PreferenceActivity {
* @param context the application context * @param context the application context
*/ */
public static void initializeDeviceName(Context context){ public static void initializeDeviceName(Context context){
// I could have used getDefaultSharedPreferences(context).contains but we need to check SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
// to checkAgainst empty String also. // Could use prefrences.contains but would need to check for empty String anyway.
String deviceName=PreferenceManager.getDefaultSharedPreferences(context).getString( String deviceName = preferences.getString(KEY_DEVICE_NAME_PREFERENCE, "");
KEY_DEVICE_NAME_PREFERENCE, if (deviceName.isEmpty()){
"");
if(deviceName.isEmpty()){
Log.i("MainSettingsActivity", "New device name: " + deviceName); Log.i("MainSettingsActivity", "New device name: " + deviceName);
PreferenceManager.getDefaultSharedPreferences(context).edit().putString( preferences.edit().putString(KEY_DEVICE_NAME_PREFERENCE, DeviceHelper.getDeviceName()).commit();
KEY_DEVICE_NAME_PREFERENCE,
DeviceHelper.getDeviceName()).commit();
} }
} }