From 0ca90d17a3e8ba9ef299dc8b8dc962eaef1f1b39 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Denis=20=C3=87erri?=
<64997243+deniscerri@users.noreply.github.com>
Date: Sat, 15 Oct 2022 23:23:20 +0200
Subject: [PATCH] added cancel button on download notification
and fixed servive bugs when app was killed and reopened
---
app/src/main/AndroidManifest.xml | 1 +
.../deniscerri/ytdlnis/DownloaderService.java | 8 ++-
.../com/deniscerri/ytdlnis/MainActivity.java | 30 +++++++---
.../ytdlnis/page/DownloadsFragment.java | 41 +++++++++++--
.../deniscerri/ytdlnis/page/HomeFragment.java | 29 +++++----
.../receiver/NotificationReceiver.java | 59 +++++++++++++++++++
.../ytdlnis/util/NotificationUtil.java | 14 +++++
7 files changed, 154 insertions(+), 28 deletions(-)
create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/receiver/NotificationReceiver.java
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 44deca19..3b56dea1 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,6 +49,7 @@
android:name=".DownloaderService"
android:enabled="true"
android:exported="false" />
+
\ No newline at end of file
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/DownloaderService.java b/app/src/main/java/com/deniscerri/ytdlnis/DownloaderService.java
index 79700225..95873812 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/DownloaderService.java
+++ b/app/src/main/java/com/deniscerri/ytdlnis/DownloaderService.java
@@ -124,10 +124,10 @@ public class DownloaderService extends Service {
@Override
- public boolean onUnbind(Intent intent) {
+ public void onDestroy() {
+ super.onDestroy();
stopForeground(true);
stopSelf();
- return super.onUnbind(intent);
}
public class LocalBinder extends Binder implements IDownloaderService {
@@ -171,7 +171,9 @@ public class DownloaderService extends Service {
YoutubeDL.getInstance().destroyProcessById(downloadProcessID);
compositeDisposable.clear();
//stopForeground(true);
- if (cancelAll) onDownloadCancelAll();
+ if (cancelAll) {
+ onDownloadCancelAll();
+ }
}catch(Exception err){
Log.e(TAG, err.getMessage());
}
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.java b/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.java
index b990a5aa..9623951c 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.java
+++ b/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.java
@@ -131,6 +131,17 @@ public class MainActivity extends AppCompatActivity{
handleIntents(intent);
}
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ try {
+ iDownloaderService.removeActivity(this);
+ context.getApplicationContext().unbindService(serviceConnection);
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
@@ -181,6 +192,7 @@ public class MainActivity extends AppCompatActivity{
if(!listeners.contains(awaitingListener)) listeners.add(awaitingListener);
Intent serviceIntent = new Intent(context, DownloaderService.class);
serviceIntent.putParcelableArrayListExtra("queue", downloadQueue);
+ context.getApplicationContext().startService(serviceIntent);
context.getApplicationContext().bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
@@ -195,6 +207,7 @@ public class MainActivity extends AppCompatActivity{
dbManager.addToHistory(v);
}
dbManager.close();
+ downloadsFragment.setDownloading(true);
downloadsFragment.initCards();
}
} catch (Exception e) {
@@ -204,12 +217,11 @@ public class MainActivity extends AppCompatActivity{
public void stopDownloadService(){
if(!isDownloadServiceRunning) return;
- iDownloaderService.removeActivity(this);
- context.getApplicationContext().unbindService(serviceConnection);
- downloaderService.stopForeground(true);
- downloaderService.stopSelf();
- NotificationUtil notificationUtil = new NotificationUtil(context.getApplicationContext());
- notificationUtil.cancelDownloadNotification(NotificationUtil.DOWNLOAD_NOTIFICATION_ID);
+ try {
+ iDownloaderService.removeActivity(this);
+ context.getApplicationContext().unbindService(serviceConnection);
+ context.getApplicationContext().stopService(new Intent(context.getApplicationContext(), DownloaderService.class));
+ }catch (Exception ignored){}
isDownloadServiceRunning = false;
}
@@ -226,8 +238,10 @@ public class MainActivity extends AppCompatActivity{
public boolean isDownloadServiceRunning() {
ActivityManager.RunningServiceInfo service = getService(DownloaderService.class);
if(service != null){
- isDownloadServiceRunning = true;
- return true;
+ if (service.foreground) {
+ isDownloadServiceRunning = true;
+ return true;
+ }
}
return false;
}
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/page/DownloadsFragment.java b/app/src/main/java/com/deniscerri/ytdlnis/page/DownloadsFragment.java
index f7ec3e71..817d37b2 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/page/DownloadsFragment.java
+++ b/app/src/main/java/com/deniscerri/ytdlnis/page/DownloadsFragment.java
@@ -56,7 +56,7 @@ import java.util.Locale;
* A fragment representing a list of Items.
*/
public class DownloadsFragment extends Fragment implements DownloadsRecyclerViewAdapter.OnItemClickListener, View.OnClickListener{
-
+ private boolean downloading = false;
private View fragmentView;
private DBManager dbManager;
Context context;
@@ -93,6 +93,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
progressBar = fragmentView.findViewWithTag(v.getURL()+v.getDownloadedType()+"##progress");
}
}catch(Exception ignored){}
+ downloading = true;
}
public void onDownloadProgress(DownloadInfo info) {
@@ -116,6 +117,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
dbManager = new DBManager(context);
dbManager.clearHistoryItem(v, false);
downloadsRecyclerViewAdapter.notifyItemRemoved(position);
+ downloading = false;
}catch(Exception ignored){}
}
@@ -171,6 +173,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
dbManager.close();
downloadsRecyclerViewAdapter.notifyItemChanged(downloadsObjects.indexOf(item));
} catch (Exception ignored) {}
+ downloading = false;
}catch(Exception ignored){}
}
@@ -182,16 +185,41 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
downloadsObjects.remove(v);
dbManager = new DBManager(context);
dbManager.clearHistoryItem(v,false);
+ dbManager.close();
downloadsRecyclerViewAdapter.setVideoList(downloadsObjects);
+
+ if (downloadsObjects.isEmpty()) initCards();
+ downloading = false;
}catch (Exception ignored){}
}
@Override
- public void onDownloadCancelAll(DownloadInfo downloadInfo){}
+ public void onDownloadCancelAll(DownloadInfo downloadInfo){
+ try {
+ dbManager = new DBManager(context);
+ while (downloadsObjects.size() > 0){
+ Video v = downloadsObjects.get(0);
+ if (v.isQueuedDownload()){
+ dbManager.clearHistoryItem(v, false);
+ downloadsObjects.remove(v);
+ downloadsRecyclerViewAdapter.setVideoList(downloadsObjects);
+ }else{
+ break;
+ }
+ }
+ dbManager.close();
+ if (downloadsObjects.isEmpty()) initCards();
+ downloading = false;
+ }catch (Exception ignored){}
+ }
public void onDownloadServiceEnd() {}
};
+ public void setDownloading(boolean d){
+ downloading = d;
+ }
+
public DownloadsFragment() {
}
@@ -226,9 +254,8 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
selectionChips = fragmentView.findViewById(R.id.downloads_selection_chips);
websiteGroup = fragmentView.findViewById(R.id.website_chip_group);
uiHandler = new Handler(Looper.getMainLooper());
-
- dbManager = new DBManager(context);
downloadsObjects = new ArrayList<>();
+ downloading = mainActivity.isDownloadServiceRunning();
recyclerView = fragmentView.findViewById(R.id.recycler_view_downloads);
downloadsRecyclerViewAdapter = new DownloadsRecyclerViewAdapter(downloadsObjects, this, activity);
@@ -247,8 +274,11 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
downloadsRecyclerViewAdapter.clear();
no_results.setVisibility(View.GONE);
selectionChips.setVisibility(View.VISIBLE);
+
+ dbManager = new DBManager(context);
try{
Thread thread = new Thread(() -> {
+ if (!downloading) dbManager.clearDownloadingHistory();
downloadsObjects = dbManager.getHistory("", format,website,sort);
uiHandler.post(() -> {
downloadsRecyclerViewAdapter.setVideoList(downloadsObjects);
@@ -264,6 +294,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
websiteGroup.removeAllViews();
});
}
+ dbManager.close();
});
thread.start();
}catch(Exception e){
@@ -297,6 +328,8 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
searchView.setInputType(InputType.TYPE_CLASS_TEXT);
searchView.setQueryHint(getString(R.string.search_history_hint));
+ dbManager = new DBManager(context);
+
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/page/HomeFragment.java b/app/src/main/java/com/deniscerri/ytdlnis/page/HomeFragment.java
index 61efa505..aaa8b37d 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/page/HomeFragment.java
+++ b/app/src/main/java/com/deniscerri/ytdlnis/page/HomeFragment.java
@@ -179,7 +179,9 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
downloading = false;
topAppBar.getMenu().findItem(R.id.cancel_download).setVisible(false);
- }catch(Exception ignored){}
+ }catch(Exception e){
+ e.printStackTrace();
+ }
}
@@ -257,9 +259,9 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
homeRecyclerViewAdapter.clear();
shimmerCards.startShimmer();
shimmerCards.setVisibility(View.VISIBLE);
+ Handler uiHandler = new Handler(Looper.getMainLooper());
try {
Thread thread = new Thread(() -> {
- Handler uiHandler = new Handler(Looper.getMainLooper());
dbManager = new DBManager(context);
resultObjects = dbManager.getResults();
String playlistTitle = "";
@@ -272,12 +274,6 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
resultObjects = infoUtil.getTrending(context);
dbManager.addToResults(resultObjects);
- uiHandler.post(() -> {
- homeRecyclerViewAdapter.setVideoList(resultObjects, true);
- shimmerCards.stopShimmer();
- shimmerCards.setVisibility(View.GONE);
- });
-
} catch (Exception e) {
Log.e(TAG, e.toString());
}
@@ -291,12 +287,15 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
updateDownloadingStatusOnResult(tmp, "video", false);
}
}
- uiHandler.post(() -> {
- shimmerCards.stopShimmer();
- shimmerCards.setVisibility(View.GONE);
- });
}
}
+
+ uiHandler.post(() -> {
+ homeRecyclerViewAdapter.setVideoList(resultObjects, true);
+ shimmerCards.stopShimmer();
+ shimmerCards.setVisibility(View.GONE);
+ });
+
dbManager.close();
if (resultObjects != null) {
uiHandler.post(this::scrollToTop);
@@ -308,6 +307,10 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
thread.start();
} catch (Exception e) {
Log.e(TAG, e.toString());
+ uiHandler.post(() -> {
+ shimmerCards.stopShimmer();
+ shimmerCards.setVisibility(View.GONE);
+ });
}
}
@@ -328,7 +331,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
}
};
- if(mainActivity.isDownloadServiceRunning()){
+ if(downloading){
topAppBar.getMenu().findItem(R.id.cancel_download).setVisible(true);
}
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/receiver/NotificationReceiver.java b/app/src/main/java/com/deniscerri/ytdlnis/receiver/NotificationReceiver.java
new file mode 100644
index 00000000..800aa158
--- /dev/null
+++ b/app/src/main/java/com/deniscerri/ytdlnis/receiver/NotificationReceiver.java
@@ -0,0 +1,59 @@
+package com.deniscerri.ytdlnis.receiver;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import com.deniscerri.ytdlnis.DownloaderService;
+import com.deniscerri.ytdlnis.MainActivity;
+import com.deniscerri.ytdlnis.service.IDownloaderListener;
+import com.deniscerri.ytdlnis.service.IDownloaderService;
+import com.deniscerri.ytdlnis.util.NotificationUtil;
+
+import java.util.ArrayList;
+
+public class NotificationReceiver extends BroadcastReceiver {
+
+ public DownloaderService downloaderService;
+ private ArrayList listeners = null;
+ private IDownloaderService iDownloaderService;
+ private Context context;
+
+ private final ServiceConnection serviceConnection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ downloaderService = ((DownloaderService.LocalBinder) service).getService();
+ iDownloaderService = (IDownloaderService) service;
+ cancelDownload();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName componentName) {
+ downloaderService = null;
+ iDownloaderService = null;
+ }
+ };
+
+
+ @Override
+ public void onReceive(Context c, Intent intent) {
+ context = c;
+ String message = intent.getStringExtra("cancel");
+ if (message != null){
+ Intent serviceIntent = new Intent(context.getApplicationContext(), DownloaderService.class);
+ serviceIntent.putExtra("rebind", true);
+ context.getApplicationContext().bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
+ }
+ }
+
+ private void cancelDownload(){
+ try {
+ iDownloaderService.cancelDownload(true);
+ context.getApplicationContext().unbindService(serviceConnection);
+ context.getApplicationContext().stopService(new Intent(context.getApplicationContext(), DownloaderService.class));
+ }catch (Exception ignored){}
+ }
+
+}
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/util/NotificationUtil.java b/app/src/main/java/com/deniscerri/ytdlnis/util/NotificationUtil.java
index ab463462..868e6520 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/util/NotificationUtil.java
+++ b/app/src/main/java/com/deniscerri/ytdlnis/util/NotificationUtil.java
@@ -5,12 +5,14 @@ import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
+import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Build;
import androidx.core.app.NotificationCompat;
import com.deniscerri.ytdlnis.R;
+import com.deniscerri.ytdlnis.receiver.NotificationReceiver;
public class NotificationUtil {
Context context;
@@ -53,6 +55,16 @@ public class NotificationUtil {
}
public Notification createDownloadServiceNotification(PendingIntent pendingIntent, String title){
+ Intent intent = new Intent(context, NotificationReceiver.class);
+ intent.putExtra("cancel", "");
+
+ PendingIntent cancelNotificationPendingIntent = PendingIntent.getBroadcast(
+ context,
+ 0,
+ intent,
+ PendingIntent.FLAG_IMMUTABLE
+ );
+
Notification notification = notificationBuilder
.setContentTitle(title)
.setOngoing(true)
@@ -65,6 +77,8 @@ public class NotificationUtil {
.setProgress(PROGRESS_MAX, PROGRESS_CURR, false)
.setContentIntent(pendingIntent)
.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE)
+ .clearActions()
+ .addAction(0, context.getString(R.string.cancel), cancelNotificationPendingIntent)
.build();
return notification;