diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index f9201f948..e74a5a761 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -15,7 +15,7 @@ Oh no, a bug! It happens. Thanks for reporting an issue with NewPipe. To make it
### Checklist
-
+
- [x] I am using the latest version - x.xx.x
- [ ] I checked, but didn't find any duplicates (open OR closed) of this issue in the repo.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index c4d378d14..361c8057f 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -11,7 +11,7 @@ assignees: ''
### Checklist
-
+
- [x] I checked, but didn't find any duplicates (open OR closed) of this issue in the repo.
- [ ] I have read the contribution guidelines given at https://github.com/TeamNewPipe/NewPipe/blob/HEAD/.github/CONTRIBUTING.md.
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index e69de29bb..000000000
diff --git a/README.ko.md b/README.ko.md
index a86eae8d9..1ca7be1be 100644
--- a/README.ko.md
+++ b/README.ko.md
@@ -6,7 +6,7 @@
-
+
@@ -98,7 +98,7 @@ NewPipe 코드의 변경이 있을 때(기능 추가 또는 버그 수정으로
1. 당신의 기록, 구독, 그리고 재생목록을 유지할 수 있도록 Settings > Content > Export Database 를 통해 데이터를 백업하십시오.
2. NewPipe를 삭제하십시오.
3. 새로운 소스에서 APK를 다운로드하고 이것을 설치하십시오.
-4. Step 1의 Settings > Content > Export Database 을 통해 데이터를 불러오십시오.
+4. Step 1의 Settings > Content > Import Database 을 통해 데이터를 불러오십시오.
## Contribution
당신이 아이디어, 번역, 디자인 변경, 코드 정리, 또는 정말 큰 코드 수정에 대한 의견이 있다면, 도움은 항상 환영합니다.
diff --git a/README.md b/README.md
index c66bcfa7f..006085a51 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
-
+
diff --git a/app/build.gradle b/app/build.gradle
index 58b5c25be..9fb9cf85f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -13,8 +13,8 @@ android {
resValue "string", "app_name", "NewPipe"
minSdkVersion 19
targetSdkVersion 29
- versionCode 960
- versionName "0.20.6"
+ versionCode 962
+ versionName "0.20.8"
multiDexEnabled true
@@ -179,7 +179,7 @@ dependencies {
// NewPipe dependencies
// You can use a local version by uncommenting a few lines in settings.gradle
- implementation 'com.github.B0pol:NewPipeExtractor:3ae924a7f18d5ee5b4aa0bd13d7179922cc094fa'
+ implementation 'com.github.TeamNewPipe:NewPipeExtractor:deb9af7bf53b3f8fd9d32322adae02df78d985ea'
implementation "com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751"
implementation "org.jsoup:jsoup:1.13.1"
@@ -203,6 +203,7 @@ dependencies {
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
+ implementation 'androidx.media:media:1.2.1'
implementation 'androidx.webkit:webkit:1.4.0'
implementation "androidx.lifecycle:lifecycle-livedata:${androidxLifecycleVersion}"
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f0a38b54f..3509f2d13 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -266,7 +266,7 @@
-
+
@@ -318,6 +318,8 @@
android:name=".RouterActivity$FetcherService"
android:exported="false" />
+
+
diff --git a/app/src/main/assets/epl1.html b/app/src/main/assets/epl1.html
new file mode 100644
index 000000000..7123552dd
--- /dev/null
+++ b/app/src/main/assets/epl1.html
@@ -0,0 +1,245 @@
+
+
+
+
+
+
+ Eclipse Public License - Version 1.0
+
+
+
+
+
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+ PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR
+ DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS
+ AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial
+ code and documentation distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+i) changes to the Program, and
+ii) additions to the Program;
+where such changes and/or additions to the Program
+ originate from and are distributed by that particular Contributor. A
+ Contribution 'originates' from a Contributor if it was added to the
+ Program by such Contributor itself or anyone acting on such
+ Contributor's behalf. Contributions do not include additions to the
+ Program which: (i) are separate modules of software distributed in
+ conjunction with the Program under their own license agreement, and (ii)
+ are not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes
+ the Program.
+
+"Licensed Patents" mean patent claims licensable by a
+ Contributor which are necessarily infringed by the use or sale of its
+ Contribution alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance
+ with this Agreement.
+
+"Recipient" means anyone who receives the Program under
+ this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each
+ Contributor hereby grants Recipient a non-exclusive, worldwide,
+ royalty-free copyright license to reproduce, prepare derivative works
+ of, publicly display, publicly perform, distribute and sublicense the
+ Contribution of such Contributor, if any, and such derivative works, in
+ source code and object code form.
+
+b) Subject to the terms of this Agreement, each
+ Contributor hereby grants Recipient a non-exclusive, worldwide,
+ royalty-free patent license under Licensed Patents to make, use, sell,
+ offer to sell, import and otherwise transfer the Contribution of such
+ Contributor, if any, in source code and object code form. This patent
+ license shall apply to the combination of the Contribution and the
+ Program if, at the time the Contribution is added by the Contributor,
+ such addition of the Contribution causes such combination to be covered
+ by the Licensed Patents. The patent license shall not apply to any other
+ combinations which include the Contribution. No hardware per se is
+ licensed hereunder.
+
+c) Recipient understands that although each Contributor
+ grants the licenses to its Contributions set forth herein, no assurances
+ are provided by any Contributor that the Program does not infringe the
+ patent or other intellectual property rights of any other entity. Each
+ Contributor disclaims any liability to Recipient for claims brought by
+ any other entity based on infringement of intellectual property rights
+ or otherwise. As a condition to exercising the rights and licenses
+ granted hereunder, each Recipient hereby assumes sole responsibility to
+ secure any other intellectual property rights needed, if any. For
+ example, if a third party patent license is required to allow Recipient
+ to distribute the Program, it is Recipient's responsibility to acquire
+ that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it
+ has sufficient copyright rights in its Contribution, if any, to grant
+ the copyright license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code
+ form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this
+ Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors
+ all warranties and conditions, express and implied, including warranties
+ or conditions of title and non-infringement, and implied warranties or
+ conditions of merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors
+ all liability for damages, including direct, indirect, special,
+ incidental and consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this
+ Agreement are offered by that Contributor alone and not by any other
+ party; and
+
+iv) states that source code for the Program is available
+ from such Contributor, and informs licensees how to obtain it in a
+ reasonable manner on or through a medium customarily used for software
+ exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each
+ copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained
+ within the Program.
+
+Each Contributor must identify itself as the originator of its
+ Contribution, if any, in a manner that reasonably allows subsequent
+ Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain
+ responsibilities with respect to end users, business partners and the
+ like. While this license is intended to facilitate the commercial use of
+ the Program, the Contributor who includes the Program in a commercial
+ product offering should do so in a manner which does not create
+ potential liability for other Contributors. Therefore, if a Contributor
+ includes the Program in a commercial product offering, such Contributor
+ ("Commercial Contributor") hereby agrees to defend and
+ indemnify every other Contributor ("Indemnified Contributor")
+ against any losses, damages and costs (collectively "Losses")
+ arising from claims, lawsuits and other legal actions brought by a third
+ party against the Indemnified Contributor to the extent caused by the
+ acts or omissions of such Commercial Contributor in connection with its
+ distribution of the Program in a commercial product offering. The
+ obligations in this section do not apply to any claims or Losses
+ relating to any actual or alleged intellectual property infringement. In
+ order to qualify, an Indemnified Contributor must: a) promptly notify
+ the Commercial Contributor in writing of such claim, and b) allow the
+ Commercial Contributor to control, and cooperate with the Commercial
+ Contributor in, the defense and any related settlement negotiations. The
+ Indemnified Contributor may participate in any such claim at its own
+ expense.
+
+For example, a Contributor might include the Program in a commercial
+ product offering, Product X. That Contributor is then a Commercial
+ Contributor. If that Commercial Contributor then makes performance
+ claims, or offers warranties related to Product X, those performance
+ claims and warranties are such Commercial Contributor's responsibility
+ alone. Under this section, the Commercial Contributor would have to
+ defend claims against the other Contributors related to those
+ performance claims and warranties, and if a court requires any other
+ Contributor to pay any damages as a result, the Commercial Contributor
+ must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
+ PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,
+ ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
+ OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+ responsible for determining the appropriateness of using and
+ distributing the Program and assumes all risks associated with its
+ exercise of rights under this Agreement , including but not limited to
+ the risks and costs of program errors, compliance with applicable laws,
+ damage to or loss of data, programs or equipment, and unavailability or
+ interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
+ NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
+ WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
+ DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+ HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under
+ applicable law, it shall not affect the validity or enforceability of
+ the remainder of the terms of this Agreement, and without further action
+ by the parties hereto, such provision shall be reformed to the minimum
+ extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity
+ (including a cross-claim or counterclaim in a lawsuit) alleging that the
+ Program itself (excluding combinations of the Program with other
+ software or hardware) infringes such Recipient's patent(s), then such
+ Recipient's rights granted under Section 2(b) shall terminate as of the
+ date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it
+ fails to comply with any of the material terms or conditions of this
+ Agreement and does not cure such failure in a reasonable period of time
+ after becoming aware of such noncompliance. If all Recipient's rights
+ under this Agreement terminate, Recipient agrees to cease use and
+ distribution of the Program as soon as reasonably practicable. However,
+ Recipient's obligations under this Agreement and any licenses granted by
+ Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this
+ Agreement, but in order to avoid inconsistency the Agreement is
+ copyrighted and may only be modified in the following manner. The
+ Agreement Steward reserves the right to publish new versions (including
+ revisions) of this Agreement from time to time. No one other than the
+ Agreement Steward has the right to modify this Agreement. The Eclipse
+ Foundation is the initial Agreement Steward. The Eclipse Foundation may
+ assign the responsibility to serve as the Agreement Steward to a
+ suitable separate entity. Each new version of the Agreement will be
+ given a distinguishing version number. The Program (including
+ Contributions) may always be distributed subject to the version of the
+ Agreement under which it was received. In addition, after a new version
+ of the Agreement is published, Contributor may elect to distribute the
+ Program (including its Contributions) under the new version. Except as
+ expressly stated in Sections 2(a) and 2(b) above, Recipient receives no
+ rights or licenses to the intellectual property of any Contributor under
+ this Agreement, whether expressly, by implication, estoppel or
+ otherwise. All rights in the Program not expressly granted under this
+ Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and
+ the intellectual property laws of the United States of America. No party
+ to this Agreement will bring a legal action under this Agreement more
+ than one year after the cause of action arose. Each party waives its
+ rights to a jury trial in any resulting litigation.
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java
index e6dce4d67..7e3466f67 100644
--- a/app/src/main/java/org/schabi/newpipe/App.java
+++ b/app/src/main/java/org/schabi/newpipe/App.java
@@ -67,8 +67,10 @@ import io.reactivex.rxjava3.plugins.RxJavaPlugins;
public class App extends MultiDexApplication {
protected static final String TAG = App.class.toString();
private static App app;
+ public static final String PACKAGE_NAME = BuildConfig.APPLICATION_ID;
- @Nullable private Disposable disposable = null;
+ @Nullable
+ private Disposable disposable = null;
@NonNull
public static App getApp() {
diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java
index ff078fa2c..0c784e9d5 100644
--- a/app/src/main/java/org/schabi/newpipe/MainActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java
@@ -129,7 +129,7 @@ public class MainActivity extends AppCompatActivity {
+ "savedInstanceState = [" + savedInstanceState + "]");
}
- // enable TLS1.1/1.2 for kitkat devices, to fix download and play for mediaCCC sources
+ // enable TLS1.1/1.2 for kitkat devices, to fix download and play for media.ccc.de sources
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
TLSSocketFactoryCompat.setAsDefault();
}
diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.java b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.java
index 6ff691561..2569f4a94 100644
--- a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.java
@@ -29,37 +29,46 @@ public class AboutActivity extends AppCompatActivity {
* List of all software components.
*/
private static final SoftwareComponent[] SOFTWARE_COMPONENTS = {
- new SoftwareComponent("Giga Get", "2014 - 2015", "Peter Cai",
+ new SoftwareComponent("ACRA", "2013", "Kevin Gaudin",
+ "https://github.com/ACRA/acra", StandardLicenses.APACHE2),
+ new SoftwareComponent("AndroidX", "2005 - 2011", "The Android Open Source Project",
+ "https://developer.android.com/jetpack", StandardLicenses.APACHE2),
+ new SoftwareComponent("CircleImageView", "2014 - 2020", "Henning Dodenhof",
+ "https://github.com/hdodenhof/CircleImageView",
+ StandardLicenses.APACHE2),
+ new SoftwareComponent("ExoPlayer", "2014 - 2020", "Google, Inc.",
+ "https://github.com/google/ExoPlayer", StandardLicenses.APACHE2),
+ new SoftwareComponent("GigaGet", "2014 - 2015", "Peter Cai",
"https://github.com/PaperAirplane-Dev-Team/GigaGet", StandardLicenses.GPL3),
+ new SoftwareComponent("Groupie", "2016", "Lisa Wray",
+ "https://github.com/lisawray/groupie", StandardLicenses.MIT),
+ new SoftwareComponent("Icepick", "2015", "Frankie Sardo",
+ "https://github.com/frankiesardo/icepick", StandardLicenses.EPL1),
+ new SoftwareComponent("Jsoup", "2009 - 2020", "Jonathan Hedley",
+ "https://github.com/jhy/jsoup", StandardLicenses.MIT),
+ new SoftwareComponent("Markwon", "2019", "Dimitry Ivanov",
+ "https://github.com/noties/Markwon", StandardLicenses.APACHE2),
+ new SoftwareComponent("Material Components for Android", "2016 - 2020", "Google, Inc.",
+ "https://github.com/material-components/material-components-android",
+ StandardLicenses.APACHE2),
new SoftwareComponent("NewPipe Extractor", "2017 - 2020", "Christian Schabesberger",
"https://github.com/TeamNewPipe/NewPipeExtractor", StandardLicenses.GPL3),
- new SoftwareComponent("Jsoup", "2017", "Jonathan Hedley",
- "https://github.com/jhy/jsoup", StandardLicenses.MIT),
- new SoftwareComponent("Rhino", "2015", "Mozilla",
- "https://www.mozilla.org/rhino/", StandardLicenses.MPL2),
- new SoftwareComponent("ACRA", "2013", "Kevin Gaudin",
- "http://www.acra.ch", StandardLicenses.APACHE2),
+ new SoftwareComponent("NoNonsense-FilePicker", "2016", "Jonas Kalderstam",
+ "https://github.com/spacecowboy/NoNonsense-FilePicker",
+ StandardLicenses.MPL2),
+ new SoftwareComponent("OkHttp", "2019", "Square, Inc.",
+ "https://square.github.io/okhttp/", StandardLicenses.APACHE2),
+ new SoftwareComponent("PrettyTime", "2012 - 2020", "Lincoln Baxter, III",
+ "https://github.com/ocpsoft/prettytime", StandardLicenses.APACHE2),
+ new SoftwareComponent("RxAndroid", "2015", "The RxAndroid authors",
+ "https://github.com/ReactiveX/RxAndroid", StandardLicenses.APACHE2),
+ new SoftwareComponent("RxBinding", "2015", "Jake Wharton",
+ "https://github.com/JakeWharton/RxBinding", StandardLicenses.APACHE2),
+ new SoftwareComponent("RxJava", "2016 - 2020", "RxJava Contributors",
+ "https://github.com/ReactiveX/RxJava", StandardLicenses.APACHE2),
new SoftwareComponent("Universal Image Loader", "2011 - 2015", "Sergey Tarasevich",
"https://github.com/nostra13/Android-Universal-Image-Loader",
StandardLicenses.APACHE2),
- new SoftwareComponent("CircleImageView", "2014 - 2020", "Henning Dodenhof",
- "https://github.com/hdodenhof/CircleImageView", StandardLicenses.APACHE2),
- new SoftwareComponent("NoNonsense-FilePicker", "2016", "Jonas Kalderstam",
- "https://github.com/spacecowboy/NoNonsense-FilePicker", StandardLicenses.MPL2),
- new SoftwareComponent("ExoPlayer", "2014 - 2020", "Google Inc",
- "https://github.com/google/ExoPlayer", StandardLicenses.APACHE2),
- new SoftwareComponent("RxAndroid", "2015 - 2018", "The RxAndroid authors",
- "https://github.com/ReactiveX/RxAndroid", StandardLicenses.APACHE2),
- new SoftwareComponent("RxJava", "2016 - 2020", "RxJava Contributors",
- "https://github.com/ReactiveX/RxJava", StandardLicenses.APACHE2),
- new SoftwareComponent("RxBinding", "2015 - 2018", "Jake Wharton",
- "https://github.com/JakeWharton/RxBinding", StandardLicenses.APACHE2),
- new SoftwareComponent("PrettyTime", "2012 - 2020", "Lincoln Baxter, III",
- "https://github.com/ocpsoft/prettytime", StandardLicenses.APACHE2),
- new SoftwareComponent("Markwon", "2017 - 2020", "Noties",
- "https://github.com/noties/Markwon", StandardLicenses.APACHE2),
- new SoftwareComponent("Groupie", "2016", "Lisa Wray",
- "https://github.com/lisawray/groupie", StandardLicenses.MIT)
};
private static final int POS_ABOUT = 0;
@@ -115,7 +124,8 @@ public class AboutActivity extends AppCompatActivity {
* A placeholder fragment containing a simple view.
*/
public static class AboutFragment extends Fragment {
- public AboutFragment() { }
+ public AboutFragment() {
+ }
/**
* Created a new instance of this fragment for the given section number.
diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.java b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.java
index 8367a75dc..6e48a0e14 100644
--- a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.java
@@ -19,6 +19,7 @@ import org.schabi.newpipe.util.ShareUtils;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Comparator;
+import java.util.Objects;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
@@ -35,12 +36,9 @@ public class LicenseFragment extends Fragment {
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
public static LicenseFragment newInstance(final SoftwareComponent[] softwareComponents) {
- if (softwareComponents == null) {
- throw new NullPointerException("softwareComponents is null");
- }
- final LicenseFragment fragment = new LicenseFragment();
final Bundle bundle = new Bundle();
- bundle.putParcelableArray(ARG_COMPONENTS, softwareComponents);
+ bundle.putParcelableArray(ARG_COMPONENTS, Objects.requireNonNull(softwareComponents));
+ final LicenseFragment fragment = new LicenseFragment();
fragment.setArguments(bundle);
return fragment;
}
diff --git a/app/src/main/java/org/schabi/newpipe/about/StandardLicenses.java b/app/src/main/java/org/schabi/newpipe/about/StandardLicenses.java
index 50ee5ebc3..60b1e168c 100644
--- a/app/src/main/java/org/schabi/newpipe/about/StandardLicenses.java
+++ b/app/src/main/java/org/schabi/newpipe/about/StandardLicenses.java
@@ -12,6 +12,8 @@ public final class StandardLicenses {
= new License("Mozilla Public License, Version 2.0", "MPL 2.0", "mpl2.html");
public static final License MIT
= new License("MIT License", "MIT", "mit.html");
+ public static final License EPL1
+ = new License("Eclipse Public License, Version 1.0", "EPL 1.0", "epl1.html");
private StandardLicenses() { }
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
index 6560ab404..aeb51f63a 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
@@ -146,15 +146,15 @@ public final class VideoDetailFragment
private static final float MAX_PLAYER_HEIGHT = 0.7f;
public static final String ACTION_SHOW_MAIN_PLAYER =
- "org.schabi.newpipe.VideoDetailFragment.ACTION_SHOW_MAIN_PLAYER";
+ App.PACKAGE_NAME + ".VideoDetailFragment.ACTION_SHOW_MAIN_PLAYER";
public static final String ACTION_HIDE_MAIN_PLAYER =
- "org.schabi.newpipe.VideoDetailFragment.ACTION_HIDE_MAIN_PLAYER";
+ App.PACKAGE_NAME + ".VideoDetailFragment.ACTION_HIDE_MAIN_PLAYER";
public static final String ACTION_PLAYER_STARTED =
- "org.schabi.newpipe.VideoDetailFragment.ACTION_PLAYER_STARTED";
+ App.PACKAGE_NAME + ".VideoDetailFragment.ACTION_PLAYER_STARTED";
public static final String ACTION_VIDEO_FRAGMENT_RESUMED =
- "org.schabi.newpipe.VideoDetailFragment.ACTION_VIDEO_FRAGMENT_RESUMED";
+ App.PACKAGE_NAME + ".VideoDetailFragment.ACTION_VIDEO_FRAGMENT_RESUMED";
public static final String ACTION_VIDEO_FRAGMENT_STOPPED =
- "org.schabi.newpipe.VideoDetailFragment.ACTION_VIDEO_FRAGMENT_STOPPED";
+ App.PACKAGE_NAME + ".VideoDetailFragment.ACTION_VIDEO_FRAGMENT_STOPPED";
private static final String COMMENTS_TAB_TAG = "COMMENTS";
private static final String RELATED_TAB_TAG = "NEXT VIDEO";
@@ -498,10 +498,10 @@ public final class VideoDetailFragment
final PlaylistAppendDialog d = PlaylistAppendDialog.fromStreamInfo(currentInfo);
disposables.add(
- PlaylistAppendDialog.onPlaylistFound(getContext(),
- () -> d.show(getFM(), TAG),
- () -> PlaylistCreationDialog.newInstance(d).show(getFM(), TAG)
- )
+ PlaylistAppendDialog.onPlaylistFound(getContext(),
+ () -> d.show(getFM(), TAG),
+ () -> PlaylistCreationDialog.newInstance(d).show(getFM(), TAG)
+ )
);
}
break;
@@ -1891,8 +1891,10 @@ public final class VideoDetailFragment
if (fullscreen) {
hideSystemUiIfNeeded();
+ viewPager.setVisibility(View.GONE);
} else {
showSystemUi();
+ viewPager.setVisibility(View.VISIBLE);
}
if (relatedStreamsLayout != null) {
@@ -2048,6 +2050,10 @@ public final class VideoDetailFragment
// Apply system brightness when the player is not in fullscreen
restoreDefaultBrightness();
} else {
+ // Do not restore if user has disabled brightness gesture
+ if (!PlayerHelper.isBrightnessGestureEnabled(activity)) {
+ return;
+ }
// Restore already saved brightness level
final float brightnessLevel = PlayerHelper.getScreenBrightness(activity);
if (brightnessLevel == lp.screenBrightness) {
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java
index c0096ed10..12eab4734 100644
--- a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java
@@ -70,7 +70,8 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
} else {
itemProgressView.setVisibility(View.GONE);
}
- } else if (item.getStreamType() == StreamType.LIVE_STREAM) {
+ } else if (item.getStreamType() == StreamType.LIVE_STREAM
+ || item.getStreamType() == StreamType.AUDIO_LIVE_STREAM) {
itemDurationView.setText(R.string.duration_live);
itemDurationView.setBackgroundColor(ContextCompat.getColor(itemBuilder.getContext(),
R.color.live_duration_background_color));
diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadService.kt b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadService.kt
index 2a0aa1c90..45e8855e7 100644
--- a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadService.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadService.kt
@@ -43,6 +43,7 @@ import io.reactivex.rxjava3.processors.PublishProcessor
import io.reactivex.rxjava3.schedulers.Schedulers
import org.reactivestreams.Subscriber
import org.reactivestreams.Subscription
+import org.schabi.newpipe.App
import org.schabi.newpipe.MainActivity.DEBUG
import org.schabi.newpipe.R
import org.schabi.newpipe.database.feed.model.FeedGroupEntity
@@ -68,7 +69,7 @@ class FeedLoadService : Service() {
companion object {
private val TAG = FeedLoadService::class.java.simpleName
private const val NOTIFICATION_ID = 7293450
- private const val ACTION_CANCEL = "org.schabi.newpipe.local.feed.service.FeedLoadService.CANCEL"
+ private const val ACTION_CANCEL = App.PACKAGE_NAME + ".local.feed.service.FeedLoadService.CANCEL"
/**
* How often the notification will be updated.
diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java
index 982701d1f..5dfb1bfe5 100644
--- a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java
@@ -27,6 +27,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
+import org.schabi.newpipe.App;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
import org.schabi.newpipe.extractor.subscription.SubscriptionItem;
@@ -50,7 +51,7 @@ public class SubscriptionsExportService extends BaseImportExportService {
* A {@link LocalBroadcastManager local broadcast} will be made with this action
* when the export is successfully completed.
*/
- public static final String EXPORT_COMPLETE_ACTION = "org.schabi.newpipe.local.subscription"
+ public static final String EXPORT_COMPLETE_ACTION = App.PACKAGE_NAME + ".local.subscription"
+ ".services.SubscriptionsExportService.EXPORT_COMPLETE";
private Subscription subscription;
diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java
index b1c67719c..90d0afe37 100644
--- a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java
@@ -29,6 +29,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
+import org.schabi.newpipe.App;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
import org.schabi.newpipe.extractor.NewPipe;
@@ -66,7 +67,7 @@ public class SubscriptionsImportService extends BaseImportExportService {
* A {@link LocalBroadcastManager local broadcast} will be made with this action
* when the import is successfully completed.
*/
- public static final String IMPORT_COMPLETE_ACTION = "org.schabi.newpipe.local.subscription"
+ public static final String IMPORT_COMPLETE_ACTION = App.PACKAGE_NAME + ".local.subscription"
+ ".services.SubscriptionsImportService.IMPORT_COMPLETE";
/**
diff --git a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java
index d5ad9cb6f..8eae33de6 100644
--- a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java
+++ b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java
@@ -19,6 +19,12 @@
package org.schabi.newpipe.player;
+import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_INTERNAL;
+import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_PERIOD_TRANSITION;
+import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK;
+import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -30,11 +36,9 @@ import android.media.AudioManager;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
-
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceManager;
-
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlaybackException;
@@ -53,7 +57,12 @@ import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
-
+import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
+import io.reactivex.rxjava3.core.Observable;
+import io.reactivex.rxjava3.disposables.CompositeDisposable;
+import io.reactivex.rxjava3.disposables.Disposable;
+import io.reactivex.rxjava3.disposables.SerialDisposable;
+import java.io.IOException;
import org.schabi.newpipe.DownloaderImpl;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
@@ -75,20 +84,6 @@ import org.schabi.newpipe.player.resolver.MediaSourceTag;
import org.schabi.newpipe.util.ImageDisplayConstants;
import org.schabi.newpipe.util.SerializedCache;
-import java.io.IOException;
-
-import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
-import io.reactivex.rxjava3.core.Observable;
-import io.reactivex.rxjava3.disposables.CompositeDisposable;
-import io.reactivex.rxjava3.disposables.Disposable;
-import io.reactivex.rxjava3.disposables.SerialDisposable;
-
-import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_INTERNAL;
-import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_PERIOD_TRANSITION;
-import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK;
-import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-
/**
* Base for the players, joining the common properties.
*
@@ -342,37 +337,36 @@ public abstract class BasePlayer implements
simpleExoPlayer.setPlayWhenReady(playWhenReady);
} else if (intent.getBooleanExtra(RESUME_PLAYBACK, false)
- && isPlaybackResumeEnabled()
- && !samePlayQueue) {
- final PlayQueueItem item = queue.getItem();
- if (item != null && item.getRecoveryPosition() == PlayQueueItem.RECOVERY_UNSET) {
- stateLoader = recordManager.loadStreamState(item)
- .observeOn(AndroidSchedulers.mainThread())
- // Do not place initPlayback() in doFinally() because
- // it restarts playback after destroy()
- //.doFinally()
- .subscribe(
- state -> {
- queue.setRecovery(queue.getIndex(), state.getProgressTime());
- initPlayback(queue, repeatMode, playbackSpeed, playbackPitch,
- playbackSkipSilence, playWhenReady, isMuted);
- },
- error -> {
- if (DEBUG) {
- error.printStackTrace();
- }
- // In case any error we can start playback without history
- initPlayback(queue, repeatMode, playbackSpeed, playbackPitch,
- playbackSkipSilence, playWhenReady, isMuted);
- },
- () -> {
- // Completed but not found in history
+ && isPlaybackResumeEnabled()
+ && !samePlayQueue
+ && !queue.isEmpty()
+ && queue.getItem().getRecoveryPosition() == PlayQueueItem.RECOVERY_UNSET) {
+ stateLoader = recordManager.loadStreamState(queue.getItem())
+ .observeOn(AndroidSchedulers.mainThread())
+ // Do not place initPlayback() in doFinally() because
+ // it restarts playback after destroy()
+ //.doFinally()
+ .subscribe(
+ state -> {
+ queue.setRecovery(queue.getIndex(), state.getProgressTime());
+ initPlayback(queue, repeatMode, playbackSpeed, playbackPitch,
+ playbackSkipSilence, playWhenReady, isMuted);
+ },
+ error -> {
+ if (DEBUG) {
+ error.printStackTrace();
+ }
+ // In case any error we can start playback without history
+ initPlayback(queue, repeatMode, playbackSpeed, playbackPitch,
+ playbackSkipSilence, playWhenReady, isMuted);
+ },
+ () -> {
+ // Completed but not found in history
initPlayback(queue, repeatMode, playbackSpeed, playbackPitch,
playbackSkipSilence, playWhenReady, isMuted);
}
);
databaseUpdateReactor.add(stateLoader);
- }
} else {
// Good to go...
// In a case of equal PlayQueues we can re-init old one but only when it is disposed
diff --git a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java
index 63f6a400e..49c836346 100644
--- a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java
+++ b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java
@@ -33,6 +33,7 @@ import android.view.WindowManager;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
+import org.schabi.newpipe.App;
import org.schabi.newpipe.R;
import org.schabi.newpipe.util.ThemeHelper;
@@ -64,25 +65,25 @@ public final class MainPlayer extends Service {
//////////////////////////////////////////////////////////////////////////*/
static final String ACTION_CLOSE
- = "org.schabi.newpipe.player.MainPlayer.CLOSE";
+ = App.PACKAGE_NAME + ".player.MainPlayer.CLOSE";
static final String ACTION_PLAY_PAUSE
- = "org.schabi.newpipe.player.MainPlayer.PLAY_PAUSE";
+ = App.PACKAGE_NAME + ".player.MainPlayer.PLAY_PAUSE";
static final String ACTION_OPEN_CONTROLS
- = "org.schabi.newpipe.player.MainPlayer.OPEN_CONTROLS";
+ = App.PACKAGE_NAME + ".player.MainPlayer.OPEN_CONTROLS";
static final String ACTION_REPEAT
- = "org.schabi.newpipe.player.MainPlayer.REPEAT";
+ = App.PACKAGE_NAME + ".player.MainPlayer.REPEAT";
static final String ACTION_PLAY_NEXT
- = "org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_NEXT";
+ = App.PACKAGE_NAME + ".player.MainPlayer.ACTION_PLAY_NEXT";
static final String ACTION_PLAY_PREVIOUS
- = "org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_PREVIOUS";
+ = App.PACKAGE_NAME + ".player.MainPlayer.ACTION_PLAY_PREVIOUS";
static final String ACTION_FAST_REWIND
- = "org.schabi.newpipe.player.MainPlayer.ACTION_FAST_REWIND";
+ = App.PACKAGE_NAME + ".player.MainPlayer.ACTION_FAST_REWIND";
static final String ACTION_FAST_FORWARD
- = "org.schabi.newpipe.player.MainPlayer.ACTION_FAST_FORWARD";
+ = App.PACKAGE_NAME + ".player.MainPlayer.ACTION_FAST_FORWARD";
static final String ACTION_SHUFFLE
- = "org.schabi.newpipe.player.MainPlayer.ACTION_SHUFFLE";
+ = App.PACKAGE_NAME + ".player.MainPlayer.ACTION_SHUFFLE";
public static final String ACTION_RECREATE_NOTIFICATION
- = "org.schabi.newpipe.player.MainPlayer.ACTION_RECREATE_NOTIFICATION";
+ = App.PACKAGE_NAME + ".player.MainPlayer.ACTION_RECREATE_NOTIFICATION";
/*//////////////////////////////////////////////////////////////////////////
// Service's LifeCycle
diff --git a/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java b/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java
index 41d66dc90..fd20fd175 100644
--- a/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java
@@ -638,12 +638,12 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
case BasePlayer.STATE_COMPLETED:
queueControlBinding.controlPlayPause.setClickable(true);
queueControlBinding.controlPlayPause.setVisibility(View.VISIBLE);
- queueControlBinding.progressBar.setVisibility(View.GONE);
+ queueControlBinding.controlProgressBar.setVisibility(View.GONE);
break;
default:
queueControlBinding.controlPlayPause.setClickable(false);
queueControlBinding.controlPlayPause.setVisibility(View.INVISIBLE);
- queueControlBinding.progressBar.setVisibility(View.VISIBLE);
+ queueControlBinding.controlProgressBar.setVisibility(View.VISIBLE);
break;
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java
index a304b4430..10887790b 100644
--- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java
+++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java
@@ -505,6 +505,11 @@ public class VideoPlayerImpl extends VideoPlayer
switch (keyCode) {
default:
break;
+ case KeyEvent.KEYCODE_SPACE:
+ if (isFullscreen) {
+ onPlayPause();
+ }
+ break;
case KeyEvent.KEYCODE_BACK:
if (DeviceUtils.isTv(service) && isControlsVisible()) {
hideControls(0, 0);
@@ -1071,11 +1076,25 @@ public class VideoPlayerImpl extends VideoPlayer
private void animatePlayButtons(final boolean show, final int duration) {
animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, show, duration);
- if (playQueue.getIndex() > 0 || !show) {
- animateView(playPreviousButton, AnimationUtils.Type.SCALE_AND_ALPHA, show, duration);
+
+ boolean showQueueButtons = show;
+ if (playQueue == null) {
+ showQueueButtons = false;
}
- if (playQueue.getIndex() + 1 < playQueue.getStreams().size() || !show) {
- animateView(playNextButton, AnimationUtils.Type.SCALE_AND_ALPHA, show, duration);
+
+ if (!showQueueButtons || playQueue.getIndex() > 0) {
+ animateView(
+ playPreviousButton,
+ AnimationUtils.Type.SCALE_AND_ALPHA,
+ showQueueButtons,
+ duration);
+ }
+ if (!showQueueButtons || playQueue.getIndex() + 1 < playQueue.getStreams().size()) {
+ animateView(
+ playNextButton,
+ AnimationUtils.Type.SCALE_AND_ALPHA,
+ showQueueButtons,
+ duration);
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java b/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java
index ffe19599d..13ee24e16 100644
--- a/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java
+++ b/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java
@@ -5,14 +5,14 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.Intent;
-import android.media.AudioFocusRequest;
import android.media.AudioManager;
import android.media.audiofx.AudioEffect;
-import android.os.Build;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
+import androidx.media.AudioFocusRequestCompat;
+import androidx.media.AudioManagerCompat;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.analytics.AnalyticsListener;
@@ -21,20 +21,17 @@ public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, An
private static final String TAG = "AudioFocusReactor";
- private static final boolean SHOULD_BUILD_FOCUS_REQUEST =
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
-
private static final int DUCK_DURATION = 1500;
private static final float DUCK_AUDIO_TO = .2f;
- private static final int FOCUS_GAIN_TYPE = AudioManager.AUDIOFOCUS_GAIN;
+ private static final int FOCUS_GAIN_TYPE = AudioManagerCompat.AUDIOFOCUS_GAIN;
private static final int STREAM_TYPE = AudioManager.STREAM_MUSIC;
private final SimpleExoPlayer player;
private final Context context;
private final AudioManager audioManager;
- private final AudioFocusRequest request;
+ private final AudioFocusRequestCompat request;
public AudioReactor(@NonNull final Context context,
@NonNull final SimpleExoPlayer player) {
@@ -43,15 +40,11 @@ public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, An
this.audioManager = ContextCompat.getSystemService(context, AudioManager.class);
player.addAnalyticsListener(this);
- if (SHOULD_BUILD_FOCUS_REQUEST) {
- request = new AudioFocusRequest.Builder(FOCUS_GAIN_TYPE)
- .setAcceptsDelayedFocusGain(true)
- .setWillPauseWhenDucked(true)
- .setOnAudioFocusChangeListener(this)
- .build();
- } else {
- request = null;
- }
+ request = new AudioFocusRequestCompat.Builder(FOCUS_GAIN_TYPE)
+ //.setAcceptsDelayedFocusGain(true)
+ .setWillPauseWhenDucked(true)
+ .setOnAudioFocusChangeListener(this)
+ .build();
}
public void dispose() {
@@ -64,19 +57,11 @@ public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, An
//////////////////////////////////////////////////////////////////////////*/
public void requestAudioFocus() {
- if (SHOULD_BUILD_FOCUS_REQUEST) {
- audioManager.requestAudioFocus(request);
- } else {
- audioManager.requestAudioFocus(this, STREAM_TYPE, FOCUS_GAIN_TYPE);
- }
+ AudioManagerCompat.requestAudioFocus(audioManager, request);
}
public void abandonAudioFocus() {
- if (SHOULD_BUILD_FOCUS_REQUEST) {
- audioManager.abandonAudioFocusRequest(request);
- } else {
- audioManager.abandonAudioFocus(this);
- }
+ AudioManagerCompat.abandonAudioFocusRequest(audioManager, request);
}
public int getVolume() {
@@ -88,7 +73,7 @@ public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, An
}
public int getMaxVolume() {
- return audioManager.getStreamMaxVolume(STREAM_TYPE);
+ return AudioManagerCompat.getStreamMaxVolume(audioManager, STREAM_TYPE);
}
/*//////////////////////////////////////////////////////////////////////////
diff --git a/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java
index a4b29fc49..8742f0937 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java
@@ -246,10 +246,7 @@ public class DownloadSettingsFragment extends BasePreferenceFragment {
// revoke permissions on the old save path (required for SAF only)
- final Context context = getContext();
- if (context == null) {
- throw new NullPointerException("getContext()");
- }
+ final Context context = requireContext();
forgetSAFTree(context, defaultPreferences.getString(key, ""));
diff --git a/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java b/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java
index ccd4d13fc..d2daaf6cc 100644
--- a/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java
+++ b/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java
@@ -44,6 +44,10 @@ public final class KioskTranslator {
return c.getString(R.string.most_liked);
case "conferences":
return c.getString(R.string.conferences);
+ case "recent":
+ return c.getString(R.string.recent);
+ case "live":
+ return c.getString(R.string.duration_live);
default:
return kioskId;
}
@@ -59,9 +63,12 @@ public final class KioskTranslator {
case "Local":
return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_kiosk_local);
case "Recently added":
+ case "recent":
return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_kiosk_recent);
case "Most liked":
return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_thumb_up);
+ case "live":
+ return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_live_tv);
default:
return 0;
}
diff --git a/app/src/main/java/us/shandian/giga/get/DownloadMission.java b/app/src/main/java/us/shandian/giga/get/DownloadMission.java
index d7c586083..2b3faa3e0 100644
--- a/app/src/main/java/us/shandian/giga/get/DownloadMission.java
+++ b/app/src/main/java/us/shandian/giga/get/DownloadMission.java
@@ -22,6 +22,7 @@ import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.channels.ClosedByInterruptException;
+import java.util.Objects;
import javax.net.ssl.SSLException;
@@ -154,8 +155,8 @@ public class DownloadMission extends Mission {
public transient Thread init = null;
public DownloadMission(String[] urls, StoredFileHelper storage, char kind, Postprocessing psInstance) {
- if (urls == null) throw new NullPointerException("urls is null");
- if (urls.length < 1) throw new IllegalArgumentException("urls is empty");
+ if (Objects.requireNonNull(urls).length < 1)
+ throw new IllegalArgumentException("urls array is empty");
this.urls = urls;
this.kind = kind;
this.offsets = new long[urls.length];
diff --git a/app/src/main/java/us/shandian/giga/get/DownloadRunnable.java b/app/src/main/java/us/shandian/giga/get/DownloadRunnable.java
index 7fb12d088..6f504cea3 100644
--- a/app/src/main/java/us/shandian/giga/get/DownloadRunnable.java
+++ b/app/src/main/java/us/shandian/giga/get/DownloadRunnable.java
@@ -8,6 +8,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.nio.channels.ClosedByInterruptException;
+import java.util.Objects;
import us.shandian.giga.get.DownloadMission.Block;
import us.shandian.giga.get.DownloadMission.HttpError;
@@ -29,8 +30,7 @@ public class DownloadRunnable extends Thread {
private HttpURLConnection mConn;
DownloadRunnable(DownloadMission mission, int id) {
- if (mission == null) throw new NullPointerException("mission is null");
- mMission = mission;
+ mMission = Objects.requireNonNull(mission);
mId = id;
}
diff --git a/app/src/main/java/us/shandian/giga/get/sqlite/FinishedMissionStore.java b/app/src/main/java/us/shandian/giga/get/sqlite/FinishedMissionStore.java
index 1d1dca0df..15c45c6fd 100644
--- a/app/src/main/java/us/shandian/giga/get/sqlite/FinishedMissionStore.java
+++ b/app/src/main/java/us/shandian/giga/get/sqlite/FinishedMissionStore.java
@@ -12,6 +12,7 @@ import androidx.annotation.NonNull;
import java.io.File;
import java.util.ArrayList;
+import java.util.Objects;
import us.shandian.giga.get.DownloadMission;
import us.shandian.giga.get.FinishedMission;
@@ -140,9 +141,7 @@ public class FinishedMissionStore extends SQLiteOpenHelper {
}
private FinishedMission getMissionFromCursor(Cursor cursor) {
- if (cursor == null) throw new NullPointerException("cursor is null");
-
- String kind = cursor.getString(cursor.getColumnIndex(KEY_KIND));
+ String kind = Objects.requireNonNull(cursor).getString(cursor.getColumnIndex(KEY_KIND));
if (kind == null || kind.isEmpty()) kind = "?";
String path = cursor.getString(cursor.getColumnIndexOrThrow(KEY_PATH));
@@ -186,15 +185,13 @@ public class FinishedMissionStore extends SQLiteOpenHelper {
}
public void addFinishedMission(DownloadMission downloadMission) {
- if (downloadMission == null) throw new NullPointerException("downloadMission is null");
+ ContentValues values = getValuesOfMission(Objects.requireNonNull(downloadMission));
SQLiteDatabase database = getWritableDatabase();
- ContentValues values = getValuesOfMission(downloadMission);
database.insert(FINISHED_TABLE_NAME, null, values);
}
public void deleteMission(Mission mission) {
- if (mission == null) throw new NullPointerException("mission is null");
- String ts = String.valueOf(mission.timestamp);
+ String ts = String.valueOf(Objects.requireNonNull(mission).timestamp);
SQLiteDatabase database = getWritableDatabase();
@@ -212,9 +209,8 @@ public class FinishedMissionStore extends SQLiteOpenHelper {
}
public void updateMission(Mission mission) {
- if (mission == null) throw new NullPointerException("mission is null");
+ ContentValues values = getValuesOfMission(Objects.requireNonNull(mission));
SQLiteDatabase database = getWritableDatabase();
- ContentValues values = getValuesOfMission(mission);
String ts = String.valueOf(mission.timestamp);
int rowsAffected;
diff --git a/app/src/main/java/us/shandian/giga/io/CircularFileWriter.java b/app/src/main/java/us/shandian/giga/io/CircularFileWriter.java
index 4d62ab200..dbceeb091 100644
--- a/app/src/main/java/us/shandian/giga/io/CircularFileWriter.java
+++ b/app/src/main/java/us/shandian/giga/io/CircularFileWriter.java
@@ -7,6 +7,7 @@ import org.schabi.newpipe.streams.io.SharpStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.util.Objects;
public class CircularFileWriter extends SharpStream {
@@ -27,9 +28,7 @@ public class CircularFileWriter extends SharpStream {
private BufferedFile aux;
public CircularFileWriter(SharpStream target, File temp, OffsetChecker checker) throws IOException {
- if (checker == null) {
- throw new NullPointerException("checker is null");
- }
+ Objects.requireNonNull(checker);
if (!temp.exists()) {
if (!temp.createNewFile()) {
diff --git a/app/src/main/res/drawable/ic_live_tv_black_24dp.xml b/app/src/main/res/drawable/ic_live_tv_black_24dp.xml
new file mode 100644
index 000000000..1f7957c4a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_live_tv_black_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_live_tv_white_24dp.xml b/app/src/main/res/drawable/ic_live_tv_white_24dp.xml
new file mode 100644
index 000000000..303858f9d
--- /dev/null
+++ b/app/src/main/res/drawable/ic_live_tv_white_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/values-v21/styles_services.xml b/app/src/main/res/values-v21/styles_services.xml
index e5b675ef8..c495a9a31 100644
--- a/app/src/main/res/values-v21/styles_services.xml
+++ b/app/src/main/res/values-v21/styles_services.xml
@@ -12,6 +12,7 @@
+
-
-
-
-
-
-
-
-