From 7a6b5dd5b7cfa4d1d06893c2168b06bffe12970d Mon Sep 17 00:00:00 2001 From: Christian Schabesberger Date: Sat, 18 Feb 2017 21:59:48 +0100 Subject: [PATCH 1/3] add initial support for NavStack --- app/src/main/AndroidManifest.xml | 1 + .../org/schabi/newpipe/ChannelActivity.java | 37 +++--- .../java/org/schabi/newpipe/MainActivity.java | 5 + .../detail/VideoItemDetailActivity.java | 33 +++-- .../detail/VideoItemDetailFragment.java | 29 ++-- .../org/schabi/newpipe/extractor/NewPipe.java | 28 ++-- .../schabi/newpipe/extractor/ServiceList.java | 13 ++ .../newpipe/extractor/StreamingService.java | 25 +++- .../newpipe/extractor/UrlIdHandler.java | 1 + .../services/youtube/YoutubeService.java | 4 +- .../youtube/YoutubeStreamUrlIdHandler.java | 14 +- .../stream_info/StreamInfoItemCollector.java | 2 +- .../newpipe/player/BackgroundPlayer.java | 5 +- .../schabi/newpipe/report/ErrorActivity.java | 5 + .../SearchInfoItemFragment.java | 21 +-- .../org/schabi/newpipe/util/NavStack.java | 125 ++++++++++++++++++ 16 files changed, 267 insertions(+), 81 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/extractor/ServiceList.java create mode 100644 app/src/main/java/org/schabi/newpipe/util/NavStack.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2b44f0b53..e070a62d2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -156,6 +156,7 @@ @@ -81,8 +86,8 @@ 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); addFragment(savedInstanceState); } } @@ -114,12 +119,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,8 +147,8 @@ 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); } @@ -168,6 +173,16 @@ public class VideoItemDetailActivity extends ThemableActivity { } } + @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 +239,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; diff --git a/app/src/main/java/org/schabi/newpipe/detail/VideoItemDetailFragment.java b/app/src/main/java/org/schabi/newpipe/detail/VideoItemDetailFragment.java index 19df2d84f..bf9a32ae2 100644 --- a/app/src/main/java/org/schabi/newpipe/detail/VideoItemDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/detail/VideoItemDetailFragment.java @@ -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 { diff --git a/app/src/main/java/org/schabi/newpipe/extractor/NewPipe.java b/app/src/main/java/org/schabi/newpipe/extractor/NewPipe.java index 17d22feea..4e8e4aa3d 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/NewPipe.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/NewPipe.java @@ -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; + } } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/ServiceList.java b/app/src/main/java/org/schabi/newpipe/extractor/ServiceList.java new file mode 100644 index 000000000..89b350cb4 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/extractor/ServiceList.java @@ -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) + }; +} diff --git a/app/src/main/java/org/schabi/newpipe/extractor/StreamingService.java b/app/src/main/java/org/schabi/newpipe/extractor/StreamingService.java index 7252cea49..ed3c17bfc 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/StreamingService.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/StreamingService.java @@ -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; + } + } } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/UrlIdHandler.java b/app/src/main/java/org/schabi/newpipe/extractor/UrlIdHandler.java index 932fd5ce9..1218e7b8c 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/UrlIdHandler.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/UrlIdHandler.java @@ -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; diff --git a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeService.java b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeService.java index 595513ace..c8cc68fd5 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeService.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeService.java @@ -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(); } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamUrlIdHandler.java b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamUrlIdHandler.java index f2e7a0483..355da0402 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamUrlIdHandler.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamUrlIdHandler.java @@ -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; + } } } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/stream_info/StreamInfoItemCollector.java b/app/src/main/java/org/schabi/newpipe/extractor/stream_info/StreamInfoItemCollector.java index 15c11b850..5c2a8e74d 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/stream_info/StreamInfoItemCollector.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/stream_info/StreamInfoItemCollector.java @@ -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(); diff --git a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java index eba1d57f2..d1c53d85a 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java @@ -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); diff --git a/app/src/main/java/org/schabi/newpipe/report/ErrorActivity.java b/app/src/main/java/org/schabi/newpipe/report/ErrorActivity.java index 932d91584..e95a5e710 100644 --- a/app/src/main/java/org/schabi/newpipe/report/ErrorActivity.java +++ b/app/src/main/java/org/schabi/newpipe/report/ErrorActivity.java @@ -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 el, final Class returnAcitivty, View rootView, final ErrorInfo errorInfo) { diff --git a/app/src/main/java/org/schabi/newpipe/search_fragment/SearchInfoItemFragment.java b/app/src/main/java/org/schabi/newpipe/search_fragment/SearchInfoItemFragment.java index ee20990d4..b710a7977 100644 --- a/app/src/main/java/org/schabi/newpipe/search_fragment/SearchInfoItemFragment.java +++ b/app/src/main/java/org/schabi/newpipe/search_fragment/SearchInfoItemFragment.java @@ -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(); diff --git a/app/src/main/java/org/schabi/newpipe/util/NavStack.java b/app/src/main/java/org/schabi/newpipe/util/NavStack.java new file mode 100644 index 000000000..b9f0165bc --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/util/NavStack.java @@ -0,0 +1,125 @@ +package org.schabi.newpipe.util; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +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.Stack; + +/** + * Created by Christian Schabesberger on 16.02.17. + * + * Copyright (C) Christian Schabesberger 2016 + * 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 . + */ + +/** + * 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 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 stack = new Stack(); + + 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 { + 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 + } else { + 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); + } + + private void openMainActivity(Activity a) { + Intent i = new Intent(a, MainActivity.class); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + NavUtils.navigateUpTo(a, i); + } +} From c28fddc4dd0bb19ea8317fa16cbfd095127c7a7e Mon Sep 17 00:00:00 2001 From: Christian Schabesberger Date: Sun, 19 Feb 2017 16:07:45 +0100 Subject: [PATCH 2/3] did some finetuning --- .../org/schabi/newpipe/ChannelActivity.java | 22 +++++- .../detail/VideoItemDetailActivity.java | 9 ++- .../newpipe/download/DownloadActivity.java | 12 +--- .../org/schabi/newpipe/util/NavStack.java | 70 +++++++++++++------ app/src/main/res/menu/download_menu.xml | 5 -- 5 files changed, 74 insertions(+), 44 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/ChannelActivity.java b/app/src/main/java/org/schabi/newpipe/ChannelActivity.java index 4c7df1e5f..c8e0ad4a8 100644 --- a/app/src/main/java/org/schabi/newpipe/ChannelActivity.java +++ b/app/src/main/java/org/schabi/newpipe/ChannelActivity.java @@ -91,9 +91,16 @@ public class ChannelActivity extends AppCompatActivity { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); rootView = findViewById(R.id.rootView); setSupportActionBar(toolbar); - Intent i = getIntent(); - channelUrl = i.getStringExtra(NavStack.URL); - serviceId = i.getIntExtra(NavStack.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); + } infoListAdapter = new InfoListAdapter(this, rootView); @@ -136,6 +143,15 @@ 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); ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar); diff --git a/app/src/main/java/org/schabi/newpipe/detail/VideoItemDetailActivity.java b/app/src/main/java/org/schabi/newpipe/detail/VideoItemDetailActivity.java index 9cb5e055d..261e219cf 100644 --- a/app/src/main/java/org/schabi/newpipe/detail/VideoItemDetailActivity.java +++ b/app/src/main/java/org/schabi/newpipe/detail/VideoItemDetailActivity.java @@ -88,6 +88,8 @@ public class VideoItemDetailActivity extends ThemableActivity { } else { videoUrl = savedInstanceState.getString(NavStack.URL); currentStreamingService = savedInstanceState.getInt(NavStack.SERVICE_ID); + NavStack.getInstance() + .restoreSavedInstanceState(savedInstanceState); addFragment(savedInstanceState); } } @@ -150,6 +152,8 @@ public class VideoItemDetailActivity extends ThemableActivity { outState.putString(NavStack.URL, videoUrl); outState.putInt(NavStack.SERVICE_ID, currentStreamingService); outState.putBoolean(VideoItemDetailFragment.AUTO_PLAY, false); + NavStack.getInstance() + .onSaveInstanceState(outState); } @Override @@ -164,9 +168,8 @@ 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); diff --git a/app/src/main/java/org/schabi/newpipe/download/DownloadActivity.java b/app/src/main/java/org/schabi/newpipe/download/DownloadActivity.java index 2cf8cedc9..3c80e3be0 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DownloadActivity.java +++ b/app/src/main/java/org/schabi/newpipe/download/DownloadActivity.java @@ -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(), - null, null, - ErrorActivity.ErrorInfo.make(ErrorActivity.USER_REPORT, - null, - "user_report", R.string.user_report)); - return true; - } default: return super.onOptionsItemSelected(item); } diff --git a/app/src/main/java/org/schabi/newpipe/util/NavStack.java b/app/src/main/java/org/schabi/newpipe/util/NavStack.java index b9f0165bc..f84c5725e 100644 --- a/app/src/main/java/org/schabi/newpipe/util/NavStack.java +++ b/app/src/main/java/org/schabi/newpipe/util/NavStack.java @@ -3,6 +3,7 @@ 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; @@ -14,6 +15,7 @@ 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; /** @@ -45,6 +47,8 @@ public class NavStack { 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 @@ -74,33 +78,39 @@ public class NavStack { } 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) { + if (stack.size() == 0) { openMainActivity(activity); // if no more page is on the stack this means we are home - } else { - 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(); + 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); } @@ -117,9 +127,25 @@ public class NavStack { context.startActivity(i); } - private void openMainActivity(Activity a) { + 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 sa = new ArrayList<>(); + for(NavEntry entry : stack) { + sa.add(entry.url); + } + state.putStringArrayList(NAV_STACK, sa); + } + + public void restoreSavedInstanceState(Bundle state) { + ArrayList sa = state.getStringArrayList(NAV_STACK); + for(String url : sa) { + stack.push(new NavEntry(url, NewPipe.getServiceByUrl(url).getServiceId())); + } + } } diff --git a/app/src/main/res/menu/download_menu.xml b/app/src/main/res/menu/download_menu.xml index a396791d0..4cbb845ea 100644 --- a/app/src/main/res/menu/download_menu.xml +++ b/app/src/main/res/menu/download_menu.xml @@ -2,12 +2,7 @@ - - - \ No newline at end of file From d0d41c6b16f167091f979842b69865c5535a9516 Mon Sep 17 00:00:00 2001 From: Christian Schabesberger Date: Sun, 19 Feb 2017 16:09:39 +0100 Subject: [PATCH 3/3] move on to v0.8.10 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index e068acff2..62cd8dc7b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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 {