diff --git a/app/build.gradle b/app/build.gradle index c010a38..8b01084 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,7 +9,7 @@ android { minSdkVersion 24 targetSdkVersion 30 versionCode 1 - versionName "1.0" + versionName "2.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/com/localtransfer/MainActivity.java b/app/src/main/java/com/localtransfer/MainActivity.java index 92f5c89..3f789c3 100644 --- a/app/src/main/java/com/localtransfer/MainActivity.java +++ b/app/src/main/java/com/localtransfer/MainActivity.java @@ -78,16 +78,14 @@ public class MainActivity extends AppCompatActivity { String action = intent.getAction(); String type = intent.getType(); - Transfer tr = new Transfer(); - if (Intent.ACTION_SEND.equals(action) && type != null) { viewPager.setCurrentItem(2); if ("text/plain".equals(type)) { String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); - tr.handleSendText(sharedText); + Transfer.handleSendText(sharedText); } else { Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM); - tr.handleSendFile(uri); + Transfer.handleSendFile(uri); } } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) { viewPager.setCurrentItem(2); @@ -95,7 +93,7 @@ public class MainActivity extends AppCompatActivity { int nbItem = fileUris.size(); Toast.makeText(this, "You select " + nbItem + " files", Toast.LENGTH_SHORT).show(); if (fileUris != null) - for(Uri uri : fileUris) tr.handleSendFile(uri); + for(Uri uri : fileUris) Transfer.handleSendFile(uri); } } @@ -110,11 +108,10 @@ public class MainActivity extends AppCompatActivity { ViewPager viewPager = this.findViewById(R.id.view_pager); viewPager.setCurrentItem(2); - Transfer tr = new Transfer(); if (type != null) { String sharedText = data.getStringExtra(Intent.EXTRA_TEXT); - tr.handleSendText(sharedText); + Transfer.handleSendText(sharedText); } else { ArrayList fileUris = new ArrayList<>(); @@ -130,7 +127,7 @@ public class MainActivity extends AppCompatActivity { fileUris.add(uri); } for (Uri uri : fileUris) { - tr.handleSendFile(uri); + Transfer.handleSendFile(uri); } } } diff --git a/app/src/main/java/com/localtransfer/Progress.java b/app/src/main/java/com/localtransfer/Progress.java index 19dc597..3a50e4a 100644 --- a/app/src/main/java/com/localtransfer/Progress.java +++ b/app/src/main/java/com/localtransfer/Progress.java @@ -1,32 +1,29 @@ package com.localtransfer; +import android.animation.ObjectAnimator; import android.app.Notification; import android.app.PendingIntent; import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.Drawable; import android.view.LayoutInflater; import android.view.View; -import android.widget.Button; +import android.view.animation.Animation; +import android.view.animation.LinearInterpolator; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; +import android.widget.Toast; -import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; -import androidx.core.content.ContextCompat; -import java.util.ArrayList; +import com.google.android.material.snackbar.Snackbar; + import java.util.ConcurrentModificationException; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; public class Progress { - public static final int UPLOAD = 1000; - public static final int DOWNLOAD = 1001; - - private static Notification.Builder bl = new Notification.Builder(Transfer.activity); private static NotificationManagerCompat notifiManager = NotificationManagerCompat.from(Transfer.activity); private static final LayoutInflater inflater = (LayoutInflater) Transfer.activity.getSystemService(Transfer.activity.LAYOUT_INFLATER_SERVICE); @@ -34,163 +31,131 @@ public class Progress { private static Intent notificationIntent = new Intent(Transfer.activity, MainActivity.class); private static PendingIntent pendingIntent = PendingIntent.getActivity(Transfer.activity,0, notificationIntent, 0); - private static List instances = new ArrayList<>(); - - private Integer id; - private String name; - - private long size; - private String HumanSize; - - public long loaded; - private String HumanLoaded; - - public long percent; - public static View root; public static boolean fragment_on = false; public static boolean app_started = false; - private Timer timer = new Timer(); - private int drawable; - private String info; + private static long savedTimeMillis; - public Button button; - private boolean run; - - public Progress(String name, long size, int type) { - - instances.add(this); - - run = true; - - this.name = name; - this.size = size; - this.HumanSize = Transfer.humanReadableByteCountBin(size); - - id = View.generateViewId(); - - switch (type) { - case Progress.DOWNLOAD: - drawable = R.drawable.ic_download_24; - info = "Download complete"; - break; - case Progress.UPLOAD: - drawable = R.drawable.ic_upload_24; - info = "Upload complete"; - break; - default: - throw new IllegalStateException("Unexpected value: " + type); - } - - Intent serviceIntent = new Intent(Transfer.activity, TransferService.class); - serviceIntent.putExtra("id", id); - ContextCompat.startForegroundService(Transfer.activity, serviceIntent); - - timer.schedule(new TimerTask() { + public static void PreProgress(Transfer tr) { + Transfer.activity.runOnUiThread(new Runnable() { @Override public void run() { - showProgress(); + + final Drawable image = Transfer.activity.getDrawable(R.drawable.ic_spinner_rotate); + + if(tr.button != null) { + int h = image.getIntrinsicHeight(); + int w = image.getIntrinsicWidth(); + image.setBounds(0, 0, w, h); + tr.button.setCompoundDrawables(tr.button.getCompoundDrawables()[0], null, image, null); + ObjectAnimator anim = ObjectAnimator.ofInt(image, "level", 0, 10000); + anim.setDuration(1000); + anim.setRepeatCount(Animation.INFINITE); + anim.setInterpolator(new LinearInterpolator()); + anim.start(); + } } - }, 0, 1000); + }); } - public static List getInstances() { - return instances; - } - - public void stopProgress() { - timer.cancel(); - showProgress(); - - run = false; - - Intent serviceIntent = new Intent(Transfer.activity, TransferService.class); - Transfer.activity.stopService(serviceIntent); - - if(! app_started) { - bl.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud) - .setContentTitle(name) - .setContentText(info) - .setProgress(0, 0, false) - .setContentIntent(pendingIntent); - notifiManager.notify(id, bl.build()); + public static void ProgressUpdateDelay(Transfer tr) { + // Run only every second to reduce CPU usage + if (System.currentTimeMillis() > (savedTimeMillis + 1000)) { + savedTimeMillis = System.currentTimeMillis(); + ProgressUpdate(tr); } - } - public void delete() { - instances.remove(this); - } + private static void ProgressUpdate(Transfer tr){ + Transfer.activity.runOnUiThread(new Runnable() { + @Override + public void run() { - public static Progress getProgress(int id) { + if (Progress.app_started && tr.button != null) + tr.button.setText(String.format("Download in progress %d%%", tr.percent)); - for (Object obj: instances) { - Progress p = (Progress) obj; - if (p.id == id) return p; - } - return null; - } + try { - public static boolean setButton(String name, Button button) { + bl.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud) + .setContentTitle(tr.fileName) + .setContentText(String.format("%d%% %s/%s", tr.percent, tr.loadedHuman, tr.fileSizeHuman)) + .setProgress(100, (int) tr.percent, false) + .setContentIntent(pendingIntent); + notifiManager.notify(Transfer.NOTIF_SERVICE, bl.build()); - for (Object obj: instances) { - Progress p = (Progress) obj; - if (name.equals(p.name) && p.run) { - p.button = button; - return true; + if (app_started && fragment_on) + showProgressFragment(tr); + + } catch (ConcurrentModificationException e) { + e.printStackTrace(); + } } - } - return false; + }); } - private void showProgress(){ + public static void PostProgress(Transfer tr) { + ProgressUpdate(tr); + Transfer.activity.runOnUiThread(new Runnable() { + @Override + public void run() { - try { + notifiManager.cancel(Transfer.NOTIF_SERVICE); - HumanLoaded = Transfer.humanReadableByteCountBin(loaded); + if (!app_started) { + bl.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud) + .setContentTitle(tr.fileName) + .setContentText(tr.info) + .setProgress(0, 0, false) + .setContentIntent(pendingIntent); + notifiManager.notify(tr.id, bl.build()); + } - bl.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud) - .setContentTitle(name) - .setContentText(String.format("%d%% %s/%s", percent, HumanLoaded, HumanSize)) - .setProgress(100, (int) percent, false) - .setContentIntent(pendingIntent); - notifiManager.notify(id, bl.build()); + if (tr.button != null) { + final LinearLayout layout = (LinearLayout) tr.button.getParent(); + layout.findViewById(R.id.file_view).setVisibility(LinearLayout.VISIBLE); + layout.findViewById(R.id.file_share).setVisibility(LinearLayout.VISIBLE); + tr.button.setVisibility(LinearLayout.GONE); + tr.button.setEnabled(true); - if(app_started && fragment_on) { - showProgressFragment(); + tr.button.setText(Transfer.activity.getString(R.string.file_download)); + tr.button.setCompoundDrawables(tr.button.getCompoundDrawables()[0], null, null, null); + } + + System.out.println(tr.message); + /*Snackbar.make(Transfer.activity.findViewById(R.id.view_pager), tr.message, Snackbar.LENGTH_LONG) + .setAction("Action", null).show();*/ + Toast.makeText(Transfer.activity, tr.message, Toast.LENGTH_SHORT).show(); } - - } catch (ConcurrentModificationException e) { - e.printStackTrace(); - } - + }); } - public void showProgressFragment(){ + public static void showProgressFragment(Transfer tr){ LinearLayout groot = root.findViewById(R.id.groot); final View progress; - if (groot.findViewById(id) != null) { - progress = groot.findViewById(id); + if (groot.findViewById(tr.id) != null) { + progress = groot.findViewById(tr.id); } else { progress = inflater.inflate(R.layout.progress, null); - progress.setId(id); + progress.setId(tr.id); Transfer.activity.runOnUiThread(() -> { groot.addView(progress, 0); }); } - Transfer.activity.runOnUiThread(() -> { - ((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", HumanLoaded, HumanSize)); - }); + ((ProgressBar) progress.findViewById(R.id.progressBar)).setProgress((int) tr.percent); + ((ImageView) progress.findViewById(R.id.transferType)).setImageResource(tr.drawable); + ((TextView) progress.findViewById(R.id.progressText)).setText(tr.percent + " %"); + ((TextView) progress.findViewById(R.id.fileName)).setText(tr.fileName); + ((TextView) progress.findViewById(R.id.fileSize)).setText(String.format("%s/%s", tr.loadedHuman, tr.fileSizeHuman)); + if (tr.state == Transfer.STATE_SUCCESS) + ((TextView) progress.findViewById(R.id.fileName)).setTextColor(Color.GREEN); + else if (tr.state == Transfer.STATE_FAILED) + ((TextView) progress.findViewById(R.id.fileName)).setTextColor(Color.RED); } } diff --git a/app/src/main/java/com/localtransfer/Transfer.java b/app/src/main/java/com/localtransfer/Transfer.java index b4272a0..2c5d544 100644 --- a/app/src/main/java/com/localtransfer/Transfer.java +++ b/app/src/main/java/com/localtransfer/Transfer.java @@ -1,25 +1,19 @@ package com.localtransfer; -import android.animation.ObjectAnimator; import android.app.Activity; import android.content.Context; +import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; -import android.graphics.drawable.Drawable; import android.net.Uri; -import android.os.Parcel; -import android.os.Parcelable; import android.provider.OpenableColumns; import android.util.Log; import android.view.View; -import android.view.animation.Animation; -import android.view.animation.LinearInterpolator; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; -import androidx.core.app.NotificationCompat; -import androidx.core.app.NotificationManagerCompat; +import androidx.core.content.ContextCompat; import androidx.core.content.FileProvider; import androidx.preference.PreferenceManager; @@ -32,7 +26,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; -import java.io.Serializable; import java.net.HttpURLConnection; import java.net.ProtocolException; import java.net.URL; @@ -41,6 +34,7 @@ import java.nio.charset.StandardCharsets; import java.text.CharacterIterator; import java.text.SimpleDateFormat; import java.text.StringCharacterIterator; +import java.util.ArrayList; import java.util.ConcurrentModificationException; import java.util.Date; import java.util.List; @@ -59,6 +53,127 @@ public class Transfer { public static Activity activity; + public static final int STATE_STANDBY = 100; + public static final int STATE_RUNNING = 101; + public static final int STATE_SUCCESS = 102; + public static final int STATE_FAILED = 103; + + public static final int TYPE_DOWNLOAD = 200; + public static final int TYPE_UPLOAD = 201; + + public static final int NOTIF_SERVICE = 1000; + public static final int NOTIF_GROUP = 1001; + + public static boolean runningTransfer = false; + + private static List instances = new ArrayList<>(); + + public static List getInstances() { + return instances; + } + + public int state; + public String error; + + public int type; + + public Integer id; + public int drawable; + public String info; + public String message; + public String fileName; + + public long fileSize; + public String fileSizeHuman; + + public long loaded; + public String loadedHuman = "0"; + public long percent; + + public Transfer(int type) { + + id = View.generateViewId(); + + switch (type) { + case TYPE_DOWNLOAD: + drawable = R.drawable.ic_download_24; + info = "Download complete"; + break; + case TYPE_UPLOAD: + drawable = R.drawable.ic_upload_24; + info = "Upload complete"; + break; + default: + throw new IllegalStateException("Unexpected value: " + type); + } + + state = STATE_STANDBY; + this.type = type; + + } + + public void AddTransfer() { + instances.add(this); + + if(!runningTransfer) { + Intent serviceIntent = new Intent(activity, TransferService.class); + ContextCompat.startForegroundService(activity, serviceIntent); + runningTransfer = true; + new Thread(() -> StartTransfer(this)).start(); + } + } + + private static void StartTransfer(Transfer tr) { + try { + switch (tr.type) { + case Transfer.TYPE_DOWNLOAD: + tr.downloadFile(); + break; + case Transfer.TYPE_UPLOAD: + tr.uploadFile(); + break; + default: + throw new IllegalStateException("Unexpected value: " + tr.type); + } + } catch (IOException e) { + final String ExceptionName = e.getClass().getSimpleName(); + final String ExceptionMess = e.getMessage(); + + tr.state = Transfer.STATE_FAILED; + tr.error = ExceptionName + ": " + ExceptionMess; + Progress.PostProgress(tr); + + if(ExceptionName != null && ExceptionMess != null) { + Transfer.error(ExceptionMess); + } + + } + + try { + for (Object obj : Transfer.getInstances()) { + Transfer transfer = (Transfer) obj; + if (transfer.state == Transfer.STATE_STANDBY) + StartTransfer(transfer); + } + } catch (ConcurrentModificationException e) { + e.printStackTrace(); + try { + Thread.sleep(10); + } catch (InterruptedException InterrupEx) { + InterrupEx.printStackTrace(); + } + for (Object obj : Transfer.getInstances()) { + Transfer transfer = (Transfer) obj; + if (transfer.state == Transfer.STATE_STANDBY) + StartTransfer(transfer); + } + } + + Intent serviceIntent = new Intent(Transfer.activity, TransferService.class); + Transfer.activity.stopService(serviceIntent); + Transfer.runningTransfer = false; + } + public static void parameter(Context context) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); @@ -72,7 +187,267 @@ public class Transfer { protocol = "http"; } - private URL checkRedirection(URL url) throws IOException { + public Uri uri; + + public static void handleSendFile(Uri uri) { + if (uri != null) { + Transfer tr = new Transfer(Transfer.TYPE_UPLOAD); + tr.uri = uri; + + Cursor cursor = activity.getContentResolver().query(uri, null, null, null, null); + cursor.moveToFirst(); + + tr.fileName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)); + tr.fileSize = cursor.getLong(cursor.getColumnIndex(OpenableColumns.SIZE)); + tr.fileSizeHuman = Transfer.humanReadableByteCountBin(tr.fileSize); + + tr.AddTransfer(); + } + } + + public static void handleSendText(String sharedText) { + if (sharedText != null) { + SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMdd_HHmmss"); + Date now = new Date(); + String strDate = sdfDate.format(now); + Uri uri = null; + + try { + File outputFile = new File(activity.getCacheDir(), strDate + ".txt"); + FileOutputStream fileOut = new FileOutputStream(outputFile); + OutputStreamWriter OutWriter = new OutputStreamWriter(fileOut); + OutWriter.append(sharedText); + OutWriter.close(); + + fileOut.flush(); + fileOut.close(); + + uri = FileProvider.getUriForFile(activity, activity.getPackageName(), outputFile); + + } catch (IOException e) { + e.printStackTrace(); + } + handleSendFile(uri); + } + } + + public String uploadFile() throws IOException { + URL url = null; + HttpURLConnection conn = null; + DataOutputStream request = null; + String boundary = "*****"; + int maxBufferSize = 1 * 1024 * 1024; + byte[] buffer = new byte[maxBufferSize]; + int bufferLength; + loaded = 0; + + String fileNameUTF8 = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1); + + String type = activity.getContentResolver().getType(uri); + + url = new URL(protocol, host, port, root + "/upload.php"); + + url = checkRedirection(url); + + Progress.PreProgress(this); + + if(url != null) { + + Log.d("URL", url.toString()); + + conn = (HttpURLConnection) url.openConnection(); + conn.setDoInput(true); // Allow Inputs + conn.setDoOutput(true); // Allow Outputs + conn.setUseCaches(false); // Don't use a Cached Copy + conn.setChunkedStreamingMode(maxBufferSize); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Connection", "keep-alive"); + conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); + + conn.connect(); + + request = new DataOutputStream(conn.getOutputStream()); + + request.writeBytes("--" + boundary + "\r\n"); + request.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileNameUTF8 + "\"\r\n"); + request.writeBytes("Content-Type: " + type + "\r\n\r\n"); + + InputStream in = activity.getContentResolver().openInputStream(uri); + + while ((bufferLength = in.read(buffer)) > 0) { + request.write(buffer, 0, bufferLength); + loaded+= (long) bufferLength; + loadedHuman = Transfer.humanReadableByteCountBin(loaded); + percent = ((loaded * 100) / fileSize); + Progress.ProgressUpdateDelay(this); + } + + request.writeBytes("\r\n"); + request.writeBytes("--" + boundary + "--\r\n"); + + in.close(); + + int responseCode = conn.getResponseCode(); + + if (responseCode == HttpURLConnection.HTTP_OK) { + message = "File " + fileName + " successful upload"; + state = Transfer.STATE_SUCCESS; + Progress.PostProgress(this); + } + else { + String s = conn.getResponseMessage(); + throw new HttpErrorException("HTTP Error code " + responseCode + " " + s); + } + + request.flush(); + + request.close(); + + conn.disconnect(); + } + + return message; + } + + + public File file; + public String href; + public Button button; + + public void downloadFile() throws IOException { + URL url = null; + HttpURLConnection conn = null; + int maxBufferSize = 1 * 1024 * 1024; + byte[] buffer = new byte[maxBufferSize]; + int bufferLength; + loaded = 0; + + Progress.PreProgress(this); + + String[] parts = href.split("/"); + String path = ""; + for(int i=0; i< parts.length - 1; i++) { + path = path + parts[i] + "/"; + } + String query = URLEncoder.encode(parts[parts.length - 1], StandardCharsets.UTF_8.toString()); + url = new URL(protocol, host, port, path + query.replace("+", "%20")); + conn = (HttpURLConnection) url.openConnection(); + conn.setDoOutput(true); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(2000); + + Log.d("URL", url.toString()); + + conn.connect(); + + int responseCode = conn.getResponseCode(); + + if (responseCode == HttpURLConnection.HTTP_OK) { + + FileOutputStream fileOutput = new FileOutputStream(file); + InputStream in = conn.getInputStream(); + + while ((bufferLength = in.read(buffer)) > 0) { + fileOutput.write(buffer, 0, bufferLength); + loaded+= (long) bufferLength; + loadedHuman = Transfer.humanReadableByteCountBin(loaded); + percent = ((loaded * 100) / fileSize); + Progress.ProgressUpdateDelay(this); + } + fileOutput.close(); + + conn.disconnect(); + + message = "File " + fileName + " successful download"; + state = Transfer.STATE_SUCCESS; + Progress.PostProgress(this); + + } + else { + String s = conn.getResponseMessage(); + throw new HttpErrorException("HTTP Error code " + responseCode + " " + s); + } + + conn.disconnect(); + } + + public static boolean setButton(String name, Button button) { + + for (Object obj: instances) { + Transfer tr = (Transfer) obj; + if (name.equals(tr.fileName) && tr.state == STATE_RUNNING) { + tr.button = button; + return true; + } + } + return false; + } + + 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("HTTP Error code " + responseCode + " " + s); + } + + conn.disconnect(); + + return fileList; + } + + public static String deleteFile(String file) throws IOException { + + URL url = null; + HttpURLConnection conn = null; + + String message; + + String query = URLEncoder.encode(file, StandardCharsets.UTF_8.toString()); + String serverUrl = root + "/delete.php?file=" + query; + url = new URL(protocol, host, port, serverUrl); + conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(2000); + + conn.connect(); + + int responseCode = conn.getResponseCode(); + + if (responseCode == HttpURLConnection.HTTP_OK) { + + message = "File " + file + " successful deleted"; + } + else { + String s = conn.getResponseMessage(); + throw new HttpErrorException("HTTP Error code " + responseCode + " " + s); + } + + conn.disconnect(); + + return message; + } + + private static URL checkRedirection(URL url) throws IOException { String location = null; HttpURLConnection conn = null; int responseCode; @@ -113,331 +488,18 @@ public class Transfer { return url; } - public void handleSendFile(Uri uri) { - if (uri != null) { - new Thread(() -> { - try { - uploadFile(uri); - } catch (IOException e) { - final String ExceptionName = e.getClass().getSimpleName(); - final String ExceptionMess = e.getMessage(); - - if(ExceptionName != null && ExceptionMess != null) { - Transfer.error(ExceptionName + ": " + ExceptionMess, null, null); - } - - } - }).start(); - } - } - - public void handleSendText(String sharedText) { - if (sharedText != null) { - SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMdd_HHmmss"); - Date now = new Date(); - String strDate = sdfDate.format(now); - new Thread(() -> { - try { - File outputFile = new File(activity.getCacheDir(), strDate + ".txt"); - FileOutputStream fileOut = new FileOutputStream(outputFile); - OutputStreamWriter OutWriter = new OutputStreamWriter(fileOut); - OutWriter.append(sharedText); - OutWriter.close(); - - fileOut.flush(); - fileOut.close(); - - Uri uri = FileProvider.getUriForFile(activity, activity.getPackageName(), outputFile); - - uploadFile(uri); - } catch (IOException e) { - e.printStackTrace(); - } - }).start(); - } - } - - public String uploadFile(Uri uri) throws IOException { - String message = null; - URL url = null; - HttpURLConnection conn = null; - DataOutputStream request = null; - String boundary = "*****"; - int maxBufferSize = 1 * 1024 * 1024; - byte[] buffer = new byte[maxBufferSize]; - int bufferLength; - long loaded = 0; - - Cursor cursor = activity.getContentResolver().query(uri, null, null, null, null); - cursor.moveToFirst(); - String fileName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)); - String fileNameUTF8 = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1); - long fileSize = cursor.getLong(cursor.getColumnIndex(OpenableColumns.SIZE)); - String type = activity.getContentResolver().getType(uri); - - url = new URL(protocol, host, port, root + "/upload.php"); - - url = checkRedirection(url); - - Progress p = new Progress(fileName, fileSize, Progress.UPLOAD); - - if(url != null) { - - Log.d("URL", url.toString()); - - conn = (HttpURLConnection) url.openConnection(); - conn.setDoInput(true); // Allow Inputs - conn.setDoOutput(true); // Allow Outputs - conn.setUseCaches(false); // Don't use a Cached Copy - conn.setChunkedStreamingMode(maxBufferSize); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Connection", "keep-alive"); - conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); - - conn.connect(); - - request = new DataOutputStream(conn.getOutputStream()); - - request.writeBytes("--" + boundary + "\r\n"); - request.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileNameUTF8 + "\"\r\n"); - request.writeBytes("Content-Type: " + type + "\r\n\r\n"); - - InputStream in = activity.getContentResolver().openInputStream(uri); - - while ((bufferLength = in.read(buffer)) > 0) { - request.write(buffer, 0, bufferLength); - loaded+= (long) bufferLength; - p.loaded = loaded; - p.percent = ((loaded * 100) / fileSize); - } - - request.writeBytes("\r\n"); - request.writeBytes("--" + boundary + "--\r\n"); - - in.close(); - - int responseCode = conn.getResponseCode(); - - if (responseCode == HttpURLConnection.HTTP_OK) { - message = "File " + fileName + " successful upload"; - p.stopProgress(); - } - else { - String s = conn.getResponseMessage(); - throw new HttpErrorException("error code: " + responseCode + " " + s); - } - - request.flush(); - - request.close(); - - conn.disconnect(); - - System.out.println(message); - if (activity != null) { - String finalMessage = message; - activity.runOnUiThread(() -> - Snackbar.make(activity.findViewById(R.id.view_pager), finalMessage, Snackbar.LENGTH_LONG) - .setAction("Action", null).show()); - } - } - - return message; - } - - public 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; - } - - public void downloadFile(final File file, String name, long fileSize, String href, Button button) throws IOException { - - /*final LinearLayout layout = activity.findViewById(id); - final Button button; - if(layout != null) - button = layout.findViewById(R.id.file_download); - else - button = null;*/ - - URL url = null; - HttpURLConnection conn = null; - int maxBufferSize = 1 * 1024 * 1024; - byte[] buffer = new byte[maxBufferSize]; - int bufferLength; - long loaded = 0; - - final Drawable image = activity.getDrawable(R.drawable.ic_spinner_rotate); - - Progress p = new Progress(name, fileSize, Progress.DOWNLOAD); - if(button != null) - p.button = button; - - if(p.button != null) { - activity.runOnUiThread(() -> { - int h = image.getIntrinsicHeight(); - int w = image.getIntrinsicWidth(); - image.setBounds(0, 0, w, h); - p.button.setCompoundDrawables(button.getCompoundDrawables()[0], null, image, null); - ObjectAnimator anim = ObjectAnimator.ofInt(image, "level", 0, 10000); - anim.setDuration(1000); - anim.setRepeatCount(Animation.INFINITE); - anim.setInterpolator(new LinearInterpolator()); - anim.start(); - }); - } - - String[] parts = href.split("/"); - String path = ""; - for(int i=0; i< parts.length - 1; i++) { - path = path + parts[i] + "/"; - } - String query = URLEncoder.encode(parts[parts.length - 1], StandardCharsets.UTF_8.toString()); - url = new URL(protocol, host, port, path + query.replace("+", "%20")); - conn = (HttpURLConnection) url.openConnection(); - conn.setDoOutput(true); - conn.setRequestMethod("GET"); - conn.setConnectTimeout(2000); - - Log.d("URL", url.toString()); - - conn.connect(); - - int responseCode = conn.getResponseCode(); - - if (responseCode == HttpURLConnection.HTTP_OK) { - - FileOutputStream fileOutput = new FileOutputStream(file); - InputStream in = conn.getInputStream(); - - while ((bufferLength = in.read(buffer)) > 0) { - fileOutput.write(buffer, 0, bufferLength); - loaded+= (long) bufferLength; - p.loaded = loaded; - p.percent = ((loaded * 100) / fileSize); - if(Progress.app_started && p.button != null) - activity.runOnUiThread(() -> p.button.setText(String.format("Download in progress %d%%", p.percent))); - } - fileOutput.close(); - - conn.disconnect(); - - p.stopProgress(); - - if(p.button != null) { - activity.runOnUiThread(() -> { - final LinearLayout layout = (LinearLayout) p.button.getParent(); - layout.findViewById(R.id.file_view).setVisibility(LinearLayout.VISIBLE); - layout.findViewById(R.id.file_share).setVisibility(LinearLayout.VISIBLE); - p.button.setVisibility(LinearLayout.GONE); - p.button.setEnabled(true); - - p.button.setText(activity.getString(R.string.file_download)); - p.button.setCompoundDrawables(p.button.getCompoundDrawables()[0], null, null, null); - }); - } - activity.runOnUiThread(() -> { - String message = "File " + name + " successful download"; - System.out.println(message); - Snackbar.make(activity.findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG) - .setAction("Action", null).show(); - }); - } - else { - String s = conn.getResponseMessage(); - throw new HttpErrorException("error code: " + responseCode + " " + s); - } - - conn.disconnect(); - } - - public String deleteFile(String file) throws IOException { - - URL url = null; - HttpURLConnection conn = null; - - String message; - - String query = URLEncoder.encode(file, StandardCharsets.UTF_8.toString()); - String serverUrl = root + "/delete.php?file=" + query; - url = new URL(protocol, host, port, serverUrl); - conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("GET"); - conn.setConnectTimeout(2000); - - conn.connect(); - - int responseCode = conn.getResponseCode(); - - if (responseCode == HttpURLConnection.HTTP_OK) { - - message = "File " + file + " successful deleted"; - } - else { - String s = conn.getResponseMessage(); - throw new HttpErrorException("error code: " + responseCode + " " + s); - } - - conn.disconnect(); - - return message; - } - - private static int timeout; - - public static void error(final String message, final TextView title, final LinearLayout layout) { + public static void error(final String message) { System.out.println(message); - if (timeout == 0) { - if (activity != null) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - if(layout != null) - layout.removeAllViews(); - if(title != null) { - layout.addView(title); - title.setText(message); - } - Snackbar.make(activity.findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG) - .setAction("Action", null).show(); - } - }); - } - timeout = 1; - new Timer().schedule(new TimerTask() { + if (activity != null) { + activity.runOnUiThread(new Runnable() { @Override public void run() { - timeout = 0; + Snackbar.make(activity.findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG) + .setAction("Action", null).show(); } - }, 3000); + }); } } diff --git a/app/src/main/java/com/localtransfer/TransferService.java b/app/src/main/java/com/localtransfer/TransferService.java index 894e9a0..02cc73f 100644 --- a/app/src/main/java/com/localtransfer/TransferService.java +++ b/app/src/main/java/com/localtransfer/TransferService.java @@ -17,7 +17,6 @@ public class TransferService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { - int id = intent.getIntExtra("id", 0); Intent notificationIntent = new Intent(this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, @@ -27,7 +26,7 @@ public class TransferService extends Service { .setContentIntent(pendingIntent) .build(); - startForeground(id, notification); + startForeground(Transfer.NOTIF_SERVICE, notification); //do heavy work on a background thread //stopSelf(); diff --git a/app/src/main/java/com/localtransfer/fragment/DownloadFragment.java b/app/src/main/java/com/localtransfer/fragment/DownloadFragment.java index 54984ca..9f33455 100644 --- a/app/src/main/java/com/localtransfer/fragment/DownloadFragment.java +++ b/app/src/main/java/com/localtransfer/fragment/DownloadFragment.java @@ -27,7 +27,6 @@ import android.widget.TextView; import com.google.android.material.snackbar.Snackbar; import com.localtransfer.BuildConfig; -import com.localtransfer.Progress; import com.localtransfer.R; import com.localtransfer.Transfer; @@ -111,8 +110,7 @@ public class DownloadFragment extends Fragment { final String file = String.valueOf(fileDesc.getTag(R.id.ID_FILE_NAME)); new Thread(() -> { try { - Transfer tr = new Transfer(); - String message = tr.deleteFile(file); + String message = Transfer.deleteFile(file); System.out.println(message); Transfer.activity.runOnUiThread(() -> Snackbar.make(getActivity().findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG) @@ -123,7 +121,7 @@ public class DownloadFragment extends Fragment { String ExceptionMess = e.getMessage(); if(ExceptionName != null && ExceptionMess != null) { - Transfer.error(ExceptionName + ": " + ExceptionMess, null, null); + Transfer.error(ExceptionMess); } } @@ -143,18 +141,24 @@ public class DownloadFragment extends Fragment { final LinearLayout main_layout = root.findViewById(R.id.main_layout); final LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(getContext().LAYOUT_INFLATER_SERVICE); - Transfer tr = new Transfer(); - String data = ""; try { - data = tr.getFileList(); + data = Transfer.getFileList(); } catch (IOException e) { final String ExceptionName = e.getClass().getSimpleName(); final String ExceptionMess = e.getMessage(); if(ExceptionName != null && ExceptionMess != null) { - Transfer.error(ExceptionName + ": " + ExceptionMess, title, main_layout); + Transfer.error(ExceptionMess); + Transfer.activity.runOnUiThread(() -> { + if(main_layout != null) + main_layout.removeAllViews(); + if(title != null) { + main_layout.addView(title); + title.setText(ExceptionMess); + } + }); } } @@ -253,7 +257,7 @@ public class DownloadFragment extends Fragment { Bshare.setVisibility(LinearLayout.GONE); } - if (Progress.setButton(name, dl)) { + if (Transfer.setButton(name, dl)) { dl.setEnabled(false); final Drawable spinner = Transfer.activity.getDrawable(R.drawable.ic_spinner_rotate); int h = spinner.getIntrinsicHeight(); @@ -304,21 +308,14 @@ public class DownloadFragment extends Fragment { new File(save_location).mkdirs(); File file = new File(save_location, name); - Transfer tr = new Transfer(); - - new Thread(() -> { - try { - tr.downloadFile(file, name, fileSize, href, button); - } catch (IOException e) { - final String ExceptionName = e.getClass().getSimpleName(); - final String ExceptionMess = e.getMessage(); - - if(ExceptionName != null && ExceptionMess != null) { - Transfer.error(ExceptionName + ": " + ExceptionMess, null, null); - } - - } - }).start(); + Transfer tr = new Transfer(Transfer.TYPE_DOWNLOAD); + tr.file = file; + tr.fileName = name; + tr.fileSize = fileSize; + tr.fileSizeHuman = Transfer.humanReadableByteCountBin(fileSize); + tr.href = href; + tr.button = button; + tr.AddTransfer(); }; private View.OnClickListener ListenerShare = v -> { diff --git a/app/src/main/java/com/localtransfer/fragment/ProgressFragment.java b/app/src/main/java/com/localtransfer/fragment/ProgressFragment.java index afe7cc0..9c70e09 100644 --- a/app/src/main/java/com/localtransfer/fragment/ProgressFragment.java +++ b/app/src/main/java/com/localtransfer/fragment/ProgressFragment.java @@ -54,10 +54,10 @@ public class ProgressFragment extends Fragment { Progress.fragment_on = true; - List instances = Progress.getInstances(); + List instances = Transfer.getInstances(); for (Object obj: instances) { - Progress p = (Progress) obj; - p.showProgressFragment(); + Transfer tr = (Transfer) obj; + Progress.showProgressFragment(tr); } }