diff options
author | Alex Ning <chineseperson5@gmail.com> | 2020-06-03 16:28:05 +0000 |
---|---|---|
committer | Alex Ning <chineseperson5@gmail.com> | 2020-06-03 16:28:05 +0000 |
commit | bb42cb713d76d997d16b5bfbc4052672c9031fed (patch) | |
tree | 8efa74f0f7219fba7bf7bd773adabe8dc013148e | |
parent | 470a59e104c07a58ad9859ec22f2734d337aa633 (diff) | |
download | infinity-for-reddit-bb42cb713d76d997d16b5bfbc4052672c9031fed.tar infinity-for-reddit-bb42cb713d76d997d16b5bfbc4052672c9031fed.tar.gz infinity-for-reddit-bb42cb713d76d997d16b5bfbc4052672c9031fed.tar.bz2 infinity-for-reddit-bb42cb713d76d997d16b5bfbc4052672c9031fed.tar.lz infinity-for-reddit-bb42cb713d76d997d16b5bfbc4052672c9031fed.tar.xz infinity-for-reddit-bb42cb713d76d997d16b5bfbc4052672c9031fed.tar.zst infinity-for-reddit-bb42cb713d76d997d16b5bfbc4052672c9031fed.zip |
Downloading videos and images is now available.
11 files changed, 371 insertions, 18 deletions
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewGIFActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewGIFActivity.java index 323cd7ab..3173c143 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewGIFActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewGIFActivity.java @@ -401,7 +401,7 @@ public class ViewGIFActivity extends AppCompatActivity { @Override public boolean onResourceReady(GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) { if (getExternalCacheDir() != null) { - new SaveGIFToFileAsyncTask(resource, getExternalCacheDir().getPath(), + new SaveGIFToFileAsyncTask(resource, getExternalCacheDir().getPath(), mImageFileName, new SaveGIFToFileAsyncTask.SaveGIFToFileAsyncTaskListener() { @Override public void saveSuccess(File imageFile) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImageActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImageActivity.java index 4533818d..68d65cb7 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImageActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImageActivity.java @@ -43,7 +43,6 @@ import com.bumptech.glide.RequestManager; import com.bumptech.glide.load.DataSource; import com.bumptech.glide.load.engine.GlideException; import com.bumptech.glide.request.RequestListener; -import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.transition.Transition; @@ -417,7 +416,7 @@ public class ViewImageActivity extends AppCompatActivity { public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) { if (getExternalCacheDir() != null) { Toast.makeText(ViewImageActivity.this, R.string.save_image_before_sharing, Toast.LENGTH_SHORT).show(); - new SaveImageToFileAsyncTask(resource, getExternalCacheDir().getPath(), + new SaveImageToFileAsyncTask(resource, getExternalCacheDir().getPath(), mImageFileName, new SaveImageToFileAsyncTask.SaveImageToFileAsyncTaskListener() { @Override public void saveSuccess(File imageFile) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImgurMediaActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImgurMediaActivity.java index 30d49eb6..d0f0071f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImgurMediaActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImgurMediaActivity.java @@ -295,9 +295,16 @@ public class ViewImgurMediaActivity extends AppCompatActivity { images = new ArrayList<>(); for (int i = 0; i < jsonArray.length(); i++) { JSONObject image = jsonArray.getJSONObject(i); - images.add(new ImgurMedia(image.getString(JSONUtils.ID_KEY), - image.getString(JSONUtils.TITLE_KEY), image.getString(JSONUtils.DESCRIPTION_KEY), - image.getString(JSONUtils.TYPE_KEY), image.getString(JSONUtils.LINK_KEY))); + String type = image.getString(JSONUtils.TYPE_KEY); + if (type.contains("gif")) { + images.add(new ImgurMedia(image.getString(JSONUtils.ID_KEY), + image.getString(JSONUtils.TITLE_KEY), image.getString(JSONUtils.DESCRIPTION_KEY), + "video/mp4", image.getString(JSONUtils.MP4_KEY))); + } else { + images.add(new ImgurMedia(image.getString(JSONUtils.ID_KEY), + image.getString(JSONUtils.TITLE_KEY), image.getString(JSONUtils.DESCRIPTION_KEY), + type, image.getString(JSONUtils.LINK_KEY))); + } } } catch (JSONException e) { e.printStackTrace(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveGIFToFileAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveGIFToFileAsyncTask.java index 39452004..c1a9ee19 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveGIFToFileAsyncTask.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveGIFToFileAsyncTask.java @@ -13,14 +13,16 @@ import java.nio.ByteBuffer; public class SaveGIFToFileAsyncTask extends AsyncTask<Void, Void, Void> { private GifDrawable resource; private String cacheDirPath; + private String fileName; private SaveGIFToFileAsyncTaskListener saveImageToFileAsyncTaskListener; private boolean saveSuccess = true; private File imageFile; - public SaveGIFToFileAsyncTask(GifDrawable resource, String cacheDirPath, + public SaveGIFToFileAsyncTask(GifDrawable resource, String cacheDirPath, String fileName, SaveGIFToFileAsyncTaskListener saveImageToFileAsyncTaskListener) { this.resource = resource; this.cacheDirPath = cacheDirPath; + this.fileName = fileName; this.saveImageToFileAsyncTaskListener = saveImageToFileAsyncTaskListener; } @@ -32,7 +34,7 @@ public class SaveGIFToFileAsyncTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... voids) { try { - imageFile = new File(cacheDirPath, "shared.gif"); + imageFile = new File(cacheDirPath, fileName); ByteBuffer byteBuffer = resource.getBuffer(); OutputStream outputStream = new FileOutputStream(imageFile); byte[] bytes = new byte[byteBuffer.capacity()]; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveImageToFileAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveImageToFileAsyncTask.java index 07164a46..65c1c199 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveImageToFileAsyncTask.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveImageToFileAsyncTask.java @@ -11,14 +11,16 @@ import java.io.OutputStream; public class SaveImageToFileAsyncTask extends AsyncTask<Void, Void, Void> { private Bitmap resource; private String cacheDirPath; + private String fileName; private SaveImageToFileAsyncTaskListener saveImageToFileAsyncTaskListener; private boolean saveSuccess = true; private File imageFile; - public SaveImageToFileAsyncTask(Bitmap resource, String cacheDirPath, + public SaveImageToFileAsyncTask(Bitmap resource, String cacheDirPath, String fileName, SaveImageToFileAsyncTaskListener saveImageToFileAsyncTaskListener) { this.resource = resource; this.cacheDirPath = cacheDirPath; + this.fileName = fileName; this.saveImageToFileAsyncTaskListener = saveImageToFileAsyncTaskListener; } @@ -30,11 +32,9 @@ public class SaveImageToFileAsyncTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... voids) { try { - imageFile = new File(cacheDirPath, "shared.jpg"); + imageFile = new File(cacheDirPath, fileName); OutputStream outputStream = new FileOutputStream(imageFile); - resource.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); - outputStream.flush(); outputStream.close(); } catch (IOException e) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurGifFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurGifFragment.java index 41bd9c1d..bc552268 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurGifFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurGifFragment.java @@ -1,9 +1,15 @@ package ml.docilealligator.infinityforreddit.Fragment; import android.app.Activity; +import android.app.DownloadManager; import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import android.os.Environment; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -12,23 +18,30 @@ import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.ProgressBar; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.content.FileProvider; import androidx.fragment.app.Fragment; -import com.alexvasilkov.gestures.views.GestureImageView; import com.bumptech.glide.Glide; import com.bumptech.glide.RequestManager; import com.bumptech.glide.load.DataSource; import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.load.resource.gif.GifDrawable; import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.target.Target; +import java.io.File; + import butterknife.BindView; import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.AsyncTask.SaveGIFToFileAsyncTask; +import ml.docilealligator.infinityforreddit.BuildConfig; import ml.docilealligator.infinityforreddit.ImgurMedia; import ml.docilealligator.infinityforreddit.R; +import pl.droidsonroids.gif.GifImageView; /** * A simple {@link Fragment} subclass. @@ -36,17 +49,20 @@ import ml.docilealligator.infinityforreddit.R; public class ViewImgurGifFragment extends Fragment { public static final String EXTRA_IMGUR_GIF = "EIG"; + private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; @BindView(R.id.progress_bar_view_imgur_gif_fragment) ProgressBar progressBar; @BindView(R.id.image_view_view_imgur_gif_fragment) - GestureImageView imageView; + GifImageView imageView; @BindView(R.id.load_image_error_linear_layout_view_imgur_gif_fragment) LinearLayout errorLinearLayout; private Activity activity; private RequestManager glide; private ImgurMedia imgurMedia; + private boolean isActionBarHidden = false; + private boolean isDownloading = false; public ViewImgurGifFragment() { // Required empty public constructor @@ -98,6 +114,44 @@ public class ViewImgurGifFragment extends Fragment { case R.id.action_download_view_imgur_image_fragments: return true; case R.id.action_share_view_imgur_image_fragments: + Toast.makeText(activity, R.string.save_gif_before_sharing, Toast.LENGTH_SHORT).show(); + glide.asGif().load(imgurMedia.getLink()).listener(new RequestListener<GifDrawable>() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<GifDrawable> target, boolean isFirstResource) { + return false; + } + + @Override + public boolean onResourceReady(GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) { + if (activity.getExternalCacheDir() != null) { + new SaveGIFToFileAsyncTask(resource, activity.getExternalCacheDir().getPath(), + imgurMedia.getFileName(), + new SaveGIFToFileAsyncTask.SaveGIFToFileAsyncTaskListener() { + @Override + public void saveSuccess(File imageFile) { + Uri uri = FileProvider.getUriForFile(activity, + BuildConfig.APPLICATION_ID + ".provider", imageFile); + Intent shareIntent = new Intent(); + shareIntent.setAction(Intent.ACTION_SEND); + shareIntent.putExtra(Intent.EXTRA_STREAM, uri); + shareIntent.setType("image/*"); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); + } + + @Override + public void saveFailed() { + Toast.makeText(activity, + R.string.cannot_save_gif, Toast.LENGTH_SHORT).show(); + } + }).execute(); + } else { + Toast.makeText(activity, + R.string.cannot_get_storage, Toast.LENGTH_SHORT).show(); + } + return false; + } + }).submit(); return true; } @@ -105,6 +159,62 @@ public class ViewImgurGifFragment extends Fragment { } @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { + if (grantResults[0] == PackageManager.PERMISSION_DENIED) { + Toast.makeText(activity, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); + } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED && isDownloading) { + download(); + } + isDownloading = false; + } + } + + private void download() { + DownloadManager.Request request = new DownloadManager.Request(Uri.parse(imgurMedia.getLink())); + request.setTitle(imgurMedia.getFileName()); + + 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, imgurMedia.getFileName()); + } 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/", imgurMedia.getFileName()); + } else { + request.setDestinationInExternalPublicDir(Environment.DIRECTORY_PICTURES, imgurMedia.getFileName()); + } + } + + DownloadManager manager = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE); + + if (manager == null) { + Toast.makeText(activity, R.string.download_failed, Toast.LENGTH_SHORT).show(); + return; + } + + manager.enqueue(request); + Toast.makeText(activity, R.string.download_started, Toast.LENGTH_SHORT).show(); + } + + @Override public void onAttach(@NonNull Context context) { super.onAttach(context); activity = (Activity) context; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurImageFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurImageFragment.java index bc30a3f8..3c9b5b41 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurImageFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurImageFragment.java @@ -1,9 +1,17 @@ package ml.docilealligator.infinityforreddit.Fragment; +import android.Manifest; import android.app.Activity; +import android.app.DownloadManager; import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import android.os.Environment; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -12,9 +20,13 @@ import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.ProgressBar; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.core.content.FileProvider; import androidx.fragment.app.Fragment; import com.alexvasilkov.gestures.views.GestureImageView; @@ -23,16 +35,23 @@ import com.bumptech.glide.RequestManager; import com.bumptech.glide.load.DataSource; import com.bumptech.glide.load.engine.GlideException; import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.target.Target; +import com.bumptech.glide.request.transition.Transition; + +import java.io.File; import butterknife.BindView; import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.AsyncTask.SaveImageToFileAsyncTask; +import ml.docilealligator.infinityforreddit.BuildConfig; import ml.docilealligator.infinityforreddit.ImgurMedia; import ml.docilealligator.infinityforreddit.R; public class ViewImgurImageFragment extends Fragment { public static final String EXTRA_IMGUR_IMAGES = "EII"; + private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; @BindView(R.id.progress_bar_view_imgur_image_fragment) ProgressBar progressBar; @@ -44,6 +63,8 @@ public class ViewImgurImageFragment extends Fragment { private Activity activity; private RequestManager glide; private ImgurMedia imgurMedia; + private boolean isActionBarHidden = false; + private boolean isDownloading = false; public ViewImgurImageFragment() { // Required empty public constructor @@ -92,8 +113,70 @@ public class ViewImgurImageFragment extends Fragment { public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.action_download_view_imgur_image_fragments: + if (isDownloading) { + return false; + } + + isDownloading = true; + + if (Build.VERSION.SDK_INT >= 23) { + if (ContextCompat.checkSelfPermission(activity, + Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + + // Permission is not granted + // No explanation needed; request the permission + ActivityCompat.requestPermissions(activity, + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); + } else { + // Permission has already been granted + download(); + } + } else { + download(); + } + return true; case R.id.action_share_view_imgur_image_fragments: + glide.asBitmap().load(imgurMedia.getLink()).into(new CustomTarget<Bitmap>() { + + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) { + if (activity.getExternalCacheDir() != null) { + Toast.makeText(activity, R.string.save_image_before_sharing, Toast.LENGTH_SHORT).show(); + new SaveImageToFileAsyncTask(resource, activity.getExternalCacheDir().getPath(), + imgurMedia.getFileName(), + new SaveImageToFileAsyncTask.SaveImageToFileAsyncTaskListener() { + @Override + public void saveSuccess(File imageFile) { + Uri uri = FileProvider.getUriForFile(activity, + BuildConfig.APPLICATION_ID + ".provider",imageFile); + Intent shareIntent = new Intent(); + shareIntent.setAction(Intent.ACTION_SEND); + shareIntent.putExtra(Intent.EXTRA_STREAM, uri); + shareIntent.setType("image/*"); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); + } + + @Override + public void saveFailed() { + Toast.makeText(activity, + R.string.cannot_save_image, Toast.LENGTH_SHORT).show(); + } + }).execute(); + } else { + Toast.makeText(activity, + R.string.cannot_get_storage, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + + } + }); return true; } @@ -101,6 +184,62 @@ public class ViewImgurImageFragment extends Fragment { } @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { + if (grantResults[0] == PackageManager.PERMISSION_DENIED) { + Toast.makeText(activity, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); + } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED && isDownloading) { + download(); + } + isDownloading = false; + } + } + + private void download() { + DownloadManager.Request request = new DownloadManager.Request(Uri.parse(imgurMedia.getLink())); + request.setTitle(imgurMedia.getFileName()); + + 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, imgurMedia.getFileName()); + } 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/", imgurMedia.getFileName()); + } else { + request.setDestinationInExternalPublicDir(Environment.DIRECTORY_PICTURES, imgurMedia.getFileName()); + } + } + + DownloadManager manager = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE); + + if (manager == null) { + Toast.makeText(activity, R.string.download_failed, Toast.LENGTH_SHORT).show(); + return; + } + + manager.enqueue(request); + Toast.makeText(activity, R.string.download_started, Toast.LENGTH_SHORT).show(); + } + + @Override public void onAttach(@NonNull Context context) { super.onAttach(context); activity = (Activity) context; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurVideoFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurVideoFragment.java index fdda3c51..3ec6eb39 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurVideoFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurVideoFragment.java @@ -1,12 +1,17 @@ package ml.docilealligator.infinityforreddit.Fragment; +import android.Manifest; import android.app.Activity; +import android.app.DownloadManager; import android.content.Context; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.content.res.Configuration; import android.media.AudioManager; import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import android.os.Environment; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -15,8 +20,11 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.LinearLayout; +import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import com.google.android.exoplayer2.ExoPlayerFactory; @@ -34,6 +42,8 @@ import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.util.Util; +import java.io.File; + import javax.inject.Inject; import javax.inject.Named; @@ -52,6 +62,7 @@ public class ViewImgurVideoFragment extends Fragment { public static final String EXTRA_IMGUR_VIDEO = "EIV"; private static final String IS_MUTE_STATE = "IMS"; private static final String POSITION_STATE = "PS"; + private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; @BindView(R.id.player_view_view_imgur_video_fragment) PlayerView videoPlayerView; @BindView(R.id.mute_exo_playback_control_view) @@ -62,6 +73,7 @@ public class ViewImgurVideoFragment extends Fragment { private DataSource.Factory dataSourceFactory; private boolean wasPlaying = false; private boolean isMute = false; + private boolean isDownloading = false; @Inject @Named("default") SharedPreferences mSharedPreferences; @@ -139,13 +151,88 @@ public class ViewImgurVideoFragment extends Fragment { @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case R.id.action_download_view_imgur_image_fragments: - return true; + if (item.getItemId() == R.id.action_download_view_imgur_image_fragments) { + isDownloading = true; + if (Build.VERSION.SDK_INT >= 23) { + if (ContextCompat.checkSelfPermission(activity, + Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + + // Permission is not granted + // No explanation needed; request the permission + ActivityCompat.requestPermissions(activity, + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); + } else { + // Permission has already been granted + download(); + } + } else { + download(); + } + return true; } return false; } + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { + if (grantResults[0] == PackageManager.PERMISSION_DENIED) { + Toast.makeText(activity, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); + } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED && isDownloading) { + download(); + } + isDownloading = false; + } + } + + private void download() { + isDownloading = false; + + DownloadManager.Request request = new DownloadManager.Request(Uri.parse(imgurMedia.getLink())); + request.setTitle(imgurMedia.getFileName()); + + 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, imgurMedia.getFileName()); + } 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/", imgurMedia.getFileName()); + } else { + request.setDestinationInExternalPublicDir(Environment.DIRECTORY_PICTURES, imgurMedia.getFileName()); + } + } + + DownloadManager manager = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE); + + if (manager == null) { + Toast.makeText(activity, R.string.download_failed, Toast.LENGTH_SHORT).show(); + return; + } + + manager.enqueue(request); + Toast.makeText(activity, R.string.download_started, Toast.LENGTH_SHORT).show(); + } + private void preparePlayer(Bundle savedInstanceState) { player.setRepeatMode(Player.REPEAT_MODE_ALL); wasPlaying = true; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ImgurMedia.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ImgurMedia.java index 577b6fde..6ae818b1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ImgurMedia.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ImgurMedia.java @@ -65,6 +65,14 @@ public class ImgurMedia implements Parcelable { return link; } + public String getFileName() { + if (type == TYPE_VIDEO) { + return "imgur-" + id + ".mp4"; + } + + return "imgur-" + id + ".jpg"; + } + @Override public int describeContents() { return 0; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/JSONUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/JSONUtils.java index 10ae166a..03e7fe9e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/JSONUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/JSONUtils.java @@ -110,4 +110,5 @@ public class JSONUtils { public static final String MP4_URL_KEY = "mp4Url"; public static final String WEBM_URL_KEY = "webmUrl"; public static final String TYPE_KEY = "type"; + public static final String MP4_KEY = "mp4"; } diff --git a/build.gradle b/build.gradle index b8837c77..88a1e4a2 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.6.3' + classpath 'com.android.tools.build:gradle:4.0.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files |