mirror of
				https://codeberg.org/tom79/Fedilab.git
				synced 2025-10-20 11:20:16 +03:00 
			
		
		
		
	Fix notification refresh + Post messages
This commit is contained in:
		
							parent
							
								
									bd43af4ab8
								
							
						
					
					
						commit
						927433a7bf
					
				
					 6 changed files with 135 additions and 123 deletions
				
			
		|  | @ -108,9 +108,6 @@ | |||
|             android:name="com.theartofdev.edmodo.cropper.CropImageActivity" | ||||
|             android:theme="@style/Base.Theme.AppCompat" /> | ||||
| 
 | ||||
|         <service | ||||
|             android:name=".services.PostMessageService" | ||||
|             android:label="@string/post_message" /> | ||||
| 
 | ||||
|         <activity | ||||
|             android:name=".activities.SearchResultTabActivity" | ||||
|  |  | |||
|  | @ -53,6 +53,7 @@ import androidx.preference.PreferenceManager; | |||
| import androidx.recyclerview.widget.LinearLayoutManager; | ||||
| import androidx.work.Data; | ||||
| import androidx.work.OneTimeWorkRequest; | ||||
| import androidx.work.OutOfQuotaPolicy; | ||||
| import androidx.work.WorkManager; | ||||
| 
 | ||||
| import java.io.File; | ||||
|  | @ -87,8 +88,8 @@ import app.fedilab.android.helper.MastodonHelper; | |||
| import app.fedilab.android.helper.MediaHelper; | ||||
| import app.fedilab.android.helper.ThemeHelper; | ||||
| import app.fedilab.android.interfaces.OnDownloadInterface; | ||||
| import app.fedilab.android.jobs.ComposeWorker; | ||||
| import app.fedilab.android.jobs.ScheduleThreadWorker; | ||||
| import app.fedilab.android.services.PostMessageService; | ||||
| import app.fedilab.android.services.ThreadMessageService; | ||||
| import app.fedilab.android.ui.drawer.AccountsReplyAdapter; | ||||
| import app.fedilab.android.ui.drawer.ComposeAdapter; | ||||
|  | @ -846,17 +847,17 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana | |||
|                     mediaCount += status.media_attachments != null ? status.media_attachments.size() : 0; | ||||
|                 } | ||||
|                 if (mediaCount > 0) { | ||||
|                     Intent intent = new Intent(ComposeActivity.this, PostMessageService.class); | ||||
|                     intent.putExtra(Helper.ARG_STATUS_DRAFT, statusDraft); | ||||
|                     intent.putExtra(Helper.ARG_INSTANCE, instance); | ||||
|                     intent.putExtra(Helper.ARG_TOKEN, token); | ||||
|                     intent.putExtra(Helper.ARG_USER_ID, account.user_id); | ||||
|                     intent.putExtra(Helper.ARG_SCHEDULED_DATE, scheduledDate); | ||||
|                     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|                         startForegroundService(intent); | ||||
|                     } else { | ||||
|                         startService(intent); | ||||
|                     } | ||||
|                     Data inputData = new Data.Builder() | ||||
|                             .putString(Helper.ARG_STATUS_DRAFT, ComposeWorker.serialize(statusDraft)) | ||||
|                             .putString(Helper.ARG_INSTANCE, instance) | ||||
|                             .putString(Helper.ARG_TOKEN, token) | ||||
|                             .putString(Helper.ARG_USER_ID, account.user_id) | ||||
|                             .putString(Helper.ARG_SCHEDULED_DATE, scheduledDate).build(); | ||||
|                     OneTimeWorkRequest request = new OneTimeWorkRequest.Builder(ComposeWorker.class) | ||||
|                             .setInputData(inputData) | ||||
|                             .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST) | ||||
|                             .build(); | ||||
|                     WorkManager.getInstance(ComposeActivity.this).enqueue(request); | ||||
|                 } else { | ||||
|                     new ThreadMessageService(ComposeActivity.this, instance, account.user_id, token, statusDraft, scheduledDate); | ||||
|                 } | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| package app.fedilab.android.services; | ||||
| /* Copyright 2021 Thomas Schneider | ||||
| package app.fedilab.android.jobs; | ||||
| /* Copyright 2022 Thomas Schneider | ||||
|  * | ||||
|  * This file is a part of Fedilab | ||||
|  * | ||||
|  | @ -14,10 +14,13 @@ package app.fedilab.android.services; | |||
|  * You should have received a copy of the GNU General Public License along with Fedilab; if not, | ||||
|  * see <http://www.gnu.org/licenses>. */ | ||||
| 
 | ||||
| import static android.content.Context.NOTIFICATION_SERVICE; | ||||
| 
 | ||||
| import android.app.IntentService; | ||||
| import android.app.Notification; | ||||
| import android.app.NotificationChannel; | ||||
| import android.app.NotificationManager; | ||||
| import android.app.PendingIntent; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
|  | @ -26,10 +29,17 @@ import android.os.Build; | |||
| import android.os.Bundle; | ||||
| 
 | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.annotation.RequiresApi; | ||||
| import androidx.core.app.NotificationCompat; | ||||
| import androidx.localbroadcastmanager.content.LocalBroadcastManager; | ||||
| import androidx.preference.PreferenceManager; | ||||
| import androidx.work.Data; | ||||
| import androidx.work.ForegroundInfo; | ||||
| import androidx.work.WorkManager; | ||||
| import androidx.work.Worker; | ||||
| import androidx.work.WorkerParameters; | ||||
| 
 | ||||
| import com.google.gson.Gson; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
|  | @ -57,25 +67,19 @@ import retrofit2.Response; | |||
| import retrofit2.Retrofit; | ||||
| import retrofit2.converter.gson.GsonConverterFactory; | ||||
| 
 | ||||
| public class PostMessageService extends IntentService { | ||||
| public class ComposeWorker extends Worker { | ||||
| 
 | ||||
|     private static final int NOTIFICATION_INT_CHANNEL_ID = 1; | ||||
|     public static String CHANNEL_ID = "post_messages"; | ||||
| 
 | ||||
|     private final NotificationManager notificationManager; | ||||
|     private NotificationCompat.Builder notificationBuilder; | ||||
|     private NotificationManager notificationManager; | ||||
| 
 | ||||
|     /** | ||||
|      * @param name - String | ||||
|      * @deprecated | ||||
|      */ | ||||
|     public PostMessageService(String name) { | ||||
|         super(name); | ||||
|     } | ||||
| 
 | ||||
|     @SuppressWarnings("unused") | ||||
|     public PostMessageService() { | ||||
|         super("PostMessageService"); | ||||
|     public ComposeWorker( | ||||
|             @NonNull Context context, | ||||
|             @NonNull WorkerParameters parameters) { | ||||
|         super(context, parameters); | ||||
|         notificationManager = (NotificationManager) | ||||
|                 context.getSystemService(NOTIFICATION_SERVICE); | ||||
|     } | ||||
| 
 | ||||
|     private static OkHttpClient getOkHttpClient(Context context) { | ||||
|  | @ -95,7 +99,7 @@ public class PostMessageService extends IntentService { | |||
|         return retrofit.create(MastodonStatusesService.class); | ||||
|     } | ||||
| 
 | ||||
|     static void publishMessage(Context context, DataPost dataPost) { | ||||
|     public static void publishMessage(Context context, DataPost dataPost) { | ||||
|         long totalMediaSize; | ||||
|         long totalBitRead; | ||||
|         MastodonStatusesService mastodonStatusesService = init(context, dataPost.instance); | ||||
|  | @ -337,41 +341,33 @@ public class PostMessageService extends IntentService { | |||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onCreate() { | ||||
|         super.onCreate(); | ||||
|         notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); | ||||
|         if (Build.VERSION.SDK_INT >= 26) { | ||||
|             String channelName = "Post messages"; | ||||
|             String channelDescription = "Post messages in background"; | ||||
|             NotificationChannel notifChannel = new NotificationChannel(CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_HIGH); | ||||
|             notifChannel.setDescription(channelDescription); | ||||
|             notificationManager.createNotificationChannel(notifChannel); | ||||
| 
 | ||||
|     public static String serialize(StatusDraft statusDraft) { | ||||
|         Gson gson = new Gson(); | ||||
|         try { | ||||
|             return gson.toJson(statusDraft); | ||||
|         } catch (Exception e) { | ||||
|             return null; | ||||
|         } | ||||
|         notificationBuilder = new NotificationCompat.Builder(getBaseContext(), CHANNEL_ID); | ||||
|         notificationBuilder.setSmallIcon(R.drawable.ic_notification) | ||||
|                 .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground)) | ||||
|                 .setContentTitle(getString(R.string.post_message)) | ||||
|                 .setDefaults(NotificationCompat.DEFAULT_ALL) | ||||
|                 .setPriority(Notification.PRIORITY_DEFAULT); | ||||
|         startForeground(NOTIFICATION_INT_CHANNEL_ID, notificationBuilder.build()); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected void onHandleIntent(@Nullable Intent intent) { | ||||
|         StatusDraft statusDraft = null; | ||||
|         String token = null, instance = null; | ||||
|         String scheduledDate = null; | ||||
|         String userId = null; | ||||
|         if (intent != null && intent.getExtras() != null) { | ||||
|             Bundle b = intent.getExtras(); | ||||
|             statusDraft = (StatusDraft) b.getSerializable(Helper.ARG_STATUS_DRAFT); | ||||
|             token = b.getString(Helper.ARG_TOKEN); | ||||
|             instance = b.getString(Helper.ARG_INSTANCE); | ||||
|             userId = b.getString(Helper.ARG_USER_ID); | ||||
|             scheduledDate = b.getString(Helper.ARG_SCHEDULED_DATE); | ||||
|     public static StatusDraft restore(String serialized) { | ||||
|         Gson gson = new Gson(); | ||||
|         try { | ||||
|             return gson.fromJson(serialized, StatusDraft.class); | ||||
|         } catch (Exception e) { | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public Result doWork() { | ||||
|         Data inputData = getInputData(); | ||||
|         StatusDraft statusDraft = restore(inputData.getString(Helper.ARG_STATUS_DRAFT)); | ||||
|         String token = inputData.getString(Helper.ARG_TOKEN); | ||||
|         String instance = inputData.getString(Helper.ARG_INSTANCE); | ||||
|         String userId = inputData.getString(Helper.ARG_USER_ID); | ||||
|         String scheduledDate = inputData.getString(Helper.ARG_SCHEDULED_DATE); | ||||
|         //Should not be null, but a simple security | ||||
|         if (token == null) { | ||||
|             token = BaseMainActivity.currentToken; | ||||
|  | @ -387,21 +383,54 @@ public class PostMessageService extends IntentService { | |||
|         dataPost.scheduledDate = scheduledDate; | ||||
|         dataPost.notificationBuilder = notificationBuilder; | ||||
|         dataPost.notificationManager = notificationManager; | ||||
|         publishMessage(PostMessageService.this, dataPost); | ||||
|         notificationManager.cancel(NOTIFICATION_INT_CHANNEL_ID); | ||||
|         // Mark the Worker as important | ||||
|         setForegroundAsync(createForegroundInfo()); | ||||
|         publishMessage(getApplicationContext(), dataPost); | ||||
|         return Result.success(); | ||||
|     } | ||||
| 
 | ||||
|     static class DataPost { | ||||
|         String instance; | ||||
|         String token; | ||||
|         String userId; | ||||
|         StatusDraft statusDraft; | ||||
|         int messageToSend; | ||||
|         int messageSent; | ||||
|         NotificationCompat.Builder notificationBuilder; | ||||
|         String scheduledDate; | ||||
|         NotificationManager notificationManager; | ||||
|         IntentService service; | ||||
|     @NonNull | ||||
|     private ForegroundInfo createForegroundInfo() { | ||||
|         // Build a notification using bytesRead and contentLength | ||||
| 
 | ||||
|         Context context = getApplicationContext(); | ||||
|         // This PendingIntent can be used to cancel the worker | ||||
|         PendingIntent intent = WorkManager.getInstance(context) | ||||
|                 .createCancelPendingIntent(getId()); | ||||
| 
 | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|             createChannel(); | ||||
|         } | ||||
|         notificationBuilder = new NotificationCompat.Builder(context, CHANNEL_ID); | ||||
|         notificationBuilder.setSmallIcon(R.drawable.ic_notification) | ||||
|                 .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher_foreground)) | ||||
|                 .setContentTitle(context.getString(R.string.post_message)) | ||||
|                 .setOngoing(true) | ||||
|                 .setDefaults(NotificationCompat.DEFAULT_ALL) | ||||
|                 .setPriority(Notification.PRIORITY_DEFAULT); | ||||
| 
 | ||||
|         return new ForegroundInfo(NOTIFICATION_INT_CHANNEL_ID, notificationBuilder.build()); | ||||
|     } | ||||
| 
 | ||||
|     @RequiresApi(Build.VERSION_CODES.O) | ||||
|     private void createChannel() { | ||||
|         String channelName = "Post messages"; | ||||
|         String channelDescription = "Post messages in background"; | ||||
|         NotificationChannel notifChannel = new NotificationChannel(CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_HIGH); | ||||
|         notifChannel.setDescription(channelDescription); | ||||
|         notificationManager.createNotificationChannel(notifChannel); | ||||
|     } | ||||
| 
 | ||||
|     public static class DataPost { | ||||
|         public String instance; | ||||
|         public String token; | ||||
|         public String userId; | ||||
|         public StatusDraft statusDraft; | ||||
|         public int messageToSend; | ||||
|         public int messageSent; | ||||
|         public NotificationCompat.Builder notificationBuilder; | ||||
|         public String scheduledDate; | ||||
|         public NotificationManager notificationManager; | ||||
|         public IntentService service; | ||||
|     } | ||||
| } | ||||
|  | @ -18,7 +18,6 @@ import android.app.Notification; | |||
| import android.app.NotificationChannel; | ||||
| import android.app.NotificationManager; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.graphics.BitmapFactory; | ||||
| import android.os.Build; | ||||
| 
 | ||||
|  | @ -29,11 +28,13 @@ import androidx.work.ForegroundInfo; | |||
| import androidx.work.Worker; | ||||
| import androidx.work.WorkerParameters; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| import app.fedilab.android.R; | ||||
| import app.fedilab.android.client.entities.app.StatusDraft; | ||||
| import app.fedilab.android.client.entities.app.Account; | ||||
| import app.fedilab.android.client.entities.app.BaseAccount; | ||||
| import app.fedilab.android.exception.DBException; | ||||
| import app.fedilab.android.helper.Helper; | ||||
| import app.fedilab.android.services.PostMessageService; | ||||
| import app.fedilab.android.helper.NotificationsHelper; | ||||
| 
 | ||||
| public class NotificationsWorker extends Worker { | ||||
| 
 | ||||
|  | @ -69,32 +70,19 @@ public class NotificationsWorker extends Worker { | |||
|     @NonNull | ||||
|     @Override | ||||
|     public Result doWork() { | ||||
| 
 | ||||
|         setForegroundAsync(createForegroundInfo()); | ||||
|         Data outputData; | ||||
|         String instance = getInputData().getString(Helper.ARG_INSTANCE); | ||||
|         String token = getInputData().getString(Helper.ARG_TOKEN); | ||||
|         String statusDraftId = getInputData().getString(Helper.ARG_STATUS_DRAFT_ID); | ||||
|         String userId = getInputData().getString(Helper.ARG_USER_ID); | ||||
|         StatusDraft statusDraft; | ||||
|         try { | ||||
|             statusDraft = new StatusDraft(getApplicationContext()).geStatusDraft(statusDraftId); | ||||
|             Intent intent = new Intent(getApplicationContext(), PostMessageService.class); | ||||
|             intent.putExtra(Helper.ARG_STATUS_DRAFT, statusDraft); | ||||
|             intent.putExtra(Helper.ARG_INSTANCE, instance); | ||||
|             intent.putExtra(Helper.ARG_TOKEN, token); | ||||
|             intent.putExtra(Helper.ARG_USER_ID, userId); | ||||
|             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|                 getApplicationContext().startForegroundService(intent); | ||||
|             } else { | ||||
|                 getApplicationContext().startService(intent); | ||||
|             List<BaseAccount> accounts = new Account(getApplicationContext()).getAll(); | ||||
|             for (BaseAccount account : accounts) { | ||||
|                 try { | ||||
|                     NotificationsHelper.task(getApplicationContext(), account.user_id + "@" + account.instance); | ||||
|                 } catch (DBException e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } | ||||
|             } | ||||
|         } catch (DBException e) { | ||||
|             e.printStackTrace(); | ||||
|             outputData = new Data.Builder().putString("WORK_RESULT", getApplicationContext().getString(R.string.toast_error)).build(); | ||||
|             return Result.failure(outputData); | ||||
|         } | ||||
| 
 | ||||
|         return Result.success(new Data.Builder().putString("WORK_RESULT", getApplicationContext().getString(R.string.toot_sent)).build()); | ||||
|         return Result.success(new Data.Builder().putString("WORK_RESULT", getApplicationContext().getString(R.string.notifications)).build()); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -14,17 +14,17 @@ package app.fedilab.android.jobs; | |||
|  * You should have received a copy of the GNU General Public License along with Fedilab; if not, | ||||
|  * see <http://www.gnu.org/licenses>. */ | ||||
| 
 | ||||
| import static app.fedilab.android.jobs.ComposeWorker.publishMessage; | ||||
| 
 | ||||
| import android.app.Notification; | ||||
| import android.app.NotificationChannel; | ||||
| import android.app.NotificationManager; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.graphics.BitmapFactory; | ||||
| import android.os.Build; | ||||
| 
 | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.core.app.NotificationCompat; | ||||
| import androidx.work.Data; | ||||
| import androidx.work.ForegroundInfo; | ||||
| import androidx.work.Worker; | ||||
| import androidx.work.WorkerParameters; | ||||
|  | @ -33,7 +33,6 @@ import app.fedilab.android.R; | |||
| import app.fedilab.android.client.entities.app.StatusDraft; | ||||
| import app.fedilab.android.exception.DBException; | ||||
| import app.fedilab.android.helper.Helper; | ||||
| import app.fedilab.android.services.PostMessageService; | ||||
| 
 | ||||
| public class ScheduleThreadWorker extends Worker { | ||||
| 
 | ||||
|  | @ -69,9 +68,7 @@ public class ScheduleThreadWorker extends Worker { | |||
|     @NonNull | ||||
|     @Override | ||||
|     public Result doWork() { | ||||
| 
 | ||||
|         setForegroundAsync(createForegroundInfo()); | ||||
|         Data outputData; | ||||
|         String instance = getInputData().getString(Helper.ARG_INSTANCE); | ||||
|         String token = getInputData().getString(Helper.ARG_TOKEN); | ||||
|         String userId = getInputData().getString(Helper.ARG_USER_ID); | ||||
|  | @ -79,22 +76,20 @@ public class ScheduleThreadWorker extends Worker { | |||
|         StatusDraft statusDraft; | ||||
|         try { | ||||
|             statusDraft = new StatusDraft(getApplicationContext()).geStatusDraft(statusDraftId); | ||||
|             Intent intent = new Intent(getApplicationContext(), PostMessageService.class); | ||||
|             intent.putExtra(Helper.ARG_STATUS_DRAFT, statusDraft); | ||||
|             intent.putExtra(Helper.ARG_INSTANCE, instance); | ||||
|             intent.putExtra(Helper.ARG_TOKEN, token); | ||||
|             intent.putExtra(Helper.ARG_USER_ID, userId); | ||||
|             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|                 getApplicationContext().startForegroundService(intent); | ||||
|             } else { | ||||
|                 getApplicationContext().startService(intent); | ||||
|             } | ||||
|             ComposeWorker.DataPost dataPost = new ComposeWorker.DataPost(); | ||||
|             dataPost.instance = instance; | ||||
|             dataPost.token = token; | ||||
|             dataPost.userId = userId; | ||||
|             dataPost.statusDraft = statusDraft; | ||||
|             dataPost.scheduledDate = null; | ||||
|             dataPost.notificationManager = notificationManager; | ||||
|             // Mark the Worker as important | ||||
|             setForegroundAsync(createForegroundInfo()); | ||||
|             publishMessage(getApplicationContext(), dataPost); | ||||
|             return Result.success(); | ||||
|         } catch (DBException e) { | ||||
|             e.printStackTrace(); | ||||
|             outputData = new Data.Builder().putString("WORK_RESULT", getApplicationContext().getString(R.string.toast_error)).build(); | ||||
|             return Result.failure(outputData); | ||||
|             return Result.failure(); | ||||
|         } | ||||
| 
 | ||||
|         return Result.success(new Data.Builder().putString("WORK_RESULT", getApplicationContext().getString(R.string.toot_sent)).build()); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -14,16 +14,18 @@ package app.fedilab.android.services; | |||
|  * You should have received a copy of the GNU General Public License along with Fedilab; if not, | ||||
|  * see <http://www.gnu.org/licenses>. */ | ||||
| 
 | ||||
| import static app.fedilab.android.services.PostMessageService.publishMessage; | ||||
| 
 | ||||
| import static app.fedilab.android.jobs.ComposeWorker.publishMessage; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| 
 | ||||
| import app.fedilab.android.client.entities.app.StatusDraft; | ||||
| import app.fedilab.android.jobs.ComposeWorker; | ||||
| 
 | ||||
| public class ThreadMessageService { | ||||
| 
 | ||||
|     public ThreadMessageService(Context context, String instance, String userId, String token, StatusDraft statusDraft, String scheduledDate) { | ||||
|         PostMessageService.DataPost dataPost = new PostMessageService.DataPost(); | ||||
|         ComposeWorker.DataPost dataPost = new ComposeWorker.DataPost(); | ||||
|         dataPost.instance = instance; | ||||
|         dataPost.userId = userId; | ||||
|         dataPost.token = token; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue