Downloading video without sound is now available. Minor bugs fixed.

This commit is contained in:
Alex Ning 2019-12-01 20:05:27 +08:00
parent c8d9269efa
commit 3d93cb37b9
12 changed files with 127 additions and 56 deletions

View File

@ -21,6 +21,7 @@
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"
tools:replace="android:label">
<activity
android:name=".Activity.ViewGIFActivity"
android:parentActivityName=".Activity.MainActivity"

View File

@ -77,7 +77,6 @@ import ml.docilealligator.infinityforreddit.Fragment.PostLayoutBottomSheetFragme
import ml.docilealligator.infinityforreddit.Fragment.PostTypeBottomSheetFragment;
import ml.docilealligator.infinityforreddit.Fragment.SortTimeBottomSheetFragment;
import ml.docilealligator.infinityforreddit.Fragment.SortTypeBottomSheetFragment;
import ml.docilealligator.infinityforreddit.FragmentCommunicator;
import ml.docilealligator.infinityforreddit.Infinity;
import ml.docilealligator.infinityforreddit.ParseAndSaveAccountInfo;
import ml.docilealligator.infinityforreddit.PostDataSource;
@ -85,12 +84,12 @@ import ml.docilealligator.infinityforreddit.PullNotificationWorker;
import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.ReadMessage;
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase;
import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils;
import ml.docilealligator.infinityforreddit.SortType;
import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback;
import ml.docilealligator.infinityforreddit.SubredditDatabase.SubredditData;
import ml.docilealligator.infinityforreddit.SubscribedSubredditDatabase.SubscribedSubredditData;
import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserData;
import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils;
import pl.droidsonroids.gif.GifImageView;
import retrofit2.Retrofit;
@ -1076,18 +1075,18 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
if (mAccessToken == null) {
switch (viewPager.getCurrentItem()) {
case 0:
return ((FragmentCommunicator) popularPostFragment).startLazyMode();
return popularPostFragment.startLazyMode();
case 1:
return ((FragmentCommunicator) allPostFragment).startLazyMode();
return allPostFragment.startLazyMode();
}
} else {
switch (viewPager.getCurrentItem()) {
case 0:
return ((FragmentCommunicator) frontPagePostFragment).startLazyMode();
return frontPagePostFragment.startLazyMode();
case 1:
return ((FragmentCommunicator) popularPostFragment).startLazyMode();
return popularPostFragment.startLazyMode();
case 2:
return ((FragmentCommunicator) allPostFragment).startLazyMode();
return allPostFragment.startLazyMode();
}
}
@ -1098,22 +1097,22 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
if (mAccessToken == null) {
switch (getCurrentLazyModeFragmentPosition()) {
case 0:
((FragmentCommunicator) popularPostFragment).stopLazyMode();
popularPostFragment.stopLazyMode();
break;
case 1:
((FragmentCommunicator) allPostFragment).stopLazyMode();
allPostFragment.stopLazyMode();
break;
}
} else {
switch (getCurrentLazyModeFragmentPosition()) {
case 0:
((FragmentCommunicator) frontPagePostFragment).stopLazyMode();
frontPagePostFragment.stopLazyMode();
break;
case 1:
((FragmentCommunicator) popularPostFragment).stopLazyMode();
popularPostFragment.stopLazyMode();
break;
case 2:
((FragmentCommunicator) allPostFragment).stopLazyMode();
allPostFragment.stopLazyMode();
break;
}
}
@ -1123,22 +1122,22 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
if (mAccessToken == null) {
switch (getCurrentLazyModeFragmentPosition()) {
case 0:
((FragmentCommunicator) popularPostFragment).resumeLazyMode(false);
popularPostFragment.resumeLazyMode(false);
break;
case 1:
((FragmentCommunicator) allPostFragment).resumeLazyMode(false);
allPostFragment.resumeLazyMode(false);
break;
}
} else {
switch (getCurrentLazyModeFragmentPosition()) {
case 0:
((FragmentCommunicator) frontPagePostFragment).resumeLazyMode(false);
frontPagePostFragment.resumeLazyMode(false);
break;
case 1:
((FragmentCommunicator) popularPostFragment).resumeLazyMode(false);
popularPostFragment.resumeLazyMode(false);
break;
case 2:
((FragmentCommunicator) allPostFragment).resumeLazyMode(false);
allPostFragment.resumeLazyMode(false);
break;
}
}
@ -1148,21 +1147,21 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
if (mAccessToken == null) {
switch (getCurrentLazyModeFragmentPosition()) {
case 0:
((FragmentCommunicator) popularPostFragment).pauseLazyMode(false);
popularPostFragment.pauseLazyMode(false);
break;
case 1:
((FragmentCommunicator) allPostFragment).pauseLazyMode(false);
allPostFragment.pauseLazyMode(false);
}
} else {
switch (getCurrentLazyModeFragmentPosition()) {
case 0:
((FragmentCommunicator) frontPagePostFragment).pauseLazyMode(false);
frontPagePostFragment.pauseLazyMode(false);
break;
case 1:
((FragmentCommunicator) popularPostFragment).pauseLazyMode(false);
popularPostFragment.pauseLazyMode(false);
break;
case 2:
((FragmentCommunicator) allPostFragment).pauseLazyMode(false);
allPostFragment.pauseLazyMode(false);
}
}
}
@ -1171,9 +1170,9 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
if (mAccessToken == null) {
if (!isInLazyMode) {
return -1;
} else if (popularPostFragment != null && ((FragmentCommunicator) popularPostFragment).isInLazyMode()) {
} else if (popularPostFragment != null && popularPostFragment.isInLazyMode()) {
return 0;
} else if (allPostFragment != null && ((FragmentCommunicator) allPostFragment).isInLazyMode()) {
} else if (allPostFragment != null && allPostFragment.isInLazyMode()) {
return 1;
} else {
return -1;
@ -1181,11 +1180,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
} else {
if (!isInLazyMode) {
return -1;
} else if (frontPagePostFragment != null && ((FragmentCommunicator) frontPagePostFragment).isInLazyMode()) {
} else if (frontPagePostFragment != null && frontPagePostFragment.isInLazyMode()) {
return 0;
} else if (popularPostFragment != null && ((FragmentCommunicator) popularPostFragment).isInLazyMode()) {
} else if (popularPostFragment != null && popularPostFragment.isInLazyMode()) {
return 1;
} else if (allPostFragment != null && ((FragmentCommunicator) allPostFragment).isInLazyMode()) {
} else if (allPostFragment != null && allPostFragment.isInLazyMode()) {
return 2;
} else {
return -1;
@ -1233,28 +1232,28 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
if (mAccessToken == null) {
if (viewPager.getCurrentItem() == 0) {
if (popularPostFragment != null) {
((FragmentCommunicator) popularPostFragment).refresh();
popularPostFragment.refresh();
}
} else {
if (allPostFragment != null) {
((FragmentCommunicator) allPostFragment).refresh();
allPostFragment.refresh();
}
}
} else {
switch (viewPager.getCurrentItem()) {
case 0:
if (frontPagePostFragment != null) {
((FragmentCommunicator) frontPagePostFragment).refresh();
frontPagePostFragment.refresh();
}
break;
case 1:
if (popularPostFragment != null) {
((FragmentCommunicator) popularPostFragment).refresh();
popularPostFragment.refresh();
}
break;
case 2:
if (allPostFragment != null) {
((FragmentCommunicator) allPostFragment).refresh();
allPostFragment.refresh();
}
}
}
@ -1277,12 +1276,12 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
if (viewPager.getCurrentItem() == 0) {
if (popularPostFragment != null) {
mSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_POPULAR_POST, postLayout).apply();
((FragmentCommunicator) popularPostFragment).changePostLayout(postLayout);
popularPostFragment.changePostLayout(postLayout);
}
} else {
if (allPostFragment != null) {
mSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_ALL_POST, postLayout).apply();
((FragmentCommunicator) allPostFragment).changePostLayout(postLayout);
allPostFragment.changePostLayout(postLayout);
}
}
} else {
@ -1290,19 +1289,19 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
case 0:
if (frontPagePostFragment != null) {
mSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_FRONT_PAGE_POST, postLayout).apply();
((FragmentCommunicator) frontPagePostFragment).changePostLayout(postLayout);
frontPagePostFragment.changePostLayout(postLayout);
}
break;
case 1:
if (popularPostFragment != null) {
mSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_POPULAR_POST, postLayout).apply();
((FragmentCommunicator) popularPostFragment).changePostLayout(postLayout);
popularPostFragment.changePostLayout(postLayout);
}
break;
case 2:
if (allPostFragment != null) {
mSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_ALL_POST, postLayout).apply();
((FragmentCommunicator) allPostFragment).changePostLayout(postLayout);
allPostFragment.changePostLayout(postLayout);
}
}
}

View File

@ -54,8 +54,8 @@ import ml.docilealligator.infinityforreddit.ContentFontStyle;
import ml.docilealligator.infinityforreddit.FontStyle;
import ml.docilealligator.infinityforreddit.Infinity;
import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils;
import ml.docilealligator.infinityforreddit.TitleFontStyle;
import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils;
public class ViewImageActivity extends AppCompatActivity {

View File

@ -4,6 +4,8 @@ import android.Manifest;
import android.animation.Animator;
import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.app.DownloadManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
@ -14,6 +16,7 @@ import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
@ -44,14 +47,17 @@ import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
import java.io.File;
import butterknife.BindView;
import butterknife.ButterKnife;
import ml.docilealligator.infinityforreddit.R;
public class ViewVideoActivity extends AppCompatActivity {
public static final String SUBREDDIT_KEY = "SK";
public static final String ID_KEY = "IK";
public static final String EXTRA_VIDEO_DOWNLOAD_URL = "EVDU";
public static final String EXTRA_SUBREDDIT = "ES";
public static final String EXTRA_ID = "EI";
private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0;
@BindView(R.id.relative_layout_view_video_activity)
RelativeLayout relativeLayout;
@ -65,6 +71,8 @@ public class ViewVideoActivity extends AppCompatActivity {
private Menu mMenu;
private Swipe swipe;
private String videoDownloadUrl;
private String videoFileName;
private boolean wasPlaying;
private boolean isDownloading = false;
private float totalLengthY = 0.0f;
@ -101,6 +109,8 @@ public class ViewVideoActivity extends AppCompatActivity {
Intent intent = getIntent();
mVideoUri = intent.getData();
videoDownloadUrl = intent.getStringExtra(EXTRA_VIDEO_DOWNLOAD_URL);
videoFileName = intent.getStringExtra(EXTRA_SUBREDDIT) + "-" + intent.getStringExtra(EXTRA_ID) + ".mp4";
final float pxHeight = getResources().getDisplayMetrics().heightPixels;
@ -285,12 +295,12 @@ public class ViewVideoActivity extends AppCompatActivity {
wasPlaying = true;
}
/*@Override
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.view_video, menu);
mMenu = menu;
return true;
}*/
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
@ -364,6 +374,48 @@ public class ViewVideoActivity extends AppCompatActivity {
private void download() {
isDownloading = false;
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(videoDownloadUrl));
request.setTitle(videoFileName);
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
//Android Q support
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_PICTURES, videoFileName);
} else {
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
File directory = new File(path + "/Infinity/");
boolean saveToInfinityFolder = true;
if (!directory.exists()) {
if (!directory.mkdir()) {
saveToInfinityFolder = false;
}
} else {
if (directory.isFile()) {
if (!(directory.delete() && directory.mkdir())) {
saveToInfinityFolder = false;
}
}
}
if (saveToInfinityFolder) {
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_PICTURES + "/Infinity/", videoFileName);
} else {
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_PICTURES, videoFileName);
}
}
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
if (manager == null) {
Toast.makeText(this, R.string.download_failed, Toast.LENGTH_SHORT).show();
return;
}
manager.enqueue(request);
Toast.makeText(this, R.string.download_started, Toast.LENGTH_SHORT).show();
}
@Override

View File

@ -474,8 +474,9 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy
((PostDetailViewHolder) holder).mImageView.setOnClickListener(view -> {
Intent intent = new Intent(mActivity, ViewVideoActivity.class);
intent.setData(videoUri);
intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, mPost.getSubredditName());
intent.putExtra(ViewVideoActivity.ID_KEY, mPost.getId());
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, mPost.getVideoDownloadUrl());
intent.putExtra(ViewVideoActivity.EXTRA_SUBREDDIT, mPost.getSubredditName());
intent.putExtra(ViewVideoActivity.EXTRA_ID, mPost.getId());
mActivity.startActivity(intent);
});
break;

View File

@ -473,8 +473,9 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView
((PostViewHolder) holder).imageView.setOnClickListener(view -> {
Intent intent = new Intent(mContext, ViewVideoActivity.class);
intent.setData(videoUri);
intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, subredditName);
intent.putExtra(ViewVideoActivity.ID_KEY, fullName);
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, post.getVideoDownloadUrl());
intent.putExtra(ViewVideoActivity.EXTRA_SUBREDDIT, subredditName);
intent.putExtra(ViewVideoActivity.EXTRA_ID, fullName);
mContext.startActivity(intent);
});
break;
@ -1021,8 +1022,9 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView
((PostCompactViewHolder) holder).imageView.setOnClickListener(view -> {
Intent intent = new Intent(mContext, ViewVideoActivity.class);
intent.setData(videoUri);
intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, subredditName);
intent.putExtra(ViewVideoActivity.ID_KEY, fullName);
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, post.getVideoDownloadUrl());
intent.putExtra(ViewVideoActivity.EXTRA_SUBREDDIT, subredditName);
intent.putExtra(ViewVideoActivity.EXTRA_ID, fullName);
mContext.startActivity(intent);
});
break;

View File

@ -230,7 +230,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
}
};
mSwipeRefreshLayout.setOnRefreshListener(() -> mPostViewModel.refresh());
mSwipeRefreshLayout.setOnRefreshListener(this::refresh);
TypedValue typedValue = new TypedValue();
activity.getTheme().resolveAttribute(R.attr.cardViewBackgroundColor, typedValue, true);
@ -540,14 +540,13 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
@Override
public void refresh() {
mPostViewModel.refresh();
if (isInLazyMode) {
stopLazyMode();
}
mAdapter.removeFooter();
mFetchPostInfoLinearLayout.setVisibility(View.GONE);
hasPost = false;
if (isInLazyMode) {
stopLazyMode();
}
mPostViewModel.refresh();
}
private void showErrorView(int stringResId) {

View File

@ -161,6 +161,7 @@ public class ParsePost {
JSONObject redditVideoObject = data.getJSONObject(JSONUtils.MEDIA_KEY).getJSONObject(JSONUtils.REDDIT_VIDEO_KEY);
int postType = Post.VIDEO_TYPE;
String videoUrl = Html.fromHtml(redditVideoObject.getString(JSONUtils.HLS_URL_KEY)).toString();
String videoDownloadUrl = redditVideoObject.getString(JSONUtils.FALLBACK_URL_KEY);
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, formattedPostTime, postTimeMillis,
title, previewUrl, thumbnailPreviewUrl, permalink, score, postType, voteType,
@ -169,12 +170,15 @@ public class ParsePost {
post.setPreviewWidth(previewWidth);
post.setPreviewHeight(previewHeight);
post.setVideoUrl(videoUrl);
post.setVideoDownloadUrl(videoDownloadUrl);
} else if (data.has(JSONUtils.PREVIEW_KEY)) {
if (data.getJSONObject(JSONUtils.PREVIEW_KEY).has(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY)) {
//Gif video post (HLS)
int postType = Post.VIDEO_TYPE;
String videoUrl = Html.fromHtml(data.getJSONObject(JSONUtils.PREVIEW_KEY)
.getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.HLS_URL_KEY)).toString();
String videoDownloadUrl = data.getJSONObject(JSONUtils.PREVIEW_KEY)
.getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.FALLBACK_URL_KEY);
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author,
formattedPostTime, postTimeMillis, title, previewUrl, thumbnailPreviewUrl, permalink, score,
@ -183,6 +187,7 @@ public class ParsePost {
post.setPreviewWidth(previewWidth);
post.setPreviewHeight(previewHeight);
post.setVideoUrl(videoUrl);
post.setVideoDownloadUrl(videoDownloadUrl);
} else {
if (url.endsWith("jpg") || url.endsWith("png")) {
//Image post

View File

@ -44,6 +44,7 @@ public class Post implements Parcelable {
private String thumbnailPreviewUrl;
private String url;
private String videoUrl;
private String videoDownloadUrl;
private String permalink;
private String flair;
private long postTimeMillis;
@ -181,6 +182,7 @@ public class Post implements Parcelable {
thumbnailPreviewUrl = in.readString();
url = in.readString();
videoUrl = in.readString();
videoDownloadUrl = in.readString();
permalink = in.readString();
flair = in.readString();
score = in.readInt();
@ -293,6 +295,14 @@ public class Post implements Parcelable {
this.videoUrl = videoUrl;
}
public String getVideoDownloadUrl() {
return videoDownloadUrl;
}
public void setVideoDownloadUrl(String videoDownloadUrl) {
this.videoDownloadUrl = videoDownloadUrl;
}
public String getPermalink() {
return permalink;
}
@ -433,6 +443,7 @@ public class Post implements Parcelable {
parcel.writeString(thumbnailPreviewUrl);
parcel.writeString(url);
parcel.writeString(videoUrl);
parcel.writeString(videoDownloadUrl);
parcel.writeString(permalink);
parcel.writeString(flair);
parcel.writeInt(score);

View File

@ -155,7 +155,7 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> {
this.params = params;
this.callback = callback;
if ("".equals(params.key) || "null".equals(params.key)) {
if (params == null || "".equals(params.key) || "null".equals(params.key)) {
return;
}

View File

@ -37,6 +37,7 @@ public class JSONUtils {
public static final String MEDIA_KEY = "media";
public static final String REDDIT_VIDEO_KEY = "reddit_video";
public static final String HLS_URL_KEY = "hls_url";
public static final String FALLBACK_URL_KEY = "fallback_url";
public static final String IS_VIDEO_KEY = "is_video";
public static final String CROSSPOST_PARENT_LIST = "crosspost_parent_list";
public static final String REDDIT_VIDEO_PREVIEW_KEY = "reddit_video_preview";

View File

@ -11,7 +11,7 @@
# The setting is particularly useful for tweaking memory settings.
android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m
org.gradle.jvmargs=-Xmx2048m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit