diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 61a9130..fb7f4a8 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 23a89bb..526b4c2 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -4,10 +4,9 @@ diff --git a/.idea/misc.xml b/.idea/misc.xml index a8f62cd..f1a2d08 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,14 @@ + + + - + diff --git a/app/build.gradle b/app/build.gradle index 8b01084..27c226f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,7 +2,6 @@ apply plugin: 'com.android.application' android { compileSdkVersion 30 - buildToolsVersion "30.0.2" defaultConfig { applicationId "com.localtransfer" @@ -21,8 +20,8 @@ android { } } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bd2ee7c..0414bfa 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,13 +3,17 @@ package="com.localtransfer"> - + + @@ -17,7 +21,7 @@ android:name=".TransferService" android:enabled="true" android:exported="true"> - + fileUris = new ArrayList<>(); @@ -127,7 +143,7 @@ public class MainActivity extends AppCompatActivity { fileUris.add(uri); } for (Uri uri : fileUris) { - Transfer.handleSendFile(uri); + tr.handleSendFile(uri); } } } @@ -137,14 +153,14 @@ public class MainActivity extends AppCompatActivity { public void onResume(){ super.onResume(); - Progress.app_started = true; + Transfer.app_started = true; } @Override public void onPause(){ super.onPause(); - Progress.app_started = false; + Transfer.app_started = false; } @Override diff --git a/app/src/main/java/com/localtransfer/Progress.java b/app/src/main/java/com/localtransfer/Progress.java deleted file mode 100644 index 3a50e4a..0000000 --- a/app/src/main/java/com/localtransfer/Progress.java +++ /dev/null @@ -1,161 +0,0 @@ -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.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.NotificationManagerCompat; - -import com.google.android.material.snackbar.Snackbar; - -import java.util.ConcurrentModificationException; - -public class Progress { - - 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); - - private static Intent notificationIntent = new Intent(Transfer.activity, MainActivity.class); - private static PendingIntent pendingIntent = PendingIntent.getActivity(Transfer.activity,0, notificationIntent, 0); - - public static View root; - public static boolean fragment_on = false; - public static boolean app_started = false; - - private static long savedTimeMillis; - - public static void PreProgress(Transfer tr) { - Transfer.activity.runOnUiThread(new Runnable() { - @Override - public void run() { - - 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(); - } - } - }); - } - - public static void ProgressUpdateDelay(Transfer tr) { - // Run only every second to reduce CPU usage - if (System.currentTimeMillis() > (savedTimeMillis + 1000)) { - savedTimeMillis = System.currentTimeMillis(); - ProgressUpdate(tr); - } - } - - private static void ProgressUpdate(Transfer tr){ - Transfer.activity.runOnUiThread(new Runnable() { - @Override - public void run() { - - if (Progress.app_started && tr.button != null) - tr.button.setText(String.format("Download in progress %d%%", tr.percent)); - - try { - - 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()); - - if (app_started && fragment_on) - showProgressFragment(tr); - - } catch (ConcurrentModificationException e) { - e.printStackTrace(); - } - } - }); - } - - public static void PostProgress(Transfer tr) { - ProgressUpdate(tr); - Transfer.activity.runOnUiThread(new Runnable() { - @Override - public void run() { - - notifiManager.cancel(Transfer.NOTIF_SERVICE); - - 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()); - } - - 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); - - 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(); - - } - }); - } - - public static void showProgressFragment(Transfer tr){ - - LinearLayout groot = root.findViewById(R.id.groot); - - final View progress; - - if (groot.findViewById(tr.id) != null) { - progress = groot.findViewById(tr.id); - } else { - progress = inflater.inflate(R.layout.progress, null); - progress.setId(tr.id); - Transfer.activity.runOnUiThread(() -> { - groot.addView(progress, 0); - }); - } - - ((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/ServerFile.java b/app/src/main/java/com/localtransfer/ServerFile.java new file mode 100644 index 0000000..61dd828 --- /dev/null +++ b/app/src/main/java/com/localtransfer/ServerFile.java @@ -0,0 +1,395 @@ +package com.localtransfer; + +import android.animation.ObjectAnimator; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.provider.MediaStore; +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.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.ConcurrentModificationException; +import java.util.List; + +public class ServerFile extends Transfer { + + private Integer id; + + public String name; + + public String href; + + public String mime; + + public String type; + + public long size; + + public String save_location; + + public Uri uri; + + public Button button; + + private static List instances = new ArrayList<>(); + + public ServerFile(Integer id) { + this.id = id; + instances.add(this); + drawable = R.drawable.ic_download_24; + info = "Download complete"; + state = STATE_NOT_REQUESTED; + } + + @Override + public void StartTransfer() { + super.StartTransfer(); + + if (uri == null && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { + ContentValues values = new ContentValues(); + values.put(MediaStore.MediaColumns.DISPLAY_NAME, name); + values.put(MediaStore.MediaColumns.MIME_TYPE, mime); + values.put(MediaStore.MediaColumns.RELATIVE_PATH, Transfer.local_storage); + uri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values); + } + try { + downloadFile(); + } catch (IOException e) { + final String ExceptionName = e.getClass().getSimpleName(); + final String ExceptionMess = e.getMessage(); + + state = Transfer.STATE_FAILED; + error = ExceptionName + ": " + ExceptionMess; + PostProgress(); + + if(ExceptionName != null && ExceptionMess != null) { + errorSnackbar(ExceptionMess); + } + + } + + try { + for (Object obj : getInstances()) { + Transfer transfer = (Transfer) obj; + if (transfer.state == Transfer.STATE_STANDBY) + StartTransfer(); + } + } catch (ConcurrentModificationException e) { + e.printStackTrace(); + try { + Thread.sleep(10); + } catch (InterruptedException InterrupEx) { + InterrupEx.printStackTrace(); + } + for (Object obj : getInstances()) { + Transfer transfer = (Transfer) obj; + if (transfer.state == Transfer.STATE_STANDBY) + StartTransfer(); + } + } + + /*Intent serviceIntent = new Intent(Transfer.activity, TransferService.class); + Transfer.activity.stopService(serviceIntent); + Transfer.runningTransfer = false;*/ + } + + public static List getInstances() { + return instances; + } + + public static ServerFile getFileById(int id) { + for (Object obj: instances) { + ServerFile p = (ServerFile) obj; + if (p.id == id) return p; + } + return null; + } + + public Integer getId() { + return id; + } + + public boolean exist(Context context) { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { + Cursor cursor = context.getContentResolver().query(MediaStore.Downloads.EXTERNAL_CONTENT_URI, null, null, null, null); + while (cursor.moveToNext()) { + String MediaStore_File_name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Downloads.DISPLAY_NAME)); + long MediaStore_File_size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Downloads.SIZE)); + if(MediaStore_File_name.equals(name) && MediaStore_File_size == size) { + int cursor_id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Downloads._ID)); + uri = ContentUris.withAppendedId(MediaStore.Downloads.EXTERNAL_CONTENT_URI, cursor_id); + return true; + } + } + } + else { + File file = new File(save_location, name); + new File(save_location).mkdirs(); + uri = Uri.fromFile(file); + if (file.exists() && file.length() == size) + return true; + } + return false; + } + + public boolean setButton(Button button) { + if (this.state == STATE_RUNNING) { + this.button = button; + return true; + } + return false; + } + + public InputStream getThumbnail() { + InputStream thumbnail = null; + URL url; + try { + String query = URLEncoder.encode(href, StandardCharsets.UTF_8.toString()); + String serverUrl = root + "/thumbnail.php?file=" + query; + url = new URL(protocol, host, port, serverUrl); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(2000); + + conn.connect(); + + thumbnail = conn.getInputStream(); + } catch (IOException e) { + e.printStackTrace(); + } + return thumbnail; + } + + 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; + + PreProgress(); + + 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) { + + OutputStream fileOutput = activity.getContentResolver().openOutputStream(uri); + InputStream in = conn.getInputStream(); + + while ((bufferLength = in.read(buffer)) > 0) { + fileOutput.write(buffer, 0, bufferLength); + loaded+= bufferLength; + percent = ((loaded * 100) / size); + ProgressUpdateDelay(); + } + fileOutput.close(); + + conn.disconnect(); + + message = "File " + name + " successful download"; + state = Transfer.STATE_SUCCESS; + PostProgress(); + + } + else { + String s = conn.getResponseMessage(); + throw new HttpErrorException("error code: " + responseCode + " " + s); + } + + conn.disconnect(); + } + + public String deleteFile() throws IOException { + + URL url = null; + HttpURLConnection conn = null; + + String message; + + String query = URLEncoder.encode(name, 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 " + name + " successful deleted"; + } + else { + String s = conn.getResponseMessage(); + throw new HttpErrorException("error code: " + responseCode + " " + s); + } + + conn.disconnect(); + + return message; + } + + public void PreProgress() { + activity.runOnUiThread(() -> { + + final Drawable image = Transfer.activity.getDrawable(R.drawable.ic_spinner_rotate); + sizeSI = Transfer.humanReadableByteCountBin(size); + + state = STATE_RUNNING; + + if(button != null) { + int h = image.getIntrinsicHeight(); + int w = image.getIntrinsicWidth(); + image.setBounds(0, 0, w, h); + 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(); + } + }); + } + + 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(() -> { + + if (app_started && button != null) + button.setText(String.format("Download in progress %d%%", percent)); + + 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 PostProgress() { + 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()); + } + + if (button != null) { + final LinearLayout layout = (LinearLayout) button.getParent(); + layout.findViewById(R.id.file_view).setVisibility(LinearLayout.VISIBLE); + layout.findViewById(R.id.file_share).setVisibility(LinearLayout.VISIBLE); + button.setVisibility(LinearLayout.GONE); + button.setEnabled(true); + + button.setText(activity.getString(R.string.file_download)); + button.setCompoundDrawables(button.getCompoundDrawables()[0], null, null, null); + } + + 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(){ + + if(Arrays.asList(STATE_RUNNING, STATE_SUCCESS, STATE_FAILED).contains(state)) { + + 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); + + } + } +} diff --git a/app/src/main/java/com/localtransfer/Transfer.java b/app/src/main/java/com/localtransfer/Transfer.java index 2c5d544..f874331 100644 --- a/app/src/main/java/com/localtransfer/Transfer.java +++ b/app/src/main/java/com/localtransfer/Transfer.java @@ -1,19 +1,21 @@ 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.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.net.Uri; import android.provider.OpenableColumns; import android.util.Log; +import android.view.LayoutInflater; import android.view.View; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.TextView; -import androidx.core.content.ContextCompat; +import androidx.core.app.NotificationManagerCompat; import androidx.core.content.FileProvider; import androidx.preference.PreferenceManager; @@ -29,22 +31,27 @@ import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.ProtocolException; import java.net.URL; -import java.net.URLEncoder; 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; -import java.util.Timer; -import java.util.TimerTask; - -import static java.lang.Integer.valueOf; 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; @@ -53,398 +60,63 @@ 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 String error; - public long fileSize; - public String fileSizeHuman; + public String sizeSI; public long loaded; - public String loadedHuman = "0"; + public String loadedSI = "0"; public long percent; - public Transfer(int type) { + public static final int NOTIF_SERVICE = 1000; - id = View.generateViewId(); + 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; - 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 boolean runningTransfer = false; public static void parameter(Context context) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); host = prefs.getString("host", null); - port = valueOf(prefs.getString("port", null)); root = prefs.getString("root", null); local_storage = prefs.getString("local_storage", null); 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 Uri uri; + public void AddTransfer() { - 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(); + if(!runningTransfer) { + /*Intent serviceIntent = new Intent(activity, TransferService.class); + ContextCompat.startForegroundService(activity, serviceIntent);*/ + runningTransfer = true; + state = STATE_STANDBY; + new Thread(() -> StartTransfer()).start(); } } - 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; + public void StartTransfer() { + int x = 35 + 65; } private static URL checkRedirection(URL url) throws IOException { @@ -488,18 +160,190 @@ public class Transfer { return url; } - public static void error(final String message) { + public static void handleSendFile(Uri uri) { + if (uri != null) { + new Thread(() -> { + try { + Transfer.uploadFile(uri); + } catch (IOException e) { + final String ExceptionName = e.getClass().getSimpleName(); + final String ExceptionMess = e.getMessage(); + + if(ExceptionName != null && ExceptionMess != null) { + Transfer.errorSnackbar(ExceptionMess); + } + + } + }).start(); + } + } + + public static void handleSendText(String sharedText) { + if (sharedText != null) { + SimpleDateFormat sdfDate = new SimpleDateFormat("text_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); + + Transfer.uploadFile(uri); + } catch (IOException e) { + e.printStackTrace(); + } + }).start(); + } + } + + public static String uploadFile(Uri uri) throws IOException { + String message = null; + URL url = null; + HttpURLConnection conn = null; + DataOutputStream request = null; + String boundary = "*****"; + final 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 type = activity.getContentResolver().getType(uri); + + String fileName = null; + int col_name = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); + if (col_name != -1) + fileName = cursor.getString(col_name); + if(fileName == null) + fileName = type.split("/")[0] + "_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + "." + type.split("/")[1]; + String fileNameUTF8 = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1); + + long fileSize = -1; + int col_size = cursor.getColumnIndex(OpenableColumns.SIZE); + if (col_size != -1) + fileSize = cursor.getLong(col_size); + + url = new URL(protocol, host, port, root + "/upload.php"); + + url = checkRedirection(url); + + 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); + + if (fileSize < 1) + fileSize = in.available(); + + //Progress p = new Progress(fileName, fileSize, Progress.UPLOAD); + + 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 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(new Runnable() { - @Override - public void run() { - Snackbar.make(activity.findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG) - .setAction("Action", null).show(); - } - }); + activity.runOnUiThread(() -> Snackbar.make(activity.findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG) + .setAction("Action", null).show()); } } diff --git a/app/src/main/java/com/localtransfer/fragment/DownloadFragment.java b/app/src/main/java/com/localtransfer/fragment/DownloadFragment.java index 9f33455..95a7af5 100644 --- a/app/src/main/java/com/localtransfer/fragment/DownloadFragment.java +++ b/app/src/main/java/com/localtransfer/fragment/DownloadFragment.java @@ -3,14 +3,10 @@ package com.localtransfer.fragment; import android.animation.ObjectAnimator; import android.content.ActivityNotFoundException; import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; -import android.net.Uri; import android.os.Bundle; - -import androidx.core.content.FileProvider; -import androidx.fragment.app.Fragment; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - import android.os.Environment; import android.view.ContextMenu; import android.view.Gravity; @@ -25,9 +21,12 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.fragment.app.Fragment; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + import com.google.android.material.snackbar.Snackbar; -import com.localtransfer.BuildConfig; import com.localtransfer.R; +import com.localtransfer.ServerFile; import com.localtransfer.Transfer; import org.json.JSONArray; @@ -35,8 +34,6 @@ import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -52,6 +49,7 @@ public class DownloadFragment extends Fragment { } private View root; + private LayoutInflater inflater; public static DownloadFragment newInstance() { DownloadFragment fragment = new DownloadFragment(); @@ -68,17 +66,20 @@ public class DownloadFragment extends Fragment { Bundle savedInstanceState) { root = inflater.inflate(R.layout.fragment_download, container, false); + this.inflater = inflater; + new Timer().schedule(new TimerTask() { @Override public void run() { - showFileList(); + listFile(); } }, 100); SwipeRefreshLayout refresh = root.findViewById(R.id.refresh); + refresh.setOnRefreshListener(() -> { - new Thread(() -> showFileList()).start(); + listFile(); refresh.setRefreshing(false); }); @@ -107,21 +108,21 @@ public class DownloadFragment extends Fragment { public boolean onContextItemSelected(MenuItem item) { if (item.getTitle() == "Delete") { LinearLayout fileDesc = (LinearLayout) root.findViewById(item.getItemId()); - final String file = String.valueOf(fileDesc.getTag(R.id.ID_FILE_NAME)); + ServerFile file = ServerFile.getFileById((Integer) fileDesc.getTag(R.id.ID_DOWNLOAD)); new Thread(() -> { try { - String message = Transfer.deleteFile(file); + String message = file.deleteFile(); System.out.println(message); - Transfer.activity.runOnUiThread(() -> + getActivity().runOnUiThread(() -> Snackbar.make(getActivity().findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG) .setAction("Action", null).show()); - showFileList(); + listFile(); } catch (IOException e) { String ExceptionName = e.getClass().getSimpleName(); String ExceptionMess = e.getMessage(); if(ExceptionName != null && ExceptionMess != null) { - Transfer.error(ExceptionMess); + Transfer.errorSnackbar(ExceptionMess); } } @@ -133,166 +134,166 @@ public class DownloadFragment extends Fragment { return true; } - public void showFileList() { + public void listFile() { + new Thread(() -> { + final TextView title = new TextView(Transfer.activity); + final LinearLayout main_layout = root.findViewById(R.id.main_layout); + try { + String data = Transfer.getFileList(); - final TextView title = new TextView(Transfer.activity); - title.setTextSize(18); - title.setGravity(Gravity.CENTER); - final LinearLayout main_layout = root.findViewById(R.id.main_layout); - final LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(getContext().LAYOUT_INFLATER_SERVICE); + if (data.equals("[]")) { + title.setTextSize(18); + title.setGravity(Gravity.CENTER); + main_layout.removeAllViews(); + main_layout.addView(title); + title.setHeight(1000); + title.setText("No file to download"); + } + else { - String data = ""; - - try { - data = Transfer.getFileList(); - } catch (IOException e) { - final String ExceptionName = e.getClass().getSimpleName(); - final String ExceptionMess = e.getMessage(); - - if(ExceptionName != null && ExceptionMess != null) { - Transfer.error(ExceptionMess); - Transfer.activity.runOnUiThread(() -> { - if(main_layout != null) + getActivity().runOnUiThread(() -> { main_layout.removeAllViews(); - if(title != null) { - main_layout.addView(title); - title.setText(ExceptionMess); - } - }); - } - - } - if (data.equals("[]")) { - Transfer.activity.runOnUiThread(() -> { - main_layout.removeAllViews(); - main_layout.addView(title); - title.setHeight(1000); - title.setText("No file to download"); - }); - return; - } - - try { - - JSONArray array; - array = new JSONArray(data); - - Transfer.activity.runOnUiThread(() -> { - main_layout.removeAllViews(); - final View line = inflater.inflate(R.layout.horizontal_line, null); - main_layout.addView(line); - }); - for (int i = 0; i < array.length(); i++) { - JSONObject row = array.getJSONObject(i); - final String name = row.getString("name"); - final String href = row.getString("href"); - final long size = row.getLong("size"); - final String mime = row.getString("mime"); - final String type = row.getString("type"); - - Transfer.activity.runOnUiThread(() -> { - title.setText("Choose file to download"); - View file_info = inflater.inflate(R.layout.file_info, null); - main_layout.addView(file_info); - ImageView image = file_info.findViewById(R.id.file_image); - TextView viewName = file_info.findViewById(R.id.file_name); - TextView viewType = file_info.findViewById(R.id.file_type); - TextView viewSize = file_info.findViewById(R.id.file_size); - LinearLayout fileDesc = file_info.findViewById(R.id.file_desc); - LinearLayout file_buttons = file_info.findViewById(R.id.file_buttons); - - fileDesc.setId(View.generateViewId()); - file_buttons.setId(View.generateViewId()); - file_buttons.setTag(R.id.ID_FILE_BUTTONS, "FOR VISIBILITY"); - - registerForContextMenu(fileDesc); - fileDesc.setTag(R.id.ID_FILE_NAME, name); - - viewName.setText(name); - viewType.setText(mime); - viewSize.setText(Transfer.humanReadableByteCountBin(size)); - - switch (type) { - case "file-image": - image.setImageResource(R.drawable.ic_icon_image); - break; - case "file-audio": - image.setImageResource(R.drawable.ic_icon_music); - break; - case "file-video": - image.setImageResource(R.drawable.ic_icon_video); - break; - default: - image.setImageResource(R.drawable.ic_icon_file); - } - - fileDesc.setOnClickListener(view -> { - String save_location; - - if (mime.equals("text/plain")) - save_location = getContext().getCacheDir().toString(); - else - save_location = Environment.getExternalStorageDirectory() + "/" + Transfer.local_storage; - - File file = new File(save_location, name); - - file_buttons.setId(View.generateViewId()); - - Button Bview = file_buttons.findViewById(R.id.file_view); - Button Bshare = file_buttons.findViewById(R.id.file_share); - Button dl = file_buttons.findViewById(R.id.file_download); - - dl.setOnClickListener(ListenerDL); - Bview.setOnClickListener(ListenerView); - Bshare.setOnClickListener(ListenerShare); - - if (file.exists() && file.length() == size) { - Bview.setVisibility(LinearLayout.VISIBLE); - Bshare.setVisibility(LinearLayout.VISIBLE); - dl.setVisibility(LinearLayout.GONE); - } - else { - dl.setVisibility(LinearLayout.VISIBLE); - Bview.setVisibility(LinearLayout.GONE); - Bshare.setVisibility(LinearLayout.GONE); - } - - if (Transfer.setButton(name, dl)) { - dl.setEnabled(false); - final Drawable spinner = Transfer.activity.getDrawable(R.drawable.ic_spinner_rotate); - int h = spinner.getIntrinsicHeight(); - int w = spinner.getIntrinsicWidth(); - spinner.setBounds(0, 0, w, h); - dl.setCompoundDrawables(dl.getCompoundDrawables()[0], null, spinner, null); - ObjectAnimator anim = ObjectAnimator.ofInt(spinner, "level", 0, 10000); - anim.setDuration(1000); - anim.setRepeatCount(Animation.INFINITE); - anim.setInterpolator(new LinearInterpolator()); - anim.start(); - } - - file_buttons.setTag(R.id.ID_FILE_NAME, name); - file_buttons.setTag(R.id.ID_FILE_SIZE, size); - file_buttons.setTag(R.id.ID_FILE_HREF, href); - file_buttons.setTag(R.id.ID_FILE_MIME, mime); - file_buttons.setTag(R.id.ID_SAVE_LOCATION, save_location); - int state = file_buttons.getVisibility(); - if(state == LinearLayout.GONE) { - for(View child : getAllChildren(main_layout)) { - if(child.getTag(R.id.ID_FILE_BUTTONS) != null) - child.setVisibility(LinearLayout.GONE); - } - file_buttons.setVisibility(LinearLayout.VISIBLE); - } - else if(state == LinearLayout.VISIBLE) - file_buttons.setVisibility(LinearLayout.GONE); + final View line = inflater.inflate(R.layout.horizontal_line, null); + main_layout.addView(line); }); - }); + try { + JSONArray array = new JSONArray(data); + for (int i = 0; i < array.length(); i++) { + Integer id = View.generateViewId(); + ServerFile trFile = new ServerFile(id); + + JSONObject row = array.getJSONObject(i); + trFile.name = row.getString("name"); + trFile.size = row.getLong("size"); + trFile.href = row.getString("href"); + trFile.mime = row.getString("mime"); + trFile.type = row.getString("type"); + + getActivity().runOnUiThread(() -> showFileList(trFile)); + + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + } catch (IOException e) { + final String ExceptionName = e.getClass().getSimpleName(); + final String ExceptionMess = e.getMessage(); + + if(ExceptionName != null && ExceptionMess != null) { + Transfer.errorSnackbar(ExceptionMess); + } + } - } catch (JSONException e) { - e.printStackTrace(); + }).start(); + } + + private void setThumbnail(ServerFile file, ImageView image) { + new Thread(() -> { + InputStream thumbnail = file.getThumbnail(); + Bitmap bitmap = BitmapFactory.decodeStream(thumbnail); + getActivity().runOnUiThread(() -> { + image.setImageBitmap(bitmap); + }); + }).start(); + } + + private void showFileList(ServerFile trFile) { + + final LinearLayout main_layout = root.findViewById(R.id.main_layout); + + View file_info = inflater.inflate(R.layout.file_info, null); + main_layout.addView(file_info); + ImageView image = file_info.findViewById(R.id.file_image); + TextView viewName = file_info.findViewById(R.id.file_name); + TextView viewType = file_info.findViewById(R.id.file_type); + TextView viewSize = file_info.findViewById(R.id.file_size); + LinearLayout fileDesc = file_info.findViewById(R.id.file_desc); + LinearLayout file_buttons = file_info.findViewById(R.id.file_buttons); + + fileDesc.setId(View.generateViewId()); + + registerForContextMenu(fileDesc); + + file_buttons.setId(trFile.getId()); + file_buttons.setTag(R.id.ID_DOWNLOAD, trFile.getId()); + fileDesc.setTag(R.id.ID_DOWNLOAD, trFile.getId()); + file_buttons.setTag(R.id.ID_FILE_BUTTONS, "FOR VISIBILITY"); + + trFile.button = file_buttons.findViewById(R.id.file_download); + + if (trFile.mime.equals("text/plain")) + trFile.save_location = getContext().getCacheDir().toString(); + else + trFile.save_location = Environment.getExternalStorageDirectory() + "/" + Transfer.local_storage; + + viewName.setText(trFile.name); + viewType.setText(trFile.mime); + viewSize.setText(Transfer.humanReadableByteCountBin(trFile.size)); + + switch (trFile.type) { + case "file-image": + image.setImageResource(R.drawable.ic_icon_image); + setThumbnail(trFile, image); + break; + case "file-video": + image.setImageResource(R.drawable.ic_icon_video); + setThumbnail(trFile, image); + break; + case "file-audio": + image.setImageResource(R.drawable.ic_icon_music); + break; + default: + image.setImageResource(R.drawable.ic_icon_file); } + + fileDesc.setOnClickListener(view -> { + + Button Bview = file_buttons.findViewById(R.id.file_view); + Button Bshare = file_buttons.findViewById(R.id.file_share); + Button Bdownload = file_buttons.findViewById(R.id.file_download); + + Bdownload.setOnClickListener(ListenerDL); + Bview.setOnClickListener(ListenerView); + Bshare.setOnClickListener(ListenerShare); + + if (trFile.exist(getContext())) { + Bview.setVisibility(LinearLayout.VISIBLE); + Bshare.setVisibility(LinearLayout.VISIBLE); + Bdownload.setVisibility(LinearLayout.GONE); + } + else { + Bdownload.setVisibility(LinearLayout.VISIBLE); + Bview.setVisibility(LinearLayout.GONE); + Bshare.setVisibility(LinearLayout.GONE); + } + + if (trFile.setButton(Bdownload)) { + Bdownload.setEnabled(false); + final Drawable spinner = Transfer.activity.getDrawable(R.drawable.ic_spinner_rotate); + int h = spinner.getIntrinsicHeight(); + int w = spinner.getIntrinsicWidth(); + spinner.setBounds(0, 0, w, h); + Bdownload.setCompoundDrawables(Bdownload.getCompoundDrawables()[0], null, spinner, null); + ObjectAnimator anim = ObjectAnimator.ofInt(spinner, "level", 0, 10000); + anim.setDuration(1000); + anim.setRepeatCount(Animation.INFINITE); + anim.setInterpolator(new LinearInterpolator()); + anim.start(); + } + + int state = file_buttons.getVisibility(); + if(state == LinearLayout.GONE) { + for(View child : getAllChildren(main_layout)) { + if(child.getTag(R.id.ID_FILE_BUTTONS) != null) + child.setVisibility(LinearLayout.GONE); + } + file_buttons.setVisibility(LinearLayout.VISIBLE); + } + else if(state == LinearLayout.VISIBLE) + file_buttons.setVisibility(LinearLayout.GONE); + }); } private View.OnClickListener ListenerDL = v -> { @@ -300,37 +301,33 @@ public class DownloadFragment extends Fragment { final LinearLayout layout = (LinearLayout) v.getParent(); final Button button = layout.findViewById(R.id.file_download); - final String name = (String) layout.getTag(R.id.ID_FILE_NAME); - final String save_location = String.valueOf(layout.getTag(R.id.ID_SAVE_LOCATION)); - final long fileSize = (long) layout.getTag(R.id.ID_FILE_SIZE); - final String href = (String) layout.getTag(R.id.ID_FILE_HREF); + final Integer id = (Integer) layout.getTag(R.id.ID_DOWNLOAD); - new File(save_location).mkdirs(); - File file = new File(save_location, name); + final Drawable image = getActivity().getDrawable(R.drawable.ic_spinner_rotate); + int h = image.getIntrinsicHeight(); + int w = image.getIntrinsicWidth(); + image.setBounds(0, 0, w, h); + 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(); - 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(); + ServerFile file = ServerFile.getFileById(id); + file.AddTransfer(); }; private View.OnClickListener ListenerShare = v -> { LinearLayout layout = (LinearLayout) v.getParent(); - final String name = (String) layout.getTag(R.id.ID_FILE_NAME); - final String type = (String) layout.getTag(R.id.ID_FILE_MIME); + final Integer id = (Integer) layout.getTag(R.id.ID_DOWNLOAD); - final String save_location = String.valueOf(layout.getTag(R.id.ID_SAVE_LOCATION)); - File file = new File(save_location, name); - Uri uri = FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID, file); + ServerFile dl = ServerFile.getFileById(id); - if(type.equals("text/plain")) { + if(dl.type.equals("text/plain")) { String text = null; try { - InputStream is = new FileInputStream(file); + InputStream is = getActivity().getContentResolver().openInputStream(dl.uri); BufferedReader buf = new BufferedReader(new InputStreamReader(is)); String line; @@ -348,7 +345,7 @@ public class DownloadFragment extends Fragment { try { Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType(type); + intent.setType(dl.type); intent.putExtra(Intent.EXTRA_TEXT, text); startActivity(Intent.createChooser(intent, getString(R.string.share_title))); } catch (ActivityNotFoundException e) { @@ -358,8 +355,8 @@ public class DownloadFragment extends Fragment { else { try { Intent intent = new Intent(Intent.ACTION_SEND); - intent.putExtra(Intent.EXTRA_STREAM, uri); - intent.setType(type); + intent.putExtra(Intent.EXTRA_STREAM, dl.uri); + intent.setType(dl.mime); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(Intent.createChooser(intent, getString(R.string.share_title))); } catch (ActivityNotFoundException e) { @@ -372,16 +369,13 @@ public class DownloadFragment extends Fragment { private View.OnClickListener ListenerView = v -> { LinearLayout layout = (LinearLayout) v.getParent(); - final String name = (String) layout.getTag(R.id.ID_FILE_NAME); - final String type = (String) layout.getTag(R.id.ID_FILE_MIME); + final Integer id = (Integer) layout.getTag(R.id.ID_DOWNLOAD); - final String save_location = String.valueOf(layout.getTag(R.id.ID_SAVE_LOCATION)); - File file = new File(save_location, name); - Uri uri = FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID, file); + ServerFile dl = ServerFile.getFileById(id); try { Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setDataAndType(uri, type); + intent.setDataAndType(dl.uri, dl.mime); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(intent); } catch (ActivityNotFoundException e) { diff --git a/app/src/main/java/com/localtransfer/fragment/ProgressFragment.java b/app/src/main/java/com/localtransfer/fragment/ProgressFragment.java index 9c70e09..c5b0214 100644 --- a/app/src/main/java/com/localtransfer/fragment/ProgressFragment.java +++ b/app/src/main/java/com/localtransfer/fragment/ProgressFragment.java @@ -2,26 +2,17 @@ package com.localtransfer.fragment; import android.os.Bundle; -import androidx.core.app.NotificationCompat; -import androidx.core.app.NotificationManagerCompat; import androidx.fragment.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.TextView; -import com.localtransfer.Progress; import com.localtransfer.R; +import com.localtransfer.ServerFile; import com.localtransfer.Transfer; -import java.util.ConcurrentModificationException; import java.util.List; -import java.util.Timer; -import java.util.TimerTask; public class ProgressFragment extends Fragment { @@ -43,21 +34,20 @@ public class ProgressFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment - Progress.root = inflater.inflate(R.layout.fragment_progress, container, false); + Transfer.fragment_progress = inflater.inflate(R.layout.fragment_progress, container, false); - return Progress.root; + return Transfer.fragment_progress; } @Override public void onResume(){ super.onResume(); - Progress.fragment_on = true; + Transfer.fragment_on = true; - List instances = Transfer.getInstances(); - for (Object obj: instances) { - Transfer tr = (Transfer) obj; - Progress.showProgressFragment(tr); + List instances = ServerFile.getInstances(); + for (ServerFile file: instances) { + file.showProgressFragment(); } } @@ -65,6 +55,6 @@ public class ProgressFragment extends Fragment { public void onPause(){ super.onPause(); - Progress.fragment_on = false; + Transfer.fragment_on = false; } } \ No newline at end of file diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml index 4be3d1e..feaf92e 100644 --- a/app/src/main/res/values/ids.xml +++ b/app/src/main/res/values/ids.xml @@ -1,9 +1,5 @@ - - - - - + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6c2f8dc..e7fe80f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -25,7 +25,7 @@ Use secure https www.netdldata.net Port - 80 + Root /transfer diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..583fb1d --- /dev/null +++ b/app/src/main/res/xml/network_security_config.xml @@ -0,0 +1,6 @@ + + + + netdldata.net + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 5e3e27e..781e205 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:4.1.2' + classpath 'com.android.tools.build:gradle:7.1.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b1f9077..3cf3705 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip