2022-02-25 17:11:23 +01:00

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());
}
}