Browse Source
Fix direct downloading and delete action when there are multiple image notifications
renovate/org.robolectric-robolectric-4.x
Fix direct downloading and delete action when there are multiple image notifications
renovate/org.robolectric-robolectric-4.x
Ammar Githam
4 years ago
8 changed files with 171 additions and 318 deletions
-
27app/src/main/AndroidManifest.xml
-
149app/src/main/java/awais/instagrabber/activities/DirectDownload.java
-
149app/src/main/java/awais/instagrabber/directdownload/DirectDownload.java
-
117app/src/main/java/awais/instagrabber/directdownload/MultiDirectDialog.java
-
7app/src/main/java/awais/instagrabber/services/DeleteImageIntentService.java
-
4app/src/main/res/layout/activity_direct.xml
-
21app/src/main/res/layout/dialog_direct.xml
-
15app/src/main/res/values/styles.xml
@ -0,0 +1,149 @@ |
|||||
|
package awais.instagrabber.activities; |
||||
|
|
||||
|
import android.Manifest; |
||||
|
import android.app.Notification; |
||||
|
import android.content.Context; |
||||
|
import android.content.Intent; |
||||
|
import android.content.pm.PackageManager; |
||||
|
import android.content.res.Resources; |
||||
|
import android.net.Uri; |
||||
|
import android.os.AsyncTask; |
||||
|
import android.os.Bundle; |
||||
|
import android.view.WindowManager; |
||||
|
|
||||
|
import androidx.annotation.NonNull; |
||||
|
import androidx.annotation.Nullable; |
||||
|
import androidx.appcompat.app.AppCompatActivity; |
||||
|
import androidx.core.app.ActivityCompat; |
||||
|
import androidx.core.app.NotificationCompat; |
||||
|
import androidx.core.app.NotificationManagerCompat; |
||||
|
import androidx.core.content.ContextCompat; |
||||
|
|
||||
|
import awais.instagrabber.R; |
||||
|
import awais.instagrabber.asyncs.PostFetcher; |
||||
|
import awais.instagrabber.interfaces.FetchListener; |
||||
|
import awais.instagrabber.models.FeedModel; |
||||
|
import awais.instagrabber.models.IntentModel; |
||||
|
import awais.instagrabber.models.enums.IntentModelType; |
||||
|
import awais.instagrabber.utils.Constants; |
||||
|
import awais.instagrabber.utils.DownloadUtils; |
||||
|
import awais.instagrabber.utils.IntentUtils; |
||||
|
import awais.instagrabber.utils.TextUtils; |
||||
|
|
||||
|
public final class DirectDownload extends AppCompatActivity { |
||||
|
private static final int NOTIFICATION_ID = 1900000000; |
||||
|
private static final int STORAGE_PERM_REQUEST_CODE = 8020; |
||||
|
|
||||
|
private boolean contextFound = false; |
||||
|
private Intent intent; |
||||
|
private Context context; |
||||
|
private NotificationManagerCompat notificationManager; |
||||
|
|
||||
|
@Override |
||||
|
protected void onCreate(@Nullable final Bundle savedInstanceState) { |
||||
|
super.onCreate(savedInstanceState); |
||||
|
setContentView(R.layout.activity_direct); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onWindowAttributesChanged(final WindowManager.LayoutParams params) { |
||||
|
super.onWindowAttributesChanged(params); |
||||
|
if (!contextFound) { |
||||
|
intent = getIntent(); |
||||
|
context = getApplicationContext(); |
||||
|
if (intent != null && context != null) { |
||||
|
contextFound = true; |
||||
|
checkPermissions(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Resources getResources() { |
||||
|
if (!contextFound) { |
||||
|
intent = getIntent(); |
||||
|
context = getApplicationContext(); |
||||
|
if (intent != null && context != null) { |
||||
|
contextFound = true; |
||||
|
checkPermissions(); |
||||
|
} |
||||
|
} |
||||
|
return super.getResources(); |
||||
|
} |
||||
|
|
||||
|
private synchronized void checkPermissions() { |
||||
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { |
||||
|
doDownload(); |
||||
|
return; |
||||
|
} |
||||
|
ActivityCompat.requestPermissions(this, DownloadUtils.PERMS, STORAGE_PERM_REQUEST_CODE); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) { |
||||
|
final boolean granted = grantResults[0] == PackageManager.PERMISSION_GRANTED; |
||||
|
if (requestCode == STORAGE_PERM_REQUEST_CODE && granted) { |
||||
|
doDownload(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private synchronized void doDownload() { |
||||
|
notificationManager = NotificationManagerCompat.from(getApplicationContext()); |
||||
|
final Intent intent = getIntent(); |
||||
|
final String action = intent.getAction(); |
||||
|
if (TextUtils.isEmpty(action) || Intent.ACTION_MAIN.equals(action)) { |
||||
|
finish(); |
||||
|
return; |
||||
|
} |
||||
|
boolean error = true; |
||||
|
|
||||
|
String data = null; |
||||
|
final Bundle extras = intent.getExtras(); |
||||
|
if (extras != null) { |
||||
|
final Object extraData = extras.get(Intent.EXTRA_TEXT); |
||||
|
if (extraData != null) { |
||||
|
error = false; |
||||
|
data = extraData.toString(); |
||||
|
} |
||||
|
} |
||||
|
if (error) { |
||||
|
final Uri intentData = intent.getData(); |
||||
|
if (intentData != null) data = intentData.toString(); |
||||
|
} |
||||
|
if (data == null || TextUtils.isEmpty(data)) { |
||||
|
finish(); |
||||
|
return; |
||||
|
} |
||||
|
final IntentModel model = IntentUtils.parseUrl(data); |
||||
|
if (model == null || model.getType() != IntentModelType.POST) { |
||||
|
finish(); |
||||
|
return; |
||||
|
} |
||||
|
final String text = model.getText(); |
||||
|
new PostFetcher(text, new FetchListener<FeedModel>() { |
||||
|
@Override |
||||
|
public void doBefore() { |
||||
|
if (notificationManager == null) return; |
||||
|
final Notification fetchingPostNotification = new NotificationCompat.Builder(getApplicationContext(), Constants.DOWNLOAD_CHANNEL_ID) |
||||
|
.setCategory(NotificationCompat.CATEGORY_STATUS) |
||||
|
.setSmallIcon(R.drawable.ic_download) |
||||
|
.setAutoCancel(false) |
||||
|
.setPriority(NotificationCompat.PRIORITY_MIN) |
||||
|
.setContentText(getString(R.string.direct_download_loading)) |
||||
|
.build(); |
||||
|
notificationManager.notify(NOTIFICATION_ID, fetchingPostNotification); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onResult(final FeedModel result) { |
||||
|
if (notificationManager != null) notificationManager.cancel(NOTIFICATION_ID); |
||||
|
if (result == null) { |
||||
|
finish(); |
||||
|
return; |
||||
|
} |
||||
|
DownloadUtils.download(getApplicationContext(), result); |
||||
|
finish(); |
||||
|
} |
||||
|
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
||||
|
} |
||||
|
} |
@ -1,149 +0,0 @@ |
|||||
package awais.instagrabber.directdownload; |
|
||||
|
|
||||
import android.Manifest; |
|
||||
import android.app.Activity; |
|
||||
import android.app.Notification; |
|
||||
import android.content.Context; |
|
||||
import android.content.Intent; |
|
||||
import android.content.pm.PackageManager; |
|
||||
import android.content.res.Resources; |
|
||||
import android.net.Uri; |
|
||||
import android.os.AsyncTask; |
|
||||
import android.os.Bundle; |
|
||||
import android.os.Handler; |
|
||||
import android.os.Looper; |
|
||||
import android.view.WindowManager; |
|
||||
import android.widget.Toast; |
|
||||
|
|
||||
import androidx.annotation.Nullable; |
|
||||
import androidx.core.app.ActivityCompat; |
|
||||
import androidx.core.app.NotificationCompat; |
|
||||
import androidx.core.app.NotificationManagerCompat; |
|
||||
import androidx.core.content.ContextCompat; |
|
||||
|
|
||||
import java.util.Collections; |
|
||||
|
|
||||
import awais.instagrabber.R; |
|
||||
import awais.instagrabber.asyncs.PostFetcher; |
|
||||
import awais.instagrabber.interfaces.FetchListener; |
|
||||
import awais.instagrabber.models.FeedModel; |
|
||||
import awais.instagrabber.models.IntentModel; |
|
||||
import awais.instagrabber.models.enums.DownloadMethod; |
|
||||
import awais.instagrabber.models.enums.IntentModelType; |
|
||||
import awais.instagrabber.models.enums.MediaItemType; |
|
||||
import awais.instagrabber.utils.Constants; |
|
||||
import awais.instagrabber.utils.DownloadUtils; |
|
||||
import awais.instagrabber.utils.IntentUtils; |
|
||||
import awais.instagrabber.utils.TextUtils; |
|
||||
|
|
||||
public final class DirectDownload extends Activity { |
|
||||
private boolean isFound = false; |
|
||||
private Intent intent; |
|
||||
private Context context; |
|
||||
private NotificationManagerCompat notificationManager; |
|
||||
|
|
||||
@Override |
|
||||
protected void onCreate(@Nullable final Bundle savedInstanceState) { |
|
||||
super.onCreate(savedInstanceState); |
|
||||
notificationManager = NotificationManagerCompat.from(getApplicationContext()); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void onWindowAttributesChanged(final WindowManager.LayoutParams params) { |
|
||||
super.onWindowAttributesChanged(params); |
|
||||
if (!isFound) { |
|
||||
intent = getIntent(); |
|
||||
context = getApplicationContext(); |
|
||||
if (intent != null && context != null) { |
|
||||
isFound = true; |
|
||||
checkIntent(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public Resources getResources() { |
|
||||
if (!isFound) { |
|
||||
intent = getIntent(); |
|
||||
context = getApplicationContext(); |
|
||||
if (intent != null && context != null) { |
|
||||
isFound = true; |
|
||||
checkIntent(); |
|
||||
} |
|
||||
} |
|
||||
return super.getResources(); |
|
||||
} |
|
||||
|
|
||||
private synchronized void checkIntent() { |
|
||||
if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) |
|
||||
doDownload(); |
|
||||
else { |
|
||||
final Handler handler = new Handler(Looper.getMainLooper()); |
|
||||
handler.post(new Runnable() { |
|
||||
@Override |
|
||||
public void run() { |
|
||||
Toast.makeText(context, R.string.direct_download_perms_ask, Toast.LENGTH_LONG).show(); |
|
||||
handler.removeCallbacks(this); |
|
||||
} |
|
||||
}); |
|
||||
ActivityCompat.requestPermissions(this, DownloadUtils.PERMS, 8020); |
|
||||
} |
|
||||
finish(); |
|
||||
} |
|
||||
|
|
||||
private synchronized void doDownload() { |
|
||||
final String action = intent.getAction(); |
|
||||
if (TextUtils.isEmpty(action) || Intent.ACTION_MAIN.equals(action)) return; |
|
||||
boolean error = true; |
|
||||
|
|
||||
String data = null; |
|
||||
final Bundle extras = intent.getExtras(); |
|
||||
if (extras != null) { |
|
||||
final Object extraData = extras.get(Intent.EXTRA_TEXT); |
|
||||
if (extraData != null) { |
|
||||
error = false; |
|
||||
data = extraData.toString(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if (error) { |
|
||||
final Uri intentData = intent.getData(); |
|
||||
if (intentData != null) data = intentData.toString(); |
|
||||
} |
|
||||
|
|
||||
if (data != null && !TextUtils.isEmpty(data)) { |
|
||||
final IntentModel model = IntentUtils.parseUrl(data); |
|
||||
if (model != null && model.getType() == IntentModelType.POST) { |
|
||||
final String text = model.getText(); |
|
||||
|
|
||||
new PostFetcher(text, new FetchListener<FeedModel>() { |
|
||||
@Override |
|
||||
public void doBefore() { |
|
||||
final Notification fetchingPostNotif = new NotificationCompat.Builder(context, Constants.DOWNLOAD_CHANNEL_ID) |
|
||||
.setCategory(NotificationCompat.CATEGORY_STATUS).setSmallIcon(R.mipmap.ic_launcher) |
|
||||
.setAutoCancel(false).setPriority(NotificationCompat.PRIORITY_MIN) |
|
||||
.setContentText(context.getString(R.string.direct_download_loading)).build(); |
|
||||
notificationManager.notify(1900000000, fetchingPostNotif); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void onResult(final FeedModel result) { |
|
||||
if (notificationManager != null) notificationManager.cancel(1900000000); |
|
||||
if (result != null) { |
|
||||
if (result.getItemType() != MediaItemType.MEDIA_TYPE_SLIDER) { |
|
||||
DownloadUtils.batchDownload(context, |
|
||||
result.getProfileModel().getUsername(), |
|
||||
DownloadMethod.DOWNLOAD_DIRECT, |
|
||||
Collections.singletonList(result)); |
|
||||
} else { |
|
||||
context.startActivity(new Intent(context, MultiDirectDialog.class) |
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) |
|
||||
.putExtra(Constants.EXTRAS_POST, result)); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -1,117 +0,0 @@ |
|||||
package awais.instagrabber.directdownload; |
|
||||
|
|
||||
import android.content.Intent; |
|
||||
import android.os.Bundle; |
|
||||
import android.view.Menu; |
|
||||
import android.view.MenuItem; |
|
||||
|
|
||||
import androidx.annotation.NonNull; |
|
||||
import androidx.annotation.Nullable; |
|
||||
import androidx.appcompat.widget.Toolbar; |
|
||||
import androidx.recyclerview.widget.RecyclerView; |
|
||||
|
|
||||
import java.util.ArrayList; |
|
||||
|
|
||||
import awais.instagrabber.R; |
|
||||
import awais.instagrabber.activities.BaseLanguageActivity; |
|
||||
import awais.instagrabber.adapters.PostsAdapter; |
|
||||
import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager; |
|
||||
import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration; |
|
||||
import awais.instagrabber.models.BasePostModel; |
|
||||
import awais.instagrabber.models.FeedModel; |
|
||||
import awais.instagrabber.models.PostModel; |
|
||||
import awais.instagrabber.models.enums.DownloadMethod; |
|
||||
import awais.instagrabber.utils.Constants; |
|
||||
import awais.instagrabber.utils.DownloadUtils; |
|
||||
import awais.instagrabber.utils.Utils; |
|
||||
|
|
||||
public final class MultiDirectDialog extends BaseLanguageActivity { |
|
||||
public final ArrayList<BasePostModel> selectedItems = new ArrayList<>(); |
|
||||
private PostsAdapter postsAdapter; |
|
||||
private MenuItem btnDownload; |
|
||||
private String username = null; |
|
||||
|
|
||||
@Override |
|
||||
protected void onCreate(@Nullable final Bundle savedInstanceState) { |
|
||||
super.onCreate(savedInstanceState); |
|
||||
setContentView(R.layout.dialog_direct); |
|
||||
|
|
||||
final Toolbar toolbar = findViewById(R.id.toolbar); |
|
||||
setSupportActionBar(toolbar); |
|
||||
|
|
||||
final FeedModel feedModel; |
|
||||
final Intent intent = getIntent(); |
|
||||
if (intent == null || !intent.hasExtra(Constants.EXTRAS_POST) |
|
||||
|| (feedModel = (FeedModel) intent.getSerializableExtra(Constants.EXTRAS_POST)) == null) { |
|
||||
Utils.errorFinish(this); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
username = feedModel.getProfileModel().getUsername(); |
|
||||
toolbar.setTitle(username); |
|
||||
toolbar.setSubtitle(feedModel.getShortCode()); |
|
||||
|
|
||||
final RecyclerView recyclerView = findViewById(R.id.mainPosts); |
|
||||
recyclerView.setNestedScrollingEnabled(false); |
|
||||
recyclerView.setLayoutManager(new GridAutofitLayoutManager(this, Utils.convertDpToPx(130))); |
|
||||
recyclerView.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4))); |
|
||||
// final ArrayList<PostModel> models = new ArrayList<>(feedModel.length - 1); |
|
||||
// for (final ViewerPostModel postModel : feedModel) |
|
||||
// models.add(new PostModel(postModel.getItemType(), postModel.getPostId(), postModel.getDisplayUrl(), |
|
||||
// postModel.getDisplayUrl(), postModel.getShortCode(), postModel.getPostCaption(), postModel.getTimestamp(), |
|
||||
// postModel.getLike(), postModel.isSaved(), postModel.getLikes())); |
|
||||
|
|
||||
// postsAdapter = new PostsAdapter(v -> { |
|
||||
// final Object tag = v.getTag(); |
|
||||
// if (tag instanceof PostModel) { |
|
||||
// final PostModel postModel = (PostModel) tag; |
|
||||
// if (postsAdapter.isSelecting) toggleSelection(postModel); |
|
||||
// else { |
|
||||
// Utils.batchDownload(this, username, DownloadMethod.DOWNLOAD_DIRECT, Collections.singletonList(postModel)); |
|
||||
// finish(); |
|
||||
// } |
|
||||
// } |
|
||||
// }, v -> { |
|
||||
// final Object tag = v.getTag(); |
|
||||
// if (tag instanceof PostModel) { |
|
||||
// postsAdapter.isSelecting = true; |
|
||||
// toggleSelection((PostModel) tag); |
|
||||
// } |
|
||||
// return true; |
|
||||
// }); |
|
||||
// |
|
||||
// recyclerView.setAdapter(postsAdapter); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public boolean onOptionsItemSelected(@NonNull final MenuItem item) { |
|
||||
DownloadUtils.batchDownload(this, username, DownloadMethod.DOWNLOAD_DIRECT, selectedItems); |
|
||||
finish(); |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public boolean onCreateOptionsMenu(final Menu menu) { |
|
||||
getMenuInflater().inflate(R.menu.menu, menu); |
|
||||
btnDownload = menu.findItem(R.id.action_download); |
|
||||
menu.findItem(R.id.action_search).setVisible(false); |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
private void toggleSelection(final PostModel postModel) { |
|
||||
if (postModel != null && postsAdapter != null) { |
|
||||
if (postModel.isSelected()) selectedItems.remove(postModel); |
|
||||
else selectedItems.add(postModel); |
|
||||
postModel.setSelected(!postModel.isSelected()); |
|
||||
notifyAdapter(postModel); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private void notifyAdapter(final PostModel postModel) { |
|
||||
// if (selectedItems.size() < 1) postsAdapter.isSelecting = false; |
|
||||
// if (postModel.getPosition() < 0) postsAdapter.notifyDataSetChanged(); |
|
||||
// else postsAdapter.notifyItemChanged(postModel.getPosition(), postModel); |
|
||||
// |
|
||||
// if (btnDownload != null) btnDownload.setVisible(postsAdapter.isSelecting); |
|
||||
} |
|
||||
} |
|
@ -0,0 +1,4 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="match_parent" /> |
@ -1,21 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|
||||
xmlns:tools="http://schemas.android.com/tools" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="match_parent" |
|
||||
android:orientation="vertical" |
|
||||
tools:viewBindingIgnore="true"> |
|
||||
|
|
||||
<include layout="@layout/layout_include_toolbar" /> |
|
||||
|
|
||||
<androidx.recyclerview.widget.RecyclerView |
|
||||
android:id="@+id/mainPosts" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="match_parent" |
|
||||
android:clipToPadding="false" |
|
||||
android:paddingStart="8dp" |
|
||||
android:paddingLeft="8dp" |
|
||||
android:paddingEnd="8dp" |
|
||||
android:paddingRight="8dp" |
|
||||
tools:listitem="@layout/item_post" /> |
|
||||
</LinearLayout> |
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue