diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java index a242a14d..20fa5d2c 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java @@ -9,6 +9,7 @@ import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.design.widget.FloatingActionButton; @@ -50,6 +51,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Locale; +import java.util.UUID; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseActivity; @@ -153,9 +155,6 @@ public class UploadActivity extends BaseActivity { progressBar = findViewById(R.id.progressBar); - /*uploadsReceiver.setDelegate(uploadDelegate); - uploadsReceiver.provideStorage(storage);*/ - findViewById(R.id.upload_outer_scrollview).setVerticalScrollBarEnabled(false); categoriesSpinners = findViewById(R.id.upload_spinners); rootCategorySpinner = findViewById(R.id.upload_spinner_category_root); @@ -388,36 +387,11 @@ public class UploadActivity extends BaseActivity { uploadTitleText, uploadDescriptionText[0], fileIcon, uploaderProfileIndex).execute(filesListArray); finish(); + return; } - Intent retryIntent = new Intent(this, UploadsReceiver.class); - retryIntent.setAction(UploadsReceiver.ACTION_RETRY_UPLOAD); - - Intent cancelIntent = new Intent(this, UploadsReceiver.class); - cancelIntent.setAction(UploadsReceiver.ACTION_CANCEL_UPLOAD); - - UploadNotificationConfig uploadNotificationConfig = new UploadNotificationConfig(); - uploadNotificationConfig.setIconForAllStatuses(android.R.drawable.stat_sys_upload); - - uploadNotificationConfig.getProgress().iconResourceID = android.R.drawable.stat_sys_upload; - uploadNotificationConfig.getCompleted().iconResourceID = android.R.drawable.stat_sys_upload_done; - uploadNotificationConfig.getError().iconResourceID = android.R.drawable.stat_sys_upload_done; - uploadNotificationConfig.getError().iconColorResourceID = R.color.error_red; - - uploadNotificationConfig.getProgress().actions.add(new UploadNotificationAction( - R.drawable.ic_cancel_accent_24dp, - this.getString(R.string.upload_notification_cancel), - PendingIntent.getBroadcast(this, 0, cancelIntent, - PendingIntent.FLAG_UPDATE_CURRENT) - )); - uploadNotificationConfig.getError().actions.add(new UploadNotificationAction( - R.drawable.ic_cached_accent_24dp, - this.getString(R.string.upload_notification_retry), - PendingIntent.getBroadcast(this, 0, retryIntent, - PendingIntent.FLAG_UPDATE_CURRENT) - )); - - if (uploadFile(this, uploadNotificationConfig, categorySelected, + String uploadID = UUID.randomUUID().toString(); + if (uploadFile(this, uploadID, getConfigForUpload(this, uploadID), categorySelected, uploadTitleText, uploadDescriptionText[0], fileIcon, uploaderProfileIndex, tempFileUri == null ? filesList.get(0).getFileUri() @@ -465,15 +439,11 @@ public class UploadActivity extends BaseActivity { protected void onResume() { drawer.setSelection(UPLOAD_ID); super.onResume(); - /*uploadsReceiver.setDelegate(uploadDelegate); - uploadsReceiver.provideStorage(storage); - uploadsReceiver.register(this);*/ } @Override protected void onPause() { super.onPause(); - //uploadsReceiver.unregister(this); } @Override @@ -699,13 +669,56 @@ public class UploadActivity extends BaseActivity { filesListView.setVisibility(View.VISIBLE); } - private static boolean uploadFile(Context context, + private static UploadNotificationConfig getConfigForUpload(Context context, String uploadID) { + UploadNotificationConfig uploadNotificationConfig = new UploadNotificationConfig(); + uploadNotificationConfig.setIconForAllStatuses(android.R.drawable.stat_sys_upload); + + uploadNotificationConfig.getProgress().iconResourceID = android.R.drawable.stat_sys_upload; + uploadNotificationConfig.getCompleted().iconResourceID = android.R.drawable.stat_sys_upload_done; + uploadNotificationConfig.getError().iconResourceID = android.R.drawable.stat_sys_upload_done; + uploadNotificationConfig.getError().iconColorResourceID = R.color.error_red; + uploadNotificationConfig.getCancelled().iconColorResourceID = android.R.drawable.stat_sys_upload_done; + + Intent combinedActionsIntent = new Intent(UploadsReceiver.ACTION_COMBINED_UPLOAD); + //combinedActionsIntent.setAction(UploadsReceiver.ACTION_COMBINED_UPLOAD); + combinedActionsIntent.putExtra(UploadsReceiver.UPLOAD_ID_KEY, uploadID); + + uploadNotificationConfig.setClickIntentForAllStatuses(PendingIntent.getBroadcast(context, + 1, combinedActionsIntent, PendingIntent.FLAG_UPDATE_CURRENT)); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + Intent retryIntent = new Intent(context, UploadsReceiver.class); + retryIntent.setAction(UploadsReceiver.ACTION_RETRY_UPLOAD); + retryIntent.putExtra(UploadsReceiver.UPLOAD_ID_KEY, uploadID); + + Intent cancelIntent = new Intent(context, UploadsReceiver.class); + cancelIntent.setAction(UploadsReceiver.ACTION_CANCEL_UPLOAD); + cancelIntent.putExtra(UploadsReceiver.UPLOAD_ID_KEY, uploadID); + + uploadNotificationConfig.getProgress().actions.add(new UploadNotificationAction( + R.drawable.ic_cancel_accent_24dp, + context.getString(R.string.upload_notification_cancel), + PendingIntent.getBroadcast(context, 0, cancelIntent, + PendingIntent.FLAG_UPDATE_CURRENT) + )); + uploadNotificationConfig.getError().actions.add(new UploadNotificationAction( + R.drawable.ic_notification, + context.getString(R.string.upload_notification_retry), + PendingIntent.getBroadcast(context, 0, retryIntent, + PendingIntent.FLAG_UPDATE_CURRENT) + )); + } + + return uploadNotificationConfig; + } + + private static boolean uploadFile(Context context, String uploadID, UploadNotificationConfig uploadNotificationConfig, String categorySelected, String uploadTitleText, String uploadDescriptionText, String fileIcon, String uploaderProfileIndex, Uri fileUri) { try { - new MultipartUploadRequest(context, uploadIndexUrl) + new MultipartUploadRequest(context, uploadID, uploadIndexUrl) .setUtf8Charset() .setNotificationConfig(uploadNotificationConfig) .addParameter("tp-dluploadtitle", uploadTitleText) @@ -718,6 +731,8 @@ public class UploadActivity extends BaseActivity { .setNotificationConfig(uploadNotificationConfig) .setMaxRetries(2) .startUpload(); + + Toast.makeText(context, "Uploading files in the background.", Toast.LENGTH_SHORT).show(); return true; } catch (Exception exception) { Timber.e(exception, "AndroidUploadService: %s", exception.getMessage()); @@ -992,34 +1007,9 @@ public class UploadActivity extends BaseActivity { return; } - Intent retryIntent = new Intent(weakActivity.get(), UploadsReceiver.class); - retryIntent.setAction(UploadsReceiver.ACTION_RETRY_UPLOAD); - - Intent cancelIntent = new Intent(weakActivity.get(), UploadsReceiver.class); - cancelIntent.setAction(UploadsReceiver.ACTION_CANCEL_UPLOAD); - - UploadNotificationConfig uploadNotificationConfig = new UploadNotificationConfig(); - uploadNotificationConfig.setIconForAllStatuses(android.R.drawable.stat_sys_upload); - - uploadNotificationConfig.getProgress().iconResourceID = android.R.drawable.stat_sys_upload; - uploadNotificationConfig.getCompleted().iconResourceID = android.R.drawable.stat_sys_upload_done; - uploadNotificationConfig.getError().iconResourceID = android.R.drawable.stat_sys_upload_done; - uploadNotificationConfig.getError().iconColorResourceID = R.color.error_red; - - uploadNotificationConfig.getProgress().actions.add(new UploadNotificationAction( - R.drawable.ic_cancel_accent_24dp, - weakActivity.get().getString(R.string.upload_notification_cancel), - PendingIntent.getBroadcast(weakActivity.get(), 0, cancelIntent, - PendingIntent.FLAG_UPDATE_CURRENT) - )); - uploadNotificationConfig.getError().actions.add(new UploadNotificationAction( - R.drawable.ic_cached_accent_24dp, - weakActivity.get().getString(R.string.upload_notification_retry), - PendingIntent.getBroadcast(weakActivity.get(), 0, retryIntent, - PendingIntent.FLAG_UPDATE_CURRENT) - )); - - if (!uploadFile(weakActivity.get(), uploadNotificationConfig, categorySelected, + String uploadID = UUID.randomUUID().toString(); + if (!uploadFile(weakActivity.get(), uploadID, + getConfigForUpload(weakActivity.get(), uploadID), categorySelected, uploadTitleText, uploadDescriptionText, fileIcon, uploaderProfileIndex, zipFileUri)) { Toast.makeText(weakActivity.get(), "Couldn't initiate upload.", Toast.LENGTH_SHORT).show(); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java index b8de8a52..9ec3bc05 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java @@ -19,9 +19,10 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.base.BaseActivity; import timber.log.Timber; -public class UploadFieldsBuilderActivity extends AppCompatActivity { +public class UploadFieldsBuilderActivity extends BaseActivity { static final String BUNDLE_UPLOAD_FIELD_BUILDER_COURSE = "UPLOAD_FIELD_BUILDER_COURSE"; static final String BUNDLE_UPLOAD_FIELD_BUILDER_SEMESTER = "UPLOAD_FIELD_BUILDER_SEMESTER"; @@ -88,7 +89,7 @@ public class UploadFieldsBuilderActivity extends AppCompatActivity { } //Initialize toolbar - Toolbar toolbar = findViewById(R.id.toolbar); + toolbar = findViewById(R.id.toolbar); toolbar.setTitle(R.string.upload_fields_builder_toolbar_title); setSupportActionBar(toolbar); if (getSupportActionBar() != null) { @@ -96,6 +97,9 @@ public class UploadFieldsBuilderActivity extends AppCompatActivity { getSupportActionBar().setDisplayShowHomeEnabled(true); } + createDrawer(); + drawer.setSelection(UPLOAD_ID, false); + semesterChooserLinear = findViewById(R.id.upload_fields_builder_choose_semester); semesterRadio = findViewById(R.id.upload_fields_builder_semester_radio_group); semesterRadio.check(Integer.parseInt(semester) % 2 == 0 diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java index f6f11188..2b7c6c1e 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -3,8 +3,10 @@ package gr.thmmy.mthmmy.base; import android.Manifest; import android.app.ProgressDialog; import android.arch.lifecycle.ViewModelProviders; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.Uri; @@ -15,13 +17,16 @@ import android.support.annotation.NonNull; import android.support.design.widget.BottomSheetDialog; import android.support.v4.content.ContextCompat; import android.support.v4.content.FileProvider; +import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.preference.PreferenceManager; import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.ImageButton; +import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; @@ -36,9 +41,10 @@ import com.mikepenz.materialdrawer.DrawerBuilder; import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; import com.mikepenz.materialdrawer.model.ProfileDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; -import com.mikepenz.materialdrawer.model.interfaces.IProfile; import com.snatik.storage.Storage; +import net.gotev.uploadservice.UploadService; + import java.io.File; import java.util.ArrayList; @@ -54,9 +60,11 @@ import gr.thmmy.mthmmy.activities.upload.UploadActivity; import gr.thmmy.mthmmy.model.Bookmark; import gr.thmmy.mthmmy.model.ThmmyFile; import gr.thmmy.mthmmy.services.DownloadHelper; +import gr.thmmy.mthmmy.services.UploadsReceiver; import gr.thmmy.mthmmy.session.SessionManager; import gr.thmmy.mthmmy.utils.FileUtils; import gr.thmmy.mthmmy.viewmodel.BaseViewModel; +import me.zhanghai.android.materialprogressbar.MaterialProgressBar; import okhttp3.OkHttpClient; import timber.log.Timber; @@ -68,6 +76,7 @@ import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_ import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_USERNAME; import static gr.thmmy.mthmmy.activities.settings.SettingsActivity.DEFAULT_HOME_TAB; import static gr.thmmy.mthmmy.services.DownloadHelper.SAVE_DIR; +import static gr.thmmy.mthmmy.services.UploadsReceiver.UPLOAD_ID_KEY; import static gr.thmmy.mthmmy.session.SessionManager.SUCCESS; import static gr.thmmy.mthmmy.utils.FileUtils.getMimeType; @@ -94,12 +103,16 @@ public abstract class BaseActivity extends AppCompatActivity { //Common UI elements protected Toolbar toolbar; protected Drawer drawer; + //Uploads progress dialog + UploadsShowDialogReceiver uploadsShowDialogReceiver; + AlertDialog uploadsProgressDialog; private MainActivity mainActivity; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + if (client == null) client = BaseApplication.getInstance().getClient(); //must check every time - e.g. @@ -124,6 +137,8 @@ public abstract class BaseActivity extends AppCompatActivity { protected void onResume() { super.onResume(); updateDrawer(); + uploadsShowDialogReceiver = new UploadsShowDialogReceiver(this); + this.registerReceiver(uploadsShowDialogReceiver, new IntentFilter(UploadsReceiver.ACTION_COMBINED_UPLOAD)); } @Override @@ -131,9 +146,11 @@ public abstract class BaseActivity extends AppCompatActivity { super.onPause(); if (drawer != null) //close drawer animation after returning to activity drawer.closeDrawer(); + if (uploadsShowDialogReceiver != null) { + this.unregisterReceiver(uploadsShowDialogReceiver); + } } - public static OkHttpClient getClient() { return client; } @@ -730,6 +747,52 @@ public abstract class BaseActivity extends AppCompatActivity { dialog.show(); } + //------------------------------------------ UPLOADS ------------------------------------------- + private class UploadsShowDialogReceiver extends BroadcastReceiver { + private final Context activityContext; + + UploadsShowDialogReceiver(Context activityContext) { + this.activityContext = activityContext; + } + + @Override + public void onReceive(Context context, Intent intent) { + Bundle intentBundle = intent.getExtras(); + if (intentBundle == null) { + return; + } + + String dialogUploadID = intentBundle.getString(UPLOAD_ID_KEY); + + if (uploadsProgressDialog == null) { + AlertDialog.Builder progressDialogBuilder = new AlertDialog.Builder(activityContext); + LayoutInflater inflater = LayoutInflater.from(activityContext); + LinearLayout progressDialogLayout = (LinearLayout) inflater.inflate(R.layout.dialog_upload_progress, null); + + MaterialProgressBar dialogProgressBar = progressDialogLayout.findViewById(R.id.dialogProgressBar); + dialogProgressBar.setMax(100); + + progressDialogBuilder.setView(progressDialogLayout); + + progressDialogBuilder.setNeutralButton("Resume on background", (progressDialog, progressWhich) -> { + progressDialog.dismiss(); + }); + progressDialogBuilder.setNegativeButton("Cancel", (progressDialog, progressWhich) -> { + UploadService.stopUpload(dialogUploadID); + progressDialog.dismiss(); + }); + + uploadsProgressDialog = progressDialogBuilder.create(); + + UploadsReceiver.setDialogDisplay(uploadsProgressDialog, dialogUploadID); + uploadsProgressDialog.show(); + } else { + UploadsReceiver.setDialogDisplay(uploadsProgressDialog, dialogUploadID); + uploadsProgressDialog.show(); + } + } + } + //----------------------------------MISC---------------------- protected void setMainActivity(MainActivity mainActivity) { this.mainActivity = mainActivity; diff --git a/app/src/main/java/gr/thmmy/mthmmy/services/UploadsReceiver.java b/app/src/main/java/gr/thmmy/mthmmy/services/UploadsReceiver.java index eb98f949..9897ae81 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/services/UploadsReceiver.java +++ b/app/src/main/java/gr/thmmy/mthmmy/services/UploadsReceiver.java @@ -4,6 +4,9 @@ import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.support.v7.app.AlertDialog; +import android.view.Window; +import android.widget.TextView; import android.widget.Toast; import com.snatik.storage.Storage; @@ -13,35 +16,66 @@ import net.gotev.uploadservice.UploadInfo; import net.gotev.uploadservice.UploadService; import net.gotev.uploadservice.UploadServiceBroadcastReceiver; +import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.upload.UploadsHelper; import gr.thmmy.mthmmy.base.BaseApplication; +import me.zhanghai.android.materialprogressbar.MaterialProgressBar; public class UploadsReceiver extends UploadServiceBroadcastReceiver { - public static final String UPLOAD_NOTIFICATION_ID_KEY = "UPLOAD_NOTIFICATION_ID_KEY"; + public static final String UPLOAD_ID_KEY = "UPLOAD_ID_KEY"; + public static final String ACTION_COMBINED_UPLOAD = "ACTION_COMBINED_UPLOAD"; public static final String ACTION_CANCEL_UPLOAD = "ACTION_CANCEL_UPLOAD"; public static final String ACTION_RETRY_UPLOAD = "ACTION_RETRY_UPLOAD"; private Storage storage; + private static AlertDialog uploadProgressDialog; + private static String dialogUploadID; @Override public void onReceive(Context context, Intent intent) { String intentAction = intent.getAction(); Bundle intentBundle = intent.getExtras(); if (intentAction == null || intentBundle == null) { + super.onReceive(context, intent); return; } - if (intentAction.equals(ACTION_CANCEL_UPLOAD)) { - String notificationID = intentBundle.getString(UPLOAD_NOTIFICATION_ID_KEY); - UploadService.stopUpload(notificationID); - } else if (intentAction.equals(ACTION_RETRY_UPLOAD)) { - //TODO + switch (intentAction) { + case ACTION_CANCEL_UPLOAD: + String notificationID = intentBundle.getString(UPLOAD_ID_KEY); + UploadService.stopUpload(notificationID); + break; + case ACTION_RETRY_UPLOAD: + //TODO + break; + default: + super.onReceive(context, intent); + break; } } @Override public void onProgress(Context context, UploadInfo uploadInfo) { + if (uploadProgressDialog != null && uploadProgressDialog.isShowing() && + uploadInfo.getUploadId().equals(dialogUploadID)) { + Window progressWindow = uploadProgressDialog.getWindow(); + if (progressWindow != null) { + MaterialProgressBar dialogProgressBar = progressWindow.findViewById(R.id.dialogProgressBar); + TextView dialogProgressText = progressWindow.findViewById(R.id.dialog_upload_progress_text); + + dialogProgressBar.setProgress(uploadInfo.getProgressPercent()); + dialogProgressText.setText(context.getResources().getString( + R.string.upload_progress_dialog_bytes_uploaded, + (float) uploadInfo.getUploadRate(), + (int) uploadInfo.getUploadedBytes() / 1000, + (int) uploadInfo.getTotalBytes() / 1000)); + } + + if (uploadInfo.getUploadedBytes() == uploadInfo.getTotalBytes()) { + uploadProgressDialog.dismiss(); + } + } } @Override @@ -79,4 +113,10 @@ public class UploadsReceiver extends UploadServiceBroadcastReceiver { notificationManager.cancel(uploadInfo.getNotificationID()); } } + + public static void setDialogDisplay(AlertDialog uploadProgressDialog, + String dialogUploadID) { + UploadsReceiver.uploadProgressDialog = uploadProgressDialog; + UploadsReceiver.dialogUploadID = dialogUploadID; + } } \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_upload_progress.xml b/app/src/main/res/layout/dialog_upload_progress.xml new file mode 100644 index 00000000..18444cb4 --- /dev/null +++ b/app/src/main/res/layout/dialog_upload_progress.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 810c537b..6ce23fc2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -124,6 +124,8 @@ Please follow the filename rules as\ndescribed in this topic.\n \nThis does not rename your local files. + Uploading + Uploading: %1$.2f Kbit/s, %2$d/%3$d KBytes "Cancel" "Retry"