2017-02-27 20:14:03 +00:00
|
|
|
package org.schabi.newpipe;
|
|
|
|
|
2018-06-17 11:55:43 +00:00
|
|
|
import android.annotation.SuppressLint;
|
2018-02-12 18:44:35 +00:00
|
|
|
import android.app.IntentService;
|
2018-04-06 09:02:51 +00:00
|
|
|
import android.content.Context;
|
2018-02-12 18:44:35 +00:00
|
|
|
import android.content.DialogInterface;
|
2017-02-27 20:14:03 +00:00
|
|
|
import android.content.Intent;
|
2018-02-12 18:44:35 +00:00
|
|
|
import android.content.SharedPreferences;
|
2018-06-20 12:46:57 +00:00
|
|
|
import android.content.pm.PackageManager;
|
2017-02-27 20:14:03 +00:00
|
|
|
import android.os.Bundle;
|
2020-08-27 20:55:57 +00:00
|
|
|
import androidx.preference.PreferenceManager;
|
2018-01-23 00:40:00 +00:00
|
|
|
import android.text.TextUtils;
|
2018-02-12 18:44:35 +00:00
|
|
|
import android.view.ContextThemeWrapper;
|
|
|
|
import android.view.LayoutInflater;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
import android.widget.Button;
|
|
|
|
import android.widget.LinearLayout;
|
|
|
|
import android.widget.RadioButton;
|
|
|
|
import android.widget.RadioGroup;
|
2017-02-27 20:14:03 +00:00
|
|
|
import android.widget.Toast;
|
|
|
|
|
2020-03-27 02:18:14 +00:00
|
|
|
import androidx.annotation.DrawableRes;
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
import androidx.appcompat.app.AlertDialog;
|
|
|
|
import androidx.appcompat.app.AppCompatActivity;
|
2020-04-01 13:15:38 +00:00
|
|
|
import androidx.appcompat.content.res.AppCompatResources;
|
2020-03-27 02:18:14 +00:00
|
|
|
import androidx.core.app.NotificationCompat;
|
2019-10-04 12:59:08 +00:00
|
|
|
import androidx.fragment.app.FragmentManager;
|
|
|
|
|
2018-06-17 11:55:43 +00:00
|
|
|
import org.schabi.newpipe.download.DownloadDialog;
|
2018-02-12 18:44:35 +00:00
|
|
|
import org.schabi.newpipe.extractor.Info;
|
|
|
|
import org.schabi.newpipe.extractor.NewPipe;
|
|
|
|
import org.schabi.newpipe.extractor.StreamingService;
|
|
|
|
import org.schabi.newpipe.extractor.StreamingService.LinkType;
|
|
|
|
import org.schabi.newpipe.extractor.channel.ChannelInfo;
|
2018-01-23 00:40:00 +00:00
|
|
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
2018-02-12 18:44:35 +00:00
|
|
|
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
|
|
|
|
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
2018-06-17 11:55:43 +00:00
|
|
|
import org.schabi.newpipe.extractor.stream.VideoStream;
|
2020-09-09 18:45:42 +00:00
|
|
|
import org.schabi.newpipe.player.helper.PlayerHelper;
|
2018-04-21 21:10:01 +00:00
|
|
|
import org.schabi.newpipe.player.playqueue.ChannelPlayQueue;
|
|
|
|
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
|
|
|
import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue;
|
|
|
|
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
|
2018-01-23 00:40:00 +00:00
|
|
|
import org.schabi.newpipe.report.UserAction;
|
2020-07-20 22:43:49 +00:00
|
|
|
import org.schabi.newpipe.util.DeviceUtils;
|
2018-12-24 18:11:21 +00:00
|
|
|
import org.schabi.newpipe.util.Constants;
|
2018-01-23 00:40:00 +00:00
|
|
|
import org.schabi.newpipe.util.ExtractorHelper;
|
2018-06-17 11:55:43 +00:00
|
|
|
import org.schabi.newpipe.util.ListHelper;
|
2017-04-09 17:34:00 +00:00
|
|
|
import org.schabi.newpipe.util.NavigationHelper;
|
2018-02-12 18:44:35 +00:00
|
|
|
import org.schabi.newpipe.util.PermissionHelper;
|
2020-06-28 11:33:08 +00:00
|
|
|
import org.schabi.newpipe.util.ShareUtils;
|
2018-02-12 18:44:35 +00:00
|
|
|
import org.schabi.newpipe.util.ThemeHelper;
|
2020-03-27 02:18:14 +00:00
|
|
|
import org.schabi.newpipe.util.urlfinder.UrlFinder;
|
2020-05-01 18:13:01 +00:00
|
|
|
import org.schabi.newpipe.views.FocusOverlayView;
|
2017-02-27 20:14:03 +00:00
|
|
|
|
2018-02-12 18:44:35 +00:00
|
|
|
import java.io.Serializable;
|
2018-04-06 09:02:51 +00:00
|
|
|
import java.util.ArrayList;
|
2018-02-12 18:44:35 +00:00
|
|
|
import java.util.Arrays;
|
2020-03-31 17:20:15 +00:00
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.HashSet;
|
2018-04-06 09:02:51 +00:00
|
|
|
import java.util.List;
|
2017-02-27 20:14:03 +00:00
|
|
|
|
2018-01-23 00:40:00 +00:00
|
|
|
import icepick.Icepick;
|
|
|
|
import icepick.State;
|
|
|
|
import io.reactivex.Observable;
|
2018-02-12 18:44:35 +00:00
|
|
|
import io.reactivex.Single;
|
2018-01-23 00:40:00 +00:00
|
|
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
|
|
|
import io.reactivex.disposables.CompositeDisposable;
|
2018-02-12 18:44:35 +00:00
|
|
|
import io.reactivex.disposables.Disposable;
|
|
|
|
import io.reactivex.functions.Consumer;
|
2018-01-23 00:40:00 +00:00
|
|
|
import io.reactivex.schedulers.Schedulers;
|
|
|
|
|
2018-04-18 14:44:46 +00:00
|
|
|
import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.AUDIO;
|
|
|
|
import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.VIDEO;
|
2018-02-12 18:44:35 +00:00
|
|
|
import static org.schabi.newpipe.util.ThemeHelper.resolveResourceIdFromAttr;
|
2017-02-27 20:14:03 +00:00
|
|
|
|
|
|
|
/**
|
2020-03-31 17:20:15 +00:00
|
|
|
* Get the url from the intent and open it in the chosen preferred player.
|
2017-02-27 20:14:03 +00:00
|
|
|
*/
|
2017-09-03 06:04:18 +00:00
|
|
|
public class RouterActivity extends AppCompatActivity {
|
2020-03-31 17:20:15 +00:00
|
|
|
public static final String INTERNAL_ROUTE_KEY = "internalRoute";
|
|
|
|
/**
|
|
|
|
* Removes invisible separators (\p{Z}) and punctuation characters including
|
|
|
|
* brackets (\p{P}). See http://www.regular-expressions.info/unicode.html for
|
|
|
|
* more details.
|
|
|
|
*/
|
|
|
|
private static final String REGEX_REMOVE_FROM_URL = "[\\p{Z}\\p{P}]";
|
|
|
|
protected final CompositeDisposable disposables = new CompositeDisposable();
|
2019-08-15 02:00:11 +00:00
|
|
|
@State
|
|
|
|
protected int currentServiceId = -1;
|
|
|
|
@State
|
|
|
|
protected LinkType currentLinkType;
|
|
|
|
@State
|
|
|
|
protected int selectedRadioPosition = -1;
|
2018-02-12 18:44:35 +00:00
|
|
|
protected int selectedPreviously = -1;
|
2018-01-23 00:40:00 +00:00
|
|
|
protected String currentUrl;
|
2019-03-01 23:42:06 +00:00
|
|
|
protected boolean internalRoute = false;
|
2020-03-31 17:20:15 +00:00
|
|
|
private StreamingService currentService;
|
2018-06-20 12:46:57 +00:00
|
|
|
private boolean selectionIsDownload = false;
|
2018-06-17 11:55:43 +00:00
|
|
|
|
2017-02-27 20:14:03 +00:00
|
|
|
@Override
|
2020-03-31 17:20:15 +00:00
|
|
|
protected void onCreate(final Bundle savedInstanceState) {
|
2017-02-27 20:14:03 +00:00
|
|
|
super.onCreate(savedInstanceState);
|
2018-01-23 00:40:00 +00:00
|
|
|
Icepick.restoreInstanceState(this, savedInstanceState);
|
2017-06-05 19:33:01 +00:00
|
|
|
|
2018-01-23 00:40:00 +00:00
|
|
|
if (TextUtils.isEmpty(currentUrl)) {
|
|
|
|
currentUrl = getUrl(getIntent());
|
|
|
|
|
|
|
|
if (TextUtils.isEmpty(currentUrl)) {
|
2018-12-24 18:11:21 +00:00
|
|
|
handleText();
|
2018-01-23 00:40:00 +00:00
|
|
|
finish();
|
|
|
|
}
|
|
|
|
}
|
2018-02-12 18:44:35 +00:00
|
|
|
|
2020-03-31 17:20:15 +00:00
|
|
|
internalRoute = getIntent().getBooleanExtra(INTERNAL_ROUTE_KEY, false);
|
2019-03-01 23:42:06 +00:00
|
|
|
|
2018-02-12 18:44:35 +00:00
|
|
|
setTheme(ThemeHelper.isLightThemeSelected(this)
|
2018-04-18 14:44:46 +00:00
|
|
|
? R.style.RouterActivityThemeLight : R.style.RouterActivityThemeDark);
|
2018-01-23 00:40:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-03-31 17:20:15 +00:00
|
|
|
protected void onSaveInstanceState(final Bundle outState) {
|
2018-06-20 12:46:57 +00:00
|
|
|
super.onSaveInstanceState(outState);
|
|
|
|
Icepick.saveInstanceState(this, outState);
|
2018-01-23 00:40:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onStart() {
|
|
|
|
super.onStart();
|
2018-12-24 18:11:21 +00:00
|
|
|
|
2018-01-23 00:40:00 +00:00
|
|
|
handleUrl(currentUrl);
|
2017-02-27 20:14:03 +00:00
|
|
|
}
|
|
|
|
|
2018-02-12 18:44:35 +00:00
|
|
|
@Override
|
|
|
|
protected void onDestroy() {
|
|
|
|
super.onDestroy();
|
|
|
|
|
|
|
|
disposables.clear();
|
|
|
|
}
|
|
|
|
|
2020-03-31 17:20:15 +00:00
|
|
|
private void handleUrl(final String url) {
|
2018-01-23 00:40:00 +00:00
|
|
|
disposables.add(Observable
|
2018-02-12 18:44:35 +00:00
|
|
|
.fromCallable(() -> {
|
|
|
|
if (currentServiceId == -1) {
|
|
|
|
currentService = NewPipe.getServiceByUrl(url);
|
|
|
|
currentServiceId = currentService.getServiceId();
|
|
|
|
currentLinkType = currentService.getLinkTypeByUrl(url);
|
2018-04-05 00:11:13 +00:00
|
|
|
currentUrl = url;
|
2018-02-12 18:44:35 +00:00
|
|
|
} else {
|
|
|
|
currentService = NewPipe.getService(currentServiceId);
|
|
|
|
}
|
|
|
|
|
|
|
|
return currentLinkType != LinkType.NONE;
|
|
|
|
})
|
2018-01-23 00:40:00 +00:00
|
|
|
.subscribeOn(Schedulers.io())
|
|
|
|
.observeOn(AndroidSchedulers.mainThread())
|
2018-02-12 18:44:35 +00:00
|
|
|
.subscribe(result -> {
|
|
|
|
if (result) {
|
|
|
|
onSuccess();
|
|
|
|
} else {
|
2020-06-28 11:33:08 +00:00
|
|
|
showUnsupportedUrlDialog(url);
|
2018-02-12 18:44:35 +00:00
|
|
|
}
|
2020-06-28 11:33:08 +00:00
|
|
|
}, throwable -> handleError(throwable, url)));
|
2018-01-23 00:40:00 +00:00
|
|
|
}
|
|
|
|
|
2020-06-28 11:33:08 +00:00
|
|
|
private void handleError(final Throwable throwable, final String url) {
|
|
|
|
throwable.printStackTrace();
|
2018-01-23 00:40:00 +00:00
|
|
|
|
2020-06-28 11:33:08 +00:00
|
|
|
if (throwable instanceof ExtractionException) {
|
|
|
|
showUnsupportedUrlDialog(url);
|
2018-01-23 00:40:00 +00:00
|
|
|
} else {
|
2020-06-28 11:33:08 +00:00
|
|
|
ExtractorHelper.handleGeneralException(this, -1, url, throwable,
|
2020-03-31 17:20:15 +00:00
|
|
|
UserAction.SOMETHING_ELSE, null);
|
2020-06-28 11:33:08 +00:00
|
|
|
finish();
|
2017-06-05 19:33:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-28 11:33:08 +00:00
|
|
|
private void showUnsupportedUrlDialog(final String url) {
|
|
|
|
final Context context = getThemeWrapperContext();
|
|
|
|
new AlertDialog.Builder(context)
|
|
|
|
.setTitle(R.string.unsupported_url)
|
|
|
|
.setMessage(R.string.unsupported_url_dialog_message)
|
|
|
|
.setIcon(ThemeHelper.resolveResourceIdFromAttr(context, R.attr.ic_share))
|
|
|
|
.setPositiveButton(R.string.open_in_browser,
|
|
|
|
(dialog, which) -> ShareUtils.openUrlInBrowser(this, url))
|
|
|
|
.setNegativeButton(R.string.share,
|
|
|
|
(dialog, which) -> ShareUtils.shareUrl(this, "", url)) // no subject
|
|
|
|
.setNeutralButton(R.string.cancel, null)
|
|
|
|
.setOnDismissListener(dialog -> finish())
|
|
|
|
.show();
|
2018-02-12 18:44:35 +00:00
|
|
|
}
|
2018-01-23 00:40:00 +00:00
|
|
|
|
2018-02-12 18:44:35 +00:00
|
|
|
protected void onSuccess() {
|
2020-03-31 17:20:15 +00:00
|
|
|
final SharedPreferences preferences = PreferenceManager
|
|
|
|
.getDefaultSharedPreferences(this);
|
|
|
|
final String selectedChoiceKey = preferences
|
|
|
|
.getString(getString(R.string.preferred_open_action_key),
|
|
|
|
getString(R.string.preferred_open_action_default));
|
2018-02-12 18:44:35 +00:00
|
|
|
|
2018-04-18 14:44:46 +00:00
|
|
|
final String showInfoKey = getString(R.string.show_info_key);
|
2018-04-06 09:02:51 +00:00
|
|
|
final String videoPlayerKey = getString(R.string.video_player_key);
|
|
|
|
final String backgroundPlayerKey = getString(R.string.background_player_key);
|
|
|
|
final String popupPlayerKey = getString(R.string.popup_player_key);
|
2018-06-17 11:55:43 +00:00
|
|
|
final String downloadKey = getString(R.string.download_key);
|
2018-02-14 18:33:43 +00:00
|
|
|
final String alwaysAskKey = getString(R.string.always_ask_open_action_key);
|
2018-02-12 18:44:35 +00:00
|
|
|
|
2018-04-18 14:44:46 +00:00
|
|
|
if (selectedChoiceKey.equals(alwaysAskKey)) {
|
2020-03-31 17:20:15 +00:00
|
|
|
final List<AdapterChoiceItem> choices
|
|
|
|
= getChoicesForService(currentService, currentLinkType);
|
2018-04-06 09:02:51 +00:00
|
|
|
|
2018-08-28 18:14:26 +00:00
|
|
|
switch (choices.size()) {
|
|
|
|
case 1:
|
|
|
|
handleChoice(choices.get(0).key);
|
|
|
|
break;
|
|
|
|
case 0:
|
|
|
|
handleChoice(showInfoKey);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
showDialog(choices);
|
|
|
|
break;
|
2018-04-18 14:44:46 +00:00
|
|
|
}
|
|
|
|
} else if (selectedChoiceKey.equals(showInfoKey)) {
|
|
|
|
handleChoice(showInfoKey);
|
2018-06-17 11:55:43 +00:00
|
|
|
} else if (selectedChoiceKey.equals(downloadKey)) {
|
|
|
|
handleChoice(downloadKey);
|
2018-02-12 18:44:35 +00:00
|
|
|
} else {
|
2020-03-31 17:20:15 +00:00
|
|
|
final boolean isExtVideoEnabled = preferences.getBoolean(
|
|
|
|
getString(R.string.use_external_video_player_key), false);
|
|
|
|
final boolean isExtAudioEnabled = preferences.getBoolean(
|
|
|
|
getString(R.string.use_external_audio_player_key), false);
|
|
|
|
final boolean isVideoPlayerSelected = selectedChoiceKey.equals(videoPlayerKey)
|
|
|
|
|| selectedChoiceKey.equals(popupPlayerKey);
|
2018-04-18 14:44:46 +00:00
|
|
|
final boolean isAudioPlayerSelected = selectedChoiceKey.equals(backgroundPlayerKey);
|
|
|
|
|
|
|
|
if (currentLinkType != LinkType.STREAM) {
|
2020-03-31 17:20:15 +00:00
|
|
|
if (isExtAudioEnabled && isAudioPlayerSelected
|
|
|
|
|| isExtVideoEnabled && isVideoPlayerSelected) {
|
|
|
|
Toast.makeText(this, R.string.external_player_unsupported_link_type,
|
|
|
|
Toast.LENGTH_LONG).show();
|
2018-04-18 14:44:46 +00:00
|
|
|
handleChoice(showInfoKey);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-31 17:20:15 +00:00
|
|
|
final List<StreamingService.ServiceInfo.MediaCapability> capabilities
|
|
|
|
= currentService.getServiceInfo().getMediaCapabilities();
|
2018-04-18 14:44:46 +00:00
|
|
|
|
|
|
|
boolean serviceSupportsChoice = false;
|
|
|
|
if (isVideoPlayerSelected) {
|
|
|
|
serviceSupportsChoice = capabilities.contains(VIDEO);
|
|
|
|
} else if (selectedChoiceKey.equals(backgroundPlayerKey)) {
|
|
|
|
serviceSupportsChoice = capabilities.contains(AUDIO);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (serviceSupportsChoice) {
|
|
|
|
handleChoice(selectedChoiceKey);
|
|
|
|
} else {
|
|
|
|
handleChoice(showInfoKey);
|
|
|
|
}
|
2018-02-12 18:44:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-18 14:44:46 +00:00
|
|
|
private void showDialog(final List<AdapterChoiceItem> choices) {
|
2018-04-06 09:02:51 +00:00
|
|
|
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
2018-04-18 14:44:46 +00:00
|
|
|
final Context themeWrapperContext = getThemeWrapperContext();
|
2018-02-12 18:44:35 +00:00
|
|
|
|
2018-04-06 09:02:51 +00:00
|
|
|
final LayoutInflater inflater = LayoutInflater.from(themeWrapperContext);
|
2020-03-31 17:20:15 +00:00
|
|
|
final LinearLayout rootLayout = (LinearLayout) inflater.inflate(
|
2020-09-08 17:02:05 +00:00
|
|
|
R.layout.single_choice_dialog_view, null, false);
|
2018-02-12 18:44:35 +00:00
|
|
|
final RadioGroup radioGroup = rootLayout.findViewById(android.R.id.list);
|
|
|
|
|
|
|
|
final DialogInterface.OnClickListener dialogButtonsClickListener = (dialog, which) -> {
|
|
|
|
final int indexOfChild = radioGroup.indexOfChild(
|
|
|
|
radioGroup.findViewById(radioGroup.getCheckedRadioButtonId()));
|
2018-04-06 09:02:51 +00:00
|
|
|
final AdapterChoiceItem choice = choices.get(indexOfChild);
|
2018-02-12 18:44:35 +00:00
|
|
|
|
|
|
|
handleChoice(choice.key);
|
|
|
|
|
2020-09-09 18:45:42 +00:00
|
|
|
// open future streams always like this one, because "always" button was used by user
|
2018-02-12 18:44:35 +00:00
|
|
|
if (which == DialogInterface.BUTTON_POSITIVE) {
|
2020-03-31 17:20:15 +00:00
|
|
|
preferences.edit()
|
|
|
|
.putString(getString(R.string.preferred_open_action_key), choice.key)
|
|
|
|
.apply();
|
2018-02-12 18:44:35 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-04-06 09:02:51 +00:00
|
|
|
final AlertDialog alertDialog = new AlertDialog.Builder(themeWrapperContext)
|
2018-04-07 18:36:52 +00:00
|
|
|
.setTitle(R.string.preferred_open_action_share_menu_title)
|
2018-02-12 18:44:35 +00:00
|
|
|
.setView(radioGroup)
|
|
|
|
.setCancelable(true)
|
|
|
|
.setNegativeButton(R.string.just_once, dialogButtonsClickListener)
|
|
|
|
.setPositiveButton(R.string.always, dialogButtonsClickListener)
|
2018-06-17 11:55:43 +00:00
|
|
|
.setOnDismissListener((dialog) -> {
|
2020-03-31 17:20:15 +00:00
|
|
|
if (!selectionIsDownload) {
|
|
|
|
finish();
|
|
|
|
}
|
2018-06-17 11:55:43 +00:00
|
|
|
})
|
2018-02-12 18:44:35 +00:00
|
|
|
.create();
|
|
|
|
|
2018-04-06 09:02:51 +00:00
|
|
|
//noinspection CodeBlock2Expr
|
2018-02-12 18:44:35 +00:00
|
|
|
alertDialog.setOnShowListener(dialog -> {
|
|
|
|
setDialogButtonsState(alertDialog, radioGroup.getCheckedRadioButtonId() != -1);
|
|
|
|
});
|
|
|
|
|
2020-03-31 17:20:15 +00:00
|
|
|
radioGroup.setOnCheckedChangeListener((group, checkedId) ->
|
|
|
|
setDialogButtonsState(alertDialog, true));
|
2018-02-12 18:44:35 +00:00
|
|
|
final View.OnClickListener radioButtonsClickListener = v -> {
|
|
|
|
final int indexOfChild = radioGroup.indexOfChild(v);
|
2020-03-31 17:20:15 +00:00
|
|
|
if (indexOfChild == -1) {
|
|
|
|
return;
|
|
|
|
}
|
2018-02-12 18:44:35 +00:00
|
|
|
|
|
|
|
selectedPreviously = selectedRadioPosition;
|
|
|
|
selectedRadioPosition = indexOfChild;
|
|
|
|
|
|
|
|
if (selectedPreviously == selectedRadioPosition) {
|
2018-04-06 09:02:51 +00:00
|
|
|
handleChoice(choices.get(selectedRadioPosition).key);
|
2018-02-12 18:44:35 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
int id = 12345;
|
2020-08-16 08:24:58 +00:00
|
|
|
for (final AdapterChoiceItem item : choices) {
|
2020-03-31 17:20:15 +00:00
|
|
|
final RadioButton radioButton
|
|
|
|
= (RadioButton) inflater.inflate(R.layout.list_radio_icon_item, null);
|
2018-02-12 18:44:35 +00:00
|
|
|
radioButton.setText(item.description);
|
2020-04-01 13:15:38 +00:00
|
|
|
radioButton.setCompoundDrawablesWithIntrinsicBounds(
|
|
|
|
AppCompatResources.getDrawable(getApplicationContext(), item.icon),
|
|
|
|
null, null, null);
|
2018-02-12 18:44:35 +00:00
|
|
|
radioButton.setChecked(false);
|
|
|
|
radioButton.setId(id++);
|
2020-03-31 17:20:15 +00:00
|
|
|
radioButton.setLayoutParams(new RadioGroup.LayoutParams(
|
|
|
|
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
2018-02-12 18:44:35 +00:00
|
|
|
radioButton.setOnClickListener(radioButtonsClickListener);
|
|
|
|
radioGroup.addView(radioButton);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selectedRadioPosition == -1) {
|
2020-03-31 17:20:15 +00:00
|
|
|
final String lastSelectedPlayer = preferences.getString(
|
|
|
|
getString(R.string.preferred_open_action_last_selected_key), null);
|
2018-02-12 18:44:35 +00:00
|
|
|
if (!TextUtils.isEmpty(lastSelectedPlayer)) {
|
2018-04-06 09:02:51 +00:00
|
|
|
for (int i = 0; i < choices.size(); i++) {
|
2020-08-16 08:24:58 +00:00
|
|
|
final AdapterChoiceItem c = choices.get(i);
|
2018-02-12 18:44:35 +00:00
|
|
|
if (lastSelectedPlayer.equals(c.key)) {
|
|
|
|
selectedRadioPosition = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-06 09:02:51 +00:00
|
|
|
selectedRadioPosition = Math.min(Math.max(-1, selectedRadioPosition), choices.size() - 1);
|
2018-02-12 18:44:35 +00:00
|
|
|
if (selectedRadioPosition != -1) {
|
|
|
|
((RadioButton) radioGroup.getChildAt(selectedRadioPosition)).setChecked(true);
|
|
|
|
}
|
|
|
|
selectedPreviously = selectedRadioPosition;
|
|
|
|
|
|
|
|
alertDialog.show();
|
2019-09-23 07:17:03 +00:00
|
|
|
|
2020-07-20 22:43:49 +00:00
|
|
|
if (DeviceUtils.isTv(this)) {
|
2019-09-23 07:17:03 +00:00
|
|
|
FocusOverlayView.setupFocusObserver(alertDialog);
|
|
|
|
}
|
2018-02-12 18:44:35 +00:00
|
|
|
}
|
|
|
|
|
2020-03-31 17:20:15 +00:00
|
|
|
private List<AdapterChoiceItem> getChoicesForService(final StreamingService service,
|
|
|
|
final LinkType linkType) {
|
2018-04-18 14:44:46 +00:00
|
|
|
final Context context = getThemeWrapperContext();
|
|
|
|
|
2018-04-06 09:02:51 +00:00
|
|
|
final List<AdapterChoiceItem> returnList = new ArrayList<>();
|
2020-03-31 17:20:15 +00:00
|
|
|
final List<StreamingService.ServiceInfo.MediaCapability> capabilities
|
|
|
|
= service.getServiceInfo().getMediaCapabilities();
|
|
|
|
|
|
|
|
final SharedPreferences preferences = PreferenceManager
|
|
|
|
.getDefaultSharedPreferences(this);
|
2020-08-16 08:24:58 +00:00
|
|
|
final boolean isExtVideoEnabled = preferences.getBoolean(
|
2020-03-31 17:20:15 +00:00
|
|
|
getString(R.string.use_external_video_player_key), false);
|
2020-08-16 08:24:58 +00:00
|
|
|
final boolean isExtAudioEnabled = preferences.getBoolean(
|
2020-03-31 17:20:15 +00:00
|
|
|
getString(R.string.use_external_audio_player_key), false);
|
|
|
|
|
2020-09-09 18:45:42 +00:00
|
|
|
final AdapterChoiceItem videoPlayer = new AdapterChoiceItem(
|
|
|
|
getString(R.string.video_player_key), getString(R.string.video_player),
|
|
|
|
resolveResourceIdFromAttr(context, R.attr.ic_play_arrow));
|
|
|
|
final AdapterChoiceItem showInfo = new AdapterChoiceItem(
|
|
|
|
getString(R.string.show_info_key), getString(R.string.show_info),
|
|
|
|
resolveResourceIdFromAttr(context, R.attr.ic_info_outline));
|
|
|
|
final AdapterChoiceItem popupPlayer = new AdapterChoiceItem(
|
|
|
|
getString(R.string.popup_player_key), getString(R.string.popup_player),
|
|
|
|
resolveResourceIdFromAttr(context, R.attr.ic_popup));
|
|
|
|
final AdapterChoiceItem backgroundPlayer = new AdapterChoiceItem(
|
|
|
|
getString(R.string.background_player_key), getString(R.string.background_player),
|
|
|
|
resolveResourceIdFromAttr(context, R.attr.ic_headset));
|
|
|
|
|
|
|
|
if (linkType == LinkType.STREAM) {
|
|
|
|
if (isExtVideoEnabled) {
|
|
|
|
// show both "show info" and "video player", they are two different activities
|
|
|
|
returnList.add(showInfo);
|
|
|
|
returnList.add(videoPlayer);
|
|
|
|
} else if (capabilities.contains(VIDEO)
|
|
|
|
&& PlayerHelper.isAutoplayAllowedByUser(context)) {
|
|
|
|
// show only "video player" since the details activity will be opened and the video
|
|
|
|
// will be autoplayed there and "show info" would do the exact same thing
|
|
|
|
returnList.add(videoPlayer);
|
|
|
|
} else {
|
|
|
|
// show only "show info" if video player is not applicable or autoplay is disabled
|
|
|
|
returnList.add(showInfo);
|
|
|
|
}
|
2018-04-06 09:02:51 +00:00
|
|
|
|
2020-09-09 18:45:42 +00:00
|
|
|
if (capabilities.contains(VIDEO)) {
|
|
|
|
returnList.add(popupPlayer);
|
|
|
|
}
|
|
|
|
if (capabilities.contains(AUDIO)) {
|
|
|
|
returnList.add(backgroundPlayer);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
returnList.add(showInfo);
|
|
|
|
if (capabilities.contains(VIDEO) && !isExtVideoEnabled) {
|
|
|
|
returnList.add(videoPlayer);
|
|
|
|
returnList.add(popupPlayer);
|
|
|
|
}
|
|
|
|
if (capabilities.contains(AUDIO) && !isExtAudioEnabled) {
|
|
|
|
returnList.add(backgroundPlayer);
|
|
|
|
}
|
2018-04-06 09:02:51 +00:00
|
|
|
}
|
|
|
|
|
2020-03-31 17:20:15 +00:00
|
|
|
returnList.add(new AdapterChoiceItem(getString(R.string.download_key),
|
|
|
|
getString(R.string.download),
|
2020-03-25 15:23:47 +00:00
|
|
|
resolveResourceIdFromAttr(context, R.attr.ic_file_download)));
|
2018-06-17 11:55:43 +00:00
|
|
|
|
2018-04-06 09:02:51 +00:00
|
|
|
return returnList;
|
|
|
|
}
|
|
|
|
|
2018-04-18 14:44:46 +00:00
|
|
|
private Context getThemeWrapperContext() {
|
2020-03-31 17:20:15 +00:00
|
|
|
return new ContextThemeWrapper(this, ThemeHelper.isLightThemeSelected(this)
|
|
|
|
? R.style.LightTheme : R.style.DarkTheme);
|
2018-04-18 14:44:46 +00:00
|
|
|
}
|
|
|
|
|
2020-03-31 17:20:15 +00:00
|
|
|
private void setDialogButtonsState(final AlertDialog dialog, final boolean state) {
|
2018-02-12 18:44:35 +00:00
|
|
|
final Button negativeButton = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
|
|
|
|
final Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
|
2020-03-31 17:20:15 +00:00
|
|
|
if (negativeButton == null || positiveButton == null) {
|
|
|
|
return;
|
|
|
|
}
|
2018-02-12 18:44:35 +00:00
|
|
|
|
|
|
|
negativeButton.setEnabled(state);
|
|
|
|
positiveButton.setEnabled(state);
|
|
|
|
}
|
|
|
|
|
2019-08-15 02:00:11 +00:00
|
|
|
private void handleText() {
|
2020-08-16 08:24:58 +00:00
|
|
|
final String searchString = getIntent().getStringExtra(Intent.EXTRA_TEXT);
|
|
|
|
final int serviceId = getIntent().getIntExtra(Constants.KEY_SERVICE_ID, 0);
|
|
|
|
final Intent intent = new Intent(getThemeWrapperContext(), MainActivity.class);
|
2018-12-24 18:11:21 +00:00
|
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
|
|
startActivity(intent);
|
2019-08-15 02:00:11 +00:00
|
|
|
NavigationHelper.openSearch(getThemeWrapperContext(), serviceId, searchString);
|
2018-12-24 18:11:21 +00:00
|
|
|
}
|
|
|
|
|
2018-04-18 14:44:46 +00:00
|
|
|
private void handleChoice(final String selectedChoiceKey) {
|
2020-03-31 17:20:15 +00:00
|
|
|
final List<String> validChoicesList = Arrays.asList(getResources()
|
|
|
|
.getStringArray(R.array.preferred_open_action_values_list));
|
2018-04-18 14:44:46 +00:00
|
|
|
if (validChoicesList.contains(selectedChoiceKey)) {
|
2018-02-12 18:44:35 +00:00
|
|
|
PreferenceManager.getDefaultSharedPreferences(this).edit()
|
2020-03-31 17:20:15 +00:00
|
|
|
.putString(getString(
|
|
|
|
R.string.preferred_open_action_last_selected_key), selectedChoiceKey)
|
2018-04-06 09:02:51 +00:00
|
|
|
.apply();
|
2018-02-12 18:44:35 +00:00
|
|
|
}
|
|
|
|
|
2020-03-31 17:20:15 +00:00
|
|
|
if (selectedChoiceKey.equals(getString(R.string.popup_player_key))
|
|
|
|
&& !PermissionHelper.isPopupEnabled(this)) {
|
2018-02-12 18:44:35 +00:00
|
|
|
PermissionHelper.showPopupEnablementToast(this);
|
|
|
|
finish();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-06-17 11:55:43 +00:00
|
|
|
if (selectedChoiceKey.equals(getString(R.string.download_key))) {
|
2020-03-31 17:20:15 +00:00
|
|
|
if (PermissionHelper.checkStoragePermissions(this,
|
|
|
|
PermissionHelper.DOWNLOAD_DIALOG_REQUEST_CODE)) {
|
2019-08-15 02:00:11 +00:00
|
|
|
selectionIsDownload = true;
|
|
|
|
openDownloadDialog();
|
|
|
|
}
|
2018-06-17 11:55:43 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-02-12 18:44:35 +00:00
|
|
|
// stop and bypass FetcherService if InfoScreen was selected since
|
|
|
|
// StreamDetailFragment can fetch data itself
|
2018-04-18 14:44:46 +00:00
|
|
|
if (selectedChoiceKey.equals(getString(R.string.show_info_key))) {
|
2018-02-12 18:44:35 +00:00
|
|
|
disposables.add(Observable
|
2018-04-05 20:45:00 +00:00
|
|
|
.fromCallable(() -> NavigationHelper.getIntentByLink(this, currentUrl))
|
2018-02-12 18:44:35 +00:00
|
|
|
.subscribeOn(Schedulers.io())
|
|
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
|
|
.subscribe(intent -> {
|
2019-08-15 02:00:11 +00:00
|
|
|
if (!internalRoute) {
|
2019-03-01 23:42:06 +00:00
|
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
|
|
|
}
|
2018-02-12 18:44:35 +00:00
|
|
|
startActivity(intent);
|
|
|
|
|
|
|
|
finish();
|
2020-06-28 11:33:08 +00:00
|
|
|
}, throwable -> handleError(throwable, currentUrl))
|
2018-02-12 18:44:35 +00:00
|
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
final Intent intent = new Intent(this, FetcherService.class);
|
2020-03-31 17:20:15 +00:00
|
|
|
final Choice choice = new Choice(currentService.getServiceId(), currentLinkType,
|
|
|
|
currentUrl, selectedChoiceKey);
|
2018-04-06 09:02:51 +00:00
|
|
|
intent.putExtra(FetcherService.KEY_CHOICE, choice);
|
2018-02-12 18:44:35 +00:00
|
|
|
startService(intent);
|
|
|
|
|
|
|
|
finish();
|
|
|
|
}
|
|
|
|
|
2018-06-20 12:46:57 +00:00
|
|
|
@SuppressLint("CheckResult")
|
|
|
|
private void openDownloadDialog() {
|
|
|
|
ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true)
|
|
|
|
.subscribeOn(Schedulers.io())
|
|
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
|
|
.subscribe((@NonNull StreamInfo result) -> {
|
2020-08-16 08:24:58 +00:00
|
|
|
final List<VideoStream> sortedVideoStreams = ListHelper
|
2020-03-31 17:20:15 +00:00
|
|
|
.getSortedStreamVideosList(this, result.getVideoStreams(),
|
|
|
|
result.getVideoOnlyStreams(), false);
|
2020-08-16 08:24:58 +00:00
|
|
|
final int selectedVideoStreamIndex = ListHelper
|
2020-03-31 17:20:15 +00:00
|
|
|
.getDefaultResolutionIndex(this, sortedVideoStreams);
|
2018-06-20 12:46:57 +00:00
|
|
|
|
2020-08-16 08:24:58 +00:00
|
|
|
final FragmentManager fm = getSupportFragmentManager();
|
|
|
|
final DownloadDialog downloadDialog = DownloadDialog.newInstance(result);
|
2018-06-20 12:46:57 +00:00
|
|
|
downloadDialog.setVideoStreams(sortedVideoStreams);
|
|
|
|
downloadDialog.setAudioStreams(result.getAudioStreams());
|
|
|
|
downloadDialog.setSelectedVideoStream(selectedVideoStreamIndex);
|
|
|
|
downloadDialog.show(fm, "downloadDialog");
|
|
|
|
fm.executePendingTransactions();
|
2020-06-28 11:33:08 +00:00
|
|
|
downloadDialog.getDialog().setOnDismissListener(dialog -> finish());
|
2018-06-20 12:46:57 +00:00
|
|
|
}, (@NonNull Throwable throwable) -> {
|
2020-06-28 11:33:08 +00:00
|
|
|
showUnsupportedUrlDialog(currentUrl);
|
2018-06-20 12:46:57 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-03-31 17:20:15 +00:00
|
|
|
public void onRequestPermissionsResult(final int requestCode,
|
|
|
|
@NonNull final String[] permissions,
|
|
|
|
@NonNull final int[] grantResults) {
|
2020-08-16 08:24:58 +00:00
|
|
|
for (final int i : grantResults) {
|
2019-08-15 02:00:11 +00:00
|
|
|
if (i == PackageManager.PERMISSION_DENIED) {
|
2018-06-20 12:46:57 +00:00
|
|
|
finish();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2019-08-15 02:00:11 +00:00
|
|
|
if (requestCode == PermissionHelper.DOWNLOAD_DIALOG_REQUEST_CODE) {
|
|
|
|
openDownloadDialog();
|
|
|
|
}
|
2018-06-20 12:46:57 +00:00
|
|
|
}
|
|
|
|
|
2020-03-31 17:20:15 +00:00
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Service Fetcher
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
|
|
|
private String removeHeadingGibberish(final String input) {
|
|
|
|
int start = 0;
|
|
|
|
for (int i = input.indexOf("://") - 1; i >= 0; i--) {
|
|
|
|
if (!input.substring(i, i + 1).matches("\\p{L}")) {
|
|
|
|
start = i + 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return input.substring(start);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Utils
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
|
|
|
private String trim(final String input) {
|
|
|
|
if (input == null || input.length() < 1) {
|
|
|
|
return input;
|
|
|
|
} else {
|
|
|
|
String output = input;
|
|
|
|
while (output.length() > 0 && output.substring(0, 1).matches(REGEX_REMOVE_FROM_URL)) {
|
|
|
|
output = output.substring(1);
|
|
|
|
}
|
|
|
|
while (output.length() > 0
|
|
|
|
&& output.substring(output.length() - 1).matches(REGEX_REMOVE_FROM_URL)) {
|
|
|
|
output = output.substring(0, output.length() - 1);
|
|
|
|
}
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves all Strings which look remotely like URLs from a text.
|
|
|
|
* Used if NewPipe was called through share menu.
|
|
|
|
*
|
|
|
|
* @param sharedText text to scan for URLs.
|
|
|
|
* @return potential URLs
|
|
|
|
*/
|
|
|
|
protected String[] getUris(final String sharedText) {
|
|
|
|
final Collection<String> result = new HashSet<>();
|
|
|
|
if (sharedText != null) {
|
|
|
|
final String[] array = sharedText.split("\\p{Space}");
|
|
|
|
for (String s : array) {
|
|
|
|
s = trim(s);
|
|
|
|
if (s.length() != 0) {
|
|
|
|
if (s.matches(".+://.+")) {
|
|
|
|
result.add(removeHeadingGibberish(s));
|
|
|
|
} else if (s.matches(".+\\..+")) {
|
|
|
|
result.add("http://" + s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-08-27 20:56:58 +00:00
|
|
|
return result.toArray(new String[0]);
|
2020-03-31 17:20:15 +00:00
|
|
|
}
|
|
|
|
|
2018-02-12 18:44:35 +00:00
|
|
|
private static class AdapterChoiceItem {
|
2020-03-31 17:20:15 +00:00
|
|
|
final String description;
|
|
|
|
final String key;
|
2019-08-15 02:00:11 +00:00
|
|
|
@DrawableRes
|
|
|
|
final int icon;
|
2018-02-12 18:44:35 +00:00
|
|
|
|
2020-03-31 17:20:15 +00:00
|
|
|
AdapterChoiceItem(final String key, final String description, final int icon) {
|
2018-02-12 18:44:35 +00:00
|
|
|
this.description = description;
|
|
|
|
this.key = key;
|
|
|
|
this.icon = icon;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static class Choice implements Serializable {
|
|
|
|
final int serviceId;
|
2020-03-31 17:20:15 +00:00
|
|
|
final String url;
|
|
|
|
final String playerChoice;
|
2018-02-12 18:44:35 +00:00
|
|
|
final LinkType linkType;
|
|
|
|
|
2020-03-31 17:20:15 +00:00
|
|
|
Choice(final int serviceId, final LinkType linkType,
|
|
|
|
final String url, final String playerChoice) {
|
2018-02-12 18:44:35 +00:00
|
|
|
this.serviceId = serviceId;
|
|
|
|
this.linkType = linkType;
|
|
|
|
this.url = url;
|
|
|
|
this.playerChoice = playerChoice;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return serviceId + ":" + url + " > " + linkType + " ::: " + playerChoice;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static class FetcherService extends IntentService {
|
|
|
|
|
|
|
|
public static final String KEY_CHOICE = "key_choice";
|
2020-03-31 17:20:15 +00:00
|
|
|
private static final int ID = 456;
|
2018-02-12 18:44:35 +00:00
|
|
|
private Disposable fetcher;
|
|
|
|
|
|
|
|
public FetcherService() {
|
|
|
|
super(FetcherService.class.getSimpleName());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onCreate() {
|
|
|
|
super.onCreate();
|
|
|
|
startForeground(ID, createNotification().build());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-03-31 17:20:15 +00:00
|
|
|
protected void onHandleIntent(@Nullable final Intent intent) {
|
|
|
|
if (intent == null) {
|
|
|
|
return;
|
|
|
|
}
|
2018-02-12 18:44:35 +00:00
|
|
|
|
|
|
|
final Serializable serializable = intent.getSerializableExtra(KEY_CHOICE);
|
2020-03-31 17:20:15 +00:00
|
|
|
if (!(serializable instanceof Choice)) {
|
|
|
|
return;
|
|
|
|
}
|
2020-08-16 08:24:58 +00:00
|
|
|
final Choice playerChoice = (Choice) serializable;
|
2018-02-12 18:44:35 +00:00
|
|
|
handleChoice(playerChoice);
|
|
|
|
}
|
|
|
|
|
2020-03-31 17:20:15 +00:00
|
|
|
public void handleChoice(final Choice choice) {
|
2018-02-12 18:44:35 +00:00
|
|
|
Single<? extends Info> single = null;
|
|
|
|
UserAction userAction = UserAction.SOMETHING_ELSE;
|
|
|
|
|
|
|
|
switch (choice.linkType) {
|
|
|
|
case STREAM:
|
|
|
|
single = ExtractorHelper.getStreamInfo(choice.serviceId, choice.url, false);
|
|
|
|
userAction = UserAction.REQUESTED_STREAM;
|
|
|
|
break;
|
|
|
|
case CHANNEL:
|
|
|
|
single = ExtractorHelper.getChannelInfo(choice.serviceId, choice.url, false);
|
|
|
|
userAction = UserAction.REQUESTED_CHANNEL;
|
|
|
|
break;
|
|
|
|
case PLAYLIST:
|
|
|
|
single = ExtractorHelper.getPlaylistInfo(choice.serviceId, choice.url, false);
|
|
|
|
userAction = UserAction.REQUESTED_PLAYLIST;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (single != null) {
|
|
|
|
final UserAction finalUserAction = userAction;
|
|
|
|
final Consumer<Info> resultHandler = getResultHandler(choice);
|
|
|
|
fetcher = single
|
|
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
|
|
.subscribe(info -> {
|
|
|
|
resultHandler.accept(info);
|
2020-03-31 17:20:15 +00:00
|
|
|
if (fetcher != null) {
|
|
|
|
fetcher.dispose();
|
|
|
|
}
|
2018-02-12 18:44:35 +00:00
|
|
|
}, throwable -> ExtractorHelper.handleGeneralException(this,
|
2020-03-31 17:20:15 +00:00
|
|
|
choice.serviceId, choice.url, throwable, finalUserAction,
|
|
|
|
", opened with " + choice.playerChoice));
|
2018-02-12 18:44:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-31 17:20:15 +00:00
|
|
|
public Consumer<Info> getResultHandler(final Choice choice) {
|
2018-02-12 18:44:35 +00:00
|
|
|
return info -> {
|
|
|
|
final String videoPlayerKey = getString(R.string.video_player_key);
|
|
|
|
final String backgroundPlayerKey = getString(R.string.background_player_key);
|
|
|
|
final String popupPlayerKey = getString(R.string.popup_player_key);
|
|
|
|
|
2020-03-31 17:20:15 +00:00
|
|
|
final SharedPreferences preferences = PreferenceManager
|
|
|
|
.getDefaultSharedPreferences(this);
|
2020-08-16 08:24:58 +00:00
|
|
|
final boolean isExtVideoEnabled = preferences.getBoolean(
|
2020-03-31 17:20:15 +00:00
|
|
|
getString(R.string.use_external_video_player_key), false);
|
2020-08-16 08:24:58 +00:00
|
|
|
final boolean isExtAudioEnabled = preferences.getBoolean(
|
2020-03-31 17:20:15 +00:00
|
|
|
getString(R.string.use_external_audio_player_key), false);
|
2018-02-12 18:44:35 +00:00
|
|
|
|
|
|
|
PlayQueue playQueue;
|
2020-08-16 08:24:58 +00:00
|
|
|
final String playerChoice = choice.playerChoice;
|
2018-02-12 18:44:35 +00:00
|
|
|
|
|
|
|
if (info instanceof StreamInfo) {
|
|
|
|
if (playerChoice.equals(backgroundPlayerKey) && isExtAudioEnabled) {
|
|
|
|
NavigationHelper.playOnExternalAudioPlayer(this, (StreamInfo) info);
|
|
|
|
|
|
|
|
} else if (playerChoice.equals(videoPlayerKey) && isExtVideoEnabled) {
|
|
|
|
NavigationHelper.playOnExternalVideoPlayer(this, (StreamInfo) info);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
playQueue = new SinglePlayQueue((StreamInfo) info);
|
|
|
|
|
|
|
|
if (playerChoice.equals(videoPlayerKey)) {
|
2019-12-29 21:15:01 +00:00
|
|
|
openMainPlayer(playQueue, choice);
|
2018-02-12 18:44:35 +00:00
|
|
|
} else if (playerChoice.equals(backgroundPlayerKey)) {
|
|
|
|
NavigationHelper.enqueueOnBackgroundPlayer(this, playQueue, true);
|
|
|
|
} else if (playerChoice.equals(popupPlayerKey)) {
|
|
|
|
NavigationHelper.enqueueOnPopupPlayer(this, playQueue, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (info instanceof ChannelInfo || info instanceof PlaylistInfo) {
|
2020-03-31 17:20:15 +00:00
|
|
|
playQueue = info instanceof ChannelInfo
|
|
|
|
? new ChannelPlayQueue((ChannelInfo) info)
|
|
|
|
: new PlaylistPlayQueue((PlaylistInfo) info);
|
2018-02-12 18:44:35 +00:00
|
|
|
|
|
|
|
if (playerChoice.equals(videoPlayerKey)) {
|
2019-12-29 21:15:01 +00:00
|
|
|
openMainPlayer(playQueue, choice);
|
2018-02-12 18:44:35 +00:00
|
|
|
} else if (playerChoice.equals(backgroundPlayerKey)) {
|
2019-04-13 07:31:32 +00:00
|
|
|
NavigationHelper.playOnBackgroundPlayer(this, playQueue, true);
|
2018-02-12 18:44:35 +00:00
|
|
|
} else if (playerChoice.equals(popupPlayerKey)) {
|
2019-04-13 07:31:32 +00:00
|
|
|
NavigationHelper.playOnPopupPlayer(this, playQueue, true);
|
2018-02-12 18:44:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-07-14 17:21:32 +00:00
|
|
|
private void openMainPlayer(final PlayQueue playQueue, final Choice choice) {
|
2020-06-27 03:25:50 +00:00
|
|
|
NavigationHelper.playOnMainPlayer(this, playQueue, choice.linkType,
|
|
|
|
choice.url, "", true, true);
|
2019-12-29 21:15:01 +00:00
|
|
|
}
|
|
|
|
|
2018-02-12 18:44:35 +00:00
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
|
|
|
super.onDestroy();
|
|
|
|
stopForeground(true);
|
2020-03-31 17:20:15 +00:00
|
|
|
if (fetcher != null) {
|
|
|
|
fetcher.dispose();
|
|
|
|
}
|
2018-02-12 18:44:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private NotificationCompat.Builder createNotification() {
|
|
|
|
return new NotificationCompat.Builder(this, getString(R.string.notification_channel_id))
|
|
|
|
.setOngoing(true)
|
|
|
|
.setSmallIcon(R.drawable.ic_newpipe_triangle_white)
|
|
|
|
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
2020-03-31 17:20:15 +00:00
|
|
|
.setContentTitle(
|
|
|
|
getString(R.string.preferred_player_fetcher_notification_title))
|
|
|
|
.setContentText(
|
|
|
|
getString(R.string.preferred_player_fetcher_notification_message));
|
2018-02-12 18:44:35 +00:00
|
|
|
}
|
2018-01-23 00:40:00 +00:00
|
|
|
}
|
|
|
|
|
2017-06-05 19:33:01 +00:00
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Utils
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
2020-03-27 02:18:14 +00:00
|
|
|
@Nullable
|
2020-03-31 17:20:15 +00:00
|
|
|
private String getUrl(final Intent intent) {
|
2020-03-27 02:18:14 +00:00
|
|
|
String foundUrl = null;
|
2017-04-09 17:34:00 +00:00
|
|
|
if (intent.getData() != null) {
|
2020-03-27 02:18:14 +00:00
|
|
|
// Called from another app
|
|
|
|
foundUrl = intent.getData().toString();
|
2017-04-09 17:34:00 +00:00
|
|
|
} else if (intent.getStringExtra(Intent.EXTRA_TEXT) != null) {
|
2020-03-27 02:18:14 +00:00
|
|
|
// Called from the share menu
|
|
|
|
final String extraText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
|
|
|
foundUrl = UrlFinder.firstUrlFromInput(extraText);
|
2017-04-09 17:34:00 +00:00
|
|
|
}
|
|
|
|
|
2020-03-27 02:18:14 +00:00
|
|
|
return foundUrl;
|
2017-02-27 20:14:03 +00:00
|
|
|
}
|
|
|
|
}
|