Merge branch 'dev' into pr3178

This commit is contained in:
Stypox 2020-09-08 23:58:10 +02:00
commit a13e6b69e3
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23
81 changed files with 318 additions and 292 deletions

View File

@ -84,7 +84,7 @@ ext {
checkstyleVersion = '8.32' checkstyleVersion = '8.32'
stethoVersion = '1.5.1' stethoVersion = '1.5.1'
leakCanaryVersion = '2.2' leakCanaryVersion = '2.2'
exoPlayerVersion = '2.11.6' exoPlayerVersion = '2.11.8'
androidxLifecycleVersion = '2.2.0' androidxLifecycleVersion = '2.2.0'
androidxRoomVersion = '2.2.5' androidxRoomVersion = '2.2.5'
groupieVersion = '2.8.0' groupieVersion = '2.8.0'
@ -139,7 +139,7 @@ afterEvaluate {
} }
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "frankiesardo:icepick:${icepickVersion}" implementation "frankiesardo:icepick:${icepickVersion}"
kapt "frankiesardo:icepick-processor:${icepickVersion}" kapt "frankiesardo:icepick-processor:${icepickVersion}"
@ -169,7 +169,7 @@ dependencies {
implementation "com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751" implementation "com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751"
implementation "org.jsoup:jsoup:1.13.1" implementation "org.jsoup:jsoup:1.13.1"
implementation "com.squareup.okhttp3:okhttp:3.12.11" implementation "com.squareup.okhttp3:okhttp:3.12.12"
implementation "com.google.android.exoplayer:exoplayer:${exoPlayerVersion}" implementation "com.google.android.exoplayer:exoplayer:${exoPlayerVersion}"
implementation "com.google.android.exoplayer:extension-mediasession:${exoPlayerVersion}" implementation "com.google.android.exoplayer:extension-mediasession:${exoPlayerVersion}"
@ -187,7 +187,6 @@ dependencies {
implementation "androidx.lifecycle:lifecycle-livedata:${androidxLifecycleVersion}" implementation "androidx.lifecycle:lifecycle-livedata:${androidxLifecycleVersion}"
implementation "androidx.lifecycle:lifecycle-viewmodel:${androidxLifecycleVersion}" implementation "androidx.lifecycle:lifecycle-viewmodel:${androidxLifecycleVersion}"
implementation "androidx.lifecycle:lifecycle-extensions:${androidxLifecycleVersion}"
implementation "androidx.room:room-runtime:${androidxRoomVersion}" implementation "androidx.room:room-runtime:${androidxRoomVersion}"
implementation "androidx.room:room-rxjava2:${androidxRoomVersion}" implementation "androidx.room:room-rxjava2:${androidxRoomVersion}"

View File

@ -2,9 +2,9 @@ package org.schabi.newpipe.report;
import android.os.Parcel; import android.os.Parcel;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest; import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;

View File

@ -300,8 +300,8 @@ public abstract class FragmentStatePagerAdapterMenuWorkaround extends PagerAdapt
mSavedState.clear(); mSavedState.clear();
mFragments.clear(); mFragments.clear();
if (fss != null) { if (fss != null) {
for (int i = 0; i < fss.length; i++) { for (final Parcelable parcelable : fss) {
mSavedState.add((Fragment.SavedState) fss[i]); mSavedState.add((Fragment.SavedState) parcelable);
} }
} }
final Iterable<String> keys = bundle.keySet(); final Iterable<String> keys = bundle.keySet();

View File

@ -220,7 +220,7 @@ public class App extends Application {
} }
public void initNotificationChannel() { public void initNotificationChannel() {
if (Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
return; return;
} }

View File

@ -11,7 +11,7 @@ import android.content.pm.Signature;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;

View File

@ -2,7 +2,7 @@ package org.schabi.newpipe;
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -114,8 +114,8 @@ public final class DownloaderImpl extends Downloader {
// Necessary because some servers (e.g. Framatube.org) // Necessary because some servers (e.g. Framatube.org)
// don't support the old cipher suites. // don't support the old cipher suites.
// https://github.com/square/okhttp/issues/4053#issuecomment-402579554 // https://github.com/square/okhttp/issues/4053#issuecomment-402579554
final List<CipherSuite> cipherSuites = new ArrayList<>(); final List<CipherSuite> cipherSuites =
cipherSuites.addAll(ConnectionSpec.MODERN_TLS.cipherSuites()); new ArrayList<>(ConnectionSpec.MODERN_TLS.cipherSuites());
cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA); cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA);
cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA); cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
final ConnectionSpec legacyTLS = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) final ConnectionSpec legacyTLS = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)

View File

@ -42,7 +42,7 @@ public class ExitActivity extends Activity {
protected void onCreate(final Bundle savedInstanceState) { protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
finishAndRemoveTask(); finishAndRemoveTask();
} else { } else {
finish(); finish();

View File

@ -4,7 +4,7 @@ import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Resources; import android.content.res.Resources;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader; import com.nostra13.universalimageloader.core.download.BaseImageDownloader;

View File

@ -27,7 +27,7 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;

View File

@ -40,7 +40,7 @@ public class PanicResponderActivity extends Activity {
ExitActivity.exitAndRemoveFromRecentApps(this); ExitActivity.exitAndRemoveFromRecentApps(this);
} }
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
finishAndRemoveTask(); finishAndRemoveTask();
} else { } else {
finish(); finish();

View File

@ -8,7 +8,7 @@ import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.ContextThemeWrapper; import android.view.ContextThemeWrapper;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -492,12 +492,8 @@ public class RouterActivity extends AppCompatActivity {
downloadDialog.setSelectedVideoStream(selectedVideoStreamIndex); downloadDialog.setSelectedVideoStream(selectedVideoStreamIndex);
downloadDialog.show(fm, "downloadDialog"); downloadDialog.show(fm, "downloadDialog");
fm.executePendingTransactions(); fm.executePendingTransactions();
downloadDialog.getDialog().setOnDismissListener(dialog -> { downloadDialog.getDialog().setOnDismissListener(dialog -> finish());
finish(); }, (@NonNull Throwable throwable) -> onError());
});
}, (@NonNull Throwable throwable) -> {
onError();
});
} }
@Override @Override
@ -572,7 +568,7 @@ public class RouterActivity extends AppCompatActivity {
} }
} }
} }
return result.toArray(new String[result.size()]); return result.toArray(new String[0]);
} }
private static class AdapterChoiceItem { private static class AdapterChoiceItem {

View File

@ -167,7 +167,7 @@ public class AboutActivity extends AppCompatActivity {
*/ */
public class SectionsPagerAdapter extends FragmentPagerAdapter { public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(final FragmentManager fm) { public SectionsPagerAdapter(final FragmentManager fm) {
super(fm); super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
} }
@Override @Override

View File

@ -14,13 +14,13 @@ import io.reactivex.Flowable;
@Dao @Dao
public interface BasicDAO<Entity> { public interface BasicDAO<Entity> {
/* Inserts */ /* Inserts */
@Insert(onConflict = OnConflictStrategy.FAIL) @Insert(onConflict = OnConflictStrategy.ABORT)
long insert(Entity entity); long insert(Entity entity);
@Insert(onConflict = OnConflictStrategy.FAIL) @Insert(onConflict = OnConflictStrategy.ABORT)
List<Long> insertAll(Entity... entities); List<Long> insertAll(Entity... entities);
@Insert(onConflict = OnConflictStrategy.FAIL) @Insert(onConflict = OnConflictStrategy.ABORT)
List<Long> insertAll(Collection<Entity> entities); List<Long> insertAll(Collection<Entity> entities);
/* Searches */ /* Searches */

View File

@ -1,6 +1,5 @@
package org.schabi.newpipe.download; package org.schabi.newpipe.download;
import android.app.FragmentTransaction;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.Menu; import android.view.Menu;
@ -11,6 +10,7 @@ import android.view.ViewTreeObserver;
import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.FragmentTransaction;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.DeviceUtils;

View File

@ -10,7 +10,7 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.IBinder; import android.os.IBinder;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -295,7 +295,7 @@ public class DownloadDialog extends DialogFragment
initToolbar(view.findViewById(R.id.toolbar)); initToolbar(view.findViewById(R.id.toolbar));
setupDownloadOptions(); setupDownloadOptions();
prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); prefs = PreferenceManager.getDefaultSharedPreferences(requireContext());
final int threads = prefs.getInt(getString(R.string.default_download_threads), 3); final int threads = prefs.getInt(getString(R.string.default_download_threads), 3);
threadsCountTextView.setText(String.valueOf(threads)); threadsCountTextView.setText(String.valueOf(threads));
@ -516,7 +516,23 @@ public class DownloadDialog extends DialogFragment
videoButton.setVisibility(isVideoStreamsAvailable ? View.VISIBLE : View.GONE); videoButton.setVisibility(isVideoStreamsAvailable ? View.VISIBLE : View.GONE);
subtitleButton.setVisibility(isSubtitleStreamsAvailable ? View.VISIBLE : View.GONE); subtitleButton.setVisibility(isSubtitleStreamsAvailable ? View.VISIBLE : View.GONE);
if (isVideoStreamsAvailable) { prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
final String defaultMedia = prefs.getString(getString(R.string.last_used_download_type),
getString(R.string.last_download_type_video_key));
if (isVideoStreamsAvailable
&& (defaultMedia.equals(getString(R.string.last_download_type_video_key)))) {
videoButton.setChecked(true);
setupVideoSpinner();
} else if (isAudioStreamsAvailable
&& (defaultMedia.equals(getString(R.string.last_download_type_audio_key)))) {
audioButton.setChecked(true);
setupAudioSpinner();
} else if (isSubtitleStreamsAvailable
&& (defaultMedia.equals(getString(R.string.last_download_type_subtitle_key)))) {
subtitleButton.setChecked(true);
setupSubtitleSpinner();
} else if (isVideoStreamsAvailable) {
videoButton.setChecked(true); videoButton.setChecked(true);
setupVideoSpinner(); setupVideoSpinner();
} else if (isAudioStreamsAvailable) { } else if (isAudioStreamsAvailable) {
@ -595,6 +611,7 @@ public class DownloadDialog extends DialogFragment
final StoredDirectoryHelper mainStorage; final StoredDirectoryHelper mainStorage;
final MediaFormat format; final MediaFormat format;
final String mime; final String mime;
final String selectedMediaType;
// first, build the filename and get the output folder (if possible) // first, build the filename and get the output folder (if possible)
// later, run a very very very large file checking logic // later, run a very very very large file checking logic
@ -603,6 +620,7 @@ public class DownloadDialog extends DialogFragment
switch (radioStreamsGroup.getCheckedRadioButtonId()) { switch (radioStreamsGroup.getCheckedRadioButtonId()) {
case R.id.audio_button: case R.id.audio_button:
selectedMediaType = getString(R.string.last_download_type_audio_key);
mainStorage = mainStorageAudio; mainStorage = mainStorageAudio;
format = audioStreamsAdapter.getItem(selectedAudioIndex).getFormat(); format = audioStreamsAdapter.getItem(selectedAudioIndex).getFormat();
switch (format) { switch (format) {
@ -617,12 +635,14 @@ public class DownloadDialog extends DialogFragment
} }
break; break;
case R.id.video_button: case R.id.video_button:
selectedMediaType = getString(R.string.last_download_type_video_key);
mainStorage = mainStorageVideo; mainStorage = mainStorageVideo;
format = videoStreamsAdapter.getItem(selectedVideoIndex).getFormat(); format = videoStreamsAdapter.getItem(selectedVideoIndex).getFormat();
mime = format.mimeType; mime = format.mimeType;
filename += format.suffix; filename += format.suffix;
break; break;
case R.id.subtitle_button: case R.id.subtitle_button:
selectedMediaType = getString(R.string.last_download_type_subtitle_key);
mainStorage = mainStorageVideo; // subtitle & video files go together mainStorage = mainStorageVideo; // subtitle & video files go together
format = subtitleStreamsAdapter.getItem(selectedSubtitleIndex).getFormat(); format = subtitleStreamsAdapter.getItem(selectedSubtitleIndex).getFormat();
mime = format.mimeType; mime = format.mimeType;
@ -664,6 +684,11 @@ public class DownloadDialog extends DialogFragment
// check for existing file with the same name // check for existing file with the same name
checkSelectedDownload(mainStorage, mainStorage.findFile(filename), filename, mime); checkSelectedDownload(mainStorage, mainStorage.findFile(filename), filename, mime);
// remember the last media type downloaded by the user
prefs.edit()
.putString(getString(R.string.last_used_download_type), selectedMediaType)
.apply();
} }
private void checkSelectedDownload(final StoredDirectoryHelper mainStorage, private void checkSelectedDownload(final StoredDirectoryHelper mainStorage,

View File

@ -3,7 +3,7 @@ package org.schabi.newpipe.fragments;
import android.content.Context; import android.content.Context;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
@ -74,7 +74,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
youtubeRestrictedModeEnabledKey = getString(R.string.youtube_restricted_mode_enabled); youtubeRestrictedModeEnabledKey = getString(R.string.youtube_restricted_mode_enabled);
previousYoutubeRestrictedModeEnabled = previousYoutubeRestrictedModeEnabled =
PreferenceManager.getDefaultSharedPreferences(getContext()) PreferenceManager.getDefaultSharedPreferences(requireContext())
.getBoolean(youtubeRestrictedModeEnabledKey, false); .getBoolean(youtubeRestrictedModeEnabledKey, false);
} }
@ -105,7 +105,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
super.onResume(); super.onResume();
final boolean youtubeRestrictedModeEnabled = final boolean youtubeRestrictedModeEnabled =
PreferenceManager.getDefaultSharedPreferences(getContext()) PreferenceManager.getDefaultSharedPreferences(requireContext())
.getBoolean(youtubeRestrictedModeEnabledKey, false); .getBoolean(youtubeRestrictedModeEnabledKey, false);
if (previousYoutubeRestrictedModeEnabled != youtubeRestrictedModeEnabled) { if (previousYoutubeRestrictedModeEnabled != youtubeRestrictedModeEnabled) {
previousYoutubeRestrictedModeEnabled = youtubeRestrictedModeEnabled; previousYoutubeRestrictedModeEnabled = youtubeRestrictedModeEnabled;

View File

@ -2,6 +2,7 @@ package org.schabi.newpipe.fragments.detail;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
@ -10,16 +11,20 @@ import androidx.fragment.app.FragmentPagerAdapter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class TabAdaptor extends FragmentPagerAdapter { public class TabAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>(); private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>(); private final List<String> mFragmentTitleList = new ArrayList<>();
private final FragmentManager fragmentManager; private final FragmentManager fragmentManager;
public TabAdaptor(final FragmentManager fm) { public TabAdapter(final FragmentManager fm) {
super(fm); // if changed to BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT => crash if enqueueing stream in
// the background and then clicking on it to open VideoDetailFragment:
// "Cannot setMaxLifecycle for Fragment not attached to FragmentManager"
super(fm, BEHAVIOR_SET_USER_VISIBLE_HINT);
this.fragmentManager = fm; this.fragmentManager = fm;
} }
@NonNull
@Override @Override
public Fragment getItem(final int position) { public Fragment getItem(final int position) {
return mFragmentList.get(position); return mFragmentList.get(position);
@ -57,7 +62,7 @@ public class TabAdaptor extends FragmentPagerAdapter {
} }
@Override @Override
public int getItemPosition(final Object object) { public int getItemPosition(@NonNull final Object object) {
if (mFragmentList.contains(object)) { if (mFragmentList.contains(object)) {
return mFragmentList.indexOf(object); return mFragmentList.indexOf(object);
} else { } else {
@ -82,7 +87,9 @@ public class TabAdaptor extends FragmentPagerAdapter {
} }
@Override @Override
public void destroyItem(final ViewGroup container, final int position, final Object object) { public void destroyItem(@NonNull final ViewGroup container,
final int position,
@NonNull final Object object) {
fragmentManager.beginTransaction().remove((Fragment) object).commitNowAllowingStateLoss(); fragmentManager.beginTransaction().remove((Fragment) object).commitNowAllowingStateLoss();
} }

View File

@ -16,9 +16,9 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.preference.PreferenceManager; import androidx.core.text.HtmlCompat;
import androidx.preference.PreferenceManager;
import android.provider.Settings; import android.provider.Settings;
import android.text.Html;
import android.text.Spanned; import android.text.Spanned;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.util.Linkify; import android.text.util.Linkify;
@ -244,7 +244,7 @@ public class VideoDetailFragment
private AppBarLayout appBarLayout; private AppBarLayout appBarLayout;
private ViewPager viewPager; private ViewPager viewPager;
private TabAdaptor pageAdapter; private TabAdapter pageAdapter;
private TabLayout tabLayout; private TabLayout tabLayout;
private FrameLayout relatedStreamsLayout; private FrameLayout relatedStreamsLayout;
@ -337,6 +337,7 @@ public class VideoDetailFragment
stopPlayerListener(); stopPlayerListener();
playerService = null; playerService = null;
player = null; player = null;
saveCurrentAndRestoreDefaultBrightness();
} }
} }
@ -425,8 +426,8 @@ public class VideoDetailFragment
if (currentWorker != null) { if (currentWorker != null) {
currentWorker.dispose(); currentWorker.dispose();
} }
setupBrightness(true); saveCurrentAndRestoreDefaultBrightness();
PreferenceManager.getDefaultSharedPreferences(getContext()) PreferenceManager.getDefaultSharedPreferences(requireContext())
.edit() .edit()
.putString(getString(R.string.stream_info_selected_tab_key), .putString(getString(R.string.stream_info_selected_tab_key),
pageAdapter.getItemTitle(viewPager.getCurrentItem())) pageAdapter.getItemTitle(viewPager.getCurrentItem()))
@ -439,7 +440,7 @@ public class VideoDetailFragment
activity.sendBroadcast(new Intent(ACTION_VIDEO_FRAGMENT_RESUMED)); activity.sendBroadcast(new Intent(ACTION_VIDEO_FRAGMENT_RESUMED));
setupBrightness(false); setupBrightness();
if (updateFlags != 0) { if (updateFlags != 0) {
if (!isLoading.get() && currentInfo != null) { if (!isLoading.get() && currentInfo != null) {
@ -552,7 +553,6 @@ public class VideoDetailFragment
Serializable serializable = savedState.getSerializable(INFO_KEY); Serializable serializable = savedState.getSerializable(INFO_KEY);
if (serializable instanceof StreamInfo) { if (serializable instanceof StreamInfo) {
//noinspection unchecked
currentInfo = (StreamInfo) serializable; currentInfo = (StreamInfo) serializable;
InfoCache.getInstance().putInfo(serviceId, url, currentInfo, InfoItem.InfoType.STREAM); InfoCache.getInstance().putInfo(serviceId, url, currentInfo, InfoItem.InfoType.STREAM);
} }
@ -672,7 +672,8 @@ public class VideoDetailFragment
} }
break; break;
case R.id.detail_title_root_layout: case R.id.detail_title_root_layout:
ShareUtils.copyToClipboard(getContext(), videoTitleTextView.getText().toString()); ShareUtils.copyToClipboard(requireContext(),
videoTitleTextView.getText().toString());
break; break;
} }
@ -751,7 +752,7 @@ public class VideoDetailFragment
appBarLayout = rootView.findViewById(R.id.appbarlayout); appBarLayout = rootView.findViewById(R.id.appbarlayout);
viewPager = rootView.findViewById(R.id.viewpager); viewPager = rootView.findViewById(R.id.viewpager);
pageAdapter = new TabAdaptor(getChildFragmentManager()); pageAdapter = new TabAdapter(getChildFragmentManager());
viewPager.setAdapter(pageAdapter); viewPager.setAdapter(pageAdapter);
tabLayout = rootView.findViewById(R.id.tablayout); tabLayout = rootView.findViewById(R.id.tablayout);
tabLayout.setupWithViewPager(viewPager); tabLayout.setupWithViewPager(viewPager);
@ -1105,7 +1106,7 @@ public class VideoDetailFragment
player.toggleFullscreen(); player.toggleFullscreen();
} }
if (!useExternalAudioPlayer && android.os.Build.VERSION.SDK_INT >= 16) { if (!useExternalAudioPlayer) {
openNormalBackgroundPlayer(append); openNormalBackgroundPlayer(append);
} else { } else {
startOnExternalPlayer(activity, currentInfo, audioStream); startOnExternalPlayer(activity, currentInfo, audioStream);
@ -1302,24 +1303,17 @@ public class VideoDetailFragment
if (description.getType() == Description.HTML) { if (description.getType() == Description.HTML) {
disposables.add(Single.just(description.getContent()) disposables.add(Single.just(description.getContent())
.map((@NonNull String descriptionText) -> { .map((@NonNull final String descriptionText) ->
final Spanned parsedDescription; HtmlCompat.fromHtml(descriptionText,
if (Build.VERSION.SDK_INT >= 24) { HtmlCompat.FROM_HTML_MODE_LEGACY))
parsedDescription = Html.fromHtml(descriptionText, 0);
} else {
//noinspection deprecation
parsedDescription = Html.fromHtml(descriptionText);
}
return parsedDescription;
})
.subscribeOn(Schedulers.computation()) .subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe((@NonNull Spanned spanned) -> { .subscribe((@NonNull final Spanned spanned) -> {
videoDescriptionView.setText(spanned); videoDescriptionView.setText(spanned);
videoDescriptionView.setVisibility(View.VISIBLE); videoDescriptionView.setVisibility(View.VISIBLE);
})); }));
} else if (description.getType() == Description.MARKDOWN) { } else if (description.getType() == Description.MARKDOWN) {
final Markwon markwon = Markwon.builder(getContext()) final Markwon markwon = Markwon.builder(requireContext())
.usePlugin(LinkifyPlugin.create()) .usePlugin(LinkifyPlugin.create())
.build(); .build();
markwon.setMarkdown(videoDescriptionView, description.getContent()); markwon.setMarkdown(videoDescriptionView, description.getContent());
@ -1908,6 +1902,7 @@ public class VideoDetailFragment
@Override @Override
public void onFullscreenStateChanged(final boolean fullscreen) { public void onFullscreenStateChanged(final boolean fullscreen) {
setupBrightness();
if (playerService.getView() == null || player.getParentActivity() == null) { if (playerService.getView() == null || player.getParentActivity() == null) {
return; return;
} }
@ -1982,6 +1977,11 @@ public class VideoDetailFragment
return; return;
} }
// Prevent jumping of the player on devices with cutout
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
activity.getWindow().getAttributes().layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
}
activity.getWindow().getDecorView().setSystemUiVisibility(0); activity.getWindow().getDecorView().setSystemUiVisibility(0);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
} }
@ -1995,6 +1995,11 @@ public class VideoDetailFragment
return; return;
} }
// Prevent jumping of the player on devices with cutout
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
activity.getWindow().getAttributes().layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
}
final int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE final int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
@ -2022,29 +2027,41 @@ public class VideoDetailFragment
&& player.getPlayer().getPlaybackState() != Player.STATE_IDLE; && player.getPlayer().getPlaybackState() != Player.STATE_IDLE;
} }
private void setupBrightness(final boolean save) { private void saveCurrentAndRestoreDefaultBrightness() {
final WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
if (lp.screenBrightness == -1) {
return;
}
// Save current brightness level
PlayerHelper.setScreenBrightness(activity, lp.screenBrightness);
// Restore the old brightness when fragment.onPause() called or
// when a player is in portrait
lp.screenBrightness = -1;
activity.getWindow().setAttributes(lp);
}
private void setupBrightness() {
if (activity == null) { if (activity == null) {
return; return;
} }
final WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); final WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
if (save) { if (player == null
// Save current brightness level || !player.videoPlayerSelected()
PlayerHelper.setScreenBrightness(activity, lp.screenBrightness); || !player.isFullscreen()
|| bottomSheetState != BottomSheetBehavior.STATE_EXPANDED) {
// Restore the old brightness when fragment.onPause() called. // Apply system brightness when the player is not in fullscreen
// It means when user leaves this fragment brightness will be set to system brightness saveCurrentAndRestoreDefaultBrightness();
lp.screenBrightness = -1;
} else { } else {
// Restore already saved brightness level // Restore already saved brightness level
final float brightnessLevel = PlayerHelper.getScreenBrightness(activity); final float brightnessLevel = PlayerHelper.getScreenBrightness(activity);
if (brightnessLevel <= 0.0f && brightnessLevel > 1.0f) { if (brightnessLevel == lp.screenBrightness) {
return; return;
} }
lp.screenBrightness = brightnessLevel; lp.screenBrightness = brightnessLevel;
activity.getWindow().setAttributes(lp);
} }
activity.getWindow().setAttributes(lp);
} }
private void checkLandscape() { private void checkLandscape() {
@ -2167,6 +2184,7 @@ public class VideoDetailFragment
* @param toMain if true than the main fragment will be focused or the player otherwise * @param toMain if true than the main fragment will be focused or the player otherwise
*/ */
private void moveFocusToMainFragment(final boolean toMain) { private void moveFocusToMainFragment(final boolean toMain) {
setupBrightness();
final ViewGroup mainFragment = requireActivity().findViewById(R.id.fragment_holder); final ViewGroup mainFragment = requireActivity().findViewById(R.id.fragment_holder);
// Hamburger button steels a focus even under bottomSheet // Hamburger button steels a focus even under bottomSheet
final Toolbar toolbar = requireActivity().findViewById(R.id.toolbar); final Toolbar toolbar = requireActivity().findViewById(R.id.toolbar);
@ -2190,7 +2208,7 @@ public class VideoDetailFragment
* Bottom padding should be equal to the mini player's height in this case * Bottom padding should be equal to the mini player's height in this case
* *
* @param showMore whether main fragment should be expanded or not * @param showMore whether main fragment should be expanded or not
* */ */
private void manageSpaceAtTheBottom(final boolean showMore) { private void manageSpaceAtTheBottom(final boolean showMore) {
final int peekHeight = getResources().getDimensionPixelSize(R.dimen.mini_player_height); final int peekHeight = getResources().getDimensionPixelSize(R.dimen.mini_player_height);
final ViewGroup holder = requireActivity().findViewById(R.id.fragment_holder); final ViewGroup holder = requireActivity().findViewById(R.id.fragment_holder);

View File

@ -6,7 +6,7 @@ import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;

View File

@ -133,7 +133,7 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
currentInfo = result; currentInfo = result;
currentNextPage = result.getNextPage(); currentNextPage = result.getNextPage();
handleResult(result); handleResult(result);
}, (@NonNull Throwable throwable) -> onError(throwable)); }, this::onError);
} }
/** /**

View File

@ -26,8 +26,6 @@ import io.reactivex.disposables.CompositeDisposable;
public class CommentsFragment extends BaseListInfoFragment<CommentsInfo> { public class CommentsFragment extends BaseListInfoFragment<CommentsInfo> {
private CompositeDisposable disposables = new CompositeDisposable(); private CompositeDisposable disposables = new CompositeDisposable();
private boolean mIsVisibleToUser = false;
public static CommentsFragment getInstance(final int serviceId, final String url, public static CommentsFragment getInstance(final int serviceId, final String url,
final String name) { final String name) {
final CommentsFragment instance = new CommentsFragment(); final CommentsFragment instance = new CommentsFragment();
@ -39,12 +37,6 @@ public class CommentsFragment extends BaseListInfoFragment<CommentsInfo> {
// LifeCycle // LifeCycle
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
@Override
public void setUserVisibleHint(final boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
mIsVisibleToUser = isVisibleToUser;
}
@Override @Override
public void onAttach(final Context context) { public void onAttach(final Context context) {
super.onAttach(context); super.onAttach(context);
@ -92,7 +84,7 @@ public class CommentsFragment extends BaseListInfoFragment<CommentsInfo> {
public void handleResult(@NonNull final CommentsInfo result) { public void handleResult(@NonNull final CommentsInfo result) {
super.handleResult(result); super.handleResult(result);
AnimationUtils.slideUp(getView(), 120, 150, 0.06f); AnimationUtils.slideUp(requireView(), 120, 150, 0.06f);
if (!result.getErrors().isEmpty()) { if (!result.getErrors().isEmpty()) {
showSnackBarError(result.getErrors(), UserAction.REQUESTED_COMMENTS, showSnackBarError(result.getErrors(), UserAction.REQUESTED_COMMENTS,

View File

@ -5,7 +5,8 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import androidx.core.text.HtmlCompat;
import androidx.preference.PreferenceManager;
import android.text.Editable; import android.text.Editable;
import android.text.Html; import android.text.Html;
import android.text.TextUtils; import android.text.TextUtils;
@ -73,7 +74,6 @@ import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.PublishSubject; import io.reactivex.subjects.PublishSubject;
import static android.text.Html.escapeHtml;
import static androidx.recyclerview.widget.ItemTouchHelper.Callback.makeMovementFlags; import static androidx.recyclerview.widget.ItemTouchHelper.Callback.makeMovementFlags;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.schabi.newpipe.util.AnimationUtils.animateView; import static org.schabi.newpipe.util.AnimationUtils.animateView;
@ -1005,10 +1005,9 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
: R.string.did_you_mean); : R.string.did_you_mean);
final String highlightedSearchSuggestion = final String highlightedSearchSuggestion =
"<b><i>" + escapeHtml(searchSuggestion) + "</i></b>"; "<b><i>" + Html.escapeHtml(searchSuggestion) + "</i></b>";
correctSuggestion.setText( final String text = String.format(helperText, highlightedSearchSuggestion);
Html.fromHtml(String.format(helperText, highlightedSearchSuggestion))); correctSuggestion.setText(HtmlCompat.fromHtml(text, HtmlCompat.FROM_HTML_MODE_LEGACY));
correctSuggestion.setOnClickListener(v -> { correctSuggestion.setOnClickListener(v -> {
correctSuggestion.setVisibility(View.GONE); correctSuggestion.setVisibility(View.GONE);

View File

@ -3,7 +3,7 @@ package org.schabi.newpipe.fragments.list.videos;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -78,11 +78,11 @@ public class RelatedVideosFragment extends BaseListInfoFragment<RelatedStreamInf
autoplaySwitch = headerRootLayout.findViewById(R.id.autoplay_switch); autoplaySwitch = headerRootLayout.findViewById(R.id.autoplay_switch);
final SharedPreferences pref = PreferenceManager final SharedPreferences pref = PreferenceManager
.getDefaultSharedPreferences(getContext()); .getDefaultSharedPreferences(requireContext());
final boolean autoplay = pref.getBoolean(getString(R.string.auto_queue_key), false); final boolean autoplay = pref.getBoolean(getString(R.string.auto_queue_key), false);
autoplaySwitch.setChecked(autoplay); autoplaySwitch.setChecked(autoplay);
autoplaySwitch.setOnCheckedChangeListener((compoundButton, b) -> autoplaySwitch.setOnCheckedChangeListener((compoundButton, b) ->
PreferenceManager.getDefaultSharedPreferences(getContext()).edit() PreferenceManager.getDefaultSharedPreferences(requireContext()).edit()
.putBoolean(getString(R.string.auto_queue_key), b).apply()); .putBoolean(getString(R.string.auto_queue_key), b).apply());
return headerRootLayout; return headerRootLayout;
} else { } else {
@ -166,12 +166,10 @@ public class RelatedVideosFragment extends BaseListInfoFragment<RelatedStreamInf
@Override @Override
public void setTitle(final String title) { public void setTitle(final String title) {
return;
} }
@Override @Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) { public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
return;
} }
private void setInitialData(final StreamInfo info) { private void setInitialData(final StreamInfo info) {
@ -201,7 +199,8 @@ public class RelatedVideosFragment extends BaseListInfoFragment<RelatedStreamInf
@Override @Override
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences,
final String s) { final String s) {
final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getContext()); final SharedPreferences pref =
PreferenceManager.getDefaultSharedPreferences(requireContext());
final boolean autoplay = pref.getBoolean(getString(R.string.auto_queue_key), false); final boolean autoplay = pref.getBoolean(getString(R.string.auto_queue_key), false);
if (autoplaySwitch != null) { if (autoplaySwitch != null) {
autoplaySwitch.setChecked(autoplay); autoplaySwitch.setChecked(autoplay);

View File

@ -1,6 +1,6 @@
package org.schabi.newpipe.info_list.holder; package org.schabi.newpipe.info_list.holder;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;

View File

@ -4,7 +4,7 @@ import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;

View File

@ -271,9 +271,8 @@ public final class BookmarkFragment extends BaseLocalListFragment<List<PlaylistL
final Builder builder = new AlertDialog.Builder(activity); final Builder builder = new AlertDialog.Builder(activity);
builder.setView(dialogView) builder.setView(dialogView)
.setPositiveButton(R.string.rename_playlist, (dialog, which) -> { .setPositiveButton(R.string.rename_playlist, (dialog, which) ->
changeLocalPlaylistName(selectedItem.uid, editText.getText().toString()); changeLocalPlaylistName(selectedItem.uid, editText.getText().toString()))
})
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.setNeutralButton(R.string.delete, (dialog, which) -> { .setNeutralButton(R.string.delete, (dialog, which) -> {
showDeleteDialog(selectedItem.name, showDeleteDialog(selectedItem.name,

View File

@ -30,7 +30,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProvider
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import icepick.State import icepick.State
import java.util.Calendar import java.util.Calendar
@ -82,7 +82,7 @@ class FeedFragment : BaseListFragment<FeedState, Unit>() {
override fun onViewCreated(rootView: View, savedInstanceState: Bundle?) { override fun onViewCreated(rootView: View, savedInstanceState: Bundle?) {
super.onViewCreated(rootView, savedInstanceState) super.onViewCreated(rootView, savedInstanceState)
viewModel = ViewModelProviders.of(this, FeedViewModel.Factory(requireContext(), groupId)).get(FeedViewModel::class.java) viewModel = ViewModelProvider(this, FeedViewModel.Factory(requireContext(), groupId)).get(FeedViewModel::class.java)
viewModel.stateLiveData.observe(viewLifecycleOwner, Observer { it?.let(::handleResult) }) viewModel.stateLiveData.observe(viewLifecycleOwner, Observer { it?.let(::handleResult) })
} }

View File

@ -27,10 +27,10 @@ import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.os.Build import android.os.Build
import android.os.IBinder import android.os.IBinder
import android.preference.PreferenceManager
import android.util.Log import android.util.Log
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
import androidx.preference.PreferenceManager
import io.reactivex.Flowable import io.reactivex.Flowable
import io.reactivex.Notification import io.reactivex.Notification
import io.reactivex.Single import io.reactivex.Single

View File

@ -20,7 +20,7 @@ package org.schabi.newpipe.local.history;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;

View File

@ -553,9 +553,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
.setView(dialogView) .setView(dialogView)
.setCancelable(true) .setCancelable(true)
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.rename, (dialogInterface, i) -> { .setPositiveButton(R.string.rename, (dialogInterface, i) ->
changePlaylistName(nameEdit.getText().toString()); changePlaylistName(nameEdit.getText().toString()));
});
dialogBuilder.show(); dialogBuilder.show();
} }

View File

@ -11,15 +11,15 @@ import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import android.os.Environment import android.os.Environment
import android.os.Parcelable import android.os.Parcelable
import android.preference.PreferenceManager
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProvider
import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import com.nononsenseapps.filepicker.Utils import com.nononsenseapps.filepicker.Utils
import com.xwray.groupie.Group import com.xwray.groupie.Group
@ -277,7 +277,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
} }
items_list.adapter = groupAdapter items_list.adapter = groupAdapter
viewModel = ViewModelProviders.of(this).get(SubscriptionViewModel::class.java) viewModel = ViewModelProvider(this).get(SubscriptionViewModel::class.java)
viewModel.stateLiveData.observe(viewLifecycleOwner, androidx.lifecycle.Observer { it?.let(this::handleResult) }) viewModel.stateLiveData.observe(viewLifecycleOwner, androidx.lifecycle.Observer { it?.let(this::handleResult) })
viewModel.feedGroupsLiveData.observe(viewLifecycleOwner, androidx.lifecycle.Observer { it?.let(this::handleFeedGroups) }) viewModel.feedGroupsLiveData.observe(viewLifecycleOwner, androidx.lifecycle.Observer { it?.let(this::handleFeedGroups) })
} }

View File

@ -252,7 +252,7 @@ class FeedGroupDialog : DialogFragment(), BackPressable {
} }
}) })
subscriptionGroupAdapter?.setOnItemClickListener(subscriptionPickerItemListener) subscriptionGroupAdapter.setOnItemClickListener(subscriptionPickerItemListener)
} }
private fun handlePositiveButton() = when { private fun handlePositiveButton() = when {

View File

@ -6,7 +6,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.ItemTouchHelper.SimpleCallback import androidx.recyclerview.widget.ItemTouchHelper.SimpleCallback
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@ -49,7 +49,7 @@ class FeedGroupReorderDialog : DialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProviders.of(this).get(FeedGroupReorderDialogViewModel::class.java) viewModel = ViewModelProvider(this).get(FeedGroupReorderDialogViewModel::class.java)
viewModel.groupsLiveData.observe(viewLifecycleOwner, Observer(::handleGroups)) viewModel.groupsLiveData.observe(viewLifecycleOwner, Observer(::handleGroups))
viewModel.dialogEventLiveData.observe(viewLifecycleOwner, Observer { viewModel.dialogEventLiveData.observe(viewLifecycleOwner, Observer {
when (it) { when (it) {

View File

@ -27,7 +27,7 @@ import android.content.SharedPreferences;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.media.AudioManager; import android.media.AudioManager;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.Toast; import android.widget.Toast;
@ -1342,6 +1342,11 @@ public abstract class BasePlayer implements
return; return;
} }
final StreamInfo currentInfo = currentMetadata.getMetadata(); final StreamInfo currentInfo = currentMetadata.getMetadata();
if (playQueue != null) {
// Save current position. It will help to restore this position once a user
// wants to play prev or next stream from the queue
playQueue.setRecovery(playQueue.getIndex(), simpleExoPlayer.getContentPosition());
}
savePlaybackState(currentInfo, simpleExoPlayer.getCurrentPosition()); savePlaybackState(currentInfo, simpleExoPlayer.getCurrentPosition());
} }

View File

@ -162,6 +162,9 @@ public final class MainPlayer extends Service {
@Override @Override
public void onTaskRemoved(final Intent rootIntent) { public void onTaskRemoved(final Intent rootIntent) {
super.onTaskRemoved(rootIntent); super.onTaskRemoved(rootIntent);
if (!playerImpl.videoPlayerSelected()) {
return;
}
onDestroy(); onDestroy();
// Unload from memory completely // Unload from memory completely
Runtime.getRuntime().halt(0); Runtime.getRuntime().halt(0);

View File

@ -30,9 +30,10 @@ import android.content.SharedPreferences;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
@ -210,18 +211,18 @@ public abstract class VideoPlayer extends BasePlayer
this.captionTextView = view.findViewById(R.id.captionTextView); this.captionTextView = view.findViewById(R.id.captionTextView);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { playbackSeekBar.getThumb()
playbackSeekBar.getThumb().setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN); .setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN));
} this.playbackSeekBar.getProgressDrawable()
this.playbackSeekBar.getProgressDrawable(). .setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY));
setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY);
this.qualityPopupMenu = new PopupMenu(context, qualityTextView); this.qualityPopupMenu = new PopupMenu(context, qualityTextView);
this.playbackSpeedPopupMenu = new PopupMenu(context, playbackSpeedTextView); this.playbackSpeedPopupMenu = new PopupMenu(context, playbackSpeedTextView);
this.captionPopupMenu = new PopupMenu(context, captionTextView); this.captionPopupMenu = new PopupMenu(context, captionTextView);
((ProgressBar) this.loadingPanel.findViewById(R.id.progressBarLoadingPanel)) ((ProgressBar) this.loadingPanel.findViewById(R.id.progressBarLoadingPanel))
.getIndeterminateDrawable().setColorFilter(Color.WHITE, PorterDuff.Mode.MULTIPLY); .getIndeterminateDrawable()
.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.MULTIPLY));
} }
protected abstract void setupSubtitleView(@NonNull SubtitleView view, float captionScale, protected abstract void setupSubtitleView(@NonNull SubtitleView view, float captionScale,
@ -249,7 +250,7 @@ public abstract class VideoPlayer extends BasePlayer
simpleExoPlayer.addTextOutput(cues -> subtitleView.onCues(cues)); simpleExoPlayer.addTextOutput(cues -> subtitleView.onCues(cues));
// Setup audio session with onboard equalizer // Setup audio session with onboard equalizer
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
trackSelector.setParameters(trackSelector.buildUponParameters() trackSelector.setParameters(trackSelector.buildUponParameters()
.setTunnelingAudioSessionId(C.generateAudioSessionIdV21(context))); .setTunnelingAudioSessionId(C.generateAudioSessionIdV21(context)));
} }
@ -456,11 +457,8 @@ public abstract class VideoPlayer extends BasePlayer
animateView(controlsRoot, false, DEFAULT_CONTROLS_DURATION); animateView(controlsRoot, false, DEFAULT_CONTROLS_DURATION);
playbackSeekBar.setEnabled(false); playbackSeekBar.setEnabled(false);
// Bug on lower api, disabling and enabling the seekBar resets the thumb color -.-, playbackSeekBar.getThumb()
// so sets the color again .setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
playbackSeekBar.getThumb().setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
}
loadingPanel.setBackgroundColor(Color.BLACK); loadingPanel.setBackgroundColor(Color.BLACK);
animateView(loadingPanel, true, 0); animateView(loadingPanel, true, 0);
@ -476,11 +474,8 @@ public abstract class VideoPlayer extends BasePlayer
showAndAnimateControl(-1, true); showAndAnimateControl(-1, true);
playbackSeekBar.setEnabled(true); playbackSeekBar.setEnabled(true);
// Bug on lower api, disabling and enabling the seekBar resets the thumb color -.-, playbackSeekBar.getThumb()
// so sets the color again .setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
playbackSeekBar.getThumb().setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
}
loadingPanel.setVisibility(View.GONE); loadingPanel.setVisibility(View.GONE);

View File

@ -32,7 +32,7 @@ import android.graphics.Point;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.provider.Settings; import android.provider.Settings;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
@ -892,8 +892,8 @@ public class VideoPlayerImpl extends VideoPlayer
// show kodi button if it supports the current service and it is enabled in settings // show kodi button if it supports the current service and it is enabled in settings
final boolean showKodiButton = playQueue != null && playQueue.getItem() != null final boolean showKodiButton = playQueue != null && playQueue.getItem() != null
&& KoreUtil.isServiceSupportedByKore(playQueue.getItem().getServiceId()) && KoreUtil.isServiceSupportedByKore(playQueue.getItem().getServiceId())
&& PreferenceManager.getDefaultSharedPreferences(context) && PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(context.getString(R.string.show_play_with_kodi_key), false); .getBoolean(context.getString(R.string.show_play_with_kodi_key), false);
playWithKodi.setVisibility(videoPlayerSelected() && kodiEnabled && showKodiButton playWithKodi.setVisibility(videoPlayerSelected() && kodiEnabled && showKodiButton
? View.VISIBLE : View.GONE); ? View.VISIBLE : View.GONE);
} }
@ -1489,9 +1489,10 @@ public class VideoPlayerImpl extends VideoPlayer
// It doesn't include NavigationBar, notches, etc. // It doesn't include NavigationBar, notches, etc.
display.getSize(size); display.getSize(size);
final boolean isLandscape = service.isLandscape();
final int width = isFullscreen final int width = isFullscreen
? (service.isLandscape() ? (isLandscape ? size.x : size.y)
? size.x : size.y) : ViewGroup.LayoutParams.MATCH_PARENT; : ViewGroup.LayoutParams.MATCH_PARENT;
final int gravity = isFullscreen final int gravity = isFullscreen
? (display.getRotation() == Surface.ROTATION_90 ? (display.getRotation() == Surface.ROTATION_90
? Gravity.START : Gravity.END) ? Gravity.START : Gravity.END)
@ -1522,14 +1523,16 @@ public class VideoPlayerImpl extends VideoPlayer
// And the situations when we need to set custom height is // And the situations when we need to set custom height is
// in fullscreen mode in tablet in non-multiWindow mode or with vertical video. // in fullscreen mode in tablet in non-multiWindow mode or with vertical video.
// Other than that MATCH_PARENT is good // Other than that MATCH_PARENT is good
final boolean navBarAtTheBottom = DeviceUtils.isTablet(service) || !service.isLandscape(); final boolean navBarAtTheBottom = DeviceUtils.isTablet(service) || !isLandscape;
controlsRoot.getLayoutParams().height = isFullscreen && !isInMultiWindow() controlsRoot.getLayoutParams().height = isFullscreen && !isInMultiWindow()
&& navBarAtTheBottom ? size.y : ViewGroup.LayoutParams.MATCH_PARENT; && navBarAtTheBottom ? size.y : ViewGroup.LayoutParams.MATCH_PARENT;
controlsRoot.requestLayout(); controlsRoot.requestLayout();
final int topPadding = isFullscreen && !isInMultiWindow() ? getStatusBarHeight() : 0; final DisplayMetrics metrics = getRootView().getResources().getDisplayMetrics();
getRootView().findViewById(R.id.playbackWindowRoot).setPadding(0, topPadding, 0, 0); int topPadding = isFullscreen && !isInMultiWindow() ? getStatusBarHeight() : 0;
getRootView().findViewById(R.id.playbackWindowRoot).requestLayout(); topPadding = !isLandscape && DeviceUtils.hasCutout(topPadding, metrics) ? 0 : topPadding;
getRootView().findViewById(R.id.playbackWindowRoot).setTranslationY(topPadding);
getBottomControlsRoot().setTranslationY(-topPadding);
} }
/** /**
@ -1538,8 +1541,12 @@ public class VideoPlayerImpl extends VideoPlayer
*/ */
private int getStatusBarHeight() { private int getStatusBarHeight() {
int statusBarHeight = 0; int statusBarHeight = 0;
final int resourceId = service.getResources().getIdentifier( final int resourceId = service.isLandscape()
"status_bar_height_landscape", "dimen", "android"); ? service.getResources().getIdentifier(
"status_bar_height_landscape", "dimen", "android")
: service.getResources().getIdentifier(
"status_bar_height", "dimen", "android");
if (resourceId > 0) { if (resourceId > 0) {
statusBarHeight = service.getResources().getDimensionPixelSize(resourceId); statusBarHeight = service.getResources().getDimensionPixelSize(resourceId);
} }
@ -1915,7 +1922,7 @@ public class VideoPlayerImpl extends VideoPlayer
} }
private int popupLayoutParamType() { private int popupLayoutParamType() {
return Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O return Build.VERSION.SDK_INT < Build.VERSION_CODES.O
? WindowManager.LayoutParams.TYPE_PHONE ? WindowManager.LayoutParams.TYPE_PHONE
: WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; : WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} }
@ -2071,7 +2078,7 @@ public class VideoPlayerImpl extends VideoPlayer
* This will be called when a user goes to another app/activity, turns off a screen. * This will be called when a user goes to another app/activity, turns off a screen.
* We don't want to interrupt playback and don't want to see notification so * We don't want to interrupt playback and don't want to see notification so
* next lines of code will enable audio-only playback only if needed * next lines of code will enable audio-only playback only if needed
* */ */
private void onFragmentStopped() { private void onFragmentStopped() {
if (videoPlayerSelected() && (isPlaying() || isLoading())) { if (videoPlayerSelected() && (isPlaying() || isLoading())) {
if (backgroundPlaybackEnabled()) { if (backgroundPlaybackEnabled()) {

View File

@ -202,7 +202,8 @@ public class PlayerGestureListener
private boolean onScrollInMain(final MotionEvent initialEvent, final MotionEvent movingEvent, private boolean onScrollInMain(final MotionEvent initialEvent, final MotionEvent movingEvent,
final float distanceX, final float distanceY) { final float distanceX, final float distanceY) {
if (!isVolumeGestureEnabled && !isBrightnessGestureEnabled) { if ((!isVolumeGestureEnabled && !isBrightnessGestureEnabled)
|| !playerImpl.isFullscreen()) {
return false; return false;
} }

View File

@ -3,7 +3,7 @@ package org.schabi.newpipe.player.helper;
import android.app.Dialog; import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.CheckBox; import android.widget.CheckBox;
@ -239,12 +239,13 @@ public class PlaybackParameterDialog extends DialogFragment {
unhookingCheckbox = rootView.findViewById(R.id.unhookCheckbox); unhookingCheckbox = rootView.findViewById(R.id.unhookCheckbox);
if (unhookingCheckbox != null) { if (unhookingCheckbox != null) {
// restore whether pitch and tempo are unhooked or not // restore whether pitch and tempo are unhooked or not
unhookingCheckbox.setChecked(PreferenceManager.getDefaultSharedPreferences(getContext()) unhookingCheckbox.setChecked(PreferenceManager
.getDefaultSharedPreferences(requireContext())
.getBoolean(getString(R.string.playback_unhook_key), true)); .getBoolean(getString(R.string.playback_unhook_key), true));
unhookingCheckbox.setOnCheckedChangeListener((compoundButton, isChecked) -> { unhookingCheckbox.setOnCheckedChangeListener((compoundButton, isChecked) -> {
// save whether pitch and tempo are unhooked or not // save whether pitch and tempo are unhooked or not
PreferenceManager.getDefaultSharedPreferences(getContext()) PreferenceManager.getDefaultSharedPreferences(requireContext())
.edit() .edit()
.putBoolean(getString(R.string.playback_unhook_key), isChecked) .putBoolean(getString(R.string.playback_unhook_key), isChecked)
.apply(); .apply();

View File

@ -2,8 +2,7 @@ package org.schabi.newpipe.player.helper;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Build; import androidx.preference.PreferenceManager;
import android.preference.PreferenceManager;
import android.provider.Settings; import android.provider.Settings;
import android.view.accessibility.CaptioningManager; import android.view.accessibility.CaptioningManager;
@ -303,10 +302,6 @@ public final class PlayerHelper {
@NonNull @NonNull
public static CaptionStyleCompat getCaptionStyle(@NonNull final Context context) { public static CaptionStyleCompat getCaptionStyle(@NonNull final Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
return CaptionStyleCompat.DEFAULT;
}
final CaptioningManager captioningManager = (CaptioningManager) final CaptioningManager captioningManager = (CaptioningManager)
context.getSystemService(Context.CAPTIONING_SERVICE); context.getSystemService(Context.CAPTIONING_SERVICE);
if (captioningManager == null || !captioningManager.isEnabled()) { if (captioningManager == null || !captioningManager.isEnabled()) {
@ -331,10 +326,6 @@ public final class PlayerHelper {
* @return caption scaling * @return caption scaling
*/ */
public static float getCaptionScale(@NonNull final Context context) { public static float getCaptionScale(@NonNull final Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
return 1f;
}
final CaptioningManager captioningManager final CaptioningManager captioningManager
= (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE); = (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
if (captioningManager == null || !captioningManager.isEnabled()) { if (captioningManager == null || !captioningManager.isEnabled()) {

View File

@ -115,7 +115,7 @@ public class VideoPlaybackResolver implements PlaybackResolver {
return mediaSources.get(0); return mediaSources.get(0);
} else { } else {
return new MergingMediaSource(mediaSources.toArray( return new MergingMediaSource(mediaSources.toArray(
new MediaSource[mediaSources.size()])); new MediaSource[0]));
} }
} }

View File

@ -216,18 +216,16 @@ public class ErrorActivity extends AppCompatActivity {
addGuruMeditation(); addGuruMeditation();
currentTimeStamp = getCurrentTimeStamp(); currentTimeStamp = getCurrentTimeStamp();
reportEmailButton.setOnClickListener((View v) -> { reportEmailButton.setOnClickListener((View v) ->
openPrivacyPolicyDialog(this, "EMAIL"); openPrivacyPolicyDialog(this, "EMAIL"));
});
copyButton.setOnClickListener((View v) -> { copyButton.setOnClickListener((View v) -> {
ShareUtils.copyToClipboard(this, buildMarkdown()); ShareUtils.copyToClipboard(this, buildMarkdown());
Toast.makeText(this, R.string.msg_copied, Toast.LENGTH_SHORT).show(); Toast.makeText(this, R.string.msg_copied, Toast.LENGTH_SHORT).show();
}); });
reportGithubButton.setOnClickListener((View v) -> { reportGithubButton.setOnClickListener((View v) ->
openPrivacyPolicyDialog(this, "GITHUB"); openPrivacyPolicyDialog(this, "GITHUB"));
});
// normal bugreport // normal bugreport
@ -278,10 +276,9 @@ public class ErrorActivity extends AppCompatActivity {
.setTitle(R.string.privacy_policy_title) .setTitle(R.string.privacy_policy_title)
.setMessage(R.string.start_accept_privacy_policy) .setMessage(R.string.start_accept_privacy_policy)
.setCancelable(false) .setCancelable(false)
.setNeutralButton(R.string.read_privacy_policy, (dialog, which) -> { .setNeutralButton(R.string.read_privacy_policy, (dialog, which) ->
ShareUtils.openUrlInBrowser(context, ShareUtils.openUrlInBrowser(context,
context.getString(R.string.privacy_policy_url)); context.getString(R.string.privacy_policy_url)))
})
.setPositiveButton(R.string.accept, (dialog, which) -> { .setPositiveButton(R.string.accept, (dialog, which) -> {
if (action.equals("EMAIL")) { // send on email if (action.equals("EMAIL")) { // send on email
final Intent i = new Intent(Intent.ACTION_SENDTO) final Intent i = new Intent(Intent.ACTION_SENDTO)
@ -469,7 +466,8 @@ public class ErrorActivity extends AppCompatActivity {
} }
private String getOsString() { private String getOsString() {
final String osBase = Build.VERSION.SDK_INT >= 23 ? Build.VERSION.BASE_OS : "Android"; final String osBase = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
? Build.VERSION.BASE_OS : "Android";
return System.getProperty("os.name") return System.getProperty("os.name")
+ " " + (osBase.isEmpty() ? "Android" : osBase) + " " + (osBase.isEmpty() ? "Android" : osBase)
+ " " + Build.VERSION.RELEASE + " " + Build.VERSION.RELEASE

View File

@ -2,7 +2,7 @@ package org.schabi.newpipe.settings;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.view.View; import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -20,7 +20,7 @@ public abstract class BasePreferenceFragment extends PreferenceFragmentCompat {
@Override @Override
public void onCreate(@Nullable final Bundle savedInstanceState) { public void onCreate(@Nullable final Bundle savedInstanceState) {
defaultPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); defaultPreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
} }

View File

@ -7,7 +7,7 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
@ -74,7 +74,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
initialSelectedContentCountry = org.schabi.newpipe.util.Localization initialSelectedContentCountry = org.schabi.newpipe.util.Localization
.getPreferredContentCountry(requireContext()); .getPreferredContentCountry(requireContext());
initialLanguage = PreferenceManager initialLanguage = PreferenceManager
.getDefaultSharedPreferences(getContext()).getString("app_language_key", "en"); .getDefaultSharedPreferences(requireContext()).getString("app_language_key", "en");
} }
@Override @Override
@ -148,7 +148,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
final ContentCountry selectedContentCountry = org.schabi.newpipe.util.Localization final ContentCountry selectedContentCountry = org.schabi.newpipe.util.Localization
.getPreferredContentCountry(requireContext()); .getPreferredContentCountry(requireContext());
final String selectedLanguage = PreferenceManager final String selectedLanguage = PreferenceManager
.getDefaultSharedPreferences(getContext()).getString("app_language_key", "en"); .getDefaultSharedPreferences(requireContext()).getString("app_language_key", "en");
if (!selectedLocalization.equals(initialSelectedLocalization) if (!selectedLocalization.equals(initialSelectedLocalization)
|| !selectedContentCountry.equals(initialSelectedContentCountry) || !selectedContentCountry.equals(initialSelectedContentCountry)
@ -217,7 +217,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
try { try {
output = new ObjectOutputStream(new FileOutputStream(dst)); output = new ObjectOutputStream(new FileOutputStream(dst));
final SharedPreferences pref final SharedPreferences pref
= PreferenceManager.getDefaultSharedPreferences(getContext()); = PreferenceManager.getDefaultSharedPreferences(requireContext());
output.writeObject(pref.getAll()); output.writeObject(pref.getAll());
} catch (final IOException e) { } catch (final IOException e) {
@ -299,7 +299,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
try { try {
input = new ObjectInputStream(new FileInputStream(src)); input = new ObjectInputStream(new FileInputStream(src));
final SharedPreferences.Editor prefEdit = PreferenceManager final SharedPreferences.Editor prefEdit = PreferenceManager
.getDefaultSharedPreferences(getContext()).edit(); .getDefaultSharedPreferences(requireContext()).edit();
prefEdit.clear(); prefEdit.clear();
final Map<String, ?> entries = (Map<String, ?>) input.readObject(); final Map<String, ?> entries = (Map<String, ?>) input.readObject();
for (final Map.Entry<String, ?> entry : entries.entrySet()) { for (final Map.Entry<String, ?> entry : entries.entrySet()) {

View File

@ -4,7 +4,7 @@ import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.text.InputType; import android.text.InputType;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
@ -203,9 +203,8 @@ public class PeertubeInstanceListFragment extends Fragment {
private void initButton(final View rootView) { private void initButton(final View rootView) {
final FloatingActionButton fab = rootView.findViewById(R.id.addInstanceButton); final FloatingActionButton fab = rootView.findViewById(R.id.addInstanceButton);
fab.setOnClickListener(v -> { fab.setOnClickListener(v ->
showAddItemDialog(requireContext()); showAddItemDialog(requireContext()));
});
} }
private void showAddItemDialog(final Context c) { private void showAddItemDialog(final Context c) {

View File

@ -208,12 +208,7 @@ public class SelectChannelFragment extends DialogFragment {
public void onBindViewHolder(final SelectChannelItemHolder holder, final int position) { public void onBindViewHolder(final SelectChannelItemHolder holder, final int position) {
final SubscriptionEntity entry = subscriptions.get(position); final SubscriptionEntity entry = subscriptions.get(position);
holder.titleView.setText(entry.getName()); holder.titleView.setText(entry.getName());
holder.view.setOnClickListener(new View.OnClickListener() { holder.view.setOnClickListener(view -> clickedItem(position));
@Override
public void onClick(final View view) {
clickedItem(position);
}
});
imageLoader.displayImage(entry.getAvatarUrl(), holder.thumbnailView, imageLoader.displayImage(entry.getAvatarUrl(), holder.thumbnailView,
DISPLAY_IMAGE_OPTIONS); DISPLAY_IMAGE_OPTIONS);
} }

View File

@ -87,7 +87,7 @@ public class VideoAudioSettingsFragment extends BasePreferenceFragment {
} }
} }
final ListPreference durations = (ListPreference) findPreference( final ListPreference durations = findPreference(
getString(R.string.seek_duration_key)); getString(R.string.seek_duration_key));
durations.setEntryValues(displayedDurationValues.toArray(new CharSequence[0])); durations.setEntryValues(displayedDurationValues.toArray(new CharSequence[0]));
durations.setEntries(displayedDescriptionValues.toArray(new CharSequence[0])); durations.setEntries(displayedDescriptionValues.toArray(new CharSequence[0]));

View File

@ -2,7 +2,7 @@ package org.schabi.newpipe.settings.tabs;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.widget.Toast; import android.widget.Toast;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;

View File

@ -236,7 +236,7 @@ public class DataReader {
if (read != amount) { if (read != amount) {
throw new EOFException("Truncated stream, missing " throw new EOFException("Truncated stream, missing "
+ String.valueOf(amount - read) + " bytes"); + (amount - read) + " bytes");
} }
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {

View File

@ -5,8 +5,8 @@ import org.schabi.newpipe.streams.io.SharpStream;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
@ -259,11 +259,7 @@ public class Mp4DashReader {
} }
private String boxName(final int type) { private String boxName(final int type) {
try { return new String(ByteBuffer.allocate(4).putInt(type).array(), StandardCharsets.UTF_8);
return new String(ByteBuffer.allocate(4).putInt(type).array(), "UTF-8");
} catch (final UnsupportedEncodingException e) {
return "0x" + Integer.toHexString(type);
}
} }
private Box readBox() throws IOException { private Box readBox() throws IOException {

View File

@ -293,7 +293,7 @@ public class WebMReader {
if (metadataExpected && (obj.info == null || obj.tracks == null)) { if (metadataExpected && (obj.info == null || obj.tracks == null)) {
throw new RuntimeException( throw new RuntimeException(
"Cluster element found without Info and/or Tracks element at position " "Cluster element found without Info and/or Tracks element at position "
+ String.valueOf(ref.offset)); + ref.offset);
} }
return obj; return obj;
@ -389,7 +389,7 @@ public class WebMReader {
final Element elem = untilElement(ref, ID_TIMECODE); final Element elem = untilElement(ref, ID_TIMECODE);
if (elem == null) { if (elem == null) {
throw new NoSuchElementException("Cluster at " + String.valueOf(ref.offset) throw new NoSuchElementException("Cluster at " + ref.offset
+ " without Timecode element"); + " without Timecode element");
} }
obj.timecode = readNumber(elem); obj.timecode = readNumber(elem);
@ -520,7 +520,7 @@ public class WebMReader {
currentSimpleBlock = readSimpleBlock(elem); currentSimpleBlock = readSimpleBlock(elem);
if (currentSimpleBlock.trackNumber == tracks[selectedTrack].trackNumber) { if (currentSimpleBlock.trackNumber == tracks[selectedTrack].trackNumber) {
currentSimpleBlock.data = stream.getView((int) currentSimpleBlock.dataSize); currentSimpleBlock.data = stream.getView(currentSimpleBlock.dataSize);
// calculate the timestamp in nanoseconds // calculate the timestamp in nanoseconds
currentSimpleBlock.absoluteTimeCodeNs = currentSimpleBlock.relativeTimeCode currentSimpleBlock.absoluteTimeCodeNs = currentSimpleBlock.relativeTimeCode

View File

@ -162,13 +162,9 @@ public final class AnimationUtils {
.ofObject(new ArgbEvaluator(), colorStart, colorEnd); .ofObject(new ArgbEvaluator(), colorStart, colorEnd);
viewPropertyAnimator.setInterpolator(new FastOutSlowInInterpolator()); viewPropertyAnimator.setInterpolator(new FastOutSlowInInterpolator());
viewPropertyAnimator.setDuration(duration); viewPropertyAnimator.setDuration(duration);
viewPropertyAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { viewPropertyAnimator.addUpdateListener(animation ->
@Override
public void onAnimationUpdate(final ValueAnimator animation) {
ViewCompat.setBackgroundTintList(view, ViewCompat.setBackgroundTintList(view,
new ColorStateList(empty, new int[]{(int) animation.getAnimatedValue()})); new ColorStateList(empty, new int[]{(int) animation.getAnimatedValue()})));
}
});
viewPropertyAnimator.addListener(new AnimatorListenerAdapter() { viewPropertyAnimator.addListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(final Animator animation) { public void onAnimationEnd(final Animator animation) {
@ -205,12 +201,8 @@ public final class AnimationUtils {
.ofObject(new ArgbEvaluator(), colorStart, colorEnd); .ofObject(new ArgbEvaluator(), colorStart, colorEnd);
viewPropertyAnimator.setInterpolator(new FastOutSlowInInterpolator()); viewPropertyAnimator.setInterpolator(new FastOutSlowInInterpolator());
viewPropertyAnimator.setDuration(duration); viewPropertyAnimator.setDuration(duration);
viewPropertyAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { viewPropertyAnimator.addUpdateListener(animation ->
@Override view.setTextColor((int) animation.getAnimatedValue()));
public void onAnimationUpdate(final ValueAnimator animation) {
view.setTextColor((int) animation.getAnimatedValue());
}
});
viewPropertyAnimator.addListener(new AnimatorListenerAdapter() { viewPropertyAnimator.addListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(final Animator animation) { public void onAnimationEnd(final Animator animation) {
@ -430,7 +422,7 @@ public final class AnimationUtils {
final long duration, final long delay, final long duration, final long delay,
final Runnable execOnEnd) { final Runnable execOnEnd) {
if (enterOrExit) { if (enterOrExit) {
view.setTranslationY(-view.getHeight() / 2); view.setTranslationY(-view.getHeight() / 2.0f);
view.setAlpha(0f); view.setAlpha(0f);
view.animate() view.animate()
.setInterpolator(new FastOutSlowInInterpolator()).alpha(1f).translationY(0) .setInterpolator(new FastOutSlowInInterpolator()).alpha(1f).translationY(0)
@ -445,7 +437,7 @@ public final class AnimationUtils {
}).start(); }).start();
} else { } else {
view.animate().setInterpolator(new FastOutSlowInInterpolator()) view.animate().setInterpolator(new FastOutSlowInInterpolator())
.alpha(0f).translationY(-view.getHeight() / 2) .alpha(0f).translationY(-view.getHeight() / 2.0f)
.setDuration(duration).setStartDelay(delay) .setDuration(duration).setStartDelay(delay)
.setListener(new AnimatorListenerAdapter() { .setListener(new AnimatorListenerAdapter() {
@Override @Override

View File

@ -6,6 +6,8 @@ import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.BatteryManager; import android.os.BatteryManager;
import android.os.Build; import android.os.Build;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.KeyEvent; import android.view.KeyEvent;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -72,4 +74,17 @@ public final class DeviceUtils {
return false; return false;
} }
} }
/*
* Compares current status bar height with default status bar height in Android and decides,
* does the device has cutout or not
* */
public static boolean hasCutout(final float statusBarHeight, final DisplayMetrics metrics) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
final float defaultStatusBarHeight = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 25, metrics);
return statusBarHeight > defaultStatusBarHeight;
}
return false;
}
} }

View File

@ -2,7 +2,7 @@ package org.schabi.newpipe.util;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;

View File

@ -3,7 +3,7 @@ package org.schabi.newpipe.util;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;

View File

@ -5,7 +5,7 @@ import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;

View File

@ -7,7 +7,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;

View File

@ -2,7 +2,7 @@ package org.schabi.newpipe.util;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import com.grack.nanojson.JsonArray; import com.grack.nanojson.JsonArray;
import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonObject;

View File

@ -26,10 +26,8 @@ public final class PermissionHelper {
private PermissionHelper() { } private PermissionHelper() { }
public static boolean checkStoragePermissions(final Activity activity, final int requestCode) { public static boolean checkStoragePermissions(final Activity activity, final int requestCode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { if (!checkReadStoragePermissions(activity, requestCode)) {
if (!checkReadStoragePermissions(activity, requestCode)) { return false;
return false;
}
} }
return checkWriteStoragePermissions(activity, requestCode); return checkWriteStoragePermissions(activity, requestCode);
} }

View File

@ -20,8 +20,7 @@ public class RelatedStreamInfo extends ListInfo<InfoItem> {
info.getOriginalUrl(), info.getUrl(), info.getId(), Collections.emptyList(), null); info.getOriginalUrl(), info.getUrl(), info.getId(), Collections.emptyList(), null);
final RelatedStreamInfo relatedStreamInfo = new RelatedStreamInfo( final RelatedStreamInfo relatedStreamInfo = new RelatedStreamInfo(
info.getServiceId(), handler, info.getName()); info.getServiceId(), handler, info.getName());
final List<InfoItem> streams = new ArrayList<>(); final List<InfoItem> streams = new ArrayList<>(info.getRelatedStreams());
streams.addAll(info.getRelatedStreams());
relatedStreamInfo.setRelatedItems(streams); relatedStreamInfo.setRelatedItems(streams);
return relatedStreamInfo; return relatedStreamInfo;
} }

View File

@ -2,7 +2,7 @@ package org.schabi.newpipe.util;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;

View File

@ -36,7 +36,6 @@ import org.schabi.newpipe.MainActivity;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
@ -254,12 +253,8 @@ public final class StateSaver {
return new SavedState(prefixFileName, file.getAbsolutePath()); return new SavedState(prefixFileName, file.getAbsolutePath());
} else { } else {
// Delete any file that contains the prefix // Delete any file that contains the prefix
final File[] files = cacheDir.listFiles(new FilenameFilter() { final File[] files = cacheDir.listFiles((dir, name) ->
@Override name.contains(prefixFileName));
public boolean accept(final File dir, final String name) {
return name.contains(prefixFileName);
}
});
for (final File fileToDelete : files) { for (final File fileToDelete : files) {
fileToDelete.delete(); fileToDelete.delete();
} }

View File

@ -106,7 +106,7 @@ public class TLSSocketFactoryCompat extends SSLSocketFactory {
} }
private Socket enableTLSOnSocket(final Socket socket) { private Socket enableTLSOnSocket(final Socket socket) {
if (socket != null && (socket instanceof SSLSocket)) { if (socket instanceof SSLSocket) {
((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.1", "TLSv1.2"}); ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.1", "TLSv1.2"});
} }
return socket; return socket;

View File

@ -22,7 +22,7 @@ package org.schabi.newpipe.util;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.ContextThemeWrapper; import android.view.ContextThemeWrapper;

View File

@ -259,7 +259,7 @@ public final class FocusOverlayView extends Drawable implements
// keyboard META key for moving between clusters). We have to fix this unfortunate accident // keyboard META key for moving between clusters). We have to fix this unfortunate accident
// While we are at it, let's deal with touchscreenBlocksFocus too. // While we are at it, let's deal with touchscreenBlocksFocus too.
if (Build.VERSION.SDK_INT < 26) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
return; return;
} }

View File

@ -155,13 +155,13 @@ public class LargeTextMovementMethod extends LinkMovementMethod {
int bestStart = -1; int bestStart = -1;
int bestEnd = -1; int bestEnd = -1;
for (int i = 0; i < candidates.length; i++) { for (final ClickableSpan candidate : candidates) {
final int start = buffer.getSpanStart(candidates[i]); final int start = buffer.getSpanStart(candidate);
final int end = buffer.getSpanEnd(candidates[i]); final int end = buffer.getSpanEnd(candidate);
if ((end < selEnd || selStart == selEnd) && start >= visibleStart) { if ((end < selEnd || selStart == selEnd) && start >= visibleStart) {
if (end > bestEnd) { if (end > bestEnd) {
bestStart = buffer.getSpanStart(candidates[i]); bestStart = buffer.getSpanStart(candidate);
bestEnd = end; bestEnd = end;
} }
} }
@ -224,14 +224,14 @@ public class LargeTextMovementMethod extends LinkMovementMethod {
int bestStart = Integer.MAX_VALUE; int bestStart = Integer.MAX_VALUE;
int bestEnd = Integer.MAX_VALUE; int bestEnd = Integer.MAX_VALUE;
for (int i = 0; i < candidates.length; i++) { for (final ClickableSpan candidate : candidates) {
final int start = buffer.getSpanStart(candidates[i]); final int start = buffer.getSpanStart(candidate);
final int end = buffer.getSpanEnd(candidates[i]); final int end = buffer.getSpanEnd(candidate);
if ((start > selStart || selStart == selEnd) && end <= visibleEnd) { if ((start > selStart || selStart == selEnd) && end <= visibleEnd) {
if (start < bestStart) { if (start < bestStart) {
bestStart = start; bestStart = start;
bestEnd = buffer.getSpanEnd(candidates[i]); bestEnd = buffer.getSpanEnd(candidate);
} }
} }
} }

View File

@ -142,7 +142,7 @@ public class NewPipeRecyclerView extends RecyclerView {
} }
private boolean tryFocusFinder(final int direction) { private boolean tryFocusFinder(final int direction) {
if (Build.VERSION.SDK_INT >= 28) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
// Android 9 implemented bunch of handy changes to focus, that render code below less // Android 9 implemented bunch of handy changes to focus, that render code below less
// useful, and also broke findNextFocusFromRect in way, that render this hack useless // useful, and also broke findNextFocusFromRect in way, that render this hack useless
return false; return false;

View File

@ -633,7 +633,7 @@ public class DownloadMission extends Mission {
calculated = offsets[current < offsets.length ? current : (offsets.length - 1)] + length; calculated = offsets[current < offsets.length ? current : (offsets.length - 1)] + length;
calculated -= offsets[0];// don't count reserved space calculated -= offsets[0];// don't count reserved space
return calculated > nearLength ? calculated : nearLength; return Math.max(calculated, nearLength);
} }
/** /**

View File

@ -30,12 +30,12 @@ public class FileStream extends SharpStream {
} }
@Override @Override
public int read(byte b[]) throws IOException { public int read(byte[] b) throws IOException {
return source.read(b); return source.read(b);
} }
@Override @Override
public int read(byte b[], int off, int len) throws IOException { public int read(byte[] b, int off, int len) throws IOException {
return source.read(b, off, len); return source.read(b, off, len);
} }

View File

@ -115,7 +115,7 @@ public abstract class Postprocessing implements Serializable {
mission.done = 0; mission.done = 0;
long length = mission.storage.length() - mission.offsets[0]; long length = mission.storage.length() - mission.offsets[0];
mission.length = length > mission.nearLength ? length : mission.nearLength; mission.length = Math.max(length, mission.nearLength);
final ProgressReport readProgress = (long position) -> { final ProgressReport readProgress = (long position) -> {
position -= mission.offsets[0]; position -= mission.offsets[0];

View File

@ -24,7 +24,7 @@ import android.os.Handler.Callback;
import android.os.IBinder; import android.os.IBinder;
import android.os.Message; import android.os.Message;
import android.os.Parcelable; import android.os.Parcelable;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.widget.Toast; import android.widget.Toast;
@ -160,7 +160,7 @@ public class DownloadManagerService extends Service {
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mNetworkStateListenerL = new ConnectivityManager.NetworkCallback() { mNetworkStateListenerL = new ConnectivityManager.NetworkCallback() {
@Override @Override
public void onAvailable(Network network) { public void onAvailable(Network network) {
@ -240,7 +240,7 @@ public class DownloadManagerService extends Service {
manageLock(false); manageLock(false);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
mConnectivityManager.unregisterNetworkCallback(mNetworkStateListenerL); mConnectivityManager.unregisterNetworkCallback(mNetworkStateListenerL);
else else
unregisterReceiver(mNetworkStateListener); unregisterReceiver(mNetworkStateListener);
@ -466,7 +466,7 @@ public class DownloadManagerService extends Service {
if (downloadDoneCount < 1) { if (downloadDoneCount < 1) {
downloadDoneList.append(name); downloadDoneList.append(name);
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
downloadDoneNotification.setContentTitle(getString(R.string.app_name)); downloadDoneNotification.setContentTitle(getString(R.string.app_name));
} else { } else {
downloadDoneNotification.setContentTitle(null); downloadDoneNotification.setContentTitle(null);
@ -505,7 +505,7 @@ public class DownloadManagerService extends Service {
.setContentIntent(mOpenDownloadList); .setContentIntent(mOpenDownloadList);
} }
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
downloadFailedNotification.setContentTitle(getString(R.string.app_name)); downloadFailedNotification.setContentTitle(getString(R.string.app_name));
downloadFailedNotification.setStyle(new NotificationCompat.BigTextStyle() downloadFailedNotification.setStyle(new NotificationCompat.BigTextStyle()
.bigText(getString(R.string.download_failed).concat(": ").concat(mission.storage.getName()))); .bigText(getString(R.string.download_failed).concat(": ").concat(mission.storage.getName())));

View File

@ -49,6 +49,7 @@ import java.io.File;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import us.shandian.giga.get.DownloadMission; import us.shandian.giga.get.DownloadMission;
@ -302,9 +303,7 @@ public class MissionAdapter extends Adapter<ViewHolder> implements Handler.Callb
float averageSpeed = speed; float averageSpeed = speed;
if (h.lastSpeedIdx < 0) { if (h.lastSpeedIdx < 0) {
for (int i = 0; i < h.lastSpeed.length; i++) { Arrays.fill(h.lastSpeed, speed);
h.lastSpeed[i] = speed;
}
h.lastSpeedIdx = 0; h.lastSpeedIdx = 0;
} else { } else {
for (int i = 0; i < h.lastSpeed.length; i++) { for (int i = 0; i < h.lastSpeed.length; i++) {

View File

@ -11,7 +11,7 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.IBinder; import android.os.IBinder;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
@ -97,7 +97,7 @@ public class MissionsFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.missions, container, false); View v = inflater.inflate(R.layout.missions, container, false);
mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); mPrefs = PreferenceManager.getDefaultSharedPreferences(requireActivity());
mLinear = mPrefs.getBoolean("linear", false); mLinear = mPrefs.getBoolean("linear", false);
// Bind the service // Bind the service

View File

@ -212,7 +212,6 @@
<string name="playback_skip_silence_key" translatable="false">playback_skip_silence_key</string> <string name="playback_skip_silence_key" translatable="false">playback_skip_silence_key</string>
<string name="app_language_key" translatable="false">app_language_key</string> <string name="app_language_key" translatable="false">app_language_key</string>
<string name="enable_lock_screen_video_thumbnail_key" translatable="false">enable_lock_screen_video_thumbnail</string>
<string name="feed_update_threshold_key" translatable="false">feed_update_threshold_key</string> <string name="feed_update_threshold_key" translatable="false">feed_update_threshold_key</string>
<string name="feed_update_threshold_default_value" translatable="false">300</string> <string name="feed_update_threshold_default_value" translatable="false">300</string>
@ -249,6 +248,11 @@
<string name="clear_playback_states_key" translatable="false">clear_playback_states</string> <string name="clear_playback_states_key" translatable="false">clear_playback_states</string>
<string name="clear_search_history_key" translatable="false">clear_search_history</string> <string name="clear_search_history_key" translatable="false">clear_search_history</string>
<string name="last_used_download_type" translatable="false">@string/last_download_type_video_key</string>
<string name="last_download_type_video_key" translatable="false">last_dl_type_video</string>
<string name="last_download_type_audio_key" translatable="false">last_dl_type_audio</string>
<string name="last_download_type_subtitle_key" translatable="false">last_dl_type_subtitle</string>
<string name="downloads_storage_ask" translatable="false">downloads_storage_ask</string> <string name="downloads_storage_ask" translatable="false">downloads_storage_ask</string>
<string name="storage_use_saf" translatable="false">storage_use_saf</string> <string name="storage_use_saf" translatable="false">storage_use_saf</string>

View File

@ -12,7 +12,7 @@
android:title="@string/theme_title" android:title="@string/theme_title"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<SwitchPreference <SwitchPreferenceCompat
android:defaultValue="true" android:defaultValue="true"
android:key="@string/show_hold_to_append_key" android:key="@string/show_hold_to_append_key"
android:summary="@string/show_hold_to_append_summary" android:summary="@string/show_hold_to_append_summary"

View File

@ -45,39 +45,39 @@
android:title="@string/peertube_instance_url_title" android:title="@string/peertube_instance_url_title"
android:summary="@string/peertube_instance_url_summary"/> android:summary="@string/peertube_instance_url_summary"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/show_age_restricted_content" android:key="@string/show_age_restricted_content"
android:title="@string/show_age_restricted_content_title"/> android:title="@string/show_age_restricted_content_title"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/youtube_restricted_mode_enabled" android:key="@string/youtube_restricted_mode_enabled"
android:title="@string/youtube_restricted_mode_enabled_title"/> android:title="@string/youtube_restricted_mode_enabled_title"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="true" android:defaultValue="true"
android:key="@string/show_search_suggestions_key" android:key="@string/show_search_suggestions_key"
android:summary="@string/show_search_suggestions_summary" android:summary="@string/show_search_suggestions_summary"
android:title="@string/show_search_suggestions_title"/> android:title="@string/show_search_suggestions_title"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="true" android:defaultValue="true"
android:key="@string/download_thumbnail_key" android:key="@string/download_thumbnail_key"
android:title="@string/download_thumbnail_title" android:title="@string/download_thumbnail_title"
android:summary="@string/download_thumbnail_summary"/> android:summary="@string/download_thumbnail_summary"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="true" android:defaultValue="true"
android:key="@string/show_next_video_key" android:key="@string/show_next_video_key"
android:title="@string/show_next_and_similar_title"/> android:title="@string/show_next_and_similar_title"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="true" android:defaultValue="true"
android:key="@string/show_comments_key" android:key="@string/show_comments_key"
@ -109,7 +109,7 @@
android:title="@string/feed_update_threshold_title" android:title="@string/feed_update_threshold_title"
android:summary="@string/feed_update_threshold_summary"/> android:summary="@string/feed_update_threshold_summary"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/feed_use_dedicated_fetch_method_key" android:key="@string/feed_use_dedicated_fetch_method_key"

View File

@ -5,21 +5,21 @@
android:key="general_preferences" android:key="general_preferences"
android:title="@string/settings_category_debug_title"> android:title="@string/settings_category_debug_title">
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/allow_heap_dumping_key" android:key="@string/allow_heap_dumping_key"
android:title="@string/enable_leak_canary_title" android:title="@string/enable_leak_canary_title"
android:summary="@string/enable_leak_canary_summary"/> android:summary="@string/enable_leak_canary_summary"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/allow_disposed_exceptions_key" android:key="@string/allow_disposed_exceptions_key"
android:title="@string/enable_disposed_exceptions_title" android:title="@string/enable_disposed_exceptions_title"
android:summary="@string/enable_disposed_exceptions_summary"/> android:summary="@string/enable_disposed_exceptions_summary"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/show_original_time_ago_key" android:key="@string/show_original_time_ago_key"

View File

@ -12,7 +12,7 @@
android:summary="@string/downloads_storage_ask_summary_kitkat" android:summary="@string/downloads_storage_ask_summary_kitkat"
android:title="@string/downloads_storage_ask_title" /> android:title="@string/downloads_storage_ask_title" />
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/storage_use_saf" android:key="@string/storage_use_saf"
@ -58,14 +58,14 @@
android:summary="@string/max_retry_desc" android:summary="@string/max_retry_desc"
android:title="@string/max_retry_msg" /> android:title="@string/max_retry_msg" />
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/downloads_cross_network" android:key="@string/downloads_cross_network"
android:summary="@string/pause_downloads_on_mobile_desc" android:summary="@string/pause_downloads_on_mobile_desc"
android:title="@string/pause_downloads_on_mobile" /> android:title="@string/pause_downloads_on_mobile" />
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="true" android:defaultValue="true"
android:key="@string/downloads_queue_limit" android:key="@string/downloads_queue_limit"

View File

@ -4,14 +4,14 @@
android:key="general_preferences" android:key="general_preferences"
android:title="@string/settings_category_history_title"> android:title="@string/settings_category_history_title">
<SwitchPreference <SwitchPreferenceCompat
android:defaultValue="true" android:defaultValue="true"
android:key="@string/enable_watch_history_key" android:key="@string/enable_watch_history_key"
android:summary="@string/enable_watch_history_summary" android:summary="@string/enable_watch_history_summary"
android:title="@string/enable_watch_history_title" android:title="@string/enable_watch_history_title"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<SwitchPreference <SwitchPreferenceCompat
android:defaultValue="true" android:defaultValue="true"
android:dependency="@string/enable_watch_history_key" android:dependency="@string/enable_watch_history_key"
android:key="@string/enable_playback_resume_key" android:key="@string/enable_playback_resume_key"
@ -19,14 +19,14 @@
android:title="@string/enable_playback_resume_title" android:title="@string/enable_playback_resume_title"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<SwitchPreference <SwitchPreferenceCompat
android:defaultValue="true" android:defaultValue="true"
android:key="@string/enable_playback_state_lists_key" android:key="@string/enable_playback_state_lists_key"
android:summary="@string/enable_playback_state_lists_summary" android:summary="@string/enable_playback_state_lists_summary"
android:title="@string/enable_playback_state_lists_title" android:title="@string/enable_playback_state_lists_title"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<SwitchPreference <SwitchPreferenceCompat
android:defaultValue="true" android:defaultValue="true"
android:key="@string/enable_search_history_key" android:key="@string/enable_search_history_key"
android:summary="@string/enable_search_history_summary" android:summary="@string/enable_search_history_summary"

View File

@ -5,7 +5,7 @@
android:key="general_preferences" android:key="general_preferences"
android:title="@string/settings_category_updates_title"> android:title="@string/settings_category_updates_title">
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="true" android:defaultValue="true"
android:key="@string/update_app_key" android:key="@string/update_app_key"

View File

@ -31,7 +31,7 @@
android:summary="%s" android:summary="%s"
android:title="@string/limit_mobile_data_usage_title" /> android:title="@string/limit_mobile_data_usage_title" />
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/show_higher_resolutions_key" android:key="@string/show_higher_resolutions_key"
@ -61,20 +61,20 @@
android:layout="@layout/settings_category_header_layout" android:layout="@layout/settings_category_header_layout"
android:title="@string/settings_category_player_title"> android:title="@string/settings_category_player_title">
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/use_external_video_player_key" android:key="@string/use_external_video_player_key"
android:summary="@string/use_external_video_player_summary" android:summary="@string/use_external_video_player_summary"
android:title="@string/use_external_video_player_title"/> android:title="@string/use_external_video_player_title"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/use_external_audio_player_key" android:key="@string/use_external_audio_player_key"
android:title="@string/use_external_audio_player_title"/> android:title="@string/use_external_audio_player_title"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/show_play_with_kodi_key" android:key="@string/show_play_with_kodi_key"
@ -114,42 +114,42 @@
android:summary="@string/autoplay_summary" android:summary="@string/autoplay_summary"
android:title="@string/autoplay_title"/> android:title="@string/autoplay_title"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/auto_queue_key" android:key="@string/auto_queue_key"
android:summary="@string/auto_queue_summary" android:summary="@string/auto_queue_summary"
android:title="@string/auto_queue_title"/> android:title="@string/auto_queue_title"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/resume_on_audio_focus_gain_key" android:key="@string/resume_on_audio_focus_gain_key"
android:summary="@string/resume_on_audio_focus_gain_summary" android:summary="@string/resume_on_audio_focus_gain_summary"
android:title="@string/resume_on_audio_focus_gain_title"/> android:title="@string/resume_on_audio_focus_gain_title"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="true" android:defaultValue="true"
android:key="@string/volume_gesture_control_key" android:key="@string/volume_gesture_control_key"
android:summary="@string/volume_gesture_control_summary" android:summary="@string/volume_gesture_control_summary"
android:title="@string/volume_gesture_control_title"/> android:title="@string/volume_gesture_control_title"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="true" android:defaultValue="true"
android:key="@string/brightness_gesture_control_key" android:key="@string/brightness_gesture_control_key"
android:summary="@string/brightness_gesture_control_summary" android:summary="@string/brightness_gesture_control_summary"
android:title="@string/brightness_gesture_control_title"/> android:title="@string/brightness_gesture_control_title"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="true" android:defaultValue="true"
android:key="@string/popup_remember_size_pos_key" android:key="@string/popup_remember_size_pos_key"
android:summary="@string/popup_remember_size_pos_summary" android:summary="@string/popup_remember_size_pos_summary"
android:title="@string/popup_remember_size_pos_title"/> android:title="@string/popup_remember_size_pos_title"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/use_inexact_seek_key" android:key="@string/use_inexact_seek_key"
@ -165,7 +165,7 @@
android:summary="%s" android:summary="%s"
android:title="@string/seek_duration_title"/> android:title="@string/seek_duration_title"/>
<SwitchPreference <SwitchPreferenceCompat
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:defaultValue="false" android:defaultValue="false"
android:key="@string/clear_queue_confirmation_key" android:key="@string/clear_queue_confirmation_key"