367 lines
11 KiB
Java
367 lines
11 KiB
Java
package com.localtransfer;
|
|
|
|
import static java.lang.Integer.valueOf;
|
|
|
|
import android.app.Activity;
|
|
import android.app.Notification;
|
|
import android.app.PendingIntent;
|
|
import android.content.ContentResolver;
|
|
import android.content.Context;
|
|
import android.content.SharedPreferences;
|
|
import android.graphics.Color;
|
|
import android.util.Log;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.widget.ImageView;
|
|
import android.widget.LinearLayout;
|
|
import android.widget.ProgressBar;
|
|
import android.widget.TextView;
|
|
import android.widget.Toast;
|
|
|
|
import androidx.core.app.NotificationManagerCompat;
|
|
import androidx.preference.PreferenceManager;
|
|
|
|
import com.google.android.material.snackbar.Snackbar;
|
|
|
|
import java.io.IOException;
|
|
import java.io.InputStreamReader;
|
|
import java.net.HttpURLConnection;
|
|
import java.net.ProtocolException;
|
|
import java.net.URL;
|
|
import java.sql.Timestamp;
|
|
import java.text.CharacterIterator;
|
|
import java.text.StringCharacterIterator;
|
|
import java.util.ArrayList;
|
|
import java.util.Comparator;
|
|
import java.util.ConcurrentModificationException;
|
|
import java.util.List;
|
|
|
|
public class Transfer {
|
|
|
|
protected static Notification.Builder notifBuilder;
|
|
protected static NotificationManagerCompat notifiManager;
|
|
protected static LayoutInflater inflater;
|
|
protected static ContentResolver resolver;
|
|
|
|
protected static PendingIntent pendingIntent;
|
|
|
|
public static View fragment_progress;
|
|
public static boolean fragment_on = false;
|
|
public static boolean app_started = false;
|
|
|
|
protected static long savedTimeMillis;
|
|
|
|
public static String host;
|
|
public static Integer port;
|
|
public static String root;
|
|
public static String protocol;
|
|
public static String shared_storage;
|
|
public static boolean use_shared_storage;
|
|
|
|
public static Activity activity;
|
|
|
|
public int state;
|
|
|
|
public int drawable;
|
|
public String info;
|
|
public String message;
|
|
|
|
public String sizeSI;
|
|
|
|
public long loaded;
|
|
public String loadedSI = "0";
|
|
public long percent;
|
|
|
|
public static final int NOTIF_SERVICE = 1000;
|
|
|
|
public static final int STATE_NOT_REQUESTED = 100;
|
|
public static final int STATE_STANDBY = 110;
|
|
public static final int STATE_RUNNING = 120;
|
|
public static final int STATE_SUCCESS = 130;
|
|
public static final int STATE_FAILED = 140;
|
|
|
|
public static Thread thread = new Thread();
|
|
|
|
Integer id;
|
|
|
|
public String name;
|
|
|
|
public long size;
|
|
|
|
Timestamp addedTime;
|
|
Timestamp startedTime;
|
|
|
|
static List<Transfer> instances = new ArrayList<>();
|
|
|
|
public static List<Transfer> getInstances() {
|
|
List<Transfer> in = new ArrayList<>();
|
|
for (Transfer file: instances) {
|
|
//if(Arrays.asList(STATE_STANDBY, STATE_RUNNING, STATE_SUCCESS, STATE_FAILED).contains(file.state)) {
|
|
if(file.state == STATE_STANDBY ||
|
|
file.state == STATE_RUNNING ||
|
|
file.state == STATE_SUCCESS ||
|
|
file.state == STATE_FAILED) {
|
|
in.add(file);
|
|
}
|
|
}
|
|
//in.sort(Comparator.comparing(Transfer::getAddedTime).reversed());
|
|
in.sort(Comparator.comparing(e -> e.addedTime));
|
|
return in;
|
|
}
|
|
|
|
public static Transfer getFileById(int id) {
|
|
for (Object obj: instances) {
|
|
Transfer p = (Transfer) obj;
|
|
if (p.id == id) return p;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public Integer getId() {
|
|
return id;
|
|
}
|
|
|
|
public static void parameter(Context context) {
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
|
|
|
host = prefs.getString("host", null);
|
|
root = prefs.getString("root", null);
|
|
shared_storage = prefs.getString("shared_storage", null);
|
|
use_shared_storage = prefs.getBoolean("use_shared_storage", false);
|
|
if(prefs.getBoolean("protocol", false))
|
|
protocol = "https";
|
|
else
|
|
protocol = "http";
|
|
String portValue = prefs.getString("port", null);
|
|
if(portValue.equals("")){
|
|
if(protocol.equals("http"))
|
|
port = 80;
|
|
else if(protocol.equals("https"))
|
|
port = 443;
|
|
}
|
|
else
|
|
port = valueOf(portValue);
|
|
}
|
|
|
|
public void AddTransfer() {
|
|
|
|
state = STATE_STANDBY;
|
|
|
|
addedTime = new Timestamp(System.currentTimeMillis());
|
|
|
|
Thread.State state = thread.getState();
|
|
|
|
if(state == Thread.State.NEW || state == Thread.State.TERMINATED) {
|
|
thread = new Thread(startTransfers);
|
|
thread.start();
|
|
|
|
/*Intent serviceIntent = new Intent(activity, TransferService.class);
|
|
ContextCompat.startForegroundService(activity, serviceIntent);*/
|
|
}
|
|
}
|
|
|
|
public void startTransfer() {
|
|
|
|
}
|
|
|
|
public static Runnable startTransfers = () -> {
|
|
try {
|
|
for (Transfer transfer : getInstances()) {
|
|
if (transfer.state == Transfer.STATE_STANDBY) {
|
|
transfer.startTransfer();
|
|
thread.run(); // restart thread for another potential standby transfer
|
|
break; // ignore remainder instance
|
|
}
|
|
}
|
|
} catch (ConcurrentModificationException e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
/*Intent serviceIntent = new Intent(Transfer.activity, TransferService.class);
|
|
Transfer.activity.stopService(serviceIntent);*/
|
|
};
|
|
|
|
public void progressUpdateDelay() {
|
|
// Run only every second to reduce CPU usage
|
|
if (System.currentTimeMillis() > (savedTimeMillis + 1000)) {
|
|
savedTimeMillis = System.currentTimeMillis();
|
|
progressUpdate();
|
|
}
|
|
}
|
|
|
|
private void progressUpdate(){
|
|
|
|
loadedSI = Transfer.humanReadableByteCountBin(loaded);
|
|
|
|
activity.runOnUiThread(() -> {
|
|
|
|
try {
|
|
|
|
notifBuilder.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud)
|
|
.setContentTitle(name)
|
|
.setContentText(String.format("%d%% %s/%s", percent, loadedSI, sizeSI))
|
|
.setProgress(100, (int) percent, false)
|
|
.setContentIntent(pendingIntent);
|
|
notifiManager.notify(Transfer.NOTIF_SERVICE, notifBuilder.build());
|
|
|
|
if (app_started && fragment_on)
|
|
showProgressFragment();
|
|
|
|
} catch (ConcurrentModificationException e) {
|
|
e.printStackTrace();
|
|
}
|
|
});
|
|
}
|
|
|
|
public void progressEnd() {
|
|
progressUpdate();
|
|
activity.runOnUiThread(() -> {
|
|
|
|
notifiManager.cancel(Transfer.NOTIF_SERVICE);
|
|
|
|
if (!app_started) {
|
|
notifBuilder.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud)
|
|
.setContentTitle(name)
|
|
.setContentText(info)
|
|
.setProgress(0, 0, false)
|
|
.setContentIntent(pendingIntent);
|
|
notifiManager.notify(id, notifBuilder.build());
|
|
}
|
|
|
|
System.out.println(message);
|
|
/*Snackbar.make(Transfer.activity.findViewById(R.id.view_pager), tr.message, Snackbar.LENGTH_LONG)
|
|
.setAction("Action", null).show();*/
|
|
Toast.makeText(activity, message, Toast.LENGTH_SHORT).show();
|
|
|
|
});
|
|
}
|
|
|
|
public void showProgressFragment(){
|
|
|
|
LinearLayout groot = fragment_progress.findViewById(R.id.groot);
|
|
|
|
View progress = groot.findViewById(id);
|
|
|
|
if (progress == null) {
|
|
progress = inflater.inflate(R.layout.progress, null);
|
|
progress.setId(id);
|
|
final View final_progress = progress;
|
|
activity.runOnUiThread(() -> {
|
|
groot.addView(final_progress, 0);
|
|
});
|
|
}
|
|
|
|
((ProgressBar) progress.findViewById(R.id.progressBar)).setProgress((int) percent);
|
|
((ImageView) progress.findViewById(R.id.transferType)).setImageResource(drawable);
|
|
((TextView) progress.findViewById(R.id.progressText)).setText(percent + " %");
|
|
((TextView) progress.findViewById(R.id.fileName)).setText(name);
|
|
((TextView) progress.findViewById(R.id.fileSize)).setText(String.format("%s/%s", loadedSI, sizeSI));
|
|
|
|
if (state == Transfer.STATE_SUCCESS)
|
|
((TextView) progress.findViewById(R.id.fileName)).setTextColor(Color.GREEN);
|
|
else if (state == Transfer.STATE_FAILED)
|
|
((TextView) progress.findViewById(R.id.fileName)).setTextColor(Color.RED);
|
|
}
|
|
|
|
static URL checkRedirection(URL url) throws IOException {
|
|
String location = null;
|
|
HttpURLConnection conn = null;
|
|
int responseCode;
|
|
int nbRedirect = 0;
|
|
|
|
do {
|
|
|
|
conn = (HttpURLConnection) url.openConnection();
|
|
conn.setRequestMethod("GET");
|
|
conn.setInstanceFollowRedirects(false);
|
|
conn.setConnectTimeout(2000);
|
|
|
|
conn.connect();
|
|
responseCode = conn.getResponseCode();
|
|
|
|
Log.d("Réponse Code", String.valueOf(responseCode));
|
|
|
|
if(responseCode != HttpURLConnection.HTTP_MOVED_PERM && responseCode != HttpURLConnection.HTTP_MOVED_TEMP) {
|
|
break;
|
|
}
|
|
|
|
location = conn.getHeaderField("Location");
|
|
Log.d("Location", location);
|
|
|
|
url = new URL(location);
|
|
|
|
|
|
conn.disconnect();
|
|
|
|
nbRedirect++;
|
|
if(nbRedirect > 10) {
|
|
throw new ProtocolException("Too many follow-up requests: " + nbRedirect);
|
|
}
|
|
|
|
|
|
} while (responseCode == HttpURLConnection.HTTP_MOVED_PERM || responseCode == HttpURLConnection.HTTP_MOVED_TEMP);
|
|
|
|
return url;
|
|
}
|
|
|
|
public static String getFileList() throws IOException {
|
|
URL url = null;
|
|
HttpURLConnection conn = null;
|
|
|
|
String fileList = "";
|
|
int buf;
|
|
|
|
url = new URL(protocol, host, port, root + "/list.php");
|
|
conn = (HttpURLConnection) url.openConnection();
|
|
conn.setConnectTimeout(2000);
|
|
|
|
conn.connect();
|
|
|
|
int responseCode = conn.getResponseCode();
|
|
|
|
if (responseCode == HttpURLConnection.HTTP_OK) {
|
|
InputStreamReader isw = new InputStreamReader(conn.getInputStream());
|
|
|
|
while ((buf = isw.read()) > 0) {
|
|
fileList = fileList + (char) buf;
|
|
}
|
|
}
|
|
else {
|
|
String s = conn.getResponseMessage();
|
|
throw new HttpErrorException("error code: " + responseCode + " " + s);
|
|
}
|
|
|
|
conn.disconnect();
|
|
|
|
return fileList;
|
|
}
|
|
|
|
private static int timeout;
|
|
|
|
public static void errorSnackbar(final String message) {
|
|
|
|
System.out.println(message);
|
|
|
|
if (activity != null) {
|
|
activity.runOnUiThread(() -> Snackbar.make(activity.findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG)
|
|
.setAction("Action", null).show());
|
|
}
|
|
}
|
|
|
|
public static String humanReadableByteCountBin(long bytes) {
|
|
long absB = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
|
|
if (absB < 1024) {
|
|
return bytes + " B";
|
|
}
|
|
long value = absB;
|
|
CharacterIterator ci = new StringCharacterIterator("KMGTPE");
|
|
for (int i = 40; i >= 0 && absB > 0xfffccccccccccccL >> i; i -= 10) {
|
|
value >>= 10;
|
|
ci.next();
|
|
}
|
|
value *= Long.signum(bytes);
|
|
return String.format("%.1f %ciB", value / 1024.0, ci.current());
|
|
}
|
|
}
|
|
|