Rewrite DownloadMediaService to run in a background thread.

This commit is contained in:
Alex Ning 2020-12-21 23:27:10 +08:00
parent 12aa4a1040
commit 664141b324
6 changed files with 324 additions and 324 deletions

View File

@ -172,6 +172,10 @@ public class CustomizePostFilterActivity extends BaseActivity {
postTypeVideoLinearLayout.setOnClickListener(view -> {
postTypeVideoCheckBox.performClick();
});
postTypeGalleryLinearLayout.setOnClickListener(view -> {
postTypeGalleryCheckBox.performClick();
});
}
@Override

View File

@ -693,7 +693,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
if (accountName != null && !accountName.equals("")) {
if (readPosts == null) {
if (getArguments().getBoolean(EXTRA_DISABLE_READ_POSTS, false)) {
initializeAndBindPostViewModel(accessToken, locale);
initializeAndBindPostViewModel(accessToken);
} else {
FetchReadPosts.fetchReadPosts(mRedditDataRoomDatabase, accountName,
postType == PostDataSource.TYPE_SUBREDDIT && subredditName != null && (subredditName.equals("all") || subredditName.equals("popular")),
@ -701,15 +701,15 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
if (activity != null && !activity.isFinishing() && !activity.isDestroyed()) {
this.readPosts = readPosts;
this.subredditFilterList = subredditFilters;
initializeAndBindPostViewModel(accessToken, locale);
initializeAndBindPostViewModel(accessToken);
}
});
}
} else {
initializeAndBindPostViewModel(accessToken, locale);
initializeAndBindPostViewModel(accessToken);
}
} else {
initializeAndBindPostViewModelForAnonymous(accessToken, locale);
initializeAndBindPostViewModelForAnonymous(accessToken);
}
vibrateWhenActionTriggered = mSharedPreferences.getBoolean(SharedPreferencesUtils.VIBRATE_WHEN_ACTION_TRIGGERED, true);
@ -821,55 +821,55 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
return rootView;
}
private void initializeAndBindPostViewModel(String accessToken, Locale locale) {
private void initializeAndBindPostViewModel(String accessToken) {
if (postType == PostDataSource.TYPE_SEARCH) {
mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken,
accountName, locale, mSharedPreferences,
accountName, mSharedPreferences,
postFeedScrolledPositionSharedPreferences, subredditName, query, postType, sortType,
postFilter, readPosts)).get(PostViewModel.class);
} else if (postType == PostDataSource.TYPE_SUBREDDIT) {
if (subredditName.equals("all") || subredditName.equals("popular")) {
mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken,
accountName, locale, mSharedPreferences,
accountName, mSharedPreferences,
postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType,
postFilter, readPosts, subredditFilterList)).get(PostViewModel.class);
} else {
mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken,
accountName, locale, mSharedPreferences,
accountName, mSharedPreferences,
postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType,
postFilter, readPosts)).get(PostViewModel.class);
}
} else if (postType == PostDataSource.TYPE_MULTI_REDDIT) {
mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken,
accountName, locale, mSharedPreferences,
accountName, mSharedPreferences,
postFeedScrolledPositionSharedPreferences, multiRedditPath, postType, sortType,
postFilter, readPosts)).get(PostViewModel.class);
} else if (postType == PostDataSource.TYPE_USER) {
mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken,
accountName, locale, mSharedPreferences,
accountName, mSharedPreferences,
postFeedScrolledPositionSharedPreferences, username, postType, sortType, postFilter,
where, readPosts)).get(PostViewModel.class);
} else {
mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mOauthRetrofit, accessToken,
accountName, locale, mSharedPreferences, postFeedScrolledPositionSharedPreferences,
accountName, mSharedPreferences, postFeedScrolledPositionSharedPreferences,
postType, sortType, postFilter, readPosts)).get(PostViewModel.class);
}
bindPostViewModel();
}
private void initializeAndBindPostViewModelForAnonymous(String accessToken, Locale locale) {
private void initializeAndBindPostViewModelForAnonymous(String accessToken) {
//For anonymous user
if (postType == PostDataSource.TYPE_SEARCH) {
mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken,
accountName, locale, mSharedPreferences,
accountName, mSharedPreferences,
postFeedScrolledPositionSharedPreferences, subredditName, query, postType, sortType,
postFilter, readPosts)).get(PostViewModel.class);
} else if (postType == PostDataSource.TYPE_SUBREDDIT) {
if (subredditName.equals("all") || subredditName.equals("popular")) {
if (subredditFilterList != null) {
mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken,
accountName, locale, mSharedPreferences,
accountName, mSharedPreferences,
postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType,
postFilter, readPosts, subredditFilterList)).get(PostViewModel.class);
} else {
@ -877,7 +877,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
if (activity != null && !activity.isFinishing() && !activity.isDestroyed()) {
subredditFilterList = subredditFilters;
mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken,
accountName, locale, mSharedPreferences,
accountName, mSharedPreferences,
postFeedScrolledPositionSharedPreferences, subredditName, postType,
sortType, postFilter, readPosts, subredditFilterList)).get(PostViewModel.class);
@ -887,23 +887,23 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
}
} else {
mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken,
accountName, locale, mSharedPreferences,
accountName, mSharedPreferences,
postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, postFilter,
readPosts)).get(PostViewModel.class);
}
} else if (postType == PostDataSource.TYPE_MULTI_REDDIT) {
mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken,
accountName, locale, mSharedPreferences,
accountName, mSharedPreferences,
postFeedScrolledPositionSharedPreferences, multiRedditPath, postType, sortType, postFilter,
readPosts)).get(PostViewModel.class);
} else if (postType == PostDataSource.TYPE_USER) {
mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken,
accountName, locale, mSharedPreferences,
accountName, mSharedPreferences,
postFeedScrolledPositionSharedPreferences, username, postType, sortType, postFilter,
where, readPosts)).get(PostViewModel.class);
} else {
mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mOauthRetrofit, accessToken,
accountName, locale, mSharedPreferences, postFeedScrolledPositionSharedPreferences,
accountName, mSharedPreferences, postFeedScrolledPositionSharedPreferences,
postType, sortType, postFilter, readPosts)).get(PostViewModel.class);
}

View File

@ -9,7 +9,6 @@ import androidx.paging.PageKeyedDataSource;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import ml.docilealligator.infinityforreddit.NetworkState;
import ml.docilealligator.infinityforreddit.PostFilter;
@ -41,7 +40,6 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> {
private Retrofit retrofit;
private String accessToken;
private String accountName;
private Locale locale;
private SharedPreferences sharedPreferences;
private SharedPreferences postFeedScrolledPositionSharedPreferences;
private String subredditOrUserName;
@ -62,14 +60,13 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> {
private LoadParams<String> params;
private LoadCallback<String, Post> callback;
PostDataSource(Retrofit retrofit, String accessToken, String accountName, Locale locale,
PostDataSource(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences,
SharedPreferences postFeedScrolledPositionSharedPreferences, int postType,
SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) {
this.retrofit = retrofit;
this.accessToken = accessToken;
this.accountName = accountName;
this.locale = locale;
this.sharedPreferences = sharedPreferences;
this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences;
paginationNetworkStateLiveData = new MutableLiveData<>();
@ -82,14 +79,13 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> {
postLinkedHashSet = new LinkedHashSet<>();
}
PostDataSource(Retrofit retrofit, String accessToken, String accountName, Locale locale,
PostDataSource(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences,
String path, int postType, SortType sortType, PostFilter postFilter,
List<ReadPost> readPostList, List<SubredditFilter> subredditFilterList) {
this.retrofit = retrofit;
this.accessToken = accessToken;
this.accountName = accountName;
this.locale = locale;
this.sharedPreferences = sharedPreferences;
this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences;
if (postType == TYPE_SUBREDDIT) {
@ -124,14 +120,13 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> {
postLinkedHashSet = new LinkedHashSet<>();
}
PostDataSource(Retrofit retrofit, String accessToken, String accountName, Locale locale,
PostDataSource(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences,
String subredditOrUserName, int postType, SortType sortType, PostFilter postFilter,
String where, List<ReadPost> readPostList) {
this.retrofit = retrofit;
this.accessToken = accessToken;
this.accountName = accountName;
this.locale = locale;
this.sharedPreferences = sharedPreferences;
this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences;
this.subredditOrUserName = subredditOrUserName;
@ -146,14 +141,13 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> {
postLinkedHashSet = new LinkedHashSet<>();
}
PostDataSource(Retrofit retrofit, String accessToken, String accountName, Locale locale,
PostDataSource(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences,
String subredditOrUserName, String query, int postType, SortType sortType, PostFilter postFilter,
List<ReadPost> readPostList) {
this.retrofit = retrofit;
this.accessToken = accessToken;
this.accountName = accountName;
this.locale = locale;
this.sharedPreferences = sharedPreferences;
this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences;
this.subredditOrUserName = subredditOrUserName;

View File

@ -1,13 +1,13 @@
package ml.docilealligator.infinityforreddit.post;
import android.content.SharedPreferences;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.MutableLiveData;
import androidx.paging.DataSource;
import java.util.List;
import java.util.Locale;
import ml.docilealligator.infinityforreddit.PostFilter;
import ml.docilealligator.infinityforreddit.SortType;
@ -19,7 +19,6 @@ class PostDataSourceFactory extends DataSource.Factory {
private Retrofit retrofit;
private String accessToken;
private String accountName;
private Locale locale;
private SharedPreferences sharedPreferences;
private SharedPreferences postFeedScrolledPositionSharedPreferences;
private String subredditName;
@ -34,14 +33,13 @@ class PostDataSourceFactory extends DataSource.Factory {
private PostDataSource postDataSource;
private MutableLiveData<PostDataSource> postDataSourceLiveData;
PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, Locale locale,
PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences,
SharedPreferences postFeedScrolledPositionSharedPreferences, int postType,
SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) {
this.retrofit = retrofit;
this.accessToken = accessToken;
this.accountName = accountName;
this.locale = locale;
this.sharedPreferences = sharedPreferences;
this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences;
postDataSourceLiveData = new MutableLiveData<>();
@ -51,14 +49,13 @@ class PostDataSourceFactory extends DataSource.Factory {
this.readPostList = readPostList;
}
PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, Locale locale,
PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences,
String subredditName, int postType, SortType sortType, PostFilter postFilter,
List<ReadPost> readPostList, List<SubredditFilter> subredditFilterList) {
this.retrofit = retrofit;
this.accessToken = accessToken;
this.accountName = accountName;
this.locale = locale;
this.sharedPreferences = sharedPreferences;
this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences;
this.subredditName = subredditName;
@ -70,14 +67,13 @@ class PostDataSourceFactory extends DataSource.Factory {
this.subredditFilterList = subredditFilterList;
}
PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, Locale locale,
PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences,
String subredditName, int postType, SortType sortType, PostFilter postFilter,
String where, List<ReadPost> readPostList) {
this.retrofit = retrofit;
this.accessToken = accessToken;
this.accountName = accountName;
this.locale = locale;
this.sharedPreferences = sharedPreferences;
this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences;
this.subredditName = subredditName;
@ -89,14 +85,13 @@ class PostDataSourceFactory extends DataSource.Factory {
this.readPostList = readPostList;
}
PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, Locale locale,
PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences,
String subredditName, String query, int postType, SortType sortType, PostFilter postFilter,
List<ReadPost> readPostList) {
this.retrofit = retrofit;
this.accessToken = accessToken;
this.accountName = accountName;
this.locale = locale;
this.sharedPreferences = sharedPreferences;
this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences;
this.subredditName = subredditName;
@ -112,19 +107,20 @@ class PostDataSourceFactory extends DataSource.Factory {
@Override
public DataSource<String, Post> create() {
if (postType == PostDataSource.TYPE_FRONT_PAGE) {
postDataSource = new PostDataSource(retrofit, accessToken, accountName, locale,
postDataSource = new PostDataSource(retrofit, accessToken, accountName,
sharedPreferences, postFeedScrolledPositionSharedPreferences, postType, sortType,
postFilter, readPostList);
} else if (postType == PostDataSource.TYPE_SEARCH) {
postDataSource = new PostDataSource(retrofit, accessToken, accountName, locale,
postDataSource = new PostDataSource(retrofit, accessToken, accountName,
sharedPreferences, postFeedScrolledPositionSharedPreferences, subredditName, query,
postType, sortType, postFilter, readPostList);
} else if (postType == PostDataSource.TYPE_SUBREDDIT || postType == PostDataSource.TYPE_MULTI_REDDIT) {
postDataSource = new PostDataSource(retrofit, accessToken, accountName, locale,
Log.i("asdasfd", "s5 " + (postFilter == null));
postDataSource = new PostDataSource(retrofit, accessToken, accountName,
sharedPreferences, postFeedScrolledPositionSharedPreferences, subredditName, postType,
sortType, postFilter, readPostList, subredditFilterList);
} else {
postDataSource = new PostDataSource(retrofit, accessToken, accountName, locale,
postDataSource = new PostDataSource(retrofit, accessToken, accountName,
sharedPreferences, postFeedScrolledPositionSharedPreferences, subredditName, postType,
sortType, postFilter, userWhere, readPostList);
}
@ -142,6 +138,7 @@ class PostDataSourceFactory extends DataSource.Factory {
}
void changeSortTypeAndPostFilter(SortType sortType, PostFilter postFilter) {
Log.i("asdasfd", "s6 " + (postFilter == null));
this.sortType = sortType;
this.postFilter = postFilter;
}

View File

@ -14,7 +14,6 @@ import androidx.paging.LivePagedListBuilder;
import androidx.paging.PagedList;
import java.util.List;
import java.util.Locale;
import ml.docilealligator.infinityforreddit.NetworkState;
import ml.docilealligator.infinityforreddit.PostFilter;
@ -31,12 +30,12 @@ public class PostViewModel extends ViewModel {
private LiveData<PagedList<Post>> posts;
private MutableLiveData<SortType> sortTypeLiveData;
private MutableLiveData<PostFilter> postFilterLiveData;
private NSFWAndSortTypeLiveData nsfwAndSortTypeLiveData;
private SortTypeAndPostFilterLiveData sortTypeAndPostFilterLiveData;
public PostViewModel(Retrofit retrofit, String accessToken, String accountName, Locale locale,
public PostViewModel(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences, SharedPreferences cache, int postType,
SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) {
postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, locale,
postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName,
sharedPreferences, cache, postType, sortType, postFilter, readPostList);
initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(),
@ -51,7 +50,7 @@ public class PostViewModel extends ViewModel {
postFilterLiveData = new MutableLiveData<>();
postFilterLiveData.postValue(postFilter);
nsfwAndSortTypeLiveData = new NSFWAndSortTypeLiveData(sortTypeLiveData, postFilterLiveData);
sortTypeAndPostFilterLiveData = new SortTypeAndPostFilterLiveData(sortTypeLiveData, postFilterLiveData);
PagedList.Config pagedListConfig =
(new PagedList.Config.Builder())
@ -59,18 +58,18 @@ public class PostViewModel extends ViewModel {
.setPageSize(25)
.build();
posts = Transformations.switchMap(nsfwAndSortTypeLiveData, nsfwAndSort -> {
posts = Transformations.switchMap(sortTypeAndPostFilterLiveData, sortAndPostFilter -> {
postDataSourceFactory.changeSortTypeAndPostFilter(
sortTypeLiveData.getValue(), postFilterLiveData.getValue());
return (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build();
});
}
public PostViewModel(Retrofit retrofit, String accessToken, String accountName, Locale locale,
public PostViewModel(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences, SharedPreferences cache, String subredditName,
int postType, SortType sortType, PostFilter postFilter,
List<ReadPost> readPostList, List<SubredditFilter> subredditFilterList) {
postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, locale,
postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName,
sharedPreferences, cache, subredditName, postType, sortType, postFilter,
readPostList, subredditFilterList);
@ -86,7 +85,7 @@ public class PostViewModel extends ViewModel {
postFilterLiveData = new MutableLiveData<>();
postFilterLiveData.postValue(postFilter);
nsfwAndSortTypeLiveData = new NSFWAndSortTypeLiveData(sortTypeLiveData, postFilterLiveData);
sortTypeAndPostFilterLiveData = new SortTypeAndPostFilterLiveData(sortTypeLiveData, postFilterLiveData);
PagedList.Config pagedListConfig =
(new PagedList.Config.Builder())
@ -94,18 +93,18 @@ public class PostViewModel extends ViewModel {
.setPageSize(25)
.build();
posts = Transformations.switchMap(nsfwAndSortTypeLiveData, nsfwAndSort -> {
posts = Transformations.switchMap(sortTypeAndPostFilterLiveData, sortAndPostFilter -> {
postDataSourceFactory.changeSortTypeAndPostFilter(
sortTypeLiveData.getValue(), postFilterLiveData.getValue());
return (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build();
});
}
public PostViewModel(Retrofit retrofit, String accessToken, String accountName, Locale locale,
public PostViewModel(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences, SharedPreferences cache, String subredditName,
int postType, SortType sortType, PostFilter postFilter, String where,
List<ReadPost> readPostList) {
postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, locale,
postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName,
sharedPreferences, cache, subredditName, postType, sortType, postFilter, where, readPostList);
initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(),
@ -120,7 +119,7 @@ public class PostViewModel extends ViewModel {
postFilterLiveData = new MutableLiveData<>();
postFilterLiveData.postValue(postFilter);
nsfwAndSortTypeLiveData = new NSFWAndSortTypeLiveData(sortTypeLiveData, postFilterLiveData);
sortTypeAndPostFilterLiveData = new SortTypeAndPostFilterLiveData(sortTypeLiveData, postFilterLiveData);
PagedList.Config pagedListConfig =
(new PagedList.Config.Builder())
@ -128,17 +127,17 @@ public class PostViewModel extends ViewModel {
.setPageSize(25)
.build();
posts = Transformations.switchMap(nsfwAndSortTypeLiveData, nsfwAndSort -> {
posts = Transformations.switchMap(sortTypeAndPostFilterLiveData, sortAndPostFilter -> {
postDataSourceFactory.changeSortTypeAndPostFilter(
sortTypeLiveData.getValue(), postFilterLiveData.getValue());
return (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build();
});
}
public PostViewModel(Retrofit retrofit, String accessToken, String accountName, Locale locale,
public PostViewModel(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences, SharedPreferences cache, String subredditName,
String query, int postType, SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) {
postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, locale,
postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName,
sharedPreferences, cache, subredditName, query, postType, sortType, postFilter,
readPostList);
@ -154,7 +153,7 @@ public class PostViewModel extends ViewModel {
postFilterLiveData = new MutableLiveData<>();
postFilterLiveData.postValue(postFilter);
nsfwAndSortTypeLiveData = new NSFWAndSortTypeLiveData(sortTypeLiveData, postFilterLiveData);
sortTypeAndPostFilterLiveData = new SortTypeAndPostFilterLiveData(sortTypeLiveData, postFilterLiveData);
PagedList.Config pagedListConfig =
(new PagedList.Config.Builder())
@ -162,7 +161,7 @@ public class PostViewModel extends ViewModel {
.setPageSize(25)
.build();
posts = Transformations.switchMap(nsfwAndSortTypeLiveData, nsfwAndSort -> {
posts = Transformations.switchMap(sortTypeAndPostFilterLiveData, sortAndPostFilter -> {
postDataSourceFactory.changeSortTypeAndPostFilter(sortTypeLiveData.getValue(),
postFilterLiveData.getValue());
return (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build();
@ -205,7 +204,6 @@ public class PostViewModel extends ViewModel {
private Retrofit retrofit;
private String accessToken;
private String accountName;
private Locale locale;
private SharedPreferences sharedPreferences;
private SharedPreferences postFeedScrolledPositionSharedPreferences;
private String subredditName;
@ -217,13 +215,12 @@ public class PostViewModel extends ViewModel {
private List<ReadPost> readPostList;
private List<SubredditFilter> subredditFilterList;
public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale,
public Factory(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences,
int postType, SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) {
this.retrofit = retrofit;
this.accessToken = accessToken;
this.accountName = accountName;
this.locale = locale;
this.sharedPreferences = sharedPreferences;
this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences;
this.postType = postType;
@ -232,14 +229,13 @@ public class PostViewModel extends ViewModel {
this.readPostList = readPostList;
}
public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale,
public Factory(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences,
SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditName,
int postType, SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) {
this.retrofit = retrofit;
this.accessToken = accessToken;
this.accountName = accountName;
this.locale = locale;
this.sharedPreferences = sharedPreferences;
this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences;
this.subredditName = subredditName;
@ -250,7 +246,7 @@ public class PostViewModel extends ViewModel {
}
//With subreddit filter
public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale,
public Factory(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences,
SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditName,
int postType, SortType sortType, PostFilter postFilter,
@ -258,7 +254,6 @@ public class PostViewModel extends ViewModel {
this.retrofit = retrofit;
this.accessToken = accessToken;
this.accountName = accountName;
this.locale = locale;
this.sharedPreferences = sharedPreferences;
this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences;
this.subredditName = subredditName;
@ -270,13 +265,12 @@ public class PostViewModel extends ViewModel {
}
//User posts
public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale,
public Factory(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditName,
int postType, SortType sortType, PostFilter postFilter, String where, List<ReadPost> readPostList) {
this.retrofit = retrofit;
this.accessToken = accessToken;
this.accountName = accountName;
this.locale = locale;
this.sharedPreferences = sharedPreferences;
this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences;
this.subredditName = subredditName;
@ -287,13 +281,12 @@ public class PostViewModel extends ViewModel {
this.readPostList = readPostList;
}
public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale,
public Factory(Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditName,
String query, int postType, SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) {
this.retrofit = retrofit;
this.accessToken = accessToken;
this.accountName = accountName;
this.locale = locale;
this.sharedPreferences = sharedPreferences;
this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences;
this.subredditName = subredditName;
@ -308,26 +301,26 @@ public class PostViewModel extends ViewModel {
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (postType == PostDataSource.TYPE_FRONT_PAGE) {
return (T) new PostViewModel(retrofit, accessToken, accountName, locale, sharedPreferences,
return (T) new PostViewModel(retrofit, accessToken, accountName, sharedPreferences,
postFeedScrolledPositionSharedPreferences, postType, sortType, postFilter, readPostList);
} else if (postType == PostDataSource.TYPE_SEARCH) {
return (T) new PostViewModel(retrofit, accessToken, accountName, locale, sharedPreferences,
return (T) new PostViewModel(retrofit, accessToken, accountName, sharedPreferences,
postFeedScrolledPositionSharedPreferences, subredditName, query, postType, sortType,
postFilter, readPostList);
} else if (postType == PostDataSource.TYPE_SUBREDDIT || postType == PostDataSource.TYPE_MULTI_REDDIT) {
return (T) new PostViewModel(retrofit, accessToken, accountName, locale, sharedPreferences,
return (T) new PostViewModel(retrofit, accessToken, accountName, sharedPreferences,
postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType,
postFilter, readPostList, subredditFilterList);
} else {
return (T) new PostViewModel(retrofit, accessToken, accountName, locale, sharedPreferences,
return (T) new PostViewModel(retrofit, accessToken, accountName, sharedPreferences,
postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType,
postFilter, userWhere, readPostList);
}
}
}
private static class NSFWAndSortTypeLiveData extends MediatorLiveData<Pair<PostFilter, SortType>> {
public NSFWAndSortTypeLiveData(LiveData<SortType> sortTypeLiveData, LiveData<PostFilter> postFilterLiveData) {
private static class SortTypeAndPostFilterLiveData extends MediatorLiveData<Pair<PostFilter, SortType>> {
public SortTypeAndPostFilterLiveData(LiveData<SortType> sortTypeLiveData, LiveData<PostFilter> postFilterLiveData) {
addSource(sortTypeLiveData, sortType -> setValue(Pair.create(postFilterLiveData.getValue(), sortType)));
addSource(postFilterLiveData, postFilter -> setValue(Pair.create(postFilter, sortTypeLiveData.getValue())));
}

View File

@ -11,13 +11,17 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.provider.MediaStore;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.documentfile.provider.DocumentFile;
@ -29,6 +33,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Random;
import javax.inject.Inject;
import javax.inject.Named;
@ -43,8 +48,6 @@ import ml.docilealligator.infinityforreddit.utils.NotificationUtils;
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
@ -71,11 +74,9 @@ public class DownloadMediaService extends Service {
SharedPreferences mSharedPreferences;
@Inject
CustomThemeWrapper mCustomThemeWrapper;
private int mediaType;
private String mimeType;
private NotificationManagerCompat notificationManager;
private NotificationCompat.Builder builder;
private boolean downloadFinished;
private ServiceHandler serviceHandler;
public DownloadMediaService() {
}
@ -85,131 +86,61 @@ public class DownloadMediaService extends Service {
return null;
}
private String getNotificationChannelId() {
switch (mediaType) {
case EXTRA_MEDIA_TYPE_GIF:
return NotificationUtils.CHANNEL_ID_DOWNLOAD_GIF;
case EXTRA_MEDIA_TYPE_VIDEO:
return NotificationUtils.CHANNEL_ID_DOWNLOAD_VIDEO;
default:
return NotificationUtils.CHANNEL_ID_DOWNLOAD_IMAGE;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
private boolean downloadFinished;
public ServiceHandler(Looper looper) {
super(looper);
}
}
@Override
public void handleMessage(Message msg) {
int randomNotificationIdOffset = msg.arg1;
Bundle intent = msg.getData();
downloadFinished = false;
String fileUrl = intent.getString(EXTRA_URL);
final String[] fileName = {intent.getString(EXTRA_FILE_NAME)};
String subredditName = intent.getString(EXTRA_SUBREDDIT_NAME);
int mediaType = intent.getInt(EXTRA_MEDIA_TYPE, EXTRA_MEDIA_TYPE_IMAGE);
String mimeType = mediaType == EXTRA_MEDIA_TYPE_VIDEO ? "video/*" : "image/*";
private String getNotificationChannel() {
switch (mediaType) {
case EXTRA_MEDIA_TYPE_GIF:
return NotificationUtils.CHANNEL_DOWNLOAD_GIF;
case EXTRA_MEDIA_TYPE_VIDEO:
return NotificationUtils.CHANNEL_DOWNLOAD_VIDEO;
default:
return NotificationUtils.CHANNEL_DOWNLOAD_IMAGE;
}
}
final DownloadProgressResponseBody.ProgressListener progressListener = new DownloadProgressResponseBody.ProgressListener() {
long time = 0;
private int getNotificationId() {
switch (mediaType) {
case EXTRA_MEDIA_TYPE_GIF:
return NotificationUtils.DOWNLOAD_GIF_NOTIFICATION_ID;
case EXTRA_MEDIA_TYPE_VIDEO:
return NotificationUtils.DOWNLOAD_VIDEO_NOTIFICATION_ID;
default:
return NotificationUtils.DOWNLOAD_IMAGE_NOTIFICATION_ID;
}
}
private String getDownloadLocation() {
switch (mediaType) {
case EXTRA_MEDIA_TYPE_GIF:
return mSharedPreferences.getString(SharedPreferencesUtils.GIF_DOWNLOAD_LOCATION, "");
case EXTRA_MEDIA_TYPE_VIDEO:
return mSharedPreferences.getString(SharedPreferencesUtils.VIDEO_DOWNLOAD_LOCATION, "");
default:
return mSharedPreferences.getString(SharedPreferencesUtils.IMAGE_DOWNLOAD_LOCATION, "");
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
((Infinity) getApplication()).getAppComponent().inject(this);
downloadFinished = false;
String fileUrl = intent.getStringExtra(EXTRA_URL);
final String[] fileName = {intent.getStringExtra(EXTRA_FILE_NAME)};
String subredditName = intent.getStringExtra(EXTRA_SUBREDDIT_NAME);
mediaType = intent.getIntExtra(EXTRA_MEDIA_TYPE, EXTRA_MEDIA_TYPE_IMAGE);
mimeType = mediaType == EXTRA_MEDIA_TYPE_VIDEO ? "video/*" : "image/*";
notificationManager = NotificationManagerCompat.from(this);
builder = new NotificationCompat.Builder(this, getNotificationChannelId());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel;
serviceChannel = new NotificationChannel(
getNotificationChannelId(),
getNotificationChannel(),
NotificationManager.IMPORTANCE_LOW
);
notificationManager.createNotificationChannel(serviceChannel);
}
switch (mediaType) {
case EXTRA_MEDIA_TYPE_GIF:
startForeground(
NotificationUtils.DOWNLOAD_GIF_NOTIFICATION_ID,
createNotification(fileName[0])
);
break;
case EXTRA_MEDIA_TYPE_VIDEO:
startForeground(
NotificationUtils.DOWNLOAD_VIDEO_NOTIFICATION_ID,
createNotification(fileName[0])
);
break;
default:
startForeground(
NotificationUtils.DOWNLOAD_IMAGE_NOTIFICATION_ID,
createNotification(fileName[0])
);
}
final DownloadProgressResponseBody.ProgressListener progressListener = new DownloadProgressResponseBody.ProgressListener() {
long time = 0;
@Override public void update(long bytesRead, long contentLength, boolean done) {
if (!done) {
if (contentLength != -1) {
long currentTime = System.currentTimeMillis();
if (currentTime - time > 1000) {
time = currentTime;
updateNotification(0, (int) ((100 * bytesRead) / contentLength), null);
@Override public void update(long bytesRead, long contentLength, boolean done) {
if (!done) {
if (contentLength != -1) {
long currentTime = System.currentTimeMillis();
if (currentTime - time > 1000) {
time = currentTime;
updateNotification(mediaType, 0,
(int) ((100 * bytesRead) / contentLength), randomNotificationIdOffset, null);
}
}
}
}
}
};
};
OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(chain -> {
okhttp3.Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.body(new DownloadProgressResponseBody(originalResponse.body(), progressListener))
.build();
})
.build();
OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(chain -> {
okhttp3.Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.body(new DownloadProgressResponseBody(originalResponse.body(), progressListener))
.build();
})
.build();
retrofit = retrofit.newBuilder().client(client).build();
retrofit = retrofit.newBuilder().client(client).build();
boolean separateDownloadFolder = mSharedPreferences.getBoolean(SharedPreferencesUtils.SEPARATE_FOLDER_FOR_EACH_SUBREDDIT, false);
boolean separateDownloadFolder = mSharedPreferences.getBoolean(SharedPreferencesUtils.SEPARATE_FOLDER_FOR_EACH_SUBREDDIT, false);
retrofit.create(DownloadFile.class).downloadFile(fileUrl).enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> response) {
Response<ResponseBody> response = null;
String destinationFileUriString = null;
boolean isDefaultDestination = true;
try {
response = retrofit.create(DownloadFile.class).downloadFile(fileUrl).execute();
if (response.isSuccessful() && response.body() != null) {
String destinationFileDirectory = getDownloadLocation();
String destinationFileUriString;
boolean isDefaultDestination;
String destinationFileDirectory = getDownloadLocation(mediaType);
if (destinationFileDirectory.equals("")) {
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
File directory = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
@ -217,12 +148,14 @@ public class DownloadMediaService extends Service {
String directoryPath = separateDownloadFolder && subredditName != null && !subredditName.equals("") ? directory.getAbsolutePath() + "/Infinity/" + subredditName + "/" : directory.getAbsolutePath() + "/Infinity/";
File infinityDir = new File(directoryPath);
if (!infinityDir.exists() && !infinityDir.mkdirs()) {
downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
downloadFinished(mediaType, randomNotificationIdOffset, mimeType,
null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
return;
}
destinationFileUriString = directoryPath + fileName[0];
} else {
downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
downloadFinished(mediaType, randomNotificationIdOffset, mimeType,
null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
return;
}
} else {
@ -237,21 +170,24 @@ public class DownloadMediaService extends Service {
if (separateDownloadFolder && subredditName != null && !subredditName.equals("")) {
dir = DocumentFile.fromTreeUri(DownloadMediaService.this, Uri.parse(destinationFileDirectory));
if (dir == null) {
downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
downloadFinished(mediaType, randomNotificationIdOffset, mimeType,
null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
return;
}
dir = dir.findFile(subredditName);
if (dir == null) {
dir = DocumentFile.fromTreeUri(DownloadMediaService.this, Uri.parse(destinationFileDirectory)).createDirectory(subredditName);
if (dir == null) {
downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
downloadFinished(mediaType, randomNotificationIdOffset, mimeType,
null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
return;
}
}
} else {
dir = DocumentFile.fromTreeUri(DownloadMediaService.this, Uri.parse(destinationFileDirectory));
if (dir == null) {
downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
downloadFinished(mediaType, randomNotificationIdOffset, mimeType,
null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
return;
}
}
@ -266,135 +202,38 @@ public class DownloadMediaService extends Service {
}
picFile = dir.createFile(mimeType, fileName[0]);
if (picFile == null) {
downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
downloadFinished(mediaType, randomNotificationIdOffset, mimeType,
null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
return;
}
destinationFileUriString = picFile.getUri().toString();
}
new SaveImageOrGifAndCopyToExternalStorageAsyncTask(response.body(), mediaType,
isDefaultDestination, fileName[0], destinationFileUriString, getContentResolver(),
(destinationFileUri, errorCode) -> downloadFinished(destinationFileUri, errorCode)).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
downloadFinished(mediaType, randomNotificationIdOffset, mimeType, null,
ERROR_FILE_CANNOT_DOWNLOAD);
}
}
@Override
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
downloadFinished(null, ERROR_FILE_CANNOT_DOWNLOAD);
}
});
return START_NOT_STICKY;
}
private Notification createNotification(String fileName) {
builder.setContentTitle(fileName).setContentText(getString(R.string.downloading)).setProgress(100, 0, false);
return builder.setSmallIcon(R.drawable.ic_notification)
.setColor(mCustomThemeWrapper.getColorPrimaryLightTheme())
.build();
}
private void updateNotification(int contentStringResId, int progress, PendingIntent pendingIntent) {
if (notificationManager != null) {
if (progress < 0) {
builder.setProgress(0, 0, false);
} else {
builder.setProgress(100, progress, false);
}
if (contentStringResId != 0) {
builder.setContentText(getString(contentStringResId));
}
if (pendingIntent != null) {
builder.setContentIntent(pendingIntent);
}
notificationManager.notify(getNotificationId(), builder.build());
}
}
private void downloadFinished(Uri destinationFileUri, int errorCode) {
if (downloadFinished) {
return;
}
downloadFinished = true;
if (errorCode != NO_ERROR) {
switch (errorCode) {
case ERROR_CANNOT_GET_DESTINATION_DIRECTORY:
updateNotification(R.string.downloading_image_or_gif_failed_cannot_get_destination_directory, -1, null);
break;
case ERROR_FILE_CANNOT_DOWNLOAD:
updateNotification(R.string.downloading_media_failed_cannot_download_media, -1, null);
break;
case ERROR_FILE_CANNOT_SAVE:
updateNotification(R.string.downloading_media_failed_cannot_save_to_destination_directory, -1, null);
break;
}
EventBus.getDefault().post(new DownloadMediaEvent(false));
} else {
MediaScannerConnection.scanFile(
this, new String[]{destinationFileUri.toString()}, null,
(path, uri) -> {
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(destinationFileUri, mimeType);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
updateNotification(R.string.downloading_media_finished, -1, pendingIntent);
EventBus.getDefault().post(new DownloadMediaEvent(true));
}
);
}
stopForeground(false);
}
private static class SaveImageOrGifAndCopyToExternalStorageAsyncTask extends AsyncTask<Void, Integer, Void> {
private ResponseBody response;
private int mediaType;
private boolean isDefaultDestination;
private String destinationFileName;
@NonNull
private String destinationFileUriString;
private ContentResolver contentResolver;
private SaveImageOrGifAndCopyToExternalStorageAsyncTaskListener saveImageOrGifAndCopyToExternalStorageAsyncTaskListener;
private int errorCode = NO_ERROR;
interface SaveImageOrGifAndCopyToExternalStorageAsyncTaskListener {
void finished(Uri destinationFileUri, int errorCode);
}
public SaveImageOrGifAndCopyToExternalStorageAsyncTask(ResponseBody response, int mediaType,
boolean isDefaultDestination,
String destinationFileName,
@NonNull String destinationFileUriString,
ContentResolver contentResolver,
SaveImageOrGifAndCopyToExternalStorageAsyncTaskListener saveImageOrGifAndCopyToExternalStorageAsyncTaskListener) {
this.response = response;
this.mediaType = mediaType;
this.isDefaultDestination = isDefaultDestination;
this.destinationFileName = destinationFileName;
this.destinationFileUriString = destinationFileUriString;
this.contentResolver = contentResolver;
this.saveImageOrGifAndCopyToExternalStorageAsyncTaskListener = saveImageOrGifAndCopyToExternalStorageAsyncTaskListener;
}
@Override
protected Void doInBackground(Void... voids) {
try {
writeResponseBodyToDisk(response);
} catch (IOException e) {
errorCode = ERROR_FILE_CANNOT_SAVE;
e.printStackTrace();
}
try {
if (response != null && response.body() != null) {
Uri destinationFileUri = writeResponseBodyToDisk(response.body(), isDefaultDestination, destinationFileUriString,
fileName[0], mediaType);
downloadFinished(mediaType, randomNotificationIdOffset,
mimeType, destinationFileUri, NO_ERROR);
}
} catch (IOException e) {
e.printStackTrace();
downloadFinished(mediaType, randomNotificationIdOffset,
mimeType, null, ERROR_FILE_CANNOT_SAVE);
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
saveImageOrGifAndCopyToExternalStorageAsyncTaskListener.finished(Uri.parse(destinationFileUriString), errorCode);
}
private void writeResponseBodyToDisk(ResponseBody body) throws IOException {
private Uri writeResponseBodyToDisk(ResponseBody body, boolean isDefaultDestination,
String destinationFileUriString, String destinationFileName,
int mediaType) throws IOException {
ContentResolver contentResolver = getContentResolver();
if (isDefaultDestination) {
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
InputStream inputStream = body.byteStream();
@ -463,6 +302,179 @@ public class DownloadMediaService extends Service {
}
}
}
return Uri.parse(destinationFileUriString);
}
private void downloadFinished(int mediaType, int randomNotificationIdOffset, String mimeType, Uri destinationFileUri, int errorCode) {
if (downloadFinished) {
return;
}
downloadFinished = true;
if (errorCode != NO_ERROR) {
switch (errorCode) {
case ERROR_CANNOT_GET_DESTINATION_DIRECTORY:
updateNotification(mediaType, R.string.downloading_image_or_gif_failed_cannot_get_destination_directory,
-1, randomNotificationIdOffset, null);
break;
case ERROR_FILE_CANNOT_DOWNLOAD:
updateNotification(mediaType, R.string.downloading_media_failed_cannot_download_media,
-1, randomNotificationIdOffset, null);
break;
case ERROR_FILE_CANNOT_SAVE:
updateNotification(mediaType, R.string.downloading_media_failed_cannot_save_to_destination_directory,
-1, randomNotificationIdOffset, null);
break;
}
EventBus.getDefault().post(new DownloadMediaEvent(false));
} else {
MediaScannerConnection.scanFile(
DownloadMediaService.this, new String[]{destinationFileUri.toString()}, null,
(path, uri) -> {
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(destinationFileUri, mimeType);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
PendingIntent pendingIntent = PendingIntent.getActivity(DownloadMediaService.this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
updateNotification(mediaType, R.string.downloading_media_finished, -1,
randomNotificationIdOffset, pendingIntent);
EventBus.getDefault().post(new DownloadMediaEvent(true));
}
);
}
stopForeground(false);
}
}
@Override
public void onCreate() {
super.onCreate();
((Infinity) getApplication()).getAppComponent().inject(this);
notificationManager = NotificationManagerCompat.from(this);
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work doesn't disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
serviceHandler = new ServiceHandler(thread.getLooper());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int mediaType = intent.getIntExtra(EXTRA_MEDIA_TYPE, EXTRA_MEDIA_TYPE_IMAGE);
builder = new NotificationCompat.Builder(this, getNotificationChannelId(mediaType));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel;
serviceChannel = new NotificationChannel(
getNotificationChannelId(mediaType),
getNotificationChannel(mediaType),
NotificationManager.IMPORTANCE_LOW
);
notificationManager.createNotificationChannel(serviceChannel);
}
int randomNotificationIdOffset = new Random().nextInt(10000);
switch (intent.getIntExtra(EXTRA_MEDIA_TYPE, EXTRA_MEDIA_TYPE_IMAGE)) {
case EXTRA_MEDIA_TYPE_GIF:
startForeground(
NotificationUtils.DOWNLOAD_GIF_NOTIFICATION_ID + randomNotificationIdOffset,
createNotification(intent.getStringExtra(EXTRA_FILE_NAME))
);
break;
case EXTRA_MEDIA_TYPE_VIDEO:
startForeground(
NotificationUtils.DOWNLOAD_VIDEO_NOTIFICATION_ID + randomNotificationIdOffset,
createNotification(intent.getStringExtra(EXTRA_FILE_NAME))
);
break;
default:
startForeground(
NotificationUtils.DOWNLOAD_IMAGE_NOTIFICATION_ID + randomNotificationIdOffset,
createNotification(intent.getStringExtra(EXTRA_FILE_NAME))
);
}
Message msg = serviceHandler.obtainMessage();
Bundle bundle = intent.getExtras();
msg.setData(bundle);
msg.arg1 = randomNotificationIdOffset;
serviceHandler.sendMessage(msg);
return START_NOT_STICKY;
}
private Notification createNotification(String fileName) {
builder.setContentTitle(fileName).setContentText(getString(R.string.downloading)).setProgress(100, 0, false);
return builder.setSmallIcon(R.drawable.ic_notification)
.setColor(mCustomThemeWrapper.getColorPrimaryLightTheme())
.build();
}
private void updateNotification(int mediaType, int contentStringResId, int progress, int randomNotificationIdOffset,
PendingIntent pendingIntent) {
if (notificationManager != null) {
if (progress < 0) {
builder.setProgress(0, 0, false);
} else {
builder.setProgress(100, progress, false);
}
if (contentStringResId != 0) {
builder.setContentText(getString(contentStringResId));
}
if (pendingIntent != null) {
builder.setContentIntent(pendingIntent);
}
notificationManager.notify(getNotificationId(mediaType, randomNotificationIdOffset), builder.build());
}
}
private String getNotificationChannelId(int mediaType) {
switch (mediaType) {
case EXTRA_MEDIA_TYPE_GIF:
return NotificationUtils.CHANNEL_ID_DOWNLOAD_GIF;
case EXTRA_MEDIA_TYPE_VIDEO:
return NotificationUtils.CHANNEL_ID_DOWNLOAD_VIDEO;
default:
return NotificationUtils.CHANNEL_ID_DOWNLOAD_IMAGE;
}
}
private String getNotificationChannel(int mediaType) {
switch (mediaType) {
case EXTRA_MEDIA_TYPE_GIF:
return NotificationUtils.CHANNEL_DOWNLOAD_GIF;
case EXTRA_MEDIA_TYPE_VIDEO:
return NotificationUtils.CHANNEL_DOWNLOAD_VIDEO;
default:
return NotificationUtils.CHANNEL_DOWNLOAD_IMAGE;
}
}
private int getNotificationId(int mediaType, int randomNotificationIdOffset) {
switch (mediaType) {
case EXTRA_MEDIA_TYPE_GIF:
return NotificationUtils.DOWNLOAD_GIF_NOTIFICATION_ID + randomNotificationIdOffset;
case EXTRA_MEDIA_TYPE_VIDEO:
return NotificationUtils.DOWNLOAD_VIDEO_NOTIFICATION_ID + randomNotificationIdOffset;
default:
return NotificationUtils.DOWNLOAD_IMAGE_NOTIFICATION_ID + randomNotificationIdOffset;
}
}
private String getDownloadLocation(int mediaType) {
switch (mediaType) {
case EXTRA_MEDIA_TYPE_GIF:
return mSharedPreferences.getString(SharedPreferencesUtils.GIF_DOWNLOAD_LOCATION, "");
case EXTRA_MEDIA_TYPE_VIDEO:
return mSharedPreferences.getString(SharedPreferencesUtils.VIDEO_DOWNLOAD_LOCATION, "");
default:
return mSharedPreferences.getString(SharedPreferencesUtils.IMAGE_DOWNLOAD_LOCATION, "");
}
}
}