diff --git a/res/values/strings.xml b/res/values/strings.xml
index 23d10dcd..2bb61978 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -67,8 +67,14 @@
Tap to open \'%1s\'
Incoming file from %1s
%1s
+ Sending file to %1s
+ %1s
Received file from %1s
Tap to open \'%1s\'
+ Sent file to %1s
+ %1s
+ Failed to send file %1s
+ %1s
Tap to answer
Reconnect
Send Right Click
diff --git a/src/org/kde/kdeconnect/Backends/BaseLink.java b/src/org/kde/kdeconnect/Backends/BaseLink.java
index 242ff679..6891986b 100644
--- a/src/org/kde/kdeconnect/Backends/BaseLink.java
+++ b/src/org/kde/kdeconnect/Backends/BaseLink.java
@@ -20,6 +20,7 @@
package org.kde.kdeconnect.Backends;
+import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPackage;
import java.security.PrivateKey;
@@ -71,7 +72,7 @@ public abstract class BaseLink {
}
//TO OVERRIDE, should be sync
- public abstract boolean sendPackage(NetworkPackage np);
- public abstract boolean sendPackageEncrypted(NetworkPackage np, PublicKey key);
+ public abstract boolean sendPackage(NetworkPackage np,Device.SendPackageStatusCallback callback);
+ public abstract boolean sendPackageEncrypted(NetworkPackage np,Device.SendPackageStatusCallback callback, PublicKey key);
}
diff --git a/src/org/kde/kdeconnect/Backends/LanBackend/LanLink.java b/src/org/kde/kdeconnect/Backends/LanBackend/LanLink.java
index ca81c136..3912e77d 100644
--- a/src/org/kde/kdeconnect/Backends/LanBackend/LanLink.java
+++ b/src/org/kde/kdeconnect/Backends/LanBackend/LanLink.java
@@ -27,6 +27,7 @@ import org.apache.mina.core.session.IoSession;
import org.json.JSONObject;
import org.kde.kdeconnect.Backends.BaseLink;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
+import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPackage;
import java.io.InputStream;
@@ -51,7 +52,7 @@ public class LanLink extends BaseLink {
this.session = session;
}
- private Thread sendPayload(NetworkPackage np) {
+ private Thread sendPayload(NetworkPackage np, final Device.SendPackageStatusCallback callback) {
try {
@@ -87,10 +88,13 @@ public class LanLink extends BaseLink {
socket = server.accept().getOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
+ long progress = 0 ;
Log.e("LanLink","Beginning to send payload");
while ((bytesRead = stream.read(buffer)) != -1) {
//Log.e("ok",""+bytesRead);
+ progress += bytesRead;
socket.write(buffer, 0, bytesRead);
+ if (callback != null) callback.progressChanged(progress);
}
Log.e("LanLink","Finished sending payload");
} catch(Exception e) {
@@ -122,7 +126,7 @@ public class LanLink extends BaseLink {
//Blocking, do not call from main thread
@Override
- public boolean sendPackage(final NetworkPackage np) {
+ public boolean sendPackage(final NetworkPackage np,Device.SendPackageStatusCallback callback) {
if (session == null) {
Log.e("LanLink", "sendPackage failed: not yet connected");
@@ -132,7 +136,7 @@ public class LanLink extends BaseLink {
try {
Thread thread = null;
if (np.hasPayload()) {
- thread = sendPayload(np);
+ thread = sendPayload(np,callback);
if (thread == null) return false;
}
@@ -155,7 +159,7 @@ public class LanLink extends BaseLink {
//Blocking, do not call from main thread
@Override
- public boolean sendPackageEncrypted(NetworkPackage np, PublicKey key) {
+ public boolean sendPackageEncrypted(NetworkPackage np,Device.SendPackageStatusCallback callback, PublicKey key) {
if (session == null) {
Log.e("LanLink", "sendPackage failed: not yet connected");
@@ -166,7 +170,7 @@ public class LanLink extends BaseLink {
Thread thread = null;
if (np.hasPayload()) {
- thread = sendPayload(np);
+ thread = sendPayload(np,callback);
if (thread == null) return false;
}
diff --git a/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java b/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java
index 19038bb4..35850eef 100644
--- a/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java
+++ b/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java
@@ -169,7 +169,7 @@ public class LanLinkProvider extends BaseLinkProvider {
@Override
public void run() {
NetworkPackage np2 = NetworkPackage.createIdentityPackage(context);
- link.sendPackage(np2);
+ link.sendPackage(np2,null);
nioSessions.put(session.getId(), link);
addLink(identityPackage, link);
diff --git a/src/org/kde/kdeconnect/Backends/LoopbackBackend/LoopbackLink.java b/src/org/kde/kdeconnect/Backends/LoopbackBackend/LoopbackLink.java
index 0461cf1f..f668fd0e 100644
--- a/src/org/kde/kdeconnect/Backends/LoopbackBackend/LoopbackLink.java
+++ b/src/org/kde/kdeconnect/Backends/LoopbackBackend/LoopbackLink.java
@@ -24,6 +24,7 @@ import android.util.Log;
import org.kde.kdeconnect.Backends.BaseLink;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
+import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPackage;
import java.security.PublicKey;
@@ -35,7 +36,7 @@ public class LoopbackLink extends BaseLink {
}
@Override
- public boolean sendPackage(NetworkPackage in) {
+ public boolean sendPackage(NetworkPackage in,Device.SendPackageStatusCallback callback) {
String s = in.serialize();
NetworkPackage out= NetworkPackage.unserialize(s);
if (in.hasPayload()) out.setPayload(in.getPayload(), in.getPayloadSize());
@@ -44,7 +45,7 @@ public class LoopbackLink extends BaseLink {
}
@Override
- public boolean sendPackageEncrypted(NetworkPackage in, PublicKey key) {
+ public boolean sendPackageEncrypted(NetworkPackage in,Device.SendPackageStatusCallback callback, PublicKey key) {
try {
in = in.encrypt(key);
String s = in.serialize();
diff --git a/src/org/kde/kdeconnect/Device.java b/src/org/kde/kdeconnect/Device.java
index b9a876b5..0c27fef9 100644
--- a/src/org/kde/kdeconnect/Device.java
+++ b/src/org/kde/kdeconnect/Device.java
@@ -191,7 +191,12 @@ public class Device implements BaseLink.PackageReceiver {
//Send our own public key
NetworkPackage np = NetworkPackage.createPublicKeyPackage(context);
- sendPackage(np, new SendPackageFinishedCallback(){
+ sendPackage(np, new SendPackageStatusCallback(){
+
+ @Override
+ public void progressChanged(long progress) {
+ // Do nothing
+ }
@Override
public void sendSuccessful() {
@@ -278,7 +283,12 @@ public class Device implements BaseLink.PackageReceiver {
//Send our own public key
NetworkPackage np = NetworkPackage.createPublicKeyPackage(context);
- sendPackage(np, new SendPackageFinishedCallback() {
+ sendPackage(np, new SendPackageStatusCallback() {
+ @Override
+ public void progressChanged(long progress) {
+ // Do nothng
+ }
+
@Override
public void sendSuccessful() {
pairingDone();
@@ -490,7 +500,8 @@ public class Device implements BaseLink.PackageReceiver {
}
- public interface SendPackageFinishedCallback {
+ public interface SendPackageStatusCallback {
+ void progressChanged(long progress);
void sendSuccessful();
void sendFailed();
}
@@ -500,7 +511,7 @@ public class Device implements BaseLink.PackageReceiver {
}
//Async
- public void sendPackage(final NetworkPackage np, final SendPackageFinishedCallback callback) {
+ public void sendPackage(final NetworkPackage np, final SendPackageStatusCallback callback) {
final Exception backtrace = new Exception();
@@ -520,9 +531,9 @@ public class Device implements BaseLink.PackageReceiver {
try {
for (BaseLink link : mLinks) {
if (useEncryption) {
- success = link.sendPackageEncrypted(np, publicKey);
+ success = link.sendPackageEncrypted(np,callback, publicKey);
} else {
- success = link.sendPackage(np);
+ success = link.sendPackage(np,callback);
}
if (success) break;
}
diff --git a/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java b/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java
index 1e7e5095..9e7c0d63 100644
--- a/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java
+++ b/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java
@@ -143,18 +143,20 @@ public class SharePlugin extends Plugin {
public void run() {
try {
OutputStream output = new FileOutputStream(destinationFullPath.getPath());
-
byte data[] = new byte[1024];
- long total = 0;
+ long progress = 0,prevProgressPercentage = 0;
int count;
while ((count = input.read(data)) >= 0) {
- total += count;
+ progress += count;
output.write(data, 0, count);
if (fileLength > 0) {
- if (total >= fileLength) break;
- float progress = (total * 100 / fileLength);
- builder.setProgress(100,(int)progress,false);
- notificationManager.notify(notificationId,builder.build());
+ if (progress >= fileLength) break;
+ long progressPercentage = (progress * 100 / fileLength);
+ if ((progressPercentage - prevProgressPercentage) > 0) {
+ prevProgressPercentage = progressPercentage;
+ builder.setProgress(100, (int) progressPercentage, false);
+ notificationManager.notify(notificationId, builder.build());
+ }
}
//else Log.e("SharePlugin", "Infinite loop? :D");
}
diff --git a/src/org/kde/kdeconnect/Plugins/SharePlugin/ShareToReceiver.java b/src/org/kde/kdeconnect/Plugins/SharePlugin/ShareToReceiver.java
index 170b7eb2..d73bea05 100644
--- a/src/org/kde/kdeconnect/Plugins/SharePlugin/ShareToReceiver.java
+++ b/src/org/kde/kdeconnect/Plugins/SharePlugin/ShareToReceiver.java
@@ -20,12 +20,21 @@
package org.kde.kdeconnect.Plugins.SharePlugin;
+import android.app.Notification;
+import android.app.NotificationManager;
import android.content.ContentResolver;
+import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.preference.PreferenceManager;
import android.provider.MediaStore;
+import android.support.v4.app.NotificationCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
@@ -204,6 +213,21 @@ public class ShareToReceiver extends ActionBarActivity {
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_SHARE);
int size = -1;
+ final NotificationManager notificationManager = (NotificationManager)getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
+ final int notificationId = (int)System.currentTimeMillis();
+ final NotificationCompat.Builder builder ;
+ Resources res = getApplicationContext().getResources();
+ builder = new NotificationCompat.Builder(getApplicationContext())
+ .setContentTitle(res.getString(R.string.outgoing_file_title, device.getName()))
+ .setTicker(res.getString(R.string.outgoing_file_title, device.getName()))
+ .setSmallIcon(android.R.drawable.stat_sys_upload)
+ .setAutoCancel(true)
+ .setOngoing(true)
+ .setProgress(100,0,true);
+ notificationManager.notify(notificationId,builder.build());
+
+ final Handler progressBarHandler = new Handler(Looper.getMainLooper());
+
if (uri.getScheme().equals("file")) {
// file:// is a non media uri, so we cannot query the ContentProvider
@@ -260,15 +284,83 @@ public class ShareToReceiver extends ActionBarActivity {
}
- device.sendPackage(np, new Device.SendPackageFinishedCallback() {
+ final long filesize = size;
+ final String filename = np.getString("filename");
+
+ builder.setContentText(res.getString(R.string.outgoing_file_text,filename));
+ notificationManager.notify(notificationId,builder.build());
+
+ device.sendPackage(np, new Device.SendPackageStatusCallback() {
+
+ int prevProgressPercentage = 0,progressPercentage;
+
+ @Override
+ public void progressChanged(final long progress) {
+ // update notification progress
+ progressPercentage = (int)((progress * 100) / filesize);
+ if (filesize > 0 && (progressPercentage - prevProgressPercentage) > 0) {
+ prevProgressPercentage = progressPercentage;
+ progressBarHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ builder.setProgress(100, progressPercentage, false);
+ notificationManager.notify(notificationId, builder.build());
+ }
+ });
+ }
+
+ }
+
@Override
public void sendSuccessful() {
+
+ progressBarHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ Resources res = getApplicationContext().getResources();
+ NotificationCompat.Builder builder1 = new NotificationCompat.Builder(getApplicationContext())
+ .setContentTitle(res.getString(R.string.sent_file_title, device.getName()))
+ .setContentText(res.getString(R.string.sent_file_text, filename))
+ .setTicker(res.getString(R.string.sent_file_title, device.getName()))
+ .setSmallIcon(android.R.drawable.stat_sys_upload_done)
+ .setOngoing(false)
+ .setAutoCancel(true);
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+ if (prefs.getBoolean("share_notification_preference", true)) {
+ builder1.setDefaults(Notification.DEFAULT_ALL);
+ }
+ notificationManager.notify(notificationId, builder1.build());
+ }
+ });
+
if (!uriList.isEmpty()) queuedSendUriList(device, uriList);
else Log.e("ShareToReceiver", "All files sent");
}
@Override
public void sendFailed() {
+
+ progressBarHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ Resources res = getApplicationContext().getResources();
+ NotificationCompat.Builder builder2 = new NotificationCompat.Builder(getApplicationContext())
+ .setContentTitle(res.getString(R.string.sent_file_failed_title, device.getName()))
+ .setContentText(res.getString(R.string.sent_file_failed_text, filename))
+ .setTicker(res.getString(R.string.sent_file_title, device.getName()))
+ .setSmallIcon(android.R.drawable.stat_notify_error)
+ .setOngoing(false)
+ .setAutoCancel(true);
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+ if (prefs.getBoolean("share_notification_preference", true)) {
+ builder2.setDefaults(Notification.DEFAULT_ALL);
+ }
+ notificationManager.notify(notificationId, builder2.build());
+ }
+ });
+
Log.e("ShareToReceiver", "Failed to send file");
}
});