Implements broadcasts

This commit is contained in:
tom79 2017-08-28 15:01:45 +02:00
parent 325d51187b
commit d43feffca8
7 changed files with 214 additions and 45 deletions

View File

@ -119,7 +119,7 @@ public class MainActivity extends AppCompatActivity
private DisplayStatusFragment homeFragment;
private DisplayNotificationsFragment notificationsFragment;
private BroadcastReceiver receive_data;
public MainActivity() {
}
@ -127,6 +127,8 @@ public class MainActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocalBroadcastManager.getInstance(this).registerReceiver(receive_data, new IntentFilter(Helper.RECEIVE_DATA));
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
final int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
@ -805,22 +807,22 @@ public class MainActivity extends AppCompatActivity
@Override
public void onResume(){
super.onResume();
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean bubbles = sharedpreferences.getBoolean(Helper.SET_BUBBLE_COUNTER, true);
if( bubbles){
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {refreshData();}
}, 1000);
}
//Proceeds to update of the authenticated account
if(Helper.isLoggedIn(getApplicationContext()))
new UpdateAccountInfoByIDAsyncTask(getApplicationContext(), MainActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@Override
protected void onPause() {
super.onPause();
MainActivity.activityPaused();
}
@Override
public void onDestroy(){
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(receive_data);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
@ -1062,6 +1064,7 @@ public class MainActivity extends AppCompatActivity
}
}
public void updateNotifCounter(int newNotifCount){
if(tabLayout.getTabAt(1) == null)
return;
@ -1081,4 +1084,18 @@ public class MainActivity extends AppCompatActivity
}
}
public static boolean isActivityVisible() {
return activityVisible;
}
private static void activityResumed() {
activityVisible = true;
}
private static void activityPaused() {
activityVisible = false;
}
private static boolean activityVisible;
}

View File

@ -99,7 +99,7 @@ public class StreamingUserAsyncTask extends AsyncTask {
eventStreaming = EventStreaming.NOTIFICATION;
break;
case "delete":
event = reader.readLine();
event = "{\"id\":" + reader.readLine() + "}";
eventStreaming = EventStreaming.DELETE;
break;
default:

View File

@ -1253,7 +1253,7 @@ public class API {
* @return Status
*/
@SuppressWarnings("InfiniteRecursion")
private static Status parseStatuses(Context context, JSONObject resobj){
public static Status parseStatuses(Context context, JSONObject resobj){
Status status = new Status();
try {
status.setId(resobj.get("id").toString());

View File

@ -15,13 +15,16 @@
package fr.gouv.etalab.mastodon.client.Entities;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Date;
/**
* Created by Thomas on 23/04/2017.
*/
public class Notification {
public class Notification implements Parcelable {
private String id;
private String type;
@ -29,6 +32,25 @@ public class Notification {
private Account account;
private Status status;
protected Notification(Parcel in) {
id = in.readString();
type = in.readString();
account = in.readParcelable(Account.class.getClassLoader());
status = in.readParcelable(Status.class.getClassLoader());
}
public static final Creator<Notification> CREATOR = new Creator<Notification>() {
@Override
public Notification createFromParcel(Parcel in) {
return new Notification(in);
}
@Override
public Notification[] newArray(int size) {
return new Notification[size];
}
};
public String getId() {
return id;
}
@ -68,4 +90,17 @@ public class Notification {
public void setStatus(Status status) {
this.status = status;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeString(type);
dest.writeParcelable(account, flags);
dest.writeParcelable(status, flags);
}
}

View File

@ -251,6 +251,7 @@ public class Helper {
//Receiver
public static final String SEARCH_VALIDATE_ACCOUNT = "search_validate_account";
public static final String HEADER_ACCOUNT = "header_account";
public static final String RECEIVE_DATA = "receive_data";
//User agent
public static final String USER_AGENT = "Mastalab/"+ BuildConfig.VERSION_NAME + " Android/"+ Build.VERSION.RELEASE;

View File

@ -21,7 +21,9 @@ import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;
import android.view.View;
import com.evernote.android.job.Job;
@ -35,6 +37,7 @@ import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
@ -43,24 +46,22 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import fr.gouv.etalab.mastodon.activities.MainActivity;
import fr.gouv.etalab.mastodon.asynctasks.RetrieveNotificationsAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.StreamingUserAsyncTask;
import fr.gouv.etalab.mastodon.client.API;
import fr.gouv.etalab.mastodon.client.APIResponse;
import fr.gouv.etalab.mastodon.client.Entities.Account;
import fr.gouv.etalab.mastodon.client.Entities.Notification;
import fr.gouv.etalab.mastodon.client.Entities.Status;
import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveNotificationsInterface;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveStreamingInterface;
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
import mastodon.etalab.gouv.fr.mastodon.R;
import static fr.gouv.etalab.mastodon.helper.Helper.HOME_TIMELINE_INTENT;
import static fr.gouv.etalab.mastodon.helper.Helper.INTENT_ACTION;
import static fr.gouv.etalab.mastodon.helper.Helper.NOTIFICATION_INTENT;
import static fr.gouv.etalab.mastodon.helper.Helper.PREF_KEY_ID;
import static fr.gouv.etalab.mastodon.helper.Helper.canNotify;
import static fr.gouv.etalab.mastodon.helper.Helper.notify_user;
@ -73,6 +74,8 @@ public class SteamingSyncJob extends Job implements OnRetrieveStreamingInterface
static final String STREAMING = "job_streaming";
private String message;
private int notificationId;
private Intent intent;
@NonNull
@Override
@ -130,7 +133,6 @@ public class SteamingSyncJob extends Job implements OnRetrieveStreamingInterface
return;
//Retrieve users in db that owner has.
for (Account account: accounts) {
String max_id = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId(), null);
new StreamingUserAsyncTask(account.getInstance(), account.getToken(), account.getAcct(), account.getId(), SteamingSyncJob.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
@ -141,23 +143,24 @@ public class SteamingSyncJob extends Job implements OnRetrieveStreamingInterface
public void onRetrieveStreaming(StreamingUserAsyncTask.EventStreaming event, JSONObject response, String acct, String userId) {
if( response == null )
return;
String new_max_id = null;
String max_id = null;
final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW, true);
boolean notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD, true);
boolean notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true);
boolean notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true);
final String max_id = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + userId, null);
//No previous notifications in cache, so no notification will be sent
boolean notify = false;
String notificationUrl = null;
String title = null;
Status status = null;
Notification notification = null;
String dataId = null;
if( event == StreamingUserAsyncTask.EventStreaming.NOTIFICATION){
Notification notification = API.parseNotificationResponse(getContext(), response);
new_max_id = notification.getId();
notification = API.parseNotificationResponse(getContext(), response);
max_id = notification.getId();
switch (notification.getType()){
case "mention":
if(notif_mention){
@ -208,32 +211,86 @@ public class SteamingSyncJob extends Job implements OnRetrieveStreamingInterface
message = notification.getStatus().getContent();
if( message!= null) {
message = message.substring(0, 17);
message = message + "...";
message = message + "";
}else{
message = "";
}
}else if ( event == StreamingUserAsyncTask.EventStreaming.UPDATE){
status = API.parseStatuses(getContext(), response);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, status.getId());
editor.apply();
message = status.getContent();
if( message!= null) {
message = message.substring(0, 17);
message = message + "";
}else{
message = "";
}
}else if( event == StreamingUserAsyncTask.EventStreaming.DELETE){
try {
dataId = response.getString("id");
} catch (JSONException e) {
e.printStackTrace();
}
}
if( new_max_id != null){
if( max_id != null){
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, new_max_id);
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, max_id);
editor.apply();
return;
}
//Check which user is connected and if activity is to front
if( notify){
final Intent intent = new Intent(getContext(), MainActivity.class);
boolean activityVisible = false;
try{
activityVisible = MainActivity.isActivityVisible();
}catch (Exception ignored){}
String userconnected = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
SQLiteDatabase db = Sqlite.getInstance(getContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
Account account = new AccountDAO(getContext(), db).getAccountByID(userconnected);
//User receiving the notification is connected and application is to front, notification won't be pushed
//Instead, the interaction is done in the activity
if( activityVisible && account != null && account.getAcct().trim().equals(acct.trim()) && account.getId().trim().equals(userId.trim())){
notify = false;
Intent intentBC = new Intent(Helper.RECEIVE_DATA);
intent.putExtra("eventStreaming", event);
Bundle b = new Bundle();
if( event == StreamingUserAsyncTask.EventStreaming.UPDATE)
b.putParcelable("data", status);
else if(event == StreamingUserAsyncTask.EventStreaming.NOTIFICATION)
b.putParcelable("data", notification);
else if(event == StreamingUserAsyncTask.EventStreaming.DELETE)
b.putString("id", dataId);
intentBC.putExtras(b);
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intentBC);
}else if(event == StreamingUserAsyncTask.EventStreaming.NOTIFICATION ){
notify = true;
intent = new Intent(getContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
intent.putExtra(INTENT_ACTION, NOTIFICATION_INTENT);
intent.putExtra(PREF_KEY_ID, userId);
long notif_id = Long.parseLong(userId);
final int notificationId = ((notif_id + 1) > 2147483647) ? (int) (2147483647 - notif_id - 1) : (int) (notif_id + 1);
notificationId = ((notif_id + 1) > 2147483647) ? (int) (2147483647 - notif_id - 1) : (int) (notif_id + 1);
}else if(event == StreamingUserAsyncTask.EventStreaming.UPDATE ){
if(acct != null && status.getAccount().getAcct().trim().equals(acct.trim())){
notify = false;
}else {
notify = true;
intent = new Intent(getContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(INTENT_ACTION, HOME_TIMELINE_INTENT);
intent.putExtra(PREF_KEY_ID, userId);
long notif_id = Long.parseLong(userId);
notificationId = ((notif_id + 2) > 2147483647) ? (int) (2147483647 - notif_id - 2) : (int) (notif_id + 2);
}
}
if( notify){
if( notificationUrl != null){
ImageLoader imageLoaderNoty = ImageLoader.getInstance();
File cacheDir = new File(getContext().getCacheDir(), getContext().getString(R.string.app_name));

View File

@ -15,9 +15,11 @@
package fr.gouv.etalab.mastodon.activities;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.PorterDuff;
@ -31,6 +33,7 @@ import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.SearchView;
@ -74,6 +77,8 @@ import java.util.concurrent.TimeUnit;
import fr.gouv.etalab.mastodon.asynctasks.StreamingUserAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoByIDAsyncTask;
import fr.gouv.etalab.mastodon.client.Entities.Account;
import fr.gouv.etalab.mastodon.client.Entities.Notification;
import fr.gouv.etalab.mastodon.client.Entities.Status;
import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
import fr.gouv.etalab.mastodon.fragments.DisplayAccountsFragment;
import fr.gouv.etalab.mastodon.fragments.DisplayFollowRequestSentFragment;
@ -125,6 +130,7 @@ public class MainActivity extends AppCompatActivity
private DisplayStatusFragment homeFragment;
private DisplayNotificationsFragment notificationsFragment;
private static final int ERROR_DIALOG_REQUEST_CODE = 97;
private BroadcastReceiver receive_data;
public MainActivity() {
}
@ -132,6 +138,42 @@ public class MainActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocalBroadcastManager.getInstance(this).registerReceiver(receive_data, new IntentFilter(Helper.RECEIVE_DATA));
receive_data = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle b = getIntent().getExtras();
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean bubbles = sharedpreferences.getBoolean(Helper.SET_BUBBLE_COUNTER, true);
StreamingUserAsyncTask.EventStreaming eventStreaming = (StreamingUserAsyncTask.EventStreaming) intent.getSerializableExtra("eventStreaming");
if( eventStreaming == StreamingUserAsyncTask.EventStreaming.NOTIFICATION){
Notification notification = b.getParcelable("data");
if( notificationsFragment.getUserVisibleHint() == true){
}else{
}
}else if(eventStreaming == StreamingUserAsyncTask.EventStreaming.UPDATE){
Status status = b.getParcelable("data");
if( notificationsFragment.getUserVisibleHint() == true){
}else{
}
}else if(eventStreaming == StreamingUserAsyncTask.EventStreaming.DELETE){
String id = b.getString("id");
if( notificationsFragment.getUserVisibleHint() == true){
}else{
}
}
}
};
ProviderInstaller.installIfNeededAsync(this, this);
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
@ -813,23 +855,23 @@ public class MainActivity extends AppCompatActivity
@Override
public void onResume(){
super.onResume();
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean bubbles = sharedpreferences.getBoolean(Helper.SET_BUBBLE_COUNTER, true);
if( bubbles){
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {refreshData();}
}, 1000);
}
MainActivity.activityResumed();
//Proceeds to update of the authenticated account
if(Helper.isLoggedIn(getApplicationContext()))
new UpdateAccountInfoByIDAsyncTask(getApplicationContext(), MainActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@Override
protected void onPause() {
super.onPause();
MainActivity.activityPaused();
}
@Override
public void onDestroy(){
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(receive_data);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
@ -1136,4 +1178,21 @@ public class MainActivity extends AppCompatActivity
}
}
public static boolean isActivityVisible() {
return activityVisible;
}
private static void activityResumed() {
activityVisible = true;
}
private static void activityPaused() {
activityVisible = false;
}
private static boolean activityVisible;
}