Upload fix, Progress fix

- transfer one by one
This commit is contained in:
lionel 2022-02-24 16:05:05 +01:00
parent f6b652fb7e
commit d87296a534
7 changed files with 411 additions and 381 deletions

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

View File

@ -5,20 +5,14 @@ import android.content.ContentUris;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.Color;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.util.Log; import android.util.Log;
import android.view.View;
import android.view.animation.Animation; import android.view.animation.Animation;
import android.view.animation.LinearInterpolator; import android.view.animation.LinearInterpolator;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -28,16 +22,9 @@ import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.sql.Timestamp;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.List;
public class ServerFile extends Transfer { public class DownloadFile extends Transfer {
private Integer id;
public String name;
public String href; public String href;
@ -45,27 +32,29 @@ public class ServerFile extends Transfer {
public String type; public String type;
public long size;
public String save_location; public String save_location;
public Uri uri; public Uri uri;
public Button button; private Button button;
private static List<ServerFile> instances = new ArrayList<>(); public DownloadFile(Integer id) {
public ServerFile(Integer id) {
this.id = id; this.id = id;
instances.add(this); instances.add(this);
drawable = R.drawable.ic_download_24;
info = "Download complete"; info = "Download complete";
state = STATE_NOT_REQUESTED; state = STATE_NOT_REQUESTED;
drawable = R.drawable.ic_download_24;
} }
@Override @Override
public void StartTransfer() { public void startTransfer() {
super.StartTransfer(); super.startTransfer();
startedTime = new Timestamp(System.currentTimeMillis());
state = STATE_RUNNING;
buttonProgressStart();
if (uri == null && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { if (uri == null && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
@ -76,59 +65,21 @@ public class ServerFile extends Transfer {
} }
try { try {
downloadFile(); downloadFile();
} catch (IOException e) { } catch (IOException | NullPointerException e) {
final String ExceptionName = e.getClass().getSimpleName(); final String ExceptionName = e.getClass().getSimpleName();
final String ExceptionMess = e.getMessage(); final String ExceptionMess = e.getMessage();
e.printStackTrace();
state = Transfer.STATE_FAILED; state = Transfer.STATE_FAILED;
error = ExceptionName + ": " + ExceptionMess; error = ExceptionName + ": " + ExceptionMess;
PostProgress(); progressEnd();
buttonProgressEnd();
if(ExceptionName != null && ExceptionMess != null) { if(ExceptionName != null && ExceptionMess != null) {
errorSnackbar(ExceptionMess); errorSnackbar(ExceptionName + ": " + 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) { public boolean exist(Context context) {
@ -154,12 +105,11 @@ public class ServerFile extends Transfer {
return false; return false;
} }
public boolean setButton(Button button) { public void setButton(Button button) {
if (this.state == STATE_RUNNING) { this.button = button;
this.button = button; if (this.state == STATE_STANDBY) {
return true; buttonProgressStart();
} }
return false;
} }
public InputStream getThumbnail() { public InputStream getThumbnail() {
@ -191,8 +141,6 @@ public class ServerFile extends Transfer {
int bufferLength; int bufferLength;
loaded = 0; loaded = 0;
PreProgress();
String[] parts = href.split("/"); String[] parts = href.split("/");
String path = ""; String path = "";
for(int i=0; i< parts.length - 1; i++) { for(int i=0; i< parts.length - 1; i++) {
@ -220,7 +168,8 @@ public class ServerFile extends Transfer {
fileOutput.write(buffer, 0, bufferLength); fileOutput.write(buffer, 0, bufferLength);
loaded+= bufferLength; loaded+= bufferLength;
percent = ((loaded * 100) / size); percent = ((loaded * 100) / size);
ProgressUpdateDelay(); progressUpdateDelay();
buttonProgressUpdate();
} }
fileOutput.close(); fileOutput.close();
@ -228,7 +177,8 @@ public class ServerFile extends Transfer {
message = "File " + name + " successful download"; message = "File " + name + " successful download";
state = Transfer.STATE_SUCCESS; state = Transfer.STATE_SUCCESS;
PostProgress(); progressEnd();
buttonProgressEnd();
} }
else { else {
@ -271,13 +221,9 @@ public class ServerFile extends Transfer {
return message; return message;
} }
public void PreProgress() { public void buttonProgressStart() {
activity.runOnUiThread(() -> { activity.runOnUiThread(() -> {
final Drawable image = Transfer.activity.getDrawable(R.drawable.ic_spinner_rotate); final Drawable image = Transfer.activity.getDrawable(R.drawable.ic_spinner_rotate);
sizeSI = Transfer.humanReadableByteCountBin(size);
state = STATE_RUNNING;
if(button != null) { if(button != null) {
int h = image.getIntrinsicHeight(); int h = image.getIntrinsicHeight();
@ -293,56 +239,15 @@ public class ServerFile extends Transfer {
}); });
} }
public void ProgressUpdateDelay() { private void buttonProgressUpdate(){
// 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(() -> { activity.runOnUiThread(() -> {
if (app_started && button != null) if (app_started && button != null)
button.setText(String.format("Download in progress %d%%", percent)); 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() { public void buttonProgressEnd() {
ProgressUpdate();
activity.runOnUiThread(() -> { 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) { if (button != null) {
final LinearLayout layout = (LinearLayout) button.getParent(); final LinearLayout layout = (LinearLayout) button.getParent();
layout.findViewById(R.id.file_view).setVisibility(LinearLayout.VISIBLE); layout.findViewById(R.id.file_view).setVisibility(LinearLayout.VISIBLE);
@ -353,43 +258,6 @@ public class ServerFile extends Transfer {
button.setText(activity.getString(R.string.file_download)); button.setText(activity.getString(R.string.file_download));
button.setCompoundDrawables(button.getCompoundDrawables()[0], null, null, null); 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);
}
}
} }

View File

@ -91,16 +91,14 @@ public class MainActivity extends AppCompatActivity {
String action = intent.getAction(); String action = intent.getAction();
String type = intent.getType(); String type = intent.getType();
Transfer tr = new Transfer();
if (Intent.ACTION_SEND.equals(action) && type != null) { if (Intent.ACTION_SEND.equals(action) && type != null) {
viewPager.setCurrentItem(2); viewPager.setCurrentItem(2);
if ("text/plain".equals(type)) { if ("text/plain".equals(type)) {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
tr.handleSendText(sharedText); UploadFile.handleSendText(sharedText);
} else { } else {
Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM); Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
tr.handleSendFile(uri); UploadFile.handleSendFile(uri);
} }
} else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) { } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
viewPager.setCurrentItem(2); viewPager.setCurrentItem(2);
@ -108,7 +106,7 @@ public class MainActivity extends AppCompatActivity {
int nbItem = fileUris.size(); int nbItem = fileUris.size();
Toast.makeText(this, "You select " + nbItem + " files", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "You select " + nbItem + " files", Toast.LENGTH_SHORT).show();
if (fileUris != null) if (fileUris != null)
for(Uri uri : fileUris) tr.handleSendFile(uri); for(Uri uri : fileUris) UploadFile.handleSendFile(uri);
} }
} }
@ -123,11 +121,10 @@ public class MainActivity extends AppCompatActivity {
ViewPager viewPager = this.findViewById(R.id.view_pager); ViewPager viewPager = this.findViewById(R.id.view_pager);
viewPager.setCurrentItem(2); viewPager.setCurrentItem(2);
Transfer tr = new Transfer();
if (type != null) { if (type != null) {
String sharedText = data.getStringExtra(Intent.EXTRA_TEXT); String sharedText = data.getStringExtra(Intent.EXTRA_TEXT);
tr.handleSendText(sharedText); UploadFile.handleSendText(sharedText);
} }
else { else {
ArrayList<Uri> fileUris = new ArrayList<>(); ArrayList<Uri> fileUris = new ArrayList<>();
@ -143,7 +140,7 @@ public class MainActivity extends AppCompatActivity {
fileUris.add(uri); fileUris.add(uri);
} }
for (Uri uri : fileUris) { for (Uri uri : fileUris) {
tr.handleSendFile(uri); UploadFile.handleSendFile(uri);
} }
} }
} }

View File

@ -8,34 +8,34 @@ import android.app.PendingIntent;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.database.Cursor; import android.graphics.Color;
import android.net.Uri;
import android.provider.OpenableColumns;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.core.app.NotificationManagerCompat; import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.FileProvider;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.ProtocolException; import java.net.ProtocolException;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets; import java.sql.Timestamp;
import java.text.CharacterIterator; import java.text.CharacterIterator;
import java.text.SimpleDateFormat;
import java.text.StringCharacterIterator; import java.text.StringCharacterIterator;
import java.util.Date; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.ConcurrentModificationException;
import java.util.List;
public class Transfer { public class Transfer {
@ -81,7 +81,46 @@ public class Transfer {
public static final int STATE_SUCCESS = 130; public static final int STATE_SUCCESS = 130;
public static final int STATE_FAILED = 140; public static final int STATE_FAILED = 140;
public static boolean runningTransfer = false; public static Thread thread = new Thread();
Integer id;
public String name;
public long size;
Timestamp addedTime;
Timestamp startedTime;
static List<Transfer> instances = new ArrayList<>();
public static List<Transfer> getInstances() {
List<Transfer> in = new ArrayList<>();
for (Transfer file: instances) {
//if(Arrays.asList(STATE_STANDBY, STATE_RUNNING, STATE_SUCCESS, STATE_FAILED).contains(file.state)) {
if(file.state == STATE_STANDBY ||
file.state == STATE_RUNNING ||
file.state == STATE_SUCCESS ||
file.state == STATE_FAILED) {
in.add(file);
}
}
//in.sort(Comparator.comparing(Transfer::getAddedTime).reversed());
in.sort(Comparator.comparing(e -> e.addedTime));
return in;
}
public static Transfer getFileById(int id) {
for (Object obj: instances) {
Transfer p = (Transfer) obj;
if (p.id == id) return p;
}
return null;
}
public Integer getId() {
return id;
}
public static void parameter(Context context) { public static void parameter(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
@ -106,20 +145,125 @@ public class Transfer {
public void AddTransfer() { public void AddTransfer() {
if(!runningTransfer) { state = STATE_STANDBY;
addedTime = new Timestamp(System.currentTimeMillis());
Thread.State state = thread.getState();
if(state == Thread.State.NEW || state == Thread.State.TERMINATED) {
thread = new Thread(startTransfers);
thread.start();
/*Intent serviceIntent = new Intent(activity, TransferService.class); /*Intent serviceIntent = new Intent(activity, TransferService.class);
ContextCompat.startForegroundService(activity, serviceIntent);*/ ContextCompat.startForegroundService(activity, serviceIntent);*/
runningTransfer = true;
state = STATE_STANDBY;
new Thread(() -> StartTransfer()).start();
} }
} }
public void StartTransfer() { public void startTransfer() {
int x = 35 + 65;
} }
private static URL checkRedirection(URL url) throws IOException { public static Runnable startTransfers = () -> {
try {
for (Transfer transfer : getInstances()) {
if (transfer.state == Transfer.STATE_STANDBY) {
transfer.startTransfer();
thread.run(); // restart thread for another potential standby transfer
break; // ignore remainder instance
}
}
} catch (ConcurrentModificationException e) {
e.printStackTrace();
}
/*Intent serviceIntent = new Intent(Transfer.activity, TransferService.class);
Transfer.activity.stopService(serviceIntent);*/
};
public void progressUpdateDelay() {
// Run only every second to reduce CPU usage
if (System.currentTimeMillis() > (savedTimeMillis + 1000)) {
savedTimeMillis = System.currentTimeMillis();
progressUpdate();
}
}
private void progressUpdate(){
loadedSI = Transfer.humanReadableByteCountBin(loaded);
activity.runOnUiThread(() -> {
try {
notifBuilder.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud)
.setContentTitle(name)
.setContentText(String.format("%d%% %s/%s", percent, loadedSI, sizeSI))
.setProgress(100, (int) percent, false)
.setContentIntent(pendingIntent);
notifiManager.notify(Transfer.NOTIF_SERVICE, notifBuilder.build());
if (app_started && fragment_on)
showProgressFragment();
} catch (ConcurrentModificationException e) {
e.printStackTrace();
}
});
}
public void progressEnd() {
progressUpdate();
activity.runOnUiThread(() -> {
notifiManager.cancel(Transfer.NOTIF_SERVICE);
if (!app_started) {
notifBuilder.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud)
.setContentTitle(name)
.setContentText(info)
.setProgress(0, 0, false)
.setContentIntent(pendingIntent);
notifiManager.notify(id, notifBuilder.build());
}
System.out.println(message);
/*Snackbar.make(Transfer.activity.findViewById(R.id.view_pager), tr.message, Snackbar.LENGTH_LONG)
.setAction("Action", null).show();*/
Toast.makeText(activity, message, Toast.LENGTH_SHORT).show();
});
}
public void showProgressFragment(){
LinearLayout groot = fragment_progress.findViewById(R.id.groot);
View progress = groot.findViewById(id);
if (progress == null) {
progress = inflater.inflate(R.layout.progress, null);
progress.setId(id);
final View final_progress = progress;
activity.runOnUiThread(() -> {
groot.addView(final_progress, 0);
});
}
((ProgressBar) progress.findViewById(R.id.progressBar)).setProgress((int) percent);
((ImageView) progress.findViewById(R.id.transferType)).setImageResource(drawable);
((TextView) progress.findViewById(R.id.progressText)).setText(percent + " %");
((TextView) progress.findViewById(R.id.fileName)).setText(name);
((TextView) progress.findViewById(R.id.fileSize)).setText(String.format("%s/%s", loadedSI, sizeSI));
if (state == Transfer.STATE_SUCCESS)
((TextView) progress.findViewById(R.id.fileName)).setTextColor(Color.GREEN);
else if (state == Transfer.STATE_FAILED)
((TextView) progress.findViewById(R.id.fileName)).setTextColor(Color.RED);
}
static URL checkRedirection(URL url) throws IOException {
String location = null; String location = null;
HttpURLConnection conn = null; HttpURLConnection conn = null;
int responseCode; int responseCode;
@ -160,149 +304,6 @@ public class Transfer {
return url; return url;
} }
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 { public static String getFileList() throws IOException {
URL url = null; URL url = null;
HttpURLConnection conn = null; HttpURLConnection conn = null;

View File

@ -0,0 +1,197 @@
package com.localtransfer;
import android.database.Cursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import android.util.Log;
import android.view.View;
import androidx.core.content.FileProvider;
import com.google.android.material.snackbar.Snackbar;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ConcurrentModificationException;
import java.util.Date;
public class UploadFile extends Transfer {
public Uri uri;
public UploadFile() {
this.id = View.generateViewId();
instances.add(this);
info = "Upload complete";
state = STATE_NOT_REQUESTED;
drawable = R.drawable.ic_upload_24;
}
public static void handleSendFile(Uri uri) {
if (uri != null) {
UploadFile file = new UploadFile();
file.uri = uri;
Cursor cursor = activity.getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
file.name = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
file.size = cursor.getLong(cursor.getColumnIndex(OpenableColumns.SIZE));
file.sizeSI = Transfer.humanReadableByteCountBin(file.size);
file.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);
}
}
@Override
public void startTransfer() {
super.startTransfer();
startedTime = new Timestamp(System.currentTimeMillis());
state = STATE_RUNNING;
try {
uploadFile();
} catch (IOException e) {
final String ExceptionName = e.getClass().getSimpleName();
final String ExceptionMess = e.getMessage();
state = Transfer.STATE_FAILED;
error = ExceptionName + ": " + ExceptionMess;
progressEnd();
if(ExceptionName != null && ExceptionMess != null) {
errorSnackbar(ExceptionMess);
}
}
}
private String uploadFile() 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;
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);
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);
size = in.available();
while ((bufferLength = in.read(buffer)) > 0) {
request.write(buffer, 0, bufferLength);
loaded+= bufferLength;
percent = ((loaded * 100) / size);
progressUpdateDelay();
}
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;
progressEnd();
}
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;
}
}

View File

@ -26,7 +26,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import com.localtransfer.R; import com.localtransfer.R;
import com.localtransfer.ServerFile; import com.localtransfer.DownloadFile;
import com.localtransfer.Transfer; import com.localtransfer.Transfer;
import org.json.JSONArray; import org.json.JSONArray;
@ -108,7 +108,7 @@ public class DownloadFragment extends Fragment {
public boolean onContextItemSelected(MenuItem item) { public boolean onContextItemSelected(MenuItem item) {
if (item.getTitle() == "Delete") { if (item.getTitle() == "Delete") {
LinearLayout fileDesc = (LinearLayout) root.findViewById(item.getItemId()); LinearLayout fileDesc = (LinearLayout) root.findViewById(item.getItemId());
ServerFile file = ServerFile.getFileById((Integer) fileDesc.getTag(R.id.ID_DOWNLOAD)); DownloadFile file = (DownloadFile) DownloadFile.getFileById((Integer) fileDesc.getTag(R.id.ID_DOWNLOAD));
new Thread(() -> { new Thread(() -> {
try { try {
String message = file.deleteFile(); String message = file.deleteFile();
@ -161,7 +161,7 @@ public class DownloadFragment extends Fragment {
JSONArray array = new JSONArray(data); JSONArray array = new JSONArray(data);
for (int i = 0; i < array.length(); i++) { for (int i = 0; i < array.length(); i++) {
Integer id = View.generateViewId(); Integer id = View.generateViewId();
ServerFile trFile = new ServerFile(id); DownloadFile trFile = new DownloadFile(id);
JSONObject row = array.getJSONObject(i); JSONObject row = array.getJSONObject(i);
trFile.name = row.getString("name"); trFile.name = row.getString("name");
@ -189,7 +189,7 @@ public class DownloadFragment extends Fragment {
}).start(); }).start();
} }
private void setThumbnail(ServerFile file, ImageView image) { private void setThumbnail(DownloadFile file, ImageView image) {
new Thread(() -> { new Thread(() -> {
InputStream thumbnail = file.getThumbnail(); InputStream thumbnail = file.getThumbnail();
Bitmap bitmap = BitmapFactory.decodeStream(thumbnail); Bitmap bitmap = BitmapFactory.decodeStream(thumbnail);
@ -199,7 +199,7 @@ public class DownloadFragment extends Fragment {
}).start(); }).start();
} }
private void showFileList(ServerFile trFile) { private void showFileList(DownloadFile trFile) {
final LinearLayout main_layout = root.findViewById(R.id.main_layout); final LinearLayout main_layout = root.findViewById(R.id.main_layout);
@ -221,7 +221,8 @@ public class DownloadFragment extends Fragment {
fileDesc.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"); file_buttons.setTag(R.id.ID_FILE_BUTTONS, "FOR VISIBILITY");
trFile.button = file_buttons.findViewById(R.id.file_download);
trFile.setButton(file_buttons.findViewById(R.id.file_download));
if (trFile.mime.equals("text/plain")) if (trFile.mime.equals("text/plain"))
trFile.save_location = getContext().getCacheDir().toString(); trFile.save_location = getContext().getCacheDir().toString();
@ -269,19 +270,7 @@ public class DownloadFragment extends Fragment {
Bshare.setVisibility(LinearLayout.GONE); Bshare.setVisibility(LinearLayout.GONE);
} }
if (trFile.setButton(Bdownload)) { 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(); int state = file_buttons.getVisibility();
if(state == LinearLayout.GONE) { if(state == LinearLayout.GONE) {
@ -299,22 +288,13 @@ public class DownloadFragment extends Fragment {
private View.OnClickListener ListenerDL = v -> { private View.OnClickListener ListenerDL = v -> {
v.setEnabled(false); v.setEnabled(false);
final LinearLayout layout = (LinearLayout) v.getParent(); final LinearLayout layout = (LinearLayout) v.getParent();
final Button button = layout.findViewById(R.id.file_download); final Button button = (Button) v;
button.setText(String.format("Download pending"));
final Integer id = (Integer) layout.getTag(R.id.ID_DOWNLOAD); final Integer id = (Integer) layout.getTag(R.id.ID_DOWNLOAD);
final Drawable image = getActivity().getDrawable(R.drawable.ic_spinner_rotate); DownloadFile file = (DownloadFile) DownloadFile.getFileById(id);
int h = image.getIntrinsicHeight(); file.sizeSI = Transfer.humanReadableByteCountBin(file.size);
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();
ServerFile file = ServerFile.getFileById(id);
file.AddTransfer(); file.AddTransfer();
}; };
@ -322,7 +302,7 @@ public class DownloadFragment extends Fragment {
LinearLayout layout = (LinearLayout) v.getParent(); LinearLayout layout = (LinearLayout) v.getParent();
final Integer id = (Integer) layout.getTag(R.id.ID_DOWNLOAD); final Integer id = (Integer) layout.getTag(R.id.ID_DOWNLOAD);
ServerFile dl = ServerFile.getFileById(id); DownloadFile dl = (DownloadFile) DownloadFile.getFileById(id);
if(dl.type.equals("text/plain")) { if(dl.type.equals("text/plain")) {
String text = null; String text = null;
@ -371,7 +351,7 @@ public class DownloadFragment extends Fragment {
LinearLayout layout = (LinearLayout) v.getParent(); LinearLayout layout = (LinearLayout) v.getParent();
final Integer id = (Integer) layout.getTag(R.id.ID_DOWNLOAD); final Integer id = (Integer) layout.getTag(R.id.ID_DOWNLOAD);
ServerFile dl = ServerFile.getFileById(id); DownloadFile dl = (DownloadFile) DownloadFile.getFileById(id);
try { try {
Intent intent = new Intent(Intent.ACTION_VIEW); Intent intent = new Intent(Intent.ACTION_VIEW);

View File

@ -9,7 +9,6 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.localtransfer.R; import com.localtransfer.R;
import com.localtransfer.ServerFile;
import com.localtransfer.Transfer; import com.localtransfer.Transfer;
import java.util.List; import java.util.List;
@ -45,8 +44,8 @@ public class ProgressFragment extends Fragment {
Transfer.fragment_on = true; Transfer.fragment_on = true;
List<ServerFile> instances = ServerFile.getInstances(); List<Transfer> instances = Transfer.getInstances();
for (ServerFile file: instances) { for (Transfer file: instances) {
file.showProgressFragment(); file.showProgressFragment();
} }
} }