mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2025-09-02 19:07:55 +00:00
Merge branch 'dev' into Merge-dev-to-refactor
# Conflicts: # app/src/main/AndroidManifest.xml
This commit is contained in:
@@ -435,6 +435,7 @@
|
||||
</activity>
|
||||
<service
|
||||
android:name=".RouterActivity$FetcherService"
|
||||
android:foregroundServiceType="dataSync"
|
||||
android:exported="false" />
|
||||
|
||||
<!-- opting out of sending metrics to Google in Android System WebView -->
|
||||
|
@@ -1,6 +1,8 @@
|
||||
package org.schabi.newpipe.local.feed.notifications
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.ServiceInfo
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.work.Constraints
|
||||
@@ -83,7 +85,9 @@ class NotificationWorker(
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
.setContentTitle(applicationContext.getString(R.string.feed_notification_loading))
|
||||
.build()
|
||||
setForegroundAsync(ForegroundInfo(FeedLoadService.NOTIFICATION_ID, notification))
|
||||
// ServiceInfo constants are not used below Android Q, so 0 is set here
|
||||
val serviceType = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC else 0
|
||||
setForegroundAsync(ForegroundInfo(FeedLoadService.NOTIFICATION_ID, notification, serviceType))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@@ -167,19 +167,17 @@ public final class NotificationUtil {
|
||||
&& notificationBuilder.mActions.get(2).actionIntent != null);
|
||||
}
|
||||
|
||||
|
||||
public void createNotificationAndStartForeground() {
|
||||
if (notificationBuilder == null) {
|
||||
notificationBuilder = createNotification();
|
||||
}
|
||||
updateNotification();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
player.getService().startForeground(NOTIFICATION_ID, notificationBuilder.build(),
|
||||
ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK);
|
||||
} else {
|
||||
player.getService().startForeground(NOTIFICATION_ID, notificationBuilder.build());
|
||||
}
|
||||
// ServiceInfo constants are not used below Android Q, so 0 is set here
|
||||
final int serviceType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|
||||
? ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK : 0;
|
||||
ServiceCompat.startForeground(player.getService(), NOTIFICATION_ID,
|
||||
notificationBuilder.build(), serviceType);
|
||||
}
|
||||
|
||||
public void cancelNotificationAndStopForeground() {
|
||||
|
@@ -9,9 +9,11 @@ import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.text.Html;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
@@ -113,14 +115,47 @@ public final class PermissionHelper {
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
public static boolean checkSystemAlertWindowPermission(final Context context) {
|
||||
if (!Settings.canDrawOverlays(context)) {
|
||||
final Intent i = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
|
||||
Uri.parse("package:" + context.getPackageName()));
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
try {
|
||||
context.startActivity(i);
|
||||
} catch (final ActivityNotFoundException ignored) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
|
||||
final Intent i = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
|
||||
Uri.parse("package:" + context.getPackageName()));
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
try {
|
||||
context.startActivity(i);
|
||||
} catch (final ActivityNotFoundException ignored) {
|
||||
}
|
||||
return false;
|
||||
// from Android R the ACTION_MANAGE_OVERLAY_PERMISSION will only point to the menu,
|
||||
// so let’s add a dialog that points the user to the right setting.
|
||||
} else {
|
||||
final String appName = context.getApplicationInfo()
|
||||
.loadLabel(context.getPackageManager()).toString();
|
||||
final String title = context.getString(R.string.permission_display_over_apps);
|
||||
final String permissionName =
|
||||
context.getString(R.string.permission_display_over_apps_permission_name);
|
||||
final String appNameItalic = "<i>" + appName + "</i>";
|
||||
final String permissionNameItalic = "<i>" + permissionName + "</i>";
|
||||
final String message =
|
||||
context.getString(R.string.permission_display_over_apps_message,
|
||||
appNameItalic,
|
||||
permissionNameItalic
|
||||
);
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(title)
|
||||
.setMessage(Html.fromHtml(message, Html.FROM_HTML_MODE_COMPACT))
|
||||
.setPositiveButton("OK", (dialog, which) -> {
|
||||
// we don’t need the package name here, since it won’t do anything on >R
|
||||
final Intent intent =
|
||||
new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
|
||||
try {
|
||||
context.startActivity(intent);
|
||||
} catch (final ActivityNotFoundException ignored) {
|
||||
}
|
||||
})
|
||||
.setCancelable(true)
|
||||
.show();
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
@@ -265,7 +265,7 @@ public class DownloadManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteMission(Mission mission) {
|
||||
public void deleteMission(Mission mission, boolean alsoDeleteFile) {
|
||||
synchronized (this) {
|
||||
if (mission instanceof DownloadMission) {
|
||||
mMissionsPending.remove(mission);
|
||||
@@ -274,7 +274,9 @@ public class DownloadManager {
|
||||
mFinishedMissionStore.deleteMission(mission);
|
||||
}
|
||||
|
||||
mission.delete();
|
||||
if (alsoDeleteFile) {
|
||||
mission.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -614,7 +614,7 @@ public class MissionAdapter extends Adapter<ViewHolder> implements Handler.Callb
|
||||
while (i.hasNext()) {
|
||||
Mission mission = i.next();
|
||||
if (mission != null) {
|
||||
mDownloadManager.deleteMission(mission);
|
||||
mDownloadManager.deleteMission(mission, true);
|
||||
mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, mission.storage.getUri()));
|
||||
}
|
||||
i.remove();
|
||||
@@ -667,7 +667,14 @@ public class MissionAdapter extends Adapter<ViewHolder> implements Handler.Callb
|
||||
shareFile(h.item.mission);
|
||||
return true;
|
||||
case R.id.delete:
|
||||
mDeleter.append(h.item.mission);
|
||||
// delete the entry and the file
|
||||
mDeleter.append(h.item.mission, true);
|
||||
applyChanges();
|
||||
checkMasterButtonsVisibility();
|
||||
return true;
|
||||
case R.id.delete_entry:
|
||||
// just delete the entry
|
||||
mDeleter.append(h.item.mission, false);
|
||||
applyChanges();
|
||||
checkMasterButtonsVisibility();
|
||||
return true;
|
||||
@@ -676,7 +683,7 @@ public class MissionAdapter extends Adapter<ViewHolder> implements Handler.Callb
|
||||
final StoredFileHelper storage = h.item.mission.storage;
|
||||
if (!storage.existsAsFile()) {
|
||||
Toast.makeText(mContext, R.string.missing_file, Toast.LENGTH_SHORT).show();
|
||||
mDeleter.append(h.item.mission);
|
||||
mDeleter.append(h.item.mission, true);
|
||||
applyChanges();
|
||||
return true;
|
||||
}
|
||||
|
@@ -13,7 +13,9 @@ import com.google.android.material.snackbar.Snackbar;
|
||||
import org.schabi.newpipe.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Optional;
|
||||
|
||||
import kotlin.Pair;
|
||||
import us.shandian.giga.get.FinishedMission;
|
||||
import us.shandian.giga.get.Mission;
|
||||
import us.shandian.giga.service.DownloadManager;
|
||||
@@ -30,7 +32,8 @@ public class Deleter {
|
||||
private static final int DELAY_RESUME = 400;// ms
|
||||
|
||||
private Snackbar snackbar;
|
||||
private ArrayList<Mission> items;
|
||||
// list of missions to be deleted, and whether to also delete the corresponding file
|
||||
private ArrayList<Pair<Mission, Boolean>> items;
|
||||
private boolean running = true;
|
||||
|
||||
private final Context mContext;
|
||||
@@ -51,7 +54,7 @@ public class Deleter {
|
||||
items = new ArrayList<>(2);
|
||||
}
|
||||
|
||||
public void append(Mission item) {
|
||||
public void append(Mission item, boolean alsoDeleteFile) {
|
||||
/* If a mission is removed from the list while the Snackbar for a previously
|
||||
* removed item is still showing, commit the action for the previous item
|
||||
* immediately. This prevents Snackbars from stacking up in reverse order.
|
||||
@@ -60,13 +63,13 @@ public class Deleter {
|
||||
commit();
|
||||
|
||||
mIterator.hide(item);
|
||||
items.add(0, item);
|
||||
items.add(0, new Pair<>(item, alsoDeleteFile));
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
private void forget() {
|
||||
mIterator.unHide(items.remove(0));
|
||||
mIterator.unHide(items.remove(0).getFirst());
|
||||
mAdapter.applyChanges();
|
||||
|
||||
show();
|
||||
@@ -84,7 +87,19 @@ public class Deleter {
|
||||
private void next() {
|
||||
if (items.size() < 1) return;
|
||||
|
||||
String msg = mContext.getString(R.string.file_deleted).concat(":\n").concat(items.get(0).storage.getName());
|
||||
final Optional<String> fileToBeDeleted = items.stream()
|
||||
.filter(Pair::getSecond)
|
||||
.map(p -> p.getFirst().storage.getName())
|
||||
.findFirst();
|
||||
|
||||
String msg;
|
||||
if (fileToBeDeleted.isPresent()) {
|
||||
msg = mContext.getString(R.string.file_deleted)
|
||||
.concat(":\n")
|
||||
.concat(fileToBeDeleted.get());
|
||||
} else {
|
||||
msg = mContext.getString(R.string.entry_deleted);
|
||||
}
|
||||
|
||||
snackbar = Snackbar.make(mView, msg, Snackbar.LENGTH_INDEFINITE);
|
||||
snackbar.setAction(R.string.undo, s -> forget());
|
||||
@@ -98,11 +113,13 @@ public class Deleter {
|
||||
if (items.size() < 1) return;
|
||||
|
||||
while (items.size() > 0) {
|
||||
Mission mission = items.remove(0);
|
||||
Pair<Mission, Boolean> missionAndAlsoDeleteFile = items.remove(0);
|
||||
Mission mission = missionAndAlsoDeleteFile.getFirst();
|
||||
boolean alsoDeleteFile = missionAndAlsoDeleteFile.getSecond();
|
||||
if (mission.deleted) continue;
|
||||
|
||||
mIterator.unHide(mission);
|
||||
mDownloadManager.deleteMission(mission);
|
||||
mDownloadManager.deleteMission(mission, alsoDeleteFile);
|
||||
|
||||
if (mission instanceof FinishedMission) {
|
||||
mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, mission.storage.getUri()));
|
||||
@@ -137,7 +154,11 @@ public class Deleter {
|
||||
|
||||
pause();
|
||||
|
||||
for (Mission mission : items) mDownloadManager.deleteMission(mission);
|
||||
for (Pair<Mission, Boolean> missionAndAlsoDeleteFile : items) {
|
||||
Mission mission = missionAndAlsoDeleteFile.getFirst();
|
||||
boolean alsoDeleteFile = missionAndAlsoDeleteFile.getSecond();
|
||||
mDownloadManager.deleteMission(mission, alsoDeleteFile);
|
||||
}
|
||||
items = null;
|
||||
}
|
||||
}
|
||||
|
@@ -27,7 +27,11 @@
|
||||
|
||||
<item
|
||||
android:id="@+id/delete"
|
||||
android:title="@string/delete" />
|
||||
android:title="@string/delete_file" />
|
||||
|
||||
<item
|
||||
android:id="@+id/delete_entry"
|
||||
android:title="@string/delete_entry" />
|
||||
|
||||
<item
|
||||
android:id="@+id/error_message_view"
|
||||
|
@@ -257,6 +257,8 @@
|
||||
<string name="restore_defaults">Restore defaults</string>
|
||||
<string name="restore_defaults_confirmation">Do you want to restore defaults?</string>
|
||||
<string name="permission_display_over_apps">Give permission to display over other apps</string>
|
||||
<string name="permission_display_over_apps_message">In order to use the Popup Player, please select %1$s in the following Android settings menu and enable %2$s.</string>
|
||||
<string name="permission_display_over_apps_permission_name">“Allow display over other apps”</string>
|
||||
<!-- error activity -->
|
||||
<string name="error_report_notification_title">NewPipe encountered an error, tap to report</string>
|
||||
<string name="error_report_notification_toast">An error occurred, see the notification</string>
|
||||
@@ -333,6 +335,8 @@
|
||||
<string name="pause">Pause</string>
|
||||
<string name="create">Create</string>
|
||||
<string name="delete">Delete</string>
|
||||
<string name="delete_file">Delete file</string>
|
||||
<string name="delete_entry">Delete entry</string>
|
||||
<string name="checksum">Checksum</string>
|
||||
<string name="dismiss">Dismiss</string>
|
||||
<string name="rename">Rename</string>
|
||||
@@ -889,4 +893,5 @@
|
||||
<string name="trending_podcasts">Trending podcasts</string>
|
||||
<string name="trending_movies">Trending movies and shows</string>
|
||||
<string name="trending_music">Trending music</string>
|
||||
<string name="entry_deleted">Entry deleted</string>
|
||||
</resources>
|
||||
|
Reference in New Issue
Block a user