diff options
-rwxr-xr-x | org.fox.ttrss/build.gradle | 1 | ||||
-rw-r--r-- | org.fox.ttrss/libs/YouTubeAndroidPlayerApi.jar | bin | 0 -> 106412 bytes | |||
-rwxr-xr-x | org.fox.ttrss/org.fox.ttrss.iml | 1 | ||||
-rwxr-xr-x | org.fox.ttrss/src/main/AndroidManifest.xml | 5 | ||||
-rwxr-xr-x | org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java | 60 | ||||
-rw-r--r-- | org.fox.ttrss/src/main/java/org/fox/ttrss/VideoPlayerActivity.java | 5 | ||||
-rw-r--r-- | org.fox.ttrss/src/main/java/org/fox/ttrss/YoutubePlayerActivity.java | 150 | ||||
-rwxr-xr-x | org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java | 1 | ||||
-rw-r--r-- | org.fox.ttrss/src/main/res/layout/activity_video_player.xml | 7 | ||||
-rw-r--r-- | org.fox.ttrss/src/main/res/layout/activity_youtube_player.xml | 30 |
10 files changed, 251 insertions, 9 deletions
diff --git a/org.fox.ttrss/build.gradle b/org.fox.ttrss/build.gradle index 85004938..d2f0b8f7 100755 --- a/org.fox.ttrss/build.gradle +++ b/org.fox.ttrss/build.gradle @@ -38,4 +38,5 @@ dependencies { compile 'com.viewpagerindicator:library:2.4.1' compile 'com.nhaarman.listviewanimations:lib-core:3.1.0@aar' compile files('libs/nineoldandroids-2.4.0.jar') + compile files('libs/YouTubeAndroidPlayerApi.jar') } diff --git a/org.fox.ttrss/libs/YouTubeAndroidPlayerApi.jar b/org.fox.ttrss/libs/YouTubeAndroidPlayerApi.jar Binary files differnew file mode 100644 index 00000000..1dc2b822 --- /dev/null +++ b/org.fox.ttrss/libs/YouTubeAndroidPlayerApi.jar diff --git a/org.fox.ttrss/org.fox.ttrss.iml b/org.fox.ttrss/org.fox.ttrss.iml index 33f61c90..f473df1f 100755 --- a/org.fox.ttrss/org.fox.ttrss.iml +++ b/org.fox.ttrss/org.fox.ttrss.iml @@ -92,6 +92,7 @@ <orderEntry type="library" exported="" name="nineoldandroids-2.4.0" level="project" /> <orderEntry type="library" exported="" name="gson-2.3" level="project" /> <orderEntry type="library" exported="" name="acra-4.5.0" level="project" /> + <orderEntry type="library" exported="" name="YouTubeAndroidPlayerApi" level="project" /> <orderEntry type="library" exported="" name="support-annotations-22.2.0" level="project" /> <orderEntry type="library" exported="" name="support-v4-22.2.0" level="project" /> <orderEntry type="library" exported="" name="circleindicator-1.1.1" level="project" /> diff --git a/org.fox.ttrss/src/main/AndroidManifest.xml b/org.fox.ttrss/src/main/AndroidManifest.xml index 3afc5eb2..6443d3d6 100755 --- a/org.fox.ttrss/src/main/AndroidManifest.xml +++ b/org.fox.ttrss/src/main/AndroidManifest.xml @@ -267,6 +267,11 @@ android:configChanges="keyboardHidden|orientation|screenSize" android:label="@string/title_activity_video_player" > </activity> + <activity + android:name=".YoutubePlayerActivity" + android:configChanges="keyboardHidden|orientation|screenSize" + android:label="@string/title_activity_video_player" > + </activity> </application> </manifest> diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java index 8e940904..3ffcc229 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; import android.content.res.Resources.Theme; import android.graphics.Bitmap; import android.graphics.Paint; @@ -76,6 +77,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -670,6 +672,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, public ImageView textImage; public ImageView textChecked; public View headlineHeader; + public boolean flavorImageEmbedded; } private class ArticleListAdapter extends ArrayAdapter<Article> { @@ -692,6 +695,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, private final DisplayImageOptions displayImageOptions; boolean showFlavorImage; private int m_minimumHeightToEmbed; + boolean m_youtubeInstalled; public ArticleListAdapter(Context context, int textViewResourceId, ArrayList<Article> items) { super(context, textViewResourceId, items); @@ -717,6 +721,13 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, .displayer(new FadeInBitmapDisplayer(500)) .build(); + List<ApplicationInfo> packages = m_activity.getPackageManager().getInstalledApplications(0); + for (ApplicationInfo pi : packages) { + if (pi.packageName.equals("com.google.android.youtube")) { + m_youtubeInstalled = true; + break; + } + } } public int getViewTypeCount() { @@ -1141,6 +1152,14 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, } else { holder.flavorImageView.setVisibility(View.VISIBLE); holder.flavorVideoKindView.setVisibility(View.VISIBLE); + + if (holder.flavorImageEmbedded) { + TypedValue tv = new TypedValue(); + if (m_activity.getTheme().resolveAttribute(R.attr.headlineHeaderBackground, tv, true)) { + holder.headlineHeader.setBackgroundColor(tv.data); + } + } + } videoFound = true; @@ -1182,7 +1201,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, Matcher matcher = pattern.matcher(srcEmbed); if (matcher.find()) { - String vid = matcher.group(1); + final String vid = matcher.group(1); final String thumbUri = "http://img.youtube.com/vi/"+vid+"/mqdefault.jpg"; final String videoUri = "https://youtu.be/" + vid; @@ -1234,15 +1253,33 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, } else { holder.flavorImageView.setVisibility(View.VISIBLE); holder.flavorVideoKindView.setVisibility(View.VISIBLE); + + if (holder.flavorImageEmbedded) { + TypedValue tv = new TypedValue(); + if (m_activity.getTheme().resolveAttribute(R.attr.headlineHeaderBackground, tv, true)) { + holder.headlineHeader.setBackgroundColor(tv.data); + } + } + } holder.flavorImageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - Intent intent = new Intent(Intent.ACTION_VIEW, - Uri.parse(videoUri)); - startActivity(intent); + + if (m_youtubeInstalled) { + Intent intent = new Intent(m_activity, YoutubePlayerActivity.class); + intent.putExtra("streamUri", videoUri); + intent.putExtra("vid", vid); + intent.putExtra("title", article.title); + + startActivity(intent); + } else { + Intent intent = new Intent(Intent.ACTION_VIEW, + Uri.parse(videoUri)); + startActivity(intent); + } } }); } @@ -1285,7 +1322,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, } }); - if (holder.flavorImageView.getTag() == null || !holder.flavorImageView.getTag().equals(imgSrc)) { + if (!imgSrc.equals(holder.flavorImageView.getTag())) { ImageAware imageAware = new ImageViewAware(holder.flavorImageView, false); @@ -1304,11 +1341,11 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, View view, Bitmap bitmap) { if (!isAdded() || bitmap == null) return; - holder.flavorImageView.setTag(finalImgSrc); holder.flavorImageLoadingBar.setVisibility(View.GONE); if (bitmap.getWidth() > FLAVOR_IMG_MIN_SIZE && bitmap.getHeight() > FLAVOR_IMG_MIN_SIZE) { holder.flavorImageView.setVisibility(View.VISIBLE); + holder.flavorImageView.setTag(finalImgSrc); if (article.flavorImageCount > 1) { holder.flavorVideoKindView.setVisibility(View.VISIBLE); @@ -1343,6 +1380,13 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, holder.flavorVideoKindView.setImageResource(R.drawable.ic_image_album); } + if (holder.flavorImageEmbedded) { + TypedValue tv = new TypedValue(); + if (m_activity.getTheme().resolveAttribute(R.attr.headlineHeaderBackground, tv, true)) { + holder.headlineHeader.setBackgroundColor(tv.data); + } + } + } } } @@ -1442,15 +1486,17 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, lp.addRule(RelativeLayout.BELOW, R.id.headline_header); holder.headlineHeader.setBackgroundDrawable(null); + holder.flavorImageEmbedded = false; } else { lp.addRule(RelativeLayout.BELOW, 0); TypedValue tv = new TypedValue(); - if (m_activity.getTheme().resolveAttribute(R.attr.headlineHeaderBackground, tv, true)) { holder.headlineHeader.setBackgroundColor(tv.data); } + + holder.flavorImageEmbedded = true; } view.setLayoutParams(lp); diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/VideoPlayerActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/VideoPlayerActivity.java index c8056866..48a0e9ff 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/VideoPlayerActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/VideoPlayerActivity.java @@ -147,6 +147,10 @@ public class VideoPlayerActivity extends CommonActivity { mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
+
+ View loadingBar = findViewById(R.id.video_loading);
+ if (loadingBar != null) loadingBar.setVisibility(View.GONE);
+
resizeSurface();
mp.setLooping(true);
mp.start();
@@ -234,7 +238,6 @@ public class VideoPlayerActivity extends CommonActivity { if (m_streamUri != null) {
Intent intent = new Intent(Intent.ACTION_SEND);
- intent.setType("video/mp4");
intent.putExtra(Intent.EXTRA_SUBJECT, m_streamUri);
intent.putExtra(Intent.EXTRA_TEXT, m_streamUri);
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/YoutubePlayerActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/YoutubePlayerActivity.java new file mode 100644 index 00000000..e7312ffa --- /dev/null +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/YoutubePlayerActivity.java @@ -0,0 +1,150 @@ +package org.fox.ttrss; + +import android.content.Intent; +import android.content.res.Configuration; +import android.net.Uri; +import android.os.Bundle; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.ContextMenu; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; + +import com.google.android.youtube.player.YouTubeInitializationResult; +import com.google.android.youtube.player.YouTubePlayer; +import com.google.android.youtube.player.YouTubePlayerSupportFragment; + + +public class YoutubePlayerActivity extends CommonActivity implements YouTubePlayer.OnInitializedListener { + + private final String TAG = this.getClass().getSimpleName(); + private static final String DEVELOPER_KEY = "AIzaSyD8BS4Uj21jg_gHZfP4v0VXrAWiwqd05nk"; + + private String m_streamUri; + private String m_videoId; + + @Override + public void onCreate(Bundle savedInstanceState) { + + setTheme(R.style.DarkTheme); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_youtube_player); + + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + if (!isPortrait()) + getSupportActionBar().hide(); + + setTitle(getIntent().getStringExtra("title")); + + if (savedInstanceState == null) { + m_streamUri = getIntent().getStringExtra("streamUri"); + m_videoId = getIntent().getStringExtra("vid"); + } else { + m_streamUri = savedInstanceState.getString("streamUri"); + m_videoId = savedInstanceState.getString("vid"); + } + + YouTubePlayerSupportFragment frag = (YouTubePlayerSupportFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_youtube_player); + frag.initialize(DEVELOPER_KEY, this); + } + + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + if (!isPortrait()) + getSupportActionBar().hide(); + else + getSupportActionBar().show(); + } + + @Override + public void onSaveInstanceState(Bundle out) { + super.onSaveInstanceState(out); + + out.putString("streamUri", m_streamUri); + out.putString("vid", m_videoId); + } + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.activity_video_player, menu); + return true; + } + + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenu.ContextMenuInfo menuInfo) { + + getMenuInflater().inflate(R.menu.activity_video_player, menu); + + super.onCreateContextMenu(menu, v, menuInfo); + } + + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + return onContextItemSelected(item); // this is really bad :() + } + + @Override + public boolean onContextItemSelected(android.view.MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + return true; + case R.id.article_vid_open: + if (m_streamUri != null) { + try { + Intent intent = new Intent(Intent.ACTION_VIEW, + Uri.parse(m_streamUri)); + startActivity(intent); + } catch (Exception e) { + e.printStackTrace(); + toast(R.string.error_other_error); + } + } + return true; + case R.id.article_vid_share: + if (m_streamUri != null) { + Intent intent = new Intent(Intent.ACTION_SEND); + + intent.putExtra(Intent.EXTRA_SUBJECT, m_streamUri); + intent.putExtra(Intent.EXTRA_TEXT, m_streamUri); + + startActivity(Intent.createChooser(intent, m_streamUri)); + } + return true; + default: + Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId()); + return super.onContextItemSelected(item); + } + } + + @Override + public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) { + Log.d(TAG, "youtube: init success"); + + findViewById(R.id.video_loading).setVisibility(View.GONE); + + if (!wasRestored) { + player.cueVideo(m_videoId); + } + } + + @Override + public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult result) { + Log.d(TAG, "youtube: init failure"); + + findViewById(R.id.video_loading).setVisibility(View.GONE); + + toast(result.toString()); + } +} diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java index 7990c55c..33cd56fa 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java @@ -38,7 +38,6 @@ public class Article implements Parcelable { public Document articleDoc; public Element flavorImage; public int flavorImageCount; - public boolean noValidFlavorImage; public Article(Parcel in) { readFromParcel(in); diff --git a/org.fox.ttrss/src/main/res/layout/activity_video_player.xml b/org.fox.ttrss/src/main/res/layout/activity_video_player.xml index 00963588..2f81860c 100644 --- a/org.fox.ttrss/src/main/res/layout/activity_video_player.xml +++ b/org.fox.ttrss/src/main/res/layout/activity_video_player.xml @@ -16,6 +16,13 @@ android:layout_gravity="center"
android:id="@+id/video_player"
android:transitionName="TRANSITION:ARTICLE_VIDEO_PLAYER" />
+
+ <ProgressBar
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/video_loading"
+ android:layout_gravity="center"
+ android:indeterminate="true" />
</FrameLayout>
<include layout="@layout/toolbar" android:id="@+id/toolbar" />
diff --git a/org.fox.ttrss/src/main/res/layout/activity_youtube_player.xml b/org.fox.ttrss/src/main/res/layout/activity_youtube_player.xml new file mode 100644 index 00000000..afd37335 --- /dev/null +++ b/org.fox.ttrss/src/main/res/layout/activity_youtube_player.xml @@ -0,0 +1,30 @@ +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" + android:layout_height="match_parent" + android:fitsSystemWindows="true" + android:background="?android:colorBackground" + tools:context="org.fox.ttrss.VideoPlayerActivity"> + + <FrameLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_below="@+id/toolbar"> + + <fragment + android:name="com.google.android.youtube.player.YouTubePlayerSupportFragment" + android:id="@+id/fragment_youtube_player" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + <ProgressBar + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/video_loading" + android:layout_gravity="center" + android:indeterminate="true" /> + + </FrameLayout> + + <include layout="@layout/toolbar" android:id="@+id/toolbar" /> + +</RelativeLayout> |