first commit
This commit is contained in:
58
app/src/main/java/com/localtransfer/Extra.java
Normal file
58
app/src/main/java/com/localtransfer/Extra.java
Normal file
@ -0,0 +1,58 @@
|
||||
package com.localtransfer;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.view.View;
|
||||
|
||||
public class Extra implements Parcelable {
|
||||
|
||||
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
|
||||
public Extra createFromParcel(Parcel in) {
|
||||
return new Extra(in);
|
||||
}
|
||||
|
||||
public Extra[] newArray(int size) {
|
||||
return new Extra[size];
|
||||
}
|
||||
};
|
||||
|
||||
public String name;
|
||||
public long size;
|
||||
public String href;
|
||||
public String uri;
|
||||
public int id;
|
||||
|
||||
// Constructor
|
||||
public Extra(Uri uri, String name, long size, String href, View view){
|
||||
this.uri = uri.toString();
|
||||
this.name = name;
|
||||
this.size = size;
|
||||
this.href = href;
|
||||
this.id = view.getId();
|
||||
}
|
||||
|
||||
|
||||
// Parcelling part
|
||||
public Extra(Parcel in){
|
||||
this.uri = in.readString();
|
||||
this.name = in.readString();
|
||||
this.size = in.readLong();
|
||||
this.href = in.readString();
|
||||
this.id = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.uri);
|
||||
dest.writeString(this.name);
|
||||
dest.writeLong(this.size);
|
||||
dest.writeString(this.href);
|
||||
dest.writeInt(this.id);
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.localtransfer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class HttpErrorException extends IOException {
|
||||
public HttpErrorException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
212
app/src/main/java/com/localtransfer/MainActivity.java
Normal file
212
app/src/main/java/com/localtransfer/MainActivity.java
Normal file
@ -0,0 +1,212 @@
|
||||
package com.localtransfer;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
|
||||
ViewPager viewPager = findViewById(R.id.view_pager);
|
||||
viewPager.setAdapter(sectionsPagerAdapter);
|
||||
TabLayout tabs = findViewById(R.id.tabs);
|
||||
tabs.setupWithViewPager(viewPager);
|
||||
FloatingActionButton fab = findViewById(R.id.flotUpload);
|
||||
fab.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
checkAndRequestPermissions();
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
if(prefs.getString("host", null) == null)
|
||||
prefs.edit()
|
||||
.putString("host", getString(R.string.server_host_def))
|
||||
.putString("port", getString(R.string.server_port_def))
|
||||
.putString("root", getString(R.string.server_root_def))
|
||||
.putString("local_storage", getString(R.string.local_storage_def))
|
||||
.apply();
|
||||
|
||||
Transfer.parameter(this);
|
||||
Transfer.activity = this;
|
||||
|
||||
Intent intent = getIntent();
|
||||
String action = intent.getAction();
|
||||
String type = intent.getType();
|
||||
|
||||
Transfer tr = new Transfer();
|
||||
|
||||
if (Intent.ACTION_SEND.equals(action) && type != null) {
|
||||
viewPager.setCurrentItem(2);
|
||||
if ("text/plain".equals(type)) {
|
||||
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||
tr.handleSendText(sharedText);
|
||||
} else {
|
||||
Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
|
||||
new Thread(() -> tr.handleSendFile(uri)).start();
|
||||
}
|
||||
} else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
|
||||
viewPager.setCurrentItem(2);
|
||||
ArrayList<Uri> fileUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
|
||||
int nbItem = fileUris.size();
|
||||
Toast.makeText(this, "You select " + nbItem + " files", Toast.LENGTH_SHORT).show();
|
||||
if (fileUris != null)
|
||||
for(Uri uri : fileUris) tr.handleSendFile(uri);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume(){
|
||||
super.onResume();
|
||||
|
||||
Progress.app_started = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause(){
|
||||
super.onPause();
|
||||
|
||||
Progress.app_started = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
File dir = getCacheDir();
|
||||
deleteDirContent(dir);
|
||||
}
|
||||
|
||||
private static void deleteDirContent(File dir) {
|
||||
if (dir != null && dir.isDirectory()) {
|
||||
String[] children = dir.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File file = new File(dir, children[i]);
|
||||
if (file.isFile())
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case R.id.action_settings:
|
||||
Intent settings = new Intent(this, SettingsActivity.class);
|
||||
startActivity(settings);
|
||||
break;
|
||||
case R.id.action_folder:
|
||||
String save_location = Environment.getExternalStorageDirectory() + "/" + Transfer.local_storage;
|
||||
Uri selectedUri = Uri.parse(save_location.toString());
|
||||
boolean intentSuccess = false;
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(selectedUri, "resource/folder");
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT |
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK |
|
||||
Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
|
||||
startActivity(intent);
|
||||
intentSuccess = true;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
intentSuccess = false;
|
||||
}
|
||||
if( ! intentSuccess && isPackageInstalled("com.sec.android.app.myfiles", getPackageManager())){
|
||||
|
||||
Intent intent = getPackageManager().getLaunchIntentForPackage("com.sec.android.app.myfiles");
|
||||
intent.setData(selectedUri);
|
||||
startActivity(intent);
|
||||
}
|
||||
else if(! intentSuccess)
|
||||
Toast.makeText(this, "No file Manager", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
public static final int REQUEST_ID_READ_EXTERNAL_STORAGE = 2001;
|
||||
|
||||
private boolean checkAndRequestPermissions() {
|
||||
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
this, Manifest.permission.READ_EXTERNAL_STORAGE) ==
|
||||
PackageManager.PERMISSION_GRANTED) {
|
||||
Log.d("READ_EXTERNAL_STORAGE", "already granted");
|
||||
}
|
||||
else {
|
||||
ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_ID_READ_EXTERNAL_STORAGE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode,
|
||||
String permissions[],
|
||||
int[] grantResults) {
|
||||
switch (requestCode) {
|
||||
case REQUEST_ID_READ_EXTERNAL_STORAGE:
|
||||
if (grantResults.length > 0 &&
|
||||
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
Log.d("READ_EXTERNAL_STORAGE", "granted");
|
||||
} else {
|
||||
Log.d("READ_EXTERNAL_STORAGE", "No granted");
|
||||
System.exit(1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPackageInstalled(String packageName, PackageManager packageManager) {
|
||||
try {
|
||||
packageManager.getPackageInfo(packageName, 0);
|
||||
return true;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
188
app/src/main/java/com/localtransfer/Progress.java
Normal file
188
app/src/main/java/com/localtransfer/Progress.java
Normal file
@ -0,0 +1,188 @@
|
||||
package com.localtransfer;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class Progress {
|
||||
|
||||
public static final int UPLOAD = 1000;
|
||||
public static final int DOWNLOAD = 1001;
|
||||
|
||||
|
||||
private static NotificationCompat.Builder bl = new NotificationCompat.Builder(Transfer.activity, null);
|
||||
private static NotificationManagerCompat notifiManager = NotificationManagerCompat.from(Transfer.activity);
|
||||
private static final LayoutInflater inflater = (LayoutInflater) Transfer.activity.getSystemService(Transfer.activity.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
private static List instances = new ArrayList();
|
||||
|
||||
private Integer id;
|
||||
private String name;
|
||||
private long size;
|
||||
|
||||
public long loaded;
|
||||
public long percent;
|
||||
|
||||
public static View root;
|
||||
public static boolean fragment_on = false;
|
||||
public static boolean app_started = false;
|
||||
|
||||
private Timer timer = new Timer();
|
||||
private int drawable;
|
||||
private String info;
|
||||
|
||||
public Button button;
|
||||
private boolean run = false;
|
||||
|
||||
public Progress(String name, long size, int type) {
|
||||
|
||||
instances.add(this);
|
||||
|
||||
run = true;
|
||||
|
||||
this.name = name;
|
||||
this.size = 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);
|
||||
}
|
||||
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
showProgress();
|
||||
}
|
||||
}, 0, 1000);
|
||||
}
|
||||
|
||||
public static List getInstances() {
|
||||
return instances;
|
||||
}
|
||||
|
||||
public void stopProgress() {
|
||||
timer.cancel();
|
||||
showProgress();
|
||||
|
||||
run = false;
|
||||
|
||||
if(! app_started) {
|
||||
bl.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud)
|
||||
.setContentTitle(name)
|
||||
.setContentText(info)
|
||||
.setProgress(0, 0, false)
|
||||
.setAutoCancel(true)
|
||||
.setOngoing(false);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
public void showProgress(){
|
||||
|
||||
try {
|
||||
|
||||
String HumanLoaded = Transfer.humanReadableByteCountBin(loaded);
|
||||
String HumanSize = Transfer.humanReadableByteCountBin(size);
|
||||
|
||||
if(app_started) {
|
||||
notifiManager.cancel(id);
|
||||
}
|
||||
else {
|
||||
|
||||
Intent intent = new Intent(Transfer.activity, MainActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(Transfer.activity, 0, intent, 0);
|
||||
|
||||
bl.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud)
|
||||
.setContentTitle(name)
|
||||
.setContentText(String.format("%d%% %s/%s", percent, HumanLoaded, HumanSize))
|
||||
.setProgress(100, (int) percent, false)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setAutoCancel(true)
|
||||
.setOngoing(true);
|
||||
notifiManager.notify(id, bl.build());
|
||||
}
|
||||
|
||||
if(app_started && fragment_on) {
|
||||
LinearLayout groot = root.findViewById(R.id.groot);
|
||||
|
||||
final View progress;
|
||||
|
||||
if (groot.findViewById(id) != null) {
|
||||
progress = groot.findViewById(id);
|
||||
} else {
|
||||
progress = inflater.inflate(R.layout.progress, null);
|
||||
progress.setId(id);
|
||||
Transfer.activity.runOnUiThread(() -> {
|
||||
groot.addView(progress, 0);
|
||||
});
|
||||
}
|
||||
|
||||
Transfer.activity.runOnUiThread(() -> {
|
||||
((ProgressBar) progress.findViewById(R.id.progressBar)).setProgress((int) percent);
|
||||
((ImageView) progress.findViewById(R.id.transferType)).setImageResource(drawable);
|
||||
((TextView) progress.findViewById(R.id.progressText)).setText(percent + " %");
|
||||
((TextView) progress.findViewById(R.id.fileName)).setText(name);
|
||||
((TextView) progress.findViewById(R.id.fileSize)).setText(String.format("%s/%s", HumanLoaded, HumanSize));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
} catch (ConcurrentModificationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.localtransfer;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
|
||||
import com.localtransfer.fragment.DownloadFragment;
|
||||
import com.localtransfer.fragment.ProgressFragment;
|
||||
import com.localtransfer.fragment.UploadFragment;
|
||||
|
||||
/**
|
||||
* A [FragmentPagerAdapter] that returns a fragment corresponding to
|
||||
* one of the sections/tabs/pages.
|
||||
*/
|
||||
public class SectionsPagerAdapter extends FragmentPagerAdapter {
|
||||
|
||||
@StringRes
|
||||
private static final int[] TAB_TITLES = new int[]{R.string.download, R.string.upload, R.string.progress};
|
||||
private final Context mContext;
|
||||
|
||||
public SectionsPagerAdapter(Context context, FragmentManager fm) {
|
||||
super(fm);
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
// getItem is called to instantiate the fragment for the given page.
|
||||
// Return a PlaceholderFragment (defined as a static inner class below).
|
||||
switch (position){
|
||||
case 0: //Page number 1
|
||||
return DownloadFragment.newInstance();
|
||||
case 1: //Page number 2
|
||||
return UploadFragment.newInstance();
|
||||
case 2: //Page number 3
|
||||
return ProgressFragment.newInstance();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
return mContext.getResources().getString(TAB_TITLES[position]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 3;
|
||||
}
|
||||
}
|
93
app/src/main/java/com/localtransfer/SettingsActivity.java
Normal file
93
app/src/main/java/com/localtransfer/SettingsActivity.java
Normal file
@ -0,0 +1,93 @@
|
||||
package com.localtransfer;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import lib.folderpicker.FolderPicker;
|
||||
|
||||
public class SettingsActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.settings_activity);
|
||||
getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.settings, new SettingsFragment())
|
||||
.commit();
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SettingsFragment extends PreferenceFragmentCompat {
|
||||
|
||||
private final static int REQUEST_DIRECTORY_PICKER = 4000;
|
||||
static Preference directory;
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
setPreferencesFromResource(R.xml.root_preferences, rootKey);
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
directory = findPreference("local_storage");
|
||||
directory.setSummary(prefs.getString("local_storage", null));
|
||||
directory.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
Intent intent = new Intent(getContext(), FolderPicker.class);
|
||||
startActivityForResult(intent, REQUEST_DIRECTORY_PICKER);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
switch (requestCode) {
|
||||
case REQUEST_DIRECTORY_PICKER:
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
String currentPath = data.getExtras().getString("data");
|
||||
if(currentPath.contains(Environment.getExternalStorageDirectory() + "/")) {
|
||||
String save_location = currentPath.replace(Environment.getExternalStorageDirectory() + "/", "");
|
||||
Log.d("Path", save_location);
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
prefs.edit().putString("local_storage", save_location).apply();
|
||||
directory.setSummary(save_location);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
Transfer.parameter(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
|
||||
if (id == android.R.id.home) {
|
||||
onBackPressed(); return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
461
app/src/main/java/com/localtransfer/Transfer.java
Normal file
461
app/src/main/java/com/localtransfer/Transfer.java
Normal file
@ -0,0 +1,461 @@
|
||||
package com.localtransfer;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
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.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Serializable;
|
||||
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.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 {
|
||||
|
||||
public static String host;
|
||||
public static Integer port;
|
||||
public static String root;
|
||||
public static String protocol;
|
||||
public static String local_storage;
|
||||
|
||||
public static Activity activity;
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
private URL checkRedirection(URL url) throws IOException {
|
||||
String location = null;
|
||||
HttpURLConnection conn = null;
|
||||
int responseCode;
|
||||
int nbRedirect = 0;
|
||||
|
||||
do {
|
||||
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setInstanceFollowRedirects(false);
|
||||
conn.setConnectTimeout(2000);
|
||||
|
||||
conn.connect();
|
||||
responseCode = conn.getResponseCode();
|
||||
|
||||
Log.d("Réponse Code", String.valueOf(responseCode));
|
||||
|
||||
if(responseCode != HttpURLConnection.HTTP_MOVED_PERM && responseCode != HttpURLConnection.HTTP_MOVED_TEMP) {
|
||||
break;
|
||||
}
|
||||
|
||||
location = conn.getHeaderField("Location");
|
||||
Log.d("Location", location);
|
||||
|
||||
url = new URL(location);
|
||||
|
||||
|
||||
conn.disconnect();
|
||||
|
||||
nbRedirect++;
|
||||
if(nbRedirect > 10) {
|
||||
throw new ProtocolException("Too many follow-up requests: " + nbRedirect);
|
||||
}
|
||||
|
||||
|
||||
} while (responseCode == HttpURLConnection.HTTP_MOVED_PERM || responseCode == HttpURLConnection.HTTP_MOVED_TEMP);
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
public void handleSendFile(Uri uri) {
|
||||
if (uri != null) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
uploadFile(uri);
|
||||
} catch (IOException e) {
|
||||
final String ExceptionName = e.getClass().getSimpleName();
|
||||
final String ExceptionMess = e.getMessage();
|
||||
|
||||
if(ExceptionName != null && ExceptionMess != null) {
|
||||
Transfer.error(ExceptionName + ": " + ExceptionMess, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
public void handleSendText(String sharedText) {
|
||||
if (sharedText != null) {
|
||||
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMdd_HHmmss");
|
||||
Date now = new Date();
|
||||
String strDate = sdfDate.format(now);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
File outputFile = new File(activity.getCacheDir(), strDate + ".txt");
|
||||
FileOutputStream fileOut = new FileOutputStream(outputFile);
|
||||
OutputStreamWriter OutWriter = new OutputStreamWriter(fileOut);
|
||||
OutWriter.append(sharedText);
|
||||
OutWriter.close();
|
||||
|
||||
fileOut.flush();
|
||||
fileOut.close();
|
||||
|
||||
Uri uri = FileProvider.getUriForFile(activity, activity.getPackageName(), outputFile);
|
||||
|
||||
uploadFile(uri);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
public String uploadFile(Uri uri) throws IOException {
|
||||
String message = null;
|
||||
URL url = null;
|
||||
HttpURLConnection conn = null;
|
||||
DataOutputStream request = null;
|
||||
String boundary = "*****";
|
||||
int maxBufferSize = 1 * 1024 * 1024;
|
||||
byte[] buffer = new byte[maxBufferSize];
|
||||
int bufferLength;
|
||||
long loaded = 0;
|
||||
|
||||
Cursor cursor = activity.getContentResolver().query(uri, null, null, null, null);
|
||||
cursor.moveToFirst();
|
||||
String fileName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
|
||||
String fileNameUTF8 = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1);
|
||||
long fileSize = cursor.getLong(cursor.getColumnIndex(OpenableColumns.SIZE));
|
||||
String type = activity.getContentResolver().getType(uri);
|
||||
|
||||
url = new URL(protocol, host, port, root + "/upload.php");
|
||||
|
||||
url = checkRedirection(url);
|
||||
|
||||
Progress p = new Progress(fileName, fileSize, Progress.UPLOAD);
|
||||
|
||||
if(url != null) {
|
||||
|
||||
Log.d("URL", url.toString());
|
||||
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setDoInput(true); // Allow Inputs
|
||||
conn.setDoOutput(true); // Allow Outputs
|
||||
conn.setUseCaches(false); // Don't use a Cached Copy
|
||||
conn.setChunkedStreamingMode(maxBufferSize);
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setRequestProperty("Connection", "keep-alive");
|
||||
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
|
||||
|
||||
conn.connect();
|
||||
|
||||
request = new DataOutputStream(conn.getOutputStream());
|
||||
|
||||
request.writeBytes("--" + boundary + "\r\n");
|
||||
request.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileNameUTF8 + "\"\r\n");
|
||||
request.writeBytes("Content-Type: " + type + "\r\n\r\n");
|
||||
|
||||
InputStream in = activity.getContentResolver().openInputStream(uri);
|
||||
|
||||
while ((bufferLength = in.read(buffer)) > 0) {
|
||||
request.write(buffer, 0, bufferLength);
|
||||
loaded+= (long) bufferLength;
|
||||
p.loaded = loaded;
|
||||
p.percent = ((loaded * 100) / fileSize);
|
||||
}
|
||||
|
||||
request.writeBytes("\r\n");
|
||||
request.writeBytes("--" + boundary + "--\r\n");
|
||||
|
||||
in.close();
|
||||
|
||||
int responseCode = conn.getResponseCode();
|
||||
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
message = "File " + fileName + " successful upload";
|
||||
p.stopProgress();
|
||||
}
|
||||
else {
|
||||
String s = conn.getResponseMessage();
|
||||
throw new HttpErrorException("error code: " + responseCode + " " + s);
|
||||
}
|
||||
|
||||
request.flush();
|
||||
|
||||
request.close();
|
||||
|
||||
conn.disconnect();
|
||||
|
||||
System.out.println(message);
|
||||
if (activity != null) {
|
||||
String finalMessage = message;
|
||||
activity.runOnUiThread(() ->
|
||||
Snackbar.make(activity.findViewById(R.id.view_pager), finalMessage, Snackbar.LENGTH_LONG)
|
||||
.setAction("Action", null).show());
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
public String getFileList() throws IOException {
|
||||
URL url = null;
|
||||
HttpURLConnection conn = null;
|
||||
|
||||
String fileList = "";
|
||||
int buf;
|
||||
|
||||
url = new URL(protocol, host, port, root + "/list.php");
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setConnectTimeout(2000);
|
||||
|
||||
conn.connect();
|
||||
|
||||
int responseCode = conn.getResponseCode();
|
||||
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
InputStreamReader isw = new InputStreamReader(conn.getInputStream());
|
||||
|
||||
while ((buf = isw.read()) > 0) {
|
||||
fileList = fileList + (char) buf;
|
||||
}
|
||||
}
|
||||
else {
|
||||
String s = conn.getResponseMessage();
|
||||
throw new HttpErrorException("error code: " + responseCode + " " + s);
|
||||
}
|
||||
|
||||
conn.disconnect();
|
||||
|
||||
return fileList;
|
||||
}
|
||||
|
||||
public void downloadFile(final Uri uri, 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;*/
|
||||
|
||||
final File file = new File(uri.getPath());
|
||||
|
||||
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);
|
||||
|
||||
if (timeout == 0) {
|
||||
if (activity != null) {
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(layout != null)
|
||||
layout.removeAllViews();
|
||||
if(title != null) {
|
||||
layout.addView(title);
|
||||
title.setText(message);
|
||||
}
|
||||
Snackbar.make(activity.findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG)
|
||||
.setAction("Action", null).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
timeout = 1;
|
||||
new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
timeout = 0;
|
||||
}
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
public static String humanReadableByteCountBin(long bytes) {
|
||||
long absB = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
|
||||
if (absB < 1024) {
|
||||
return bytes + " B";
|
||||
}
|
||||
long value = absB;
|
||||
CharacterIterator ci = new StringCharacterIterator("KMGTPE");
|
||||
for (int i = 40; i >= 0 && absB > 0xfffccccccccccccL >> i; i -= 10) {
|
||||
value >>= 10;
|
||||
ci.next();
|
||||
}
|
||||
value *= Long.signum(bytes);
|
||||
return String.format("%.1f %ciB", value / 1024.0, ci.current());
|
||||
}
|
||||
}
|
||||
|
75
app/src/main/java/com/localtransfer/TransferService.java
Normal file
75
app/src/main/java/com/localtransfer/TransferService.java
Normal file
@ -0,0 +1,75 @@
|
||||
package com.localtransfer;
|
||||
|
||||
import android.app.IntentService;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TransferService extends IntentService {
|
||||
|
||||
public static final String ACTION_UPLOAD = "com.localtransfer.action.FOO";
|
||||
public static final String ACTION_DOWNLOAD = "com.localtransfer.action.BAZ";
|
||||
|
||||
public static final String EXTRA_URI = "com.localtransfer.extra.URI";
|
||||
public static final String EXTRA = "com.localtransfer.extra.EXTRA";
|
||||
|
||||
public TransferService() {
|
||||
super("TransferService");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
if (intent != null) {
|
||||
final String action = intent.getAction();
|
||||
switch (action) {
|
||||
case ACTION_UPLOAD:
|
||||
handleUpload(intent);
|
||||
break;
|
||||
case ACTION_DOWNLOAD:
|
||||
handleDownload(intent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleUpload(Intent intent) {
|
||||
final Uri uri = intent.getParcelableExtra(EXTRA_URI);
|
||||
|
||||
Transfer tr = new Transfer();
|
||||
try {
|
||||
tr.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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDownload(Intent intent) {
|
||||
Extra ex = (Extra) intent.getExtras().getParcelable(EXTRA);
|
||||
final LinearLayout layout = Transfer.activity.findViewById(ex.id);
|
||||
Button button = null;
|
||||
if(layout != null)
|
||||
button = layout.findViewById(R.id.file_download);
|
||||
|
||||
Transfer tr = new Transfer();
|
||||
try {
|
||||
tr.downloadFile(Uri.parse(ex.uri), ex.name, ex.size, ex.href, button);
|
||||
} catch (IOException e) {
|
||||
final String ExceptionName = e.getClass().getSimpleName();
|
||||
final String ExceptionMess = e.getMessage();
|
||||
|
||||
if(ExceptionName != null && ExceptionMess != null) {
|
||||
Transfer.error(ExceptionName + ": " + ExceptionMess, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,416 @@
|
||||
package com.localtransfer.fragment;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
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.os.Parcelable;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.localtransfer.BuildConfig;
|
||||
import com.localtransfer.Extra;
|
||||
import com.localtransfer.Progress;
|
||||
import com.localtransfer.R;
|
||||
import com.localtransfer.Transfer;
|
||||
import com.localtransfer.TransferService;
|
||||
|
||||
import org.json.JSONArray;
|
||||
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;
|
||||
import java.text.CharacterIterator;
|
||||
import java.text.StringCharacterIterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class DownloadFragment extends Fragment {
|
||||
|
||||
public DownloadFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
private View root;
|
||||
|
||||
public static DownloadFragment newInstance() {
|
||||
DownloadFragment fragment = new DownloadFragment();
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
root = inflater.inflate(R.layout.fragment_download, container, false);
|
||||
|
||||
new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
showFileList();
|
||||
}
|
||||
}, 100);
|
||||
|
||||
SwipeRefreshLayout refresh = root.findViewById(R.id.refresh);
|
||||
|
||||
refresh.setOnRefreshListener(() -> {
|
||||
new Thread(() -> showFileList()).start();
|
||||
refresh.setRefreshing(false);
|
||||
});
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause(){
|
||||
super.onPause();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
super.onCreateContextMenu(menu, v, menuInfo);
|
||||
menu.add ( 0 , v.getId (), 0 , "Delete" );
|
||||
}
|
||||
|
||||
@Override
|
||||
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));
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Transfer tr = new Transfer();
|
||||
String message = tr.deleteFile(file);
|
||||
System.out.println(message);
|
||||
Transfer.activity.runOnUiThread(() ->
|
||||
Snackbar.make(getActivity().findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG)
|
||||
.setAction("Action", null).show());
|
||||
showFileList();
|
||||
} catch (IOException e) {
|
||||
String ExceptionName = e.getClass().getSimpleName();
|
||||
String ExceptionMess = e.getMessage();
|
||||
|
||||
if(ExceptionName != null && ExceptionMess != null) {
|
||||
Transfer.error(ExceptionName + ": " + ExceptionMess, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void showFileList() {
|
||||
|
||||
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);
|
||||
|
||||
Transfer tr = new Transfer();
|
||||
|
||||
String data = "";
|
||||
|
||||
try {
|
||||
data = tr.getFileList();
|
||||
} catch (IOException e) {
|
||||
final String ExceptionName = e.getClass().getSimpleName();
|
||||
final String ExceptionMess = e.getMessage();
|
||||
|
||||
if(ExceptionName != null && ExceptionMess != null) {
|
||||
Transfer.error(ExceptionName + ": " + ExceptionMess, title, main_layout);
|
||||
}
|
||||
|
||||
}
|
||||
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 (Progress.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);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private View.OnClickListener ListenerDL = v -> {
|
||||
v.setEnabled(false);
|
||||
final LinearLayout layout = (LinearLayout) v.getParent();
|
||||
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);
|
||||
|
||||
new File(save_location).mkdirs();
|
||||
Uri uri = Uri.fromFile(new File(save_location, name));
|
||||
|
||||
Intent intent = new Intent(getActivity(), TransferService.class);
|
||||
intent.setAction(TransferService.ACTION_DOWNLOAD);
|
||||
intent.putExtra(TransferService.EXTRA, new Extra(uri, name, fileSize, href, layout));
|
||||
getActivity().startService(intent);
|
||||
|
||||
};
|
||||
|
||||
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 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);
|
||||
|
||||
if(type.equals("text/plain")) {
|
||||
String text = null;
|
||||
try {
|
||||
InputStream is = new FileInputStream(file);
|
||||
BufferedReader buf = new BufferedReader(new InputStreamReader(is));
|
||||
|
||||
String line;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
while((line = buf.readLine()) != null) {
|
||||
sb.append(line).append("\n");
|
||||
}
|
||||
|
||||
text = sb.toString();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
intent.setType(type);
|
||||
intent.putExtra(Intent.EXTRA_TEXT, text);
|
||||
startActivity(Intent.createChooser(intent, getString(R.string.share_title)));
|
||||
} catch (ActivityNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
intent.putExtra(Intent.EXTRA_STREAM, uri);
|
||||
intent.setType(type);
|
||||
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
startActivity(Intent.createChooser(intent, getString(R.string.share_title)));
|
||||
} catch (ActivityNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
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 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);
|
||||
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(uri, type);
|
||||
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
startActivity(intent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
private List<View> getAllChildren(View v) {
|
||||
|
||||
if (!(v instanceof ViewGroup)) {
|
||||
ArrayList<View> viewArrayList = new ArrayList<View>();
|
||||
viewArrayList.add(v);
|
||||
return viewArrayList;
|
||||
}
|
||||
|
||||
ArrayList<View> result = new ArrayList<View>();
|
||||
|
||||
ViewGroup viewGroup = (ViewGroup) v;
|
||||
for (int i = 0; i < viewGroup.getChildCount(); i++) {
|
||||
|
||||
View child = viewGroup.getChildAt(i);
|
||||
|
||||
//add child
|
||||
result.add(child);
|
||||
|
||||
//Do the same with child of child
|
||||
result.addAll(getAllChildren(child));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
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.Transfer;
|
||||
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class ProgressFragment extends Fragment {
|
||||
|
||||
public ProgressFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
public static ProgressFragment newInstance() {
|
||||
ProgressFragment fragment = new ProgressFragment();
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
|
||||
return Progress.root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume(){
|
||||
super.onResume();
|
||||
|
||||
Progress.fragment_on = true;
|
||||
|
||||
List instances = Progress.getInstances();
|
||||
for (Object obj: instances) {
|
||||
Progress p = (Progress) obj;
|
||||
p.showProgress();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause(){
|
||||
super.onPause();
|
||||
|
||||
Progress.fragment_on = false;
|
||||
}
|
||||
}
|
103
app/src/main/java/com/localtransfer/fragment/UploadFragment.java
Normal file
103
app/src/main/java/com/localtransfer/fragment/UploadFragment.java
Normal file
@ -0,0 +1,103 @@
|
||||
package com.localtransfer.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.localtransfer.MainActivity;
|
||||
import com.localtransfer.R;
|
||||
import com.localtransfer.Transfer;
|
||||
import com.localtransfer.TransferService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class UploadFragment extends Fragment {
|
||||
|
||||
public UploadFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
public static UploadFragment newInstance() {
|
||||
UploadFragment fragment = new UploadFragment();
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
final View root = inflater.inflate(R.layout.fragment_upload, container, false);
|
||||
|
||||
Button upload = (Button) root.findViewById(R.id.upload);
|
||||
upload.setOnClickListener(v -> selectFile());
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public static final int REQUEST_ID_CHOOSE_FILES = 2002;
|
||||
|
||||
private void selectFile() {
|
||||
Intent intent = new Intent()
|
||||
.setType("*/*")
|
||||
.setAction(Intent.ACTION_GET_CONTENT)
|
||||
.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
|
||||
|
||||
startActivityForResult(Intent.createChooser(intent, "Select a file"), REQUEST_ID_CHOOSE_FILES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
Log.d("RequestCode", String.valueOf(requestCode));
|
||||
if (requestCode == REQUEST_ID_CHOOSE_FILES && resultCode == Activity.RESULT_OK) {
|
||||
String type = data.getType();
|
||||
|
||||
ViewPager viewPager = getActivity().findViewById(R.id.view_pager);
|
||||
viewPager.setCurrentItem(2);
|
||||
|
||||
Transfer tr = new Transfer();
|
||||
|
||||
if (type != null) {
|
||||
String sharedText = data.getStringExtra(Intent.EXTRA_TEXT);
|
||||
tr.handleSendText(sharedText);
|
||||
}
|
||||
else {
|
||||
ArrayList<Uri> fileUris = new ArrayList<>();
|
||||
if (data.getClipData() != null) { // Checking for selection multiple files
|
||||
int nbItem = data.getClipData().getItemCount();
|
||||
Toast.makeText(getContext(), "You select " + nbItem + " files", Toast.LENGTH_SHORT).show();
|
||||
for (int i = 0; i < nbItem; i++) {
|
||||
Uri uri = data.getClipData().getItemAt(i).getUri();
|
||||
fileUris.add(uri);
|
||||
}
|
||||
} else {
|
||||
Uri uri = data.getData(); //The uri with the location of the file
|
||||
fileUris.add(uri);
|
||||
}
|
||||
for (Uri uri : fileUris) {
|
||||
Intent intent = new Intent(getActivity(), TransferService.class);
|
||||
intent.setAction(TransferService.ACTION_UPLOAD);
|
||||
intent.putExtra(TransferService.EXTRA_URI, uri);
|
||||
getActivity().startService(intent);
|
||||
//tr.handleSendFile(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user