kopia lustrzana https://github.com/TeamNewPipe/NewPipe
Merge remote-tracking branch 'origin/master'
commit
b79ed8185f
|
@ -8,8 +8,8 @@ android {
|
|||
applicationId "org.schabi.newpipe"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 25
|
||||
versionCode 23
|
||||
versionName "0.8.9"
|
||||
versionCode 24
|
||||
versionName "0.8.10"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
|
|
@ -156,6 +156,7 @@
|
|||
<activity
|
||||
android:name=".ChannelActivity"
|
||||
android:label="@string/title_activity_channel"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/AppTheme.NoActionBar" />
|
||||
|
||||
<activity
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
|||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
import org.schabi.newpipe.util.NavStack;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
@ -62,15 +63,9 @@ import static android.os.Build.VERSION.SDK_INT;
|
|||
*/
|
||||
|
||||
public class ChannelActivity extends AppCompatActivity {
|
||||
|
||||
|
||||
private static final String TAG = ChannelActivity.class.toString();
|
||||
private View rootView = null;
|
||||
|
||||
// intent const
|
||||
public static final String CHANNEL_URL = "channel_url";
|
||||
public static final String SERVICE_ID = "service_id";
|
||||
|
||||
private int serviceId = -1;
|
||||
private String channelUrl = "";
|
||||
private int pageNumber = 0;
|
||||
|
@ -82,21 +77,31 @@ public class ChannelActivity extends AppCompatActivity {
|
|||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
//since we set themeing we have to set translucent statusBar by hand
|
||||
if (PreferenceManager.getDefaultSharedPreferences(this)
|
||||
.getString("theme", getResources().getString(R.string.light_theme_title)).
|
||||
equals(getResources().getString(R.string.dark_theme_title))) {
|
||||
setTheme(R.style.DarkTheme_NoActionBar);
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
setTranslucentStatusBar(getWindow());
|
||||
|
||||
setContentView(R.layout.activity_channel);
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
rootView = findViewById(R.id.rootView);
|
||||
setSupportActionBar(toolbar);
|
||||
Intent i = getIntent();
|
||||
channelUrl = i.getStringExtra(CHANNEL_URL);
|
||||
serviceId = i.getIntExtra(SERVICE_ID, -1);
|
||||
if(savedInstanceState == null) {
|
||||
Intent i = getIntent();
|
||||
channelUrl = i.getStringExtra(NavStack.URL);
|
||||
serviceId = i.getIntExtra(NavStack.SERVICE_ID, -1);
|
||||
} else {
|
||||
channelUrl = savedInstanceState.getString(NavStack.URL);
|
||||
serviceId = savedInstanceState.getInt(NavStack.SERVICE_ID);
|
||||
NavStack.getInstance()
|
||||
.restoreSavedInstanceState(savedInstanceState);
|
||||
}
|
||||
|
||||
setTranslucentStatusBar(getWindow());
|
||||
|
||||
infoListAdapter = new InfoListAdapter(this, rootView);
|
||||
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.channel_streams_view);
|
||||
|
@ -107,11 +112,8 @@ public class ChannelActivity extends AppCompatActivity {
|
|||
new InfoItemBuilder.OnInfoItemSelectedListener() {
|
||||
@Override
|
||||
public void selected(String url, int serviceId) {
|
||||
Intent detailIntent = new Intent(ChannelActivity.this, VideoItemDetailActivity.class);
|
||||
detailIntent.putExtra(VideoItemDetailFragment.VIDEO_URL, url);
|
||||
detailIntent.putExtra(
|
||||
VideoItemDetailFragment.STREAMING_SERVICE, serviceId);
|
||||
startActivity(detailIntent);
|
||||
NavStack.getInstance()
|
||||
.openDetailActivity(ChannelActivity.this, url, serviceId);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -141,7 +143,14 @@ public class ChannelActivity extends AppCompatActivity {
|
|||
requestData(false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(NavStack.URL, channelUrl);
|
||||
outState.putInt(NavStack.SERVICE_ID, serviceId);
|
||||
NavStack.getInstance()
|
||||
.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
private void updateUi(final ChannelInfo info) {
|
||||
CollapsingToolbarLayout ctl = (CollapsingToolbarLayout) findViewById(R.id.channel_toolbar_layout);
|
||||
|
@ -312,4 +321,14 @@ public class ChannelActivity extends AppCompatActivity {
|
|||
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
try {
|
||||
NavStack.getInstance()
|
||||
.navBack(this);
|
||||
} catch (Exception e) {
|
||||
ErrorActivity.reportUiError(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -86,4 +86,9 @@ public class MainActivity extends ThemableActivity {
|
|||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
//ignore back
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.schabi.newpipe.detail;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Bundle;
|
||||
|
@ -16,10 +17,14 @@ import org.schabi.newpipe.R;
|
|||
import org.schabi.newpipe.ThemableActivity;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
import org.schabi.newpipe.util.NavStack;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
|
||||
|
||||
/**
|
||||
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
||||
|
@ -81,8 +86,10 @@ public class VideoItemDetailActivity extends ThemableActivity {
|
|||
if (savedInstanceState == null) {
|
||||
handleIntent(getIntent());
|
||||
} else {
|
||||
videoUrl = savedInstanceState.getString(VideoItemDetailFragment.VIDEO_URL);
|
||||
currentStreamingService = savedInstanceState.getInt(VideoItemDetailFragment.STREAMING_SERVICE);
|
||||
videoUrl = savedInstanceState.getString(NavStack.URL);
|
||||
currentStreamingService = savedInstanceState.getInt(NavStack.SERVICE_ID);
|
||||
NavStack.getInstance()
|
||||
.restoreSavedInstanceState(savedInstanceState);
|
||||
addFragment(savedInstanceState);
|
||||
}
|
||||
}
|
||||
|
@ -114,12 +121,12 @@ public class VideoItemDetailActivity extends ThemableActivity {
|
|||
currentStreamingService = getServiceIdByUrl(videoUrl);
|
||||
} else {
|
||||
//this is if the video was called through another NewPipe activity
|
||||
videoUrl = intent.getStringExtra(VideoItemDetailFragment.VIDEO_URL);
|
||||
currentStreamingService = intent.getIntExtra(VideoItemDetailFragment.STREAMING_SERVICE, -1);
|
||||
videoUrl = intent.getStringExtra(NavStack.URL);
|
||||
currentStreamingService = intent.getIntExtra(NavStack.SERVICE_ID, -1);
|
||||
}
|
||||
arguments.putBoolean(VideoItemDetailFragment.AUTO_PLAY, autoplay);
|
||||
arguments.putString(VideoItemDetailFragment.VIDEO_URL, videoUrl);
|
||||
arguments.putInt(VideoItemDetailFragment.STREAMING_SERVICE, currentStreamingService);
|
||||
arguments.putString(NavStack.URL, videoUrl);
|
||||
arguments.putInt(NavStack.SERVICE_ID, currentStreamingService);
|
||||
addFragment(arguments);
|
||||
}
|
||||
|
||||
|
@ -142,9 +149,11 @@ public class VideoItemDetailActivity extends ThemableActivity {
|
|||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(VideoItemDetailFragment.VIDEO_URL, videoUrl);
|
||||
outState.putInt(VideoItemDetailFragment.STREAMING_SERVICE, currentStreamingService);
|
||||
outState.putString(NavStack.URL, videoUrl);
|
||||
outState.putInt(NavStack.SERVICE_ID, currentStreamingService);
|
||||
outState.putBoolean(VideoItemDetailFragment.AUTO_PLAY, false);
|
||||
NavStack.getInstance()
|
||||
.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -159,15 +168,24 @@ public class VideoItemDetailActivity extends ThemableActivity {
|
|||
|
||||
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
|
||||
|
||||
Intent intent = new Intent(this, MainActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
NavUtils.navigateUpTo(this, intent);
|
||||
NavStack.getInstance()
|
||||
.openMainActivity(this);
|
||||
return true;
|
||||
} else {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
try {
|
||||
NavStack.getInstance()
|
||||
.navBack(this);
|
||||
} catch (Exception e) {
|
||||
ErrorActivity.reportUiError(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all Strings which look remotely like URLs from a text.
|
||||
* Used if NewPipe was called through share menu.
|
||||
|
@ -224,7 +242,7 @@ public class VideoItemDetailActivity extends ThemableActivity {
|
|||
StreamingService[] serviceList = NewPipe.getServices();
|
||||
int service = -1;
|
||||
for (int i = 0; i < serviceList.length; i++) {
|
||||
if (serviceList[i].getUrlIdHandlerInstance().acceptUrl(videoUrl)) {
|
||||
if (serviceList[i].getStreamUrlIdHandlerInstance().acceptUrl(videoUrl)) {
|
||||
service = i;
|
||||
//videoExtractor = ServiceList.getService(i).getExtractorInstance();
|
||||
break;
|
||||
|
|
|
@ -40,7 +40,6 @@ import com.nostra13.universalimageloader.core.assist.FailReason;
|
|||
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
||||
|
||||
import org.schabi.newpipe.ActivityCommunicator;
|
||||
import org.schabi.newpipe.ChannelActivity;
|
||||
import org.schabi.newpipe.ImageErrorLoadingListener;
|
||||
import org.schabi.newpipe.Localization;
|
||||
import org.schabi.newpipe.R;
|
||||
|
@ -51,7 +50,6 @@ import org.schabi.newpipe.extractor.MediaFormat;
|
|||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.stream_info.AudioStream;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfo;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.stream_info.VideoStream;
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.player.BackgroundPlayer;
|
||||
|
@ -59,6 +57,8 @@ import org.schabi.newpipe.player.ExoPlayerActivity;
|
|||
import org.schabi.newpipe.player.PlayVideoActivity;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.schabi.newpipe.util.NavStack;
|
||||
import org.schabi.newpipe.util.PermissionHelper;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
@ -92,8 +92,6 @@ public class VideoItemDetailFragment extends Fragment {
|
|||
* The fragment argument representing the item ID that this fragment
|
||||
* represents.
|
||||
*/
|
||||
public static final String VIDEO_URL = "video_url";
|
||||
public static final String STREAMING_SERVICE = "streaming_service";
|
||||
public static final String AUTO_PLAY = "auto_play";
|
||||
|
||||
private AppCompatActivity activity;
|
||||
|
@ -289,10 +287,8 @@ public class VideoItemDetailFragment extends Fragment {
|
|||
channelButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Intent i = new Intent(activity, ChannelActivity.class);
|
||||
i.putExtra(ChannelActivity.CHANNEL_URL, info.channel_url);
|
||||
i.putExtra(ChannelActivity.SERVICE_ID, info.service_id);
|
||||
startActivity(i);
|
||||
NavStack.getInstance()
|
||||
.openChannelActivity(getActivity(), info.channel_url, info.service_id);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
@ -544,7 +540,8 @@ public class VideoItemDetailFragment extends Fragment {
|
|||
new InfoItemBuilder.OnInfoItemSelectedListener() {
|
||||
@Override
|
||||
public void selected(String url, int serviceId) {
|
||||
openStreamUrl(url);
|
||||
NavStack.getInstance()
|
||||
.openDetailActivity(getContext(), url, serviceId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -679,8 +676,8 @@ public class VideoItemDetailFragment extends Fragment {
|
|||
// then we must not try to access objects of this fragment.
|
||||
// Otherwise the applications would crash.
|
||||
if(backgroundButton != null) {
|
||||
streamingServiceId = getArguments().getInt(STREAMING_SERVICE);
|
||||
String videoUrl = getArguments().getString(VIDEO_URL);
|
||||
streamingServiceId = getArguments().getInt(NavStack.SERVICE_ID);
|
||||
String videoUrl = getArguments().getString(NavStack.URL);
|
||||
StreamInfoWorker siw = StreamInfoWorker.getInstance();
|
||||
siw.search(streamingServiceId, videoUrl, getActivity());
|
||||
|
||||
|
@ -813,21 +810,13 @@ public class VideoItemDetailFragment extends Fragment {
|
|||
stringResource, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private void openStreamUrl(String url) {
|
||||
Intent detailIntent = new Intent(activity, VideoItemDetailActivity.class);
|
||||
detailIntent.putExtra(VideoItemDetailFragment.VIDEO_URL, url);
|
||||
detailIntent.putExtra(
|
||||
VideoItemDetailFragment.STREAMING_SERVICE, streamingServiceId);
|
||||
activity.startActivity(detailIntent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
switch (requestCode) {
|
||||
case RECAPTCHA_REQUEST:
|
||||
if (resultCode == RESULT_OK) {
|
||||
String videoUrl = getArguments().getString(VIDEO_URL);
|
||||
String videoUrl = getArguments().getString(NavStack.URL);
|
||||
StreamInfoWorker siw = StreamInfoWorker.getInstance();
|
||||
siw.search(streamingServiceId, videoUrl, getActivity());
|
||||
} else {
|
||||
|
|
|
@ -242,9 +242,7 @@ public class DownloadActivity extends ThemableActivity implements AdapterView.On
|
|||
|
||||
switch (id) {
|
||||
case android.R.id.home: {
|
||||
Intent intent = new Intent(this, org.schabi.newpipe.MainActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
NavUtils.navigateUpTo(this, intent);
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
case R.id.action_settings: {
|
||||
|
@ -252,14 +250,6 @@ public class DownloadActivity extends ThemableActivity implements AdapterView.On
|
|||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
case R.id.action_report_error: {
|
||||
ErrorActivity.reportError(DownloadActivity.this, new Vector<Throwable>(),
|
||||
null, null,
|
||||
ErrorActivity.ErrorInfo.make(ErrorActivity.USER_REPORT,
|
||||
null,
|
||||
"user_report", R.string.user_report));
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
|
|
@ -34,25 +34,22 @@ public class NewPipe {
|
|||
|
||||
private static final String TAG = NewPipe.class.toString();
|
||||
|
||||
private static final StreamingService[] serviceList = {
|
||||
new YoutubeService(0)
|
||||
};
|
||||
|
||||
private static Downloader downloader = null;
|
||||
|
||||
public static StreamingService[] getServices() {
|
||||
return serviceList;
|
||||
return ServiceList.serviceList;
|
||||
}
|
||||
public static StreamingService getService(int serviceId)throws ExtractionException {
|
||||
for(StreamingService s : serviceList) {
|
||||
for(StreamingService s : ServiceList.serviceList) {
|
||||
if(s.getServiceId() == serviceId) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
throw new ExtractionException("Service not known: " + Integer.toString(serviceId));
|
||||
return null;
|
||||
}
|
||||
public static StreamingService getService(String serviceName) throws ExtractionException {
|
||||
return serviceList[getIdOfService(serviceName)];
|
||||
return ServiceList.serviceList[getIdOfService(serviceName)];
|
||||
}
|
||||
public static String getNameOfService(int id) {
|
||||
try {
|
||||
|
@ -63,13 +60,13 @@ public class NewPipe {
|
|||
return "";
|
||||
}
|
||||
}
|
||||
public static int getIdOfService(String serviceName) throws ExtractionException {
|
||||
for(int i = 0; i < serviceList.length; i++) {
|
||||
if(serviceList[i].getServiceInfo().name.equals(serviceName)) {
|
||||
public static int getIdOfService(String serviceName) {
|
||||
for(int i = 0; i < ServiceList.serviceList.length; i++) {
|
||||
if(ServiceList.serviceList[i].getServiceInfo().name.equals(serviceName)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new ExtractionException("Error: Service " + serviceName + " not known.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static void init(Downloader d) {
|
||||
|
@ -79,4 +76,13 @@ public class NewPipe {
|
|||
public static Downloader getDownloader() {
|
||||
return downloader;
|
||||
}
|
||||
|
||||
public static StreamingService getServiceByUrl(String url) {
|
||||
for(StreamingService s : ServiceList.serviceList) {
|
||||
if(s.getLinkTypeByUrl(url) != StreamingService.LinkType.NONE) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package org.schabi.newpipe.extractor;
|
||||
|
||||
import org.schabi.newpipe.extractor.services.youtube.YoutubeService;
|
||||
|
||||
/**
|
||||
* Created by the-scrabi on 18.02.17.
|
||||
*/
|
||||
|
||||
class ServiceList {
|
||||
public static final StreamingService[] serviceList = {
|
||||
new YoutubeService(0)
|
||||
};
|
||||
}
|
|
@ -32,6 +32,13 @@ public abstract class StreamingService {
|
|||
public String name = "";
|
||||
}
|
||||
|
||||
public enum LinkType {
|
||||
NONE,
|
||||
STREAM,
|
||||
CHANNEL,
|
||||
PLAYLIST
|
||||
}
|
||||
|
||||
private int serviceId;
|
||||
|
||||
public StreamingService(int id) {
|
||||
|
@ -43,7 +50,7 @@ public abstract class StreamingService {
|
|||
public abstract StreamExtractor getExtractorInstance(String url)
|
||||
throws IOException, ExtractionException;
|
||||
public abstract SearchEngine getSearchEngineInstance();
|
||||
public abstract UrlIdHandler getUrlIdHandlerInstance();
|
||||
public abstract UrlIdHandler getStreamUrlIdHandlerInstance();
|
||||
public abstract UrlIdHandler getChannelUrlIdHandlerInstance();
|
||||
public abstract ChannelExtractor getChannelExtractorInstance(String url, int page)
|
||||
throws ExtractionException, IOException;
|
||||
|
@ -52,4 +59,20 @@ public abstract class StreamingService {
|
|||
public final int getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* figure out where the link is pointing to (a channel, video, playlist, etc.)
|
||||
*/
|
||||
public final LinkType getLinkTypeByUrl(String url) {
|
||||
UrlIdHandler sH = getStreamUrlIdHandlerInstance();
|
||||
UrlIdHandler cH = getChannelUrlIdHandlerInstance();
|
||||
|
||||
if(sH.acceptUrl(url)) {
|
||||
return LinkType.STREAM;
|
||||
} else if(cH.acceptUrl(url)) {
|
||||
return LinkType.CHANNEL;
|
||||
} else {
|
||||
return LinkType.NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
|||
*/
|
||||
|
||||
public interface UrlIdHandler {
|
||||
|
||||
String getUrl(String videoId);
|
||||
String getId(String siteUrl) throws ParsingException;
|
||||
String cleanUrl(String siteUrl) throws ParsingException;
|
||||
|
|
|
@ -56,11 +56,11 @@ public class YoutubeService extends StreamingService {
|
|||
}
|
||||
@Override
|
||||
public SearchEngine getSearchEngineInstance() {
|
||||
return new YoutubeSearchEngine(getUrlIdHandlerInstance(), getServiceId());
|
||||
return new YoutubeSearchEngine(getStreamUrlIdHandlerInstance(), getServiceId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public UrlIdHandler getUrlIdHandlerInstance() {
|
||||
public UrlIdHandler getStreamUrlIdHandlerInstance() {
|
||||
return YoutubeStreamUrlIdHandler.getInstance();
|
||||
}
|
||||
|
||||
|
|
|
@ -150,7 +150,17 @@ public class YoutubeStreamUrlIdHandler implements UrlIdHandler {
|
|||
@Override
|
||||
public boolean acceptUrl(String videoUrl) {
|
||||
videoUrl = videoUrl.toLowerCase();
|
||||
return videoUrl.contains("youtube") ||
|
||||
videoUrl.contains("youtu.be");
|
||||
if(videoUrl.contains("youtube") ||
|
||||
videoUrl.contains("youtu.be")) {
|
||||
// bad programming I know
|
||||
try {
|
||||
getId(videoUrl);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ public class StreamInfoItemCollector extends InfoItemCollector {
|
|||
throw new ParsingException("Error: UrlIdHandler not set");
|
||||
} else if (!resultItem.webpage_url.isEmpty()) {
|
||||
resultItem.id = NewPipe.getService(getServiceId())
|
||||
.getUrlIdHandlerInstance()
|
||||
.getStreamUrlIdHandlerInstance()
|
||||
.getId(resultItem.webpage_url);
|
||||
}
|
||||
resultItem.title = extractor.getTitle();
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.schabi.newpipe.BuildConfig;
|
|||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.detail.VideoItemDetailActivity;
|
||||
import org.schabi.newpipe.detail.VideoItemDetailFragment;
|
||||
import org.schabi.newpipe.util.NavStack;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
@ -355,8 +356,8 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
|
|||
//build intent to return to video, on tapping notification
|
||||
Intent openDetailViewIntent = new Intent(getApplicationContext(),
|
||||
VideoItemDetailActivity.class);
|
||||
openDetailViewIntent.putExtra(VideoItemDetailFragment.STREAMING_SERVICE, serviceId);
|
||||
openDetailViewIntent.putExtra(VideoItemDetailFragment.VIDEO_URL, webUrl);
|
||||
openDetailViewIntent.putExtra(NavStack.SERVICE_ID, serviceId);
|
||||
openDetailViewIntent.putExtra(NavStack.URL, webUrl);
|
||||
openDetailViewIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
PendingIntent openDetailView = PendingIntent.getActivity(owner, noteID,
|
||||
openDetailViewIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
|
|
@ -16,6 +16,7 @@ import android.support.v4.app.NavUtils;
|
|||
import android.support.v7.app.ActionBar;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
|
@ -161,6 +162,10 @@ public class ErrorActivity extends ThemableActivity {
|
|||
private TextView infoView;
|
||||
private TextView errorMessageView;
|
||||
|
||||
public static void reportUiError(final AppCompatActivity activity, final Throwable el) {
|
||||
reportError(activity, el, activity.getClass(), null, ErrorInfo.make(UI_ERROR, "none", "", R.string.app_ui_crash));
|
||||
}
|
||||
|
||||
public static void reportError(final Context context, final List<Throwable> el,
|
||||
final Class returnAcitivty, View rootView, final ErrorInfo errorInfo) {
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.schabi.newpipe.R;
|
|||
import org.schabi.newpipe.detail.VideoItemDetailActivity;
|
||||
import org.schabi.newpipe.detail.VideoItemDetailFragment;
|
||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
||||
import org.schabi.newpipe.util.NavStack;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
|
@ -224,13 +225,15 @@ public class SearchInfoItemFragment extends Fragment {
|
|||
new InfoItemBuilder.OnInfoItemSelectedListener() {
|
||||
@Override
|
||||
public void selected(String url, int serviceId) {
|
||||
startDetailActivity(url);
|
||||
NavStack.getInstance()
|
||||
.openDetailActivity(getContext(), url, serviceId);
|
||||
}
|
||||
});
|
||||
infoListAdapter.setOnChannelInfoItemSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener() {
|
||||
@Override
|
||||
public void selected(String url, int serviceId) {
|
||||
startChannelActivity(url, serviceId);
|
||||
NavStack.getInstance()
|
||||
.openChannelActivity(getContext(), url, serviceId);
|
||||
}
|
||||
});
|
||||
recyclerView.setAdapter(infoListAdapter);
|
||||
|
@ -257,20 +260,6 @@ public class SearchInfoItemFragment extends Fragment {
|
|||
return view;
|
||||
}
|
||||
|
||||
private void startDetailActivity(String url) {
|
||||
Intent i = new Intent(getActivity(), VideoItemDetailActivity.class);
|
||||
i.putExtra(VideoItemDetailFragment.STREAMING_SERVICE, streamingServiceId);
|
||||
i.putExtra(VideoItemDetailFragment.VIDEO_URL, url);
|
||||
getActivity().startActivity(i);
|
||||
}
|
||||
|
||||
private void startChannelActivity(String url, int serviceId) {
|
||||
Intent i = new Intent(getActivity(), ChannelActivity.class);
|
||||
i.putExtra(ChannelActivity.CHANNEL_URL, url);
|
||||
i.putExtra(ChannelActivity.SERVICE_ID, serviceId);
|
||||
startActivity(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
package org.schabi.newpipe.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.Log;
|
||||
|
||||
import org.schabi.newpipe.ChannelActivity;
|
||||
import org.schabi.newpipe.MainActivity;
|
||||
import org.schabi.newpipe.detail.VideoItemDetailActivity;
|
||||
import org.schabi.newpipe.detail.VideoItemDetailFragment;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 16.02.17.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
||||
* NavStack.java is part of NewPipe.
|
||||
*
|
||||
* NewPipe is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* NewPipe is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* class helps to navigate within the app
|
||||
* IMPORTAND: the top of the stack is the current activity !!!
|
||||
*/
|
||||
public class NavStack {
|
||||
private static final String TAG = NavStack.class.toString();
|
||||
public static final String SERVICE_ID = "service_id";
|
||||
public static final String URL = "url";
|
||||
|
||||
private static final String NAV_STACK="nav_stack";
|
||||
|
||||
private enum ActivityId {
|
||||
CHANNEL,
|
||||
DETAIL
|
||||
}
|
||||
|
||||
private class NavEntry {
|
||||
public NavEntry(String url, int serviceId) {
|
||||
this.url = url;
|
||||
this.serviceId = serviceId;
|
||||
}
|
||||
public String url;
|
||||
public int serviceId;
|
||||
}
|
||||
|
||||
private static NavStack instance = new NavStack();
|
||||
private Stack<NavEntry> stack = new Stack<NavEntry>();
|
||||
|
||||
private NavStack() {
|
||||
}
|
||||
|
||||
public static NavStack getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private void addEntry(String url, Class ac, int serviceId) {
|
||||
stack.push(new NavEntry(url, serviceId));
|
||||
}
|
||||
|
||||
public void navBack(Activity activity) throws Exception {
|
||||
if(stack.size() == 0) { // if stack is already empty here, activity was probably called
|
||||
// from another app
|
||||
activity.finish();
|
||||
return;
|
||||
}
|
||||
stack.pop(); // remove curent activty, since we dont want to return to itself
|
||||
if (stack.size() == 0) {
|
||||
openMainActivity(activity); // if no more page is on the stack this means we are home
|
||||
return;
|
||||
}
|
||||
NavEntry entry = stack.pop(); // this element will reapear, since by calling the old page
|
||||
// this element will be pushed on top again
|
||||
try {
|
||||
StreamingService service = NewPipe.getService(entry.serviceId);
|
||||
switch (service.getLinkTypeByUrl(entry.url)) {
|
||||
case STREAM:
|
||||
openDetailActivity(activity, entry.url, entry.serviceId);
|
||||
break;
|
||||
case CHANNEL:
|
||||
openChannelActivity(activity, entry.url, entry.serviceId);
|
||||
break;
|
||||
case NONE:
|
||||
throw new Exception("Url not known to service. service="
|
||||
+ Integer.toString(entry.serviceId) + " url=" + entry.url);
|
||||
default:
|
||||
openMainActivity(activity);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void openChannelActivity(Context context, String url, int serviceId) {
|
||||
openActivity(context, url, serviceId, ChannelActivity.class);
|
||||
}
|
||||
|
||||
public void openDetailActivity(Context context, String url, int serviceId) {
|
||||
openActivity(context, url, serviceId, VideoItemDetailActivity.class);
|
||||
}
|
||||
|
||||
private void openActivity(Context context, String url, int serviceId, Class acitivtyClass) {
|
||||
stack.push(new NavEntry(url, serviceId));
|
||||
Intent i = new Intent(context, acitivtyClass);
|
||||
i.putExtra(SERVICE_ID, serviceId);
|
||||
i.putExtra(URL, url);
|
||||
context.startActivity(i);
|
||||
}
|
||||
|
||||
public void openMainActivity(Activity a) {
|
||||
stack.clear();
|
||||
Intent i = new Intent(a, MainActivity.class);
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
NavUtils.navigateUpTo(a, i);
|
||||
}
|
||||
|
||||
public void onSaveInstanceState(Bundle state) {
|
||||
ArrayList<String> sa = new ArrayList<>();
|
||||
for(NavEntry entry : stack) {
|
||||
sa.add(entry.url);
|
||||
}
|
||||
state.putStringArrayList(NAV_STACK, sa);
|
||||
}
|
||||
|
||||
public void restoreSavedInstanceState(Bundle state) {
|
||||
ArrayList<String> sa = state.getStringArrayList(NAV_STACK);
|
||||
for(String url : sa) {
|
||||
stack.push(new NavEntry(url, NewPipe.getServiceByUrl(url).getServiceId()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,12 +2,7 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
|
||||
<item android:id="@+id/action_settings"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/settings"/>
|
||||
|
||||
<item android:id="@+id/action_report_error"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/report_error" />
|
||||
</menu>
|
Ładowanie…
Reference in New Issue