aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Ning <chineseperson5@gmail.com>2020-12-22 07:56:55 +0000
committerAlex Ning <chineseperson5@gmail.com>2020-12-22 07:56:55 +0000
commitf4d061ceccf7c386321faf4093e27dab00e3e071 (patch)
tree952f2d5172cfd42ddbd7905e15ae0911485a0da0
parent664141b3240808597929901d52123c75c0b35427 (diff)
downloadinfinity-for-reddit-f4d061ceccf7c386321faf4093e27dab00e3e071.tar
infinity-for-reddit-f4d061ceccf7c386321faf4093e27dab00e3e071.tar.gz
infinity-for-reddit-f4d061ceccf7c386321faf4093e27dab00e3e071.tar.bz2
infinity-for-reddit-f4d061ceccf7c386321faf4093e27dab00e3e071.tar.lz
infinity-for-reddit-f4d061ceccf7c386321faf4093e27dab00e3e071.tar.xz
infinity-for-reddit-f4d061ceccf7c386321faf4093e27dab00e3e071.tar.zst
infinity-for-reddit-f4d061ceccf7c386321faf4093e27dab00e3e071.zip
Rewrite DownloadRedditVideoService to run the service in a background thread.
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java3
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java3
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadMediaService.java19
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java559
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/utils/NotificationUtils.java1
5 files changed, 263 insertions, 322 deletions
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java
index a654eab4..274d1ad7 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java
@@ -11,7 +11,6 @@ import androidx.annotation.Nullable;
import com.evernote.android.state.StateSaver;
import com.livefront.bridge.Bridge;
import com.livefront.bridge.SavedStateHandler;
-import com.melegy.redscreenofdeath.RedScreenOfDeath;
import org.greenrobot.eventbus.EventBus;
@@ -27,7 +26,7 @@ public class Infinity extends Application {
public void onCreate() {
super.onCreate();
- RedScreenOfDeath.init(this);
+ //RedScreenOfDeath.init(this);
mAppComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java
index f7cd0e5b..aaa1450d 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java
@@ -45,7 +45,8 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase {
RedditDataRoomDatabase.class, "reddit_data")
.addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5,
MIGRATION_5_6, MIGRATION_6_7, MIGRATION_7_8, MIGRATION_8_9,
- MIGRATION_9_10, MIGRATION_10_11, MIGRATION_11_12, MIGRATION_12_13)
+ MIGRATION_9_10, MIGRATION_10_11, MIGRATION_11_12, MIGRATION_12_13,
+ MIGRATION_13_14)
.build();
}
}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadMediaService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadMediaService.java
index 2d5f641b..1246634a 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadMediaService.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadMediaService.java
@@ -99,7 +99,7 @@ public class DownloadMediaService extends Service {
Bundle intent = msg.getData();
downloadFinished = false;
String fileUrl = intent.getString(EXTRA_URL);
- final String[] fileName = {intent.getString(EXTRA_FILE_NAME)};
+ 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/*";
@@ -152,7 +152,7 @@ public class DownloadMediaService extends Service {
null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
return;
}
- destinationFileUriString = directoryPath + fileName[0];
+ destinationFileUriString = directoryPath + fileName;
} else {
downloadFinished(mediaType, randomNotificationIdOffset, mimeType,
null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
@@ -191,16 +191,16 @@ public class DownloadMediaService extends Service {
return;
}
}
- DocumentFile checkForDuplicates = dir.findFile(fileName[0]);
- int extensionPosition = fileName[0].lastIndexOf('.');
- String extension = fileName[0].substring(extensionPosition);
+ DocumentFile checkForDuplicates = dir.findFile(fileName);
+ int extensionPosition = fileName.lastIndexOf('.');
+ String extension = fileName.substring(extensionPosition);
int num = 1;
while (checkForDuplicates != null) {
- fileName[0] = fileName[0].substring(0, extensionPosition) + " (" + num + ")" + extension;
- checkForDuplicates = dir.findFile(fileName[0]);
+ fileName = fileName.substring(0, extensionPosition) + " (" + num + ")" + extension;
+ checkForDuplicates = dir.findFile(fileName);
num++;
}
- picFile = dir.createFile(mimeType, fileName[0]);
+ picFile = dir.createFile(mimeType, fileName);
if (picFile == null) {
downloadFinished(mediaType, randomNotificationIdOffset, mimeType,
null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
@@ -219,7 +219,7 @@ public class DownloadMediaService extends Service {
try {
if (response != null && response.body() != null) {
Uri destinationFileUri = writeResponseBodyToDisk(response.body(), isDefaultDestination, destinationFileUriString,
- fileName[0], mediaType);
+ fileName, mediaType);
downloadFinished(mediaType, randomNotificationIdOffset,
mimeType, destinationFileUri, NO_ERROR);
}
@@ -348,7 +348,6 @@ public class DownloadMediaService extends Service {
@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
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java
index 696a1d34..c4f37aca 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java
@@ -15,13 +15,17 @@ import android.media.MediaFormat;
import android.media.MediaMuxer;
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;
@@ -35,6 +39,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
+import java.util.Random;
import javax.inject.Inject;
import javax.inject.Named;
@@ -49,8 +54,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;
@@ -79,101 +82,82 @@ public class DownloadRedditVideoService extends Service {
SharedPreferences sharedPreferences;
@Inject
CustomThemeWrapper customThemeWrapper;
- String resultFile;
+ private ServiceHandler serviceHandler;
private NotificationManagerCompat notificationManager;
private NotificationCompat.Builder builder;
public DownloadRedditVideoService() {
}
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- ((Infinity) getApplication()).getAppComponent().inject(this);
-
- String videoUrl = intent.getStringExtra(EXTRA_VIDEO_URL);
- String audioUrl = videoUrl.substring(0, videoUrl.lastIndexOf('/')) + "/DASH_audio.mp4";
- String subredditName = intent.getStringExtra(EXTRA_SUBREDDIT);
- final String[] fileNameWithoutExtension = {subredditName + "-" + intent.getStringExtra(EXTRA_POST_ID)};
-
- notificationManager = NotificationManagerCompat.from(this);
- builder = new NotificationCompat.Builder(this, NotificationUtils.CHANNEL_ID_DOWNLOAD_REDDIT_VIDEO);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- NotificationChannel serviceChannel;
- serviceChannel = new NotificationChannel(
- NotificationUtils.CHANNEL_ID_DOWNLOAD_REDDIT_VIDEO,
- NotificationUtils.CHANNEL_DOWNLOAD_REDDIT_VIDEO,
- NotificationManager.IMPORTANCE_LOW
- );
-
- notificationManager.createNotificationChannel(serviceChannel);
+ private final class ServiceHandler extends Handler {
+ public ServiceHandler(Looper looper) {
+ super(looper);
}
-
- startForeground(
- NotificationUtils.DOWNLOAD_REDDIT_VIDEO_NOTIFICATION_ID,
- createNotification(fileNameWithoutExtension[0] + ".mp4")
- );
-
- 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 handleMessage(Message msg) {
+ Bundle intent = msg.getData();
+ String videoUrl = intent.getString(EXTRA_VIDEO_URL);
+ String audioUrl = videoUrl.substring(0, videoUrl.lastIndexOf('/')) + "/DASH_audio.mp4";
+ String subredditName = intent.getString(EXTRA_SUBREDDIT);
+ String fileNameWithoutExtension = subredditName + "-" + intent.getString(EXTRA_POST_ID);
+ int randomNotificationIdOffset = msg.arg1;
+
+ 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),
+ 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();
- DownloadFile downloadFile = retrofit.create(DownloadFile.class);
+ DownloadFile downloadFile = retrofit.create(DownloadFile.class);
- boolean separateDownloadFolder = sharedPreferences.getBoolean(SharedPreferencesUtils.SEPARATE_FOLDER_FOR_EACH_SUBREDDIT, false);
+ boolean separateDownloadFolder = sharedPreferences.getBoolean(SharedPreferencesUtils.SEPARATE_FOLDER_FOR_EACH_SUBREDDIT, false);
- File directory = getExternalCacheDir();
- String destinationFileName = fileNameWithoutExtension[0] + ".mp4";
- if (directory != null) {
- String directoryPath = directory.getAbsolutePath() + "/";
- downloadFile.downloadFile(videoUrl).enqueue(new Callback<ResponseBody>() {
- @Override
- public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> videoResponse) {
+ File externalCacheDirectory = getExternalCacheDir();
+ if (externalCacheDirectory != null) {
+ String destinationFileName = fileNameWithoutExtension + ".mp4";
+
+ try {
+ Response<ResponseBody> videoResponse = downloadFile.downloadFile(videoUrl).execute();
if (videoResponse.isSuccessful() && videoResponse.body() != null) {
+ String externalCacheDirectoryPath = externalCacheDirectory.getAbsolutePath() + "/";
String destinationFileDirectory = sharedPreferences.getString(SharedPreferencesUtils.VIDEO_DOWNLOAD_LOCATION, "");
String destinationFileUriString;
boolean isDefaultDestination;
if (destinationFileDirectory.equals("")) {
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
- File directory = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
- if (directory != null) {
- String directoryPath = separateDownloadFolder ? directory.getAbsolutePath() + "/Infinity/" + subredditName + "/" : directory.getAbsolutePath() + "/Infinity/";
- File infinityDir = new File(directoryPath);
+ File destinationDirectory = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
+ if (destinationDirectory != null) {
+ String destinationDirectoryPath = separateDownloadFolder ? destinationDirectory.getAbsolutePath() + "/Infinity/" + subredditName + "/" : destinationDirectory.getAbsolutePath() + "/Infinity/";
+ File infinityDir = new File(destinationDirectoryPath);
if (!infinityDir.exists() && !infinityDir.mkdir()) {
- downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
+ downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY, randomNotificationIdOffset);
return;
}
- destinationFileUriString = directoryPath + destinationFileName;
+ destinationFileUriString = destinationDirectoryPath + destinationFileName;
} else {
- downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
+ downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY, randomNotificationIdOffset);
return;
}
} else {
@@ -187,272 +171,104 @@ public class DownloadRedditVideoService extends Service {
if (separateDownloadFolder) {
dir = DocumentFile.fromTreeUri(DownloadRedditVideoService.this, Uri.parse(destinationFileDirectory));
if (dir == null) {
- downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
+ downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY, randomNotificationIdOffset);
return;
}
dir = dir.findFile(subredditName);
if (dir == null) {
dir = DocumentFile.fromTreeUri(DownloadRedditVideoService.this, Uri.parse(destinationFileDirectory)).createDirectory(subredditName);
if (dir == null) {
- downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
+ downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY, randomNotificationIdOffset);
return;
}
}
} else {
dir = DocumentFile.fromTreeUri(DownloadRedditVideoService.this, Uri.parse(destinationFileDirectory));
if (dir == null) {
- downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
+ downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY, randomNotificationIdOffset);
return;
}
}
DocumentFile checkForDuplicates = dir.findFile(destinationFileName);
int num = 1;
while (checkForDuplicates != null) {
- fileNameWithoutExtension[0] = fileNameWithoutExtension[0] + " (" + num + ")";
- checkForDuplicates = dir.findFile(fileNameWithoutExtension[0] + ".mp4");
+ fileNameWithoutExtension = fileNameWithoutExtension + " (" + num + ")";
+ checkForDuplicates = dir.findFile(fileNameWithoutExtension + ".mp4");
num++;
}
- picFile = dir.createFile("video/*", fileNameWithoutExtension[0] + ".mp4");
+ picFile = dir.createFile("video/*", fileNameWithoutExtension + ".mp4");
if (picFile == null) {
- downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY);
+ downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY, randomNotificationIdOffset);
return;
}
destinationFileUriString = picFile.getUri().toString();
}
- updateNotification(R.string.downloading_reddit_video_audio_track, 0, null);
- downloadFile.downloadFile(audioUrl).enqueue(new Callback<ResponseBody>() {
- @Override
- public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> audioResponse) {
- if (audioResponse.isSuccessful() && audioResponse.body() != null) {
- String videoFilePath = directoryPath + fileNameWithoutExtension[0] + "-cache.mp4";
- String audioFilePath = directoryPath + fileNameWithoutExtension[0] + "-cache.mp3";
- String outputFilePath = directoryPath + fileNameWithoutExtension[0] + ".mp4";
- new SaveTempMuxAndCopyAsyncTask(videoResponse.body(),
- audioResponse.body(), videoFilePath, audioFilePath, outputFilePath,
- destinationFileName, destinationFileUriString, isDefaultDestination,
- getContentResolver(),
- new SaveTempMuxAndCopyAsyncTask.SaveTempMuxAndCopyAsyncTaskListener() {
- @Override
- public void finished(Uri destinationFileUri, int errorCode) {
- new File(videoFilePath).delete();
- new File(audioFilePath).delete();
- new File(outputFilePath).delete();
- downloadFinished(destinationFileUri, errorCode);
- }
-
- @Override
- public void updateProgressNotification(int stringResId) {
- updateNotification(stringResId, -1, null);
- }
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- } else {
- String videoFilePath = directoryPath + fileNameWithoutExtension[0] + "-cache.mp4";
- new SaveTempMuxAndCopyAsyncTask(videoResponse.body(),
- null, videoFilePath, null, null,
- destinationFileName, destinationFileUriString, isDefaultDestination,
- getContentResolver(),
- new SaveTempMuxAndCopyAsyncTask.SaveTempMuxAndCopyAsyncTaskListener() {
- @Override
- public void finished(Uri destinationFileUri, int errorCode) {
- new File(videoFilePath).delete();
- downloadFinished(destinationFileUri, errorCode);
- }
-
- @Override
- public void updateProgressNotification(int stringResId) {
- updateNotification(stringResId, -1, null);
- }
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
+ updateNotification(R.string.downloading_reddit_video_audio_track, 0,
+ randomNotificationIdOffset, null);
+
+ Response<ResponseBody> audioResponse = downloadFile.downloadFile(audioUrl).execute();
+ if (audioResponse.isSuccessful() && audioResponse.body() != null) {
+ String videoFilePath = externalCacheDirectoryPath + fileNameWithoutExtension + "-cache.mp4";
+ String audioFilePath = externalCacheDirectoryPath + fileNameWithoutExtension + "-cache.mp3";
+ String outputFilePath = externalCacheDirectoryPath + fileNameWithoutExtension + ".mp4";
+
+ String savedVideoFilePath = writeResponseBodyToDisk(videoResponse.body(), videoFilePath);
+ if (savedVideoFilePath == null) {
+ downloadFinished(null, ERROR_VIDEO_FILE_CANNOT_SAVE, randomNotificationIdOffset);
+ return;
+ }
+ String savedAudioFilePath = writeResponseBodyToDisk(audioResponse.body(), audioFilePath);
+ if (savedAudioFilePath == null) {
+ downloadFinished(null, ERROR_AUDIO_FILE_CANNOT_SAVE, randomNotificationIdOffset);
+ return;
}
- @Override
- public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
- String videoFilePath = directoryPath + fileNameWithoutExtension[0] + "-cache.mp4";
- new SaveTempMuxAndCopyAsyncTask(videoResponse.body(),
- null, videoFilePath, null, null,
- destinationFileName, destinationFileUriString, isDefaultDestination,
- getContentResolver(),
- new SaveTempMuxAndCopyAsyncTask.SaveTempMuxAndCopyAsyncTaskListener() {
- @Override
- public void finished(Uri destinationFileUri, int errorCode) {
- new File(videoFilePath).delete();
- downloadFinished(destinationFileUri, errorCode);
- }
-
- @Override
- public void updateProgressNotification(int stringResId) {
- updateNotification(stringResId, -1, null);
- }
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ updateNotification(R.string.downloading_reddit_video_muxing, -1,
+ randomNotificationIdOffset, null);
+ if (!muxVideoAndAudio(videoFilePath, audioFilePath, outputFilePath)) {
+ downloadFinished(null, ERROR_MUX_FAILED, randomNotificationIdOffset);
+ return;
}
- });
- } else {
- downloadFinished(null, ERROR_VIDEO_FILE_CANNOT_DOWNLOAD);
- }
- }
- @Override
- public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
- downloadFinished(null, ERROR_VIDEO_FILE_CANNOT_DOWNLOAD);
- }
- });
- } else {
- downloadFinished(null, ERROR_CANNOT_GET_CACHE_DIRECTORY);
- }
+ updateNotification(R.string.downloading_reddit_video_save_file_to_public_dir, -1,
+ randomNotificationIdOffset, null);
+ try {
+ Uri destinationFileUri = copyToDestination(outputFilePath, destinationFileUriString, destinationFileName, isDefaultDestination);
- return START_NOT_STICKY;
- }
+ new File(videoFilePath).delete();
+ new File(audioFilePath).delete();
+ new File(outputFilePath).delete();
- private void downloadFinished(Uri destinationFileUri, int errorCode) {
- if (errorCode != NO_ERROR) {
- switch (errorCode) {
- case ERROR_CANNOT_GET_CACHE_DIRECTORY:
- updateNotification(R.string.downloading_reddit_video_failed_cannot_get_cache_directory, -1, null);
- break;
- case ERROR_VIDEO_FILE_CANNOT_DOWNLOAD:
- updateNotification(R.string.downloading_reddit_video_failed_cannot_download_video, -1, null);
- break;
- case ERROR_VIDEO_FILE_CANNOT_SAVE:
- updateNotification(R.string.downloading_reddit_video_failed_cannot_save_video, -1, null);
- break;
- case ERROR_AUDIO_FILE_CANNOT_SAVE:
- updateNotification(R.string.downloading_reddit_video_failed_cannot_save_audio, -1, null);
- break;
- case ERROR_MUX_FAILED:
- updateNotification(R.string.downloading_reddit_video_failed_cannot_mux, -1, null);
- break;
- case ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE:
- updateNotification(R.string.downloading_reddit_video_failed_cannot_save_mux_video, -1, null);
- break;
- case ERROR_CANNOT_GET_DESTINATION_DIRECTORY:
- updateNotification(R.string.downloading_media_failed_cannot_save_to_destination_directory, -1, null);
- break;
- }
- EventBus.getDefault().post(new DownloadRedditVideoEvent(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, "video/*");
- intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
- updateNotification(R.string.downloading_reddit_video_finished, -1, pendingIntent);
- EventBus.getDefault().post(new DownloadRedditVideoEvent(true));
+ downloadFinished(destinationFileUri, NO_ERROR, randomNotificationIdOffset);
+ } catch (IOException e) {
+ e.printStackTrace();
+ downloadFinished(null, ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE, randomNotificationIdOffset);
+ }
+ } else {
+ String videoFilePath = externalCacheDirectoryPath + fileNameWithoutExtension + "-cache.mp4";
+
+ updateNotification(R.string.downloading_reddit_video_save_file_to_public_dir, -1,
+ randomNotificationIdOffset, null);
+ try {
+ Uri destinationFileUri = copyToDestination(videoFilePath, destinationFileUriString, destinationFileName, isDefaultDestination);
+ new File(videoFilePath).delete();
+ downloadFinished(destinationFileUri, NO_ERROR, randomNotificationIdOffset);
+ } catch (IOException e) {
+ e.printStackTrace();
+ downloadFinished(null, ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE, randomNotificationIdOffset);
+ }
+ }
+ } else {
+ downloadFinished(null, ERROR_VIDEO_FILE_CANNOT_DOWNLOAD, randomNotificationIdOffset);
}
- );
- }
- stopForeground(false);
- }
-
- private Notification createNotification(String fileName) {
- builder.setContentTitle(fileName).setContentText(getString(R.string.downloading_reddit_video)).setProgress(100, 0, false);
- return builder.setSmallIcon(R.drawable.ic_notification)
- .setColor(customThemeWrapper.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(NotificationUtils.DOWNLOAD_REDDIT_VIDEO_NOTIFICATION_ID, builder.build());
- }
- }
-
- private static class SaveTempMuxAndCopyAsyncTask extends AsyncTask<Void, Integer, Void> {
-
- private ResponseBody videoResponse;
- private ResponseBody audioResponse;
- private String videoFilePath;
- private String audioFilePath;
- private String outputFilePath;
- private String destinationFileName;
- @NonNull
- private String destinationFileUriString;
- private boolean isDefaultDestination;
- private ContentResolver contentResolver;
- private SaveTempMuxAndCopyAsyncTaskListener saveTempMuxAndCopyAsyncTaskListener;
- private int errorCode = NO_ERROR;
-
- public SaveTempMuxAndCopyAsyncTask(ResponseBody videoResponse, ResponseBody audioResponse,
- String videoFilePath, String audioFilePath, String outputFilePath,
- String destinationFileName, @NonNull String destinationFileUriString,
- boolean isDefaultDestination, ContentResolver contentResolver,
- SaveTempMuxAndCopyAsyncTaskListener saveTempMuxAndCopyAsyncTaskListener) {
- this.videoResponse = videoResponse;
- this.audioResponse = audioResponse;
- this.videoFilePath = videoFilePath;
- this.audioFilePath = audioFilePath;
- this.outputFilePath = outputFilePath;
- this.destinationFileName = destinationFileName;
- this.destinationFileUriString = destinationFileUriString;
- this.isDefaultDestination = isDefaultDestination;
- this.contentResolver = contentResolver;
- this.saveTempMuxAndCopyAsyncTaskListener = saveTempMuxAndCopyAsyncTaskListener;
- }
-
- @Override
- protected void onProgressUpdate(Integer... values) {
- super.onProgressUpdate(values);
- saveTempMuxAndCopyAsyncTaskListener.updateProgressNotification(values[0]);
- }
-
- @Override
- protected Void doInBackground(Void... voids) {
- String savedVideoFilePath = writeResponseBodyToDisk(videoResponse, videoFilePath);
- if (savedVideoFilePath == null) {
- errorCode = ERROR_VIDEO_FILE_CANNOT_SAVE;
- return null;
- }
- if (audioResponse != null) {
- String savedAudioFilePath = writeResponseBodyToDisk(audioResponse, audioFilePath);
- if (savedAudioFilePath == null) {
- errorCode = ERROR_AUDIO_FILE_CANNOT_SAVE;
- return null;
- }
-
- publishProgress(R.string.downloading_reddit_video_muxing);
- if (!muxVideoAndAudio(videoFilePath, audioFilePath, outputFilePath)) {
- errorCode = ERROR_MUX_FAILED;
- return null;
- }
-
- publishProgress(R.string.downloading_reddit_video_save_file_to_public_dir);
- try {
- copyToDestination(outputFilePath);
} catch (IOException e) {
e.printStackTrace();
- errorCode = ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE;
+ downloadFinished(null, ERROR_VIDEO_FILE_CANNOT_DOWNLOAD, randomNotificationIdOffset);
}
} else {
- publishProgress(R.string.downloading_reddit_video_save_file_to_public_dir);
- try {
- copyToDestination(videoFilePath);
- } catch (IOException e) {
- e.printStackTrace();
- errorCode = ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE;
- }
+ downloadFinished(null, ERROR_CANNOT_GET_CACHE_DIRECTORY, randomNotificationIdOffset);
}
- return null;
- }
-
- @Override
- protected void onPostExecute(Void aVoid) {
- super.onPostExecute(aVoid);
- saveTempMuxAndCopyAsyncTaskListener.finished(Uri.parse(destinationFileUriString), errorCode);
}
private String writeResponseBodyToDisk(ResponseBody body, String filePath) {
@@ -576,7 +392,9 @@ public class DownloadRedditVideoService extends Service {
return true;
}
- private void copyToDestination(String srcPath) throws IOException {
+ private Uri copyToDestination(String srcPath, String destinationFileUriString, String destinationFileName,
+ boolean isDefaultDestination) throws IOException {
+ ContentResolver contentResolver = getContentResolver();
if (isDefaultDestination) {
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
InputStream in = new FileInputStream(srcPath);
@@ -623,7 +441,7 @@ public class DownloadRedditVideoService extends Service {
contentValues.clear();
contentValues.put(MediaStore.Video.Media.IS_PENDING, 0);
contentResolver.update(uri, contentValues, null, null);
- destinationFileUriString = uri.toString();
+ return uri;
} catch (IOException e) {
if (uri != null) {
// Don't leave an orphan entry in the MediaStore
@@ -651,11 +469,136 @@ public class DownloadRedditVideoService extends Service {
stream.write(buf, 0, len);
}
}
+
+ return Uri.parse(destinationFileUriString);
+ }
+ }
+
+ @Override
+ public void 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 IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ builder = new NotificationCompat.Builder(DownloadRedditVideoService.this, NotificationUtils.CHANNEL_ID_DOWNLOAD_REDDIT_VIDEO);
+
+ String subredditName = intent.getStringExtra(EXTRA_SUBREDDIT);
+ String fileNameWithoutExtension = subredditName + "-" + intent.getStringExtra(EXTRA_POST_ID);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ NotificationChannel serviceChannel;
+ serviceChannel = new NotificationChannel(
+ NotificationUtils.CHANNEL_ID_DOWNLOAD_REDDIT_VIDEO,
+ NotificationUtils.CHANNEL_DOWNLOAD_REDDIT_VIDEO,
+ NotificationManager.IMPORTANCE_LOW
+ );
+
+ notificationManager.createNotificationChannel(serviceChannel);
+ }
+
+ int randomNotificationIdOffset = new Random().nextInt(10000);
+ startForeground(
+ NotificationUtils.DOWNLOAD_REDDIT_VIDEO_NOTIFICATION_ID + randomNotificationIdOffset,
+ createNotification(fileNameWithoutExtension + ".mp4")
+ );
+
+ Message msg = serviceHandler.obtainMessage();
+ Bundle bundle = intent.getExtras();
+ msg.setData(bundle);
+ msg.arg1 = randomNotificationIdOffset;
+ serviceHandler.sendMessage(msg);
+
+ return START_NOT_STICKY;
+ }
+
+ private void downloadFinished(Uri destinationFileUri, int errorCode, int randomNotificationIdOffset) {
+ if (errorCode != NO_ERROR) {
+ switch (errorCode) {
+ case ERROR_CANNOT_GET_CACHE_DIRECTORY:
+ updateNotification(R.string.downloading_reddit_video_failed_cannot_get_cache_directory, -1,
+ randomNotificationIdOffset, null);
+ break;
+ case ERROR_VIDEO_FILE_CANNOT_DOWNLOAD:
+ updateNotification(R.string.downloading_reddit_video_failed_cannot_download_video, -1,
+ randomNotificationIdOffset, null);
+ break;
+ case ERROR_VIDEO_FILE_CANNOT_SAVE:
+ updateNotification(R.string.downloading_reddit_video_failed_cannot_save_video, -1,
+ randomNotificationIdOffset, null);
+ break;
+ case ERROR_AUDIO_FILE_CANNOT_SAVE:
+ updateNotification(R.string.downloading_reddit_video_failed_cannot_save_audio, -1,
+ randomNotificationIdOffset, null);
+ break;
+ case ERROR_MUX_FAILED:
+ updateNotification(R.string.downloading_reddit_video_failed_cannot_mux, -1,
+ randomNotificationIdOffset, null);
+ break;
+ case ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE:
+ updateNotification(R.string.downloading_reddit_video_failed_cannot_save_mux_video, -1,
+ randomNotificationIdOffset, null);
+ break;
+ case ERROR_CANNOT_GET_DESTINATION_DIRECTORY:
+ updateNotification(R.string.downloading_media_failed_cannot_save_to_destination_directory, -1,
+ randomNotificationIdOffset, null);
+ break;
+ }
+ EventBus.getDefault().post(new DownloadRedditVideoEvent(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, "video/*");
+ intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+ updateNotification(R.string.downloading_reddit_video_finished, -1, randomNotificationIdOffset, pendingIntent);
+ EventBus.getDefault().post(new DownloadRedditVideoEvent(true));
+ }
+ );
}
+ stopForeground(false);
+ }
- interface SaveTempMuxAndCopyAsyncTaskListener {
- void finished(Uri destinationFileUri, int errorCode);
- void updateProgressNotification(int stringResId);
+ private Notification createNotification(String fileName) {
+ builder.setContentTitle(fileName).setContentText(getString(R.string.downloading_reddit_video)).setProgress(100, 0, false);
+ return builder.setSmallIcon(R.drawable.ic_notification)
+ .setColor(customThemeWrapper.getColorPrimaryLightTheme())
+ .build();
+ }
+
+ private void updateNotification(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(NotificationUtils.DOWNLOAD_REDDIT_VIDEO_NOTIFICATION_ID + randomNotificationIdOffset, builder.build());
}
}
}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/NotificationUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/NotificationUtils.java
index 940838af..75cc004a 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/NotificationUtils.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/NotificationUtils.java
@@ -26,7 +26,6 @@ public class NotificationUtils {
public static final int DOWNLOAD_VIDEO_NOTIFICATION_ID = 30000;
public static final int DOWNLOAD_IMAGE_NOTIFICATION_ID = 40000;
public static final int DOWNLOAD_GIF_NOTIFICATION_ID = 50000;
- public static final int PULL_NOTIFICATION_ALARM_RECEIVER_REQUEST_CODE = 12;
private static final int SUMMARY_BASE_ID_UNREAD_MESSAGE = 0;
private static final int NOTIFICATION_BASE_ID_UNREAD_MESSAGE = 1;