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 instances = new ArrayList<>(); public static List getInstances() { List 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()); } }