Foreground Service Integration

- Add Foreground Service
- Reviewed Progress Method
- Reviewed Transfer Object Integration
- Fix Some Error
This commit is contained in:
lionel 2021-03-14 19:40:41 +01:00
parent 493e836f56
commit 168e01e09a
7 changed files with 515 additions and 495 deletions

View File

@ -9,7 +9,7 @@ android {
minSdkVersion 24 minSdkVersion 24
targetSdkVersion 30 targetSdkVersion 30
versionCode 1 versionCode 1
versionName "1.0" versionName "2.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }

View File

@ -78,16 +78,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); Transfer.handleSendText(sharedText);
} else { } else {
Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM); Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
tr.handleSendFile(uri); Transfer.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);
@ -95,7 +93,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) Transfer.handleSendFile(uri);
} }
} }
@ -110,11 +108,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); Transfer.handleSendText(sharedText);
} }
else { else {
ArrayList<Uri> fileUris = new ArrayList<>(); ArrayList<Uri> fileUris = new ArrayList<>();
@ -130,7 +127,7 @@ public class MainActivity extends AppCompatActivity {
fileUris.add(uri); fileUris.add(uri);
} }
for (Uri uri : fileUris) { for (Uri uri : fileUris) {
tr.handleSendFile(uri); Transfer.handleSendFile(uri);
} }
} }
} }

View File

@ -1,32 +1,29 @@
package com.localtransfer; package com.localtransfer;
import android.animation.ObjectAnimator;
import android.app.Notification; import android.app.Notification;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.Button; import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat; import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;
import java.util.ArrayList; import com.google.android.material.snackbar.Snackbar;
import java.util.ConcurrentModificationException; import java.util.ConcurrentModificationException;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class Progress { public class Progress {
public static final int UPLOAD = 1000;
public static final int DOWNLOAD = 1001;
private static Notification.Builder bl = new Notification.Builder(Transfer.activity); private static Notification.Builder bl = new Notification.Builder(Transfer.activity);
private static NotificationManagerCompat notifiManager = NotificationManagerCompat.from(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 final LayoutInflater inflater = (LayoutInflater) Transfer.activity.getSystemService(Transfer.activity.LAYOUT_INFLATER_SERVICE);
@ -34,163 +31,131 @@ public class Progress {
private static Intent notificationIntent = new Intent(Transfer.activity, MainActivity.class); private static Intent notificationIntent = new Intent(Transfer.activity, MainActivity.class);
private static PendingIntent pendingIntent = PendingIntent.getActivity(Transfer.activity,0, notificationIntent, 0); private static PendingIntent pendingIntent = PendingIntent.getActivity(Transfer.activity,0, notificationIntent, 0);
private static List<Progress> instances = new ArrayList<>();
private Integer id;
private String name;
private long size;
private String HumanSize;
public long loaded;
private String HumanLoaded;
public long percent;
public static View root; public static View root;
public static boolean fragment_on = false; public static boolean fragment_on = false;
public static boolean app_started = false; public static boolean app_started = false;
private Timer timer = new Timer(); private static long savedTimeMillis;
private int drawable;
private String info;
public Button button; public static void PreProgress(Transfer tr) {
private boolean run; Transfer.activity.runOnUiThread(new Runnable() {
public Progress(String name, long size, int type) {
instances.add(this);
run = true;
this.name = name;
this.size = size;
this.HumanSize = Transfer.humanReadableByteCountBin(size);
id = View.generateViewId();
switch (type) {
case Progress.DOWNLOAD:
drawable = R.drawable.ic_download_24;
info = "Download complete";
break;
case Progress.UPLOAD:
drawable = R.drawable.ic_upload_24;
info = "Upload complete";
break;
default:
throw new IllegalStateException("Unexpected value: " + type);
}
Intent serviceIntent = new Intent(Transfer.activity, TransferService.class);
serviceIntent.putExtra("id", id);
ContextCompat.startForegroundService(Transfer.activity, serviceIntent);
timer.schedule(new TimerTask() {
@Override @Override
public void run() { public void run() {
showProgress();
}
}, 0, 1000);
}
public static List getInstances() { final Drawable image = Transfer.activity.getDrawable(R.drawable.ic_spinner_rotate);
return instances;
}
public void stopProgress() { if(tr.button != null) {
timer.cancel(); int h = image.getIntrinsicHeight();
showProgress(); int w = image.getIntrinsicWidth();
image.setBounds(0, 0, w, h);
run = false; tr.button.setCompoundDrawables(tr.button.getCompoundDrawables()[0], null, image, null);
ObjectAnimator anim = ObjectAnimator.ofInt(image, "level", 0, 10000);
Intent serviceIntent = new Intent(Transfer.activity, TransferService.class); anim.setDuration(1000);
Transfer.activity.stopService(serviceIntent); anim.setRepeatCount(Animation.INFINITE);
anim.setInterpolator(new LinearInterpolator());
if(! app_started) { anim.start();
bl.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud)
.setContentTitle(name)
.setContentText(info)
.setProgress(0, 0, false)
.setContentIntent(pendingIntent);
notifiManager.notify(id, bl.build());
}
}
public void delete() {
instances.remove(this);
}
public static Progress getProgress(int id) {
for (Object obj: instances) {
Progress p = (Progress) obj;
if (p.id == id) return p;
}
return null;
}
public static boolean setButton(String name, Button button) {
for (Object obj: instances) {
Progress p = (Progress) obj;
if (name.equals(p.name) && p.run) {
p.button = button;
return true;
} }
} }
return false; });
} }
private void showProgress(){ 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 { try {
HumanLoaded = Transfer.humanReadableByteCountBin(loaded);
bl.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud) bl.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud)
.setContentTitle(name) .setContentTitle(tr.fileName)
.setContentText(String.format("%d%% %s/%s", percent, HumanLoaded, HumanSize)) .setContentText(String.format("%d%% %s/%s", tr.percent, tr.loadedHuman, tr.fileSizeHuman))
.setProgress(100, (int) percent, false) .setProgress(100, (int) tr.percent, false)
.setContentIntent(pendingIntent); .setContentIntent(pendingIntent);
notifiManager.notify(id, bl.build()); notifiManager.notify(Transfer.NOTIF_SERVICE, bl.build());
if(app_started && fragment_on) { if (app_started && fragment_on)
showProgressFragment(); showProgressFragment(tr);
}
} catch (ConcurrentModificationException e) { } catch (ConcurrentModificationException e) {
e.printStackTrace(); e.printStackTrace();
} }
}
});
} }
public void showProgressFragment(){ 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); LinearLayout groot = root.findViewById(R.id.groot);
final View progress; final View progress;
if (groot.findViewById(id) != null) { if (groot.findViewById(tr.id) != null) {
progress = groot.findViewById(id); progress = groot.findViewById(tr.id);
} else { } else {
progress = inflater.inflate(R.layout.progress, null); progress = inflater.inflate(R.layout.progress, null);
progress.setId(id); progress.setId(tr.id);
Transfer.activity.runOnUiThread(() -> { Transfer.activity.runOnUiThread(() -> {
groot.addView(progress, 0); groot.addView(progress, 0);
}); });
} }
Transfer.activity.runOnUiThread(() -> { ((ProgressBar) progress.findViewById(R.id.progressBar)).setProgress((int) tr.percent);
((ProgressBar) progress.findViewById(R.id.progressBar)).setProgress((int) percent); ((ImageView) progress.findViewById(R.id.transferType)).setImageResource(tr.drawable);
((ImageView) progress.findViewById(R.id.transferType)).setImageResource(drawable); ((TextView) progress.findViewById(R.id.progressText)).setText(tr.percent + " %");
((TextView) progress.findViewById(R.id.progressText)).setText(percent + " %"); ((TextView) progress.findViewById(R.id.fileName)).setText(tr.fileName);
((TextView) progress.findViewById(R.id.fileName)).setText(name); ((TextView) progress.findViewById(R.id.fileSize)).setText(String.format("%s/%s", tr.loadedHuman, tr.fileSizeHuman));
((TextView) progress.findViewById(R.id.fileSize)).setText(String.format("%s/%s", HumanLoaded, HumanSize));
});
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);
} }
} }

View File

@ -1,25 +1,19 @@
package com.localtransfer; package com.localtransfer;
import android.animation.ObjectAnimator;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.OpenableColumns; import android.provider.OpenableColumns;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.widget.Button; import android.widget.Button;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.core.app.NotificationCompat; import androidx.core.content.ContextCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.FileProvider; import androidx.core.content.FileProvider;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
@ -32,7 +26,6 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.ProtocolException; import java.net.ProtocolException;
import java.net.URL; import java.net.URL;
@ -41,6 +34,7 @@ import java.nio.charset.StandardCharsets;
import java.text.CharacterIterator; import java.text.CharacterIterator;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.text.StringCharacterIterator; import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.ConcurrentModificationException; import java.util.ConcurrentModificationException;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -59,6 +53,127 @@ public class Transfer {
public static Activity activity; 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<Transfer> instances = new ArrayList<>();
public static List getInstances() {
return instances;
}
public int state;
public String error;
public int type;
public Integer id;
public int drawable;
public String info;
public String message;
public String fileName;
public long fileSize;
public String fileSizeHuman;
public long loaded;
public String loadedHuman = "0";
public long percent;
public Transfer(int type) {
id = View.generateViewId();
switch (type) {
case TYPE_DOWNLOAD:
drawable = R.drawable.ic_download_24;
info = "Download complete";
break;
case TYPE_UPLOAD:
drawable = R.drawable.ic_upload_24;
info = "Upload complete";
break;
default:
throw new IllegalStateException("Unexpected value: " + type);
}
state = STATE_STANDBY;
this.type = type;
}
public void AddTransfer() {
instances.add(this);
if(!runningTransfer) {
Intent serviceIntent = new Intent(activity, TransferService.class);
ContextCompat.startForegroundService(activity, serviceIntent);
runningTransfer = true;
new Thread(() -> StartTransfer(this)).start();
}
}
private static void StartTransfer(Transfer tr) {
try {
switch (tr.type) {
case Transfer.TYPE_DOWNLOAD:
tr.downloadFile();
break;
case Transfer.TYPE_UPLOAD:
tr.uploadFile();
break;
default:
throw new IllegalStateException("Unexpected value: " + tr.type);
}
} catch (IOException e) {
final String ExceptionName = e.getClass().getSimpleName();
final String ExceptionMess = e.getMessage();
tr.state = Transfer.STATE_FAILED;
tr.error = ExceptionName + ": " + ExceptionMess;
Progress.PostProgress(tr);
if(ExceptionName != null && ExceptionMess != null) {
Transfer.error(ExceptionMess);
}
}
try {
for (Object obj : Transfer.getInstances()) {
Transfer transfer = (Transfer) obj;
if (transfer.state == Transfer.STATE_STANDBY)
StartTransfer(transfer);
}
} catch (ConcurrentModificationException e) {
e.printStackTrace();
try {
Thread.sleep(10);
} catch (InterruptedException InterrupEx) {
InterrupEx.printStackTrace();
}
for (Object obj : Transfer.getInstances()) {
Transfer transfer = (Transfer) obj;
if (transfer.state == Transfer.STATE_STANDBY)
StartTransfer(transfer);
}
}
Intent serviceIntent = new Intent(Transfer.activity, TransferService.class);
Transfer.activity.stopService(serviceIntent);
Transfer.runningTransfer = false;
}
public static void parameter(Context context) { public static void parameter(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
@ -72,7 +187,267 @@ public class Transfer {
protocol = "http"; protocol = "http";
} }
private URL checkRedirection(URL url) throws IOException { public Uri uri;
public static void handleSendFile(Uri uri) {
if (uri != null) {
Transfer tr = new Transfer(Transfer.TYPE_UPLOAD);
tr.uri = uri;
Cursor cursor = activity.getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
tr.fileName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
tr.fileSize = cursor.getLong(cursor.getColumnIndex(OpenableColumns.SIZE));
tr.fileSizeHuman = Transfer.humanReadableByteCountBin(tr.fileSize);
tr.AddTransfer();
}
}
public static void handleSendText(String sharedText) {
if (sharedText != null) {
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMdd_HHmmss");
Date now = new Date();
String strDate = sdfDate.format(now);
Uri uri = null;
try {
File outputFile = new File(activity.getCacheDir(), strDate + ".txt");
FileOutputStream fileOut = new FileOutputStream(outputFile);
OutputStreamWriter OutWriter = new OutputStreamWriter(fileOut);
OutWriter.append(sharedText);
OutWriter.close();
fileOut.flush();
fileOut.close();
uri = FileProvider.getUriForFile(activity, activity.getPackageName(), outputFile);
} catch (IOException e) {
e.printStackTrace();
}
handleSendFile(uri);
}
}
public String uploadFile() throws IOException {
URL url = null;
HttpURLConnection conn = null;
DataOutputStream request = null;
String boundary = "*****";
int maxBufferSize = 1 * 1024 * 1024;
byte[] buffer = new byte[maxBufferSize];
int bufferLength;
loaded = 0;
String fileNameUTF8 = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1);
String type = activity.getContentResolver().getType(uri);
url = new URL(protocol, host, port, root + "/upload.php");
url = checkRedirection(url);
Progress.PreProgress(this);
if(url != null) {
Log.d("URL", url.toString());
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setChunkedStreamingMode(maxBufferSize);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "keep-alive");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
conn.connect();
request = new DataOutputStream(conn.getOutputStream());
request.writeBytes("--" + boundary + "\r\n");
request.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileNameUTF8 + "\"\r\n");
request.writeBytes("Content-Type: " + type + "\r\n\r\n");
InputStream in = activity.getContentResolver().openInputStream(uri);
while ((bufferLength = in.read(buffer)) > 0) {
request.write(buffer, 0, bufferLength);
loaded+= (long) bufferLength;
loadedHuman = Transfer.humanReadableByteCountBin(loaded);
percent = ((loaded * 100) / fileSize);
Progress.ProgressUpdateDelay(this);
}
request.writeBytes("\r\n");
request.writeBytes("--" + boundary + "--\r\n");
in.close();
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
message = "File " + fileName + " successful upload";
state = Transfer.STATE_SUCCESS;
Progress.PostProgress(this);
}
else {
String s = conn.getResponseMessage();
throw new HttpErrorException("HTTP Error code " + responseCode + " " + s);
}
request.flush();
request.close();
conn.disconnect();
}
return message;
}
public File file;
public String href;
public Button button;
public void downloadFile() throws IOException {
URL url = null;
HttpURLConnection conn = null;
int maxBufferSize = 1 * 1024 * 1024;
byte[] buffer = new byte[maxBufferSize];
int bufferLength;
loaded = 0;
Progress.PreProgress(this);
String[] parts = href.split("/");
String path = "";
for(int i=0; i< parts.length - 1; i++) {
path = path + parts[i] + "/";
}
String query = URLEncoder.encode(parts[parts.length - 1], StandardCharsets.UTF_8.toString());
url = new URL(protocol, host, port, path + query.replace("+", "%20"));
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("GET");
conn.setConnectTimeout(2000);
Log.d("URL", url.toString());
conn.connect();
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream in = conn.getInputStream();
while ((bufferLength = in.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
loaded+= (long) bufferLength;
loadedHuman = Transfer.humanReadableByteCountBin(loaded);
percent = ((loaded * 100) / fileSize);
Progress.ProgressUpdateDelay(this);
}
fileOutput.close();
conn.disconnect();
message = "File " + fileName + " successful download";
state = Transfer.STATE_SUCCESS;
Progress.PostProgress(this);
}
else {
String s = conn.getResponseMessage();
throw new HttpErrorException("HTTP Error code " + responseCode + " " + s);
}
conn.disconnect();
}
public static boolean setButton(String name, Button button) {
for (Object obj: instances) {
Transfer tr = (Transfer) obj;
if (name.equals(tr.fileName) && tr.state == STATE_RUNNING) {
tr.button = button;
return true;
}
}
return false;
}
public static String getFileList() throws IOException {
URL url = null;
HttpURLConnection conn = null;
String fileList = "";
int buf;
url = new URL(protocol, host, port, root + "/list.php");
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(2000);
conn.connect();
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStreamReader isw = new InputStreamReader(conn.getInputStream());
while ((buf = isw.read()) > 0) {
fileList = fileList + (char) buf;
}
}
else {
String s = conn.getResponseMessage();
throw new HttpErrorException("HTTP Error code " + responseCode + " " + s);
}
conn.disconnect();
return fileList;
}
public static String deleteFile(String file) throws IOException {
URL url = null;
HttpURLConnection conn = null;
String message;
String query = URLEncoder.encode(file, StandardCharsets.UTF_8.toString());
String serverUrl = root + "/delete.php?file=" + query;
url = new URL(protocol, host, port, serverUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(2000);
conn.connect();
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
message = "File " + file + " successful deleted";
}
else {
String s = conn.getResponseMessage();
throw new HttpErrorException("HTTP Error code " + responseCode + " " + s);
}
conn.disconnect();
return message;
}
private static URL checkRedirection(URL url) throws IOException {
String location = null; String location = null;
HttpURLConnection conn = null; HttpURLConnection conn = null;
int responseCode; int responseCode;
@ -113,332 +488,19 @@ public class Transfer {
return url; return url;
} }
public void handleSendFile(Uri uri) { public static void error(final String message) {
if (uri != null) {
new Thread(() -> {
try {
uploadFile(uri);
} catch (IOException e) {
final String ExceptionName = e.getClass().getSimpleName();
final String ExceptionMess = e.getMessage();
if(ExceptionName != null && ExceptionMess != null) {
Transfer.error(ExceptionName + ": " + ExceptionMess, null, null);
}
}
}).start();
}
}
public void handleSendText(String sharedText) {
if (sharedText != null) {
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMdd_HHmmss");
Date now = new Date();
String strDate = sdfDate.format(now);
new Thread(() -> {
try {
File outputFile = new File(activity.getCacheDir(), strDate + ".txt");
FileOutputStream fileOut = new FileOutputStream(outputFile);
OutputStreamWriter OutWriter = new OutputStreamWriter(fileOut);
OutWriter.append(sharedText);
OutWriter.close();
fileOut.flush();
fileOut.close();
Uri uri = FileProvider.getUriForFile(activity, activity.getPackageName(), outputFile);
uploadFile(uri);
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
public String uploadFile(Uri uri) throws IOException {
String message = null;
URL url = null;
HttpURLConnection conn = null;
DataOutputStream request = null;
String boundary = "*****";
int maxBufferSize = 1 * 1024 * 1024;
byte[] buffer = new byte[maxBufferSize];
int bufferLength;
long loaded = 0;
Cursor cursor = activity.getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
String fileName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
String fileNameUTF8 = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1);
long fileSize = cursor.getLong(cursor.getColumnIndex(OpenableColumns.SIZE));
String type = activity.getContentResolver().getType(uri);
url = new URL(protocol, host, port, root + "/upload.php");
url = checkRedirection(url);
Progress p = new Progress(fileName, fileSize, Progress.UPLOAD);
if(url != null) {
Log.d("URL", url.toString());
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setChunkedStreamingMode(maxBufferSize);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "keep-alive");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
conn.connect();
request = new DataOutputStream(conn.getOutputStream());
request.writeBytes("--" + boundary + "\r\n");
request.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileNameUTF8 + "\"\r\n");
request.writeBytes("Content-Type: " + type + "\r\n\r\n");
InputStream in = activity.getContentResolver().openInputStream(uri);
while ((bufferLength = in.read(buffer)) > 0) {
request.write(buffer, 0, bufferLength);
loaded+= (long) bufferLength;
p.loaded = loaded;
p.percent = ((loaded * 100) / fileSize);
}
request.writeBytes("\r\n");
request.writeBytes("--" + boundary + "--\r\n");
in.close();
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
message = "File " + fileName + " successful upload";
p.stopProgress();
}
else {
String s = conn.getResponseMessage();
throw new HttpErrorException("error code: " + responseCode + " " + s);
}
request.flush();
request.close();
conn.disconnect();
System.out.println(message);
if (activity != null) {
String finalMessage = message;
activity.runOnUiThread(() ->
Snackbar.make(activity.findViewById(R.id.view_pager), finalMessage, Snackbar.LENGTH_LONG)
.setAction("Action", null).show());
}
}
return message;
}
public String getFileList() throws IOException {
URL url = null;
HttpURLConnection conn = null;
String fileList = "";
int buf;
url = new URL(protocol, host, port, root + "/list.php");
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(2000);
conn.connect();
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStreamReader isw = new InputStreamReader(conn.getInputStream());
while ((buf = isw.read()) > 0) {
fileList = fileList + (char) buf;
}
}
else {
String s = conn.getResponseMessage();
throw new HttpErrorException("error code: " + responseCode + " " + s);
}
conn.disconnect();
return fileList;
}
public void downloadFile(final File file, String name, long fileSize, String href, Button button) throws IOException {
/*final LinearLayout layout = activity.findViewById(id);
final Button button;
if(layout != null)
button = layout.findViewById(R.id.file_download);
else
button = null;*/
URL url = null;
HttpURLConnection conn = null;
int maxBufferSize = 1 * 1024 * 1024;
byte[] buffer = new byte[maxBufferSize];
int bufferLength;
long loaded = 0;
final Drawable image = activity.getDrawable(R.drawable.ic_spinner_rotate);
Progress p = new Progress(name, fileSize, Progress.DOWNLOAD);
if(button != null)
p.button = button;
if(p.button != null) {
activity.runOnUiThread(() -> {
int h = image.getIntrinsicHeight();
int w = image.getIntrinsicWidth();
image.setBounds(0, 0, w, h);
p.button.setCompoundDrawables(button.getCompoundDrawables()[0], null, image, null);
ObjectAnimator anim = ObjectAnimator.ofInt(image, "level", 0, 10000);
anim.setDuration(1000);
anim.setRepeatCount(Animation.INFINITE);
anim.setInterpolator(new LinearInterpolator());
anim.start();
});
}
String[] parts = href.split("/");
String path = "";
for(int i=0; i< parts.length - 1; i++) {
path = path + parts[i] + "/";
}
String query = URLEncoder.encode(parts[parts.length - 1], StandardCharsets.UTF_8.toString());
url = new URL(protocol, host, port, path + query.replace("+", "%20"));
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("GET");
conn.setConnectTimeout(2000);
Log.d("URL", url.toString());
conn.connect();
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream in = conn.getInputStream();
while ((bufferLength = in.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
loaded+= (long) bufferLength;
p.loaded = loaded;
p.percent = ((loaded * 100) / fileSize);
if(Progress.app_started && p.button != null)
activity.runOnUiThread(() -> p.button.setText(String.format("Download in progress %d%%", p.percent)));
}
fileOutput.close();
conn.disconnect();
p.stopProgress();
if(p.button != null) {
activity.runOnUiThread(() -> {
final LinearLayout layout = (LinearLayout) p.button.getParent();
layout.findViewById(R.id.file_view).setVisibility(LinearLayout.VISIBLE);
layout.findViewById(R.id.file_share).setVisibility(LinearLayout.VISIBLE);
p.button.setVisibility(LinearLayout.GONE);
p.button.setEnabled(true);
p.button.setText(activity.getString(R.string.file_download));
p.button.setCompoundDrawables(p.button.getCompoundDrawables()[0], null, null, null);
});
}
activity.runOnUiThread(() -> {
String message = "File " + name + " successful download";
System.out.println(message);
Snackbar.make(activity.findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
});
}
else {
String s = conn.getResponseMessage();
throw new HttpErrorException("error code: " + responseCode + " " + s);
}
conn.disconnect();
}
public String deleteFile(String file) throws IOException {
URL url = null;
HttpURLConnection conn = null;
String message;
String query = URLEncoder.encode(file, StandardCharsets.UTF_8.toString());
String serverUrl = root + "/delete.php?file=" + query;
url = new URL(protocol, host, port, serverUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(2000);
conn.connect();
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
message = "File " + file + " successful deleted";
}
else {
String s = conn.getResponseMessage();
throw new HttpErrorException("error code: " + responseCode + " " + s);
}
conn.disconnect();
return message;
}
private static int timeout;
public static void error(final String message, final TextView title, final LinearLayout layout) {
System.out.println(message); System.out.println(message);
if (timeout == 0) {
if (activity != null) { if (activity != null) {
activity.runOnUiThread(new Runnable() { activity.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
if(layout != null)
layout.removeAllViews();
if(title != null) {
layout.addView(title);
title.setText(message);
}
Snackbar.make(activity.findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG) Snackbar.make(activity.findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG)
.setAction("Action", null).show(); .setAction("Action", null).show();
} }
}); });
} }
timeout = 1;
new Timer().schedule(new TimerTask() {
@Override
public void run() {
timeout = 0;
}
}, 3000);
}
} }
public static String humanReadableByteCountBin(long bytes) { public static String humanReadableByteCountBin(long bytes) {

View File

@ -17,7 +17,6 @@ public class TransferService extends Service {
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
int id = intent.getIntExtra("id", 0);
Intent notificationIntent = new Intent(this, MainActivity.class); Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, PendingIntent pendingIntent = PendingIntent.getActivity(this,
@ -27,7 +26,7 @@ public class TransferService extends Service {
.setContentIntent(pendingIntent) .setContentIntent(pendingIntent)
.build(); .build();
startForeground(id, notification); startForeground(Transfer.NOTIF_SERVICE, notification);
//do heavy work on a background thread //do heavy work on a background thread
//stopSelf(); //stopSelf();

View File

@ -27,7 +27,6 @@ import android.widget.TextView;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import com.localtransfer.BuildConfig; import com.localtransfer.BuildConfig;
import com.localtransfer.Progress;
import com.localtransfer.R; import com.localtransfer.R;
import com.localtransfer.Transfer; import com.localtransfer.Transfer;
@ -111,8 +110,7 @@ public class DownloadFragment extends Fragment {
final String file = String.valueOf(fileDesc.getTag(R.id.ID_FILE_NAME)); final String file = String.valueOf(fileDesc.getTag(R.id.ID_FILE_NAME));
new Thread(() -> { new Thread(() -> {
try { try {
Transfer tr = new Transfer(); String message = Transfer.deleteFile(file);
String message = tr.deleteFile(file);
System.out.println(message); System.out.println(message);
Transfer.activity.runOnUiThread(() -> Transfer.activity.runOnUiThread(() ->
Snackbar.make(getActivity().findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG) Snackbar.make(getActivity().findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG)
@ -123,7 +121,7 @@ public class DownloadFragment extends Fragment {
String ExceptionMess = e.getMessage(); String ExceptionMess = e.getMessage();
if(ExceptionName != null && ExceptionMess != null) { if(ExceptionName != null && ExceptionMess != null) {
Transfer.error(ExceptionName + ": " + ExceptionMess, null, null); Transfer.error(ExceptionMess);
} }
} }
@ -143,18 +141,24 @@ public class DownloadFragment extends Fragment {
final LinearLayout main_layout = root.findViewById(R.id.main_layout); final LinearLayout main_layout = root.findViewById(R.id.main_layout);
final LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(getContext().LAYOUT_INFLATER_SERVICE); final LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(getContext().LAYOUT_INFLATER_SERVICE);
Transfer tr = new Transfer();
String data = ""; String data = "";
try { try {
data = tr.getFileList(); data = Transfer.getFileList();
} catch (IOException e) { } catch (IOException e) {
final String ExceptionName = e.getClass().getSimpleName(); final String ExceptionName = e.getClass().getSimpleName();
final String ExceptionMess = e.getMessage(); final String ExceptionMess = e.getMessage();
if(ExceptionName != null && ExceptionMess != null) { if(ExceptionName != null && ExceptionMess != null) {
Transfer.error(ExceptionName + ": " + ExceptionMess, title, main_layout); Transfer.error(ExceptionMess);
Transfer.activity.runOnUiThread(() -> {
if(main_layout != null)
main_layout.removeAllViews();
if(title != null) {
main_layout.addView(title);
title.setText(ExceptionMess);
}
});
} }
} }
@ -253,7 +257,7 @@ public class DownloadFragment extends Fragment {
Bshare.setVisibility(LinearLayout.GONE); Bshare.setVisibility(LinearLayout.GONE);
} }
if (Progress.setButton(name, dl)) { if (Transfer.setButton(name, dl)) {
dl.setEnabled(false); dl.setEnabled(false);
final Drawable spinner = Transfer.activity.getDrawable(R.drawable.ic_spinner_rotate); final Drawable spinner = Transfer.activity.getDrawable(R.drawable.ic_spinner_rotate);
int h = spinner.getIntrinsicHeight(); int h = spinner.getIntrinsicHeight();
@ -304,21 +308,14 @@ public class DownloadFragment extends Fragment {
new File(save_location).mkdirs(); new File(save_location).mkdirs();
File file = new File(save_location, name); File file = new File(save_location, name);
Transfer tr = new Transfer(); Transfer tr = new Transfer(Transfer.TYPE_DOWNLOAD);
tr.file = file;
new Thread(() -> { tr.fileName = name;
try { tr.fileSize = fileSize;
tr.downloadFile(file, name, fileSize, href, button); tr.fileSizeHuman = Transfer.humanReadableByteCountBin(fileSize);
} catch (IOException e) { tr.href = href;
final String ExceptionName = e.getClass().getSimpleName(); tr.button = button;
final String ExceptionMess = e.getMessage(); tr.AddTransfer();
if(ExceptionName != null && ExceptionMess != null) {
Transfer.error(ExceptionName + ": " + ExceptionMess, null, null);
}
}
}).start();
}; };
private View.OnClickListener ListenerShare = v -> { private View.OnClickListener ListenerShare = v -> {

View File

@ -54,10 +54,10 @@ public class ProgressFragment extends Fragment {
Progress.fragment_on = true; Progress.fragment_on = true;
List instances = Progress.getInstances(); List instances = Transfer.getInstances();
for (Object obj: instances) { for (Object obj: instances) {
Progress p = (Progress) obj; Transfer tr = (Transfer) obj;
p.showProgressFragment(); Progress.showProgressFragment(tr);
} }
} }