com.apptentive.android.sdk.module.messagecenter.MessageManager.java Source code

Java tutorial

Introduction

Here is the source code for com.apptentive.android.sdk.module.messagecenter.MessageManager.java

Source

/*
 * Copyright (c) 2014, Apptentive, Inc. All Rights Reserved.
 * Please refer to the LICENSE file for the terms and conditions
 * under which redistribution and use of this file is permitted.
 */

package com.apptentive.android.sdk.module.messagecenter;

import android.content.Context;
import android.content.SharedPreferences;
import com.apptentive.android.sdk.GlobalInfo;
import com.apptentive.android.sdk.Log;
import com.apptentive.android.sdk.comm.ApptentiveClient;
import com.apptentive.android.sdk.comm.ApptentiveHttpResponse;
import com.apptentive.android.sdk.model.AutomatedMessage;
import com.apptentive.android.sdk.model.FileMessage;
import com.apptentive.android.sdk.model.Message;
import com.apptentive.android.sdk.model.MessageFactory;
import com.apptentive.android.sdk.storage.ApptentiveDatabase;
import com.apptentive.android.sdk.storage.MessageStore;
import com.apptentive.android.sdk.util.Constants;
import com.apptentive.android.sdk.util.Util;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Sky Kelsey
 */
public class MessageManager {

    private static OnSentMessageListener sentMessageListener;
    private static OnNewMessagesListener internalNewMessagesListener;
    private static UnreadMessagesListener hostUnreadMessagesListener;

    /**
     * Performs a request against the server to check for messages in the conversation since the latest message we already have.
     * Make sure to run this off the UI Thread, as it blocks on IO.
     *
     * @returns true if messages were returned, else false.
     */
    public static boolean fetchAndStoreMessages(Context context) {
        if (GlobalInfo.conversationToken == null) {
            return false;
        }
        if (!Util.isNetworkConnectionPresent(context)) {
            return false;
        }

        // Fetch the messages.
        String lastId = getMessageStore(context).getLastReceivedMessageId();
        Log.d("Fetching messages after last id: " + lastId);
        List<Message> messagesToSave = fetchMessages(lastId);

        if (messagesToSave != null && messagesToSave.size() > 0) {
            Log.d("Messages retrieved.");
            // Also get the count of incoming unread messages.
            int incomingUnreadMessages = 0;
            // Mark messages from server where sender is the app user as read.
            for (Message message : messagesToSave) {
                if (message.isOutgoingMessage()) {
                    message.setRead(true);
                } else {
                    incomingUnreadMessages++;
                }
            }
            getMessageStore(context)
                    .addOrUpdateMessages(messagesToSave.toArray(new Message[messagesToSave.size()]));

            if (incomingUnreadMessages > 0) {
                if (internalNewMessagesListener != null) {
                    internalNewMessagesListener.onMessagesUpdated();
                }
            }

            notifyHostUnreadMessagesListener(getUnreadMessageCount(context));
            return incomingUnreadMessages > 0;
        }
        return false;
    }

    public static List<Message> getMessages(Context context) {
        return getMessageStore(context).getAllMessages();
    }

    public static void sendMessage(Context context, Message message) {
        getMessageStore(context).addOrUpdateMessages(message);
        ApptentiveDatabase.getInstance(context).addPayload(message);
    }

    /**
     * This doesn't need to be run during normal program execution. Testing only.
     */
    public static void deleteAllMessages(Context context) {
        Log.e("Deleting all messages.");
        getMessageStore(context).deleteAllMessages();
    }

    private static List<Message> fetchMessages(String after_id) {
        Log.d("Fetching messages newer than: " + after_id);
        ApptentiveHttpResponse response = ApptentiveClient.getMessages(null, after_id, null);

        List<Message> ret = new ArrayList<Message>();
        if (!response.isSuccessful()) {
            return ret;
        }
        try {
            ret = parseMessagesString(response.getContent());
        } catch (JSONException e) {
            Log.e("Error parsing messages JSON.", e);
        } catch (Exception e) {
            Log.e("Unexpected error parsing messages JSON.", e);
        }
        return ret;
    }

    public static void updateMessage(Context context, Message message) {
        getMessageStore(context).updateMessage(message);
    }

    public static List<Message> parseMessagesString(String messageString) throws JSONException {
        List<Message> ret = new ArrayList<Message>();
        JSONObject root = new JSONObject(messageString);
        if (!root.isNull("items")) {
            JSONArray items = root.getJSONArray("items");
            for (int i = 0; i < items.length(); i++) {
                String json = items.getJSONObject(i).toString();
                Message message = MessageFactory.fromJson(json);
                // Since these came back from the server, mark them saved before updating them in the DB.
                message.setState(Message.State.saved);
                ret.add(message);
            }
        }
        return ret;
    }

    public static void onSentMessage(Context context, Message message, ApptentiveHttpResponse response) {
        if (response == null || !response.isSuccessful()) {
            if (message instanceof FileMessage) {
                ((FileMessage) message).deleteStoredFile(context);
            }
            return;
        }
        if (response.isSuccessful()) {
            // Don't store hidden messages once sent. Delete them.
            if (message.isHidden()) {
                if (message instanceof FileMessage) {
                    ((FileMessage) message).deleteStoredFile(context);
                }
                getMessageStore(context).deleteMessage(message.getNonce());
                return;
            }
            try {
                JSONObject responseJson = new JSONObject(response.getContent());
                if (message.getState() == Message.State.sending) {
                    message.setState(Message.State.sent);
                }
                message.setId(responseJson.getString(Message.KEY_ID));
                message.setCreatedAt(responseJson.getDouble(Message.KEY_CREATED_AT));
            } catch (JSONException e) {
                Log.e("Error parsing sent message response.", e);
            }
            getMessageStore(context).updateMessage(message);

            if (sentMessageListener != null) {
                sentMessageListener.onSentMessage(message);
            }
        }
        /*
              if(response.isBadPayload()) {
                 // TODO: Tell the user that this message failed to send. It will be deleted by the record send worker.
              }
        */
    }

    /**
     * This method will show either a Welcome or a No Love AutomatedMessage. If a No Love message has been shown, no other
     * AutomatedMessage shall be shown, and no AutomatedMessage shall be shown twice.
     *
     * @param context The context from which this method is called.
     * @param forced  If true, show a Welcome AutomatedMessage, else show a NoLove AutomatedMessage.
     */
    public static void createMessageCenterAutoMessage(Context context, boolean forced) {
        SharedPreferences prefs = context.getSharedPreferences(Constants.PREF_NAME, Context.MODE_PRIVATE);

        boolean shownAutoMessage = prefs.getBoolean(Constants.PREF_KEY_AUTO_MESSAGE_SHOWN_AUTO_MESSAGE, false);

        // Migrate old values if needed.
        boolean shownManual = prefs.getBoolean(Constants.PREF_KEY_AUTO_MESSAGE_SHOWN_MANUAL, false);
        boolean shownNoLove = prefs.getBoolean(Constants.PREF_KEY_AUTO_MESSAGE_SHOWN_NO_LOVE, false);
        if (!shownAutoMessage) {
            if (shownManual || shownNoLove) {
                shownAutoMessage = true;
                prefs.edit().putBoolean(Constants.PREF_KEY_AUTO_MESSAGE_SHOWN_AUTO_MESSAGE, true).commit();
            }
        }

        AutomatedMessage message = null;

        if (!shownAutoMessage) {
            if (forced) {
                message = AutomatedMessage.createWelcomeMessage(context);
            } else {
                message = AutomatedMessage.createNoLoveMessage(context);
            }
            if (message != null) {
                prefs.edit().putBoolean(Constants.PREF_KEY_AUTO_MESSAGE_SHOWN_AUTO_MESSAGE, true).commit();
                getMessageStore(context).addOrUpdateMessages(message);
                ApptentiveDatabase.getInstance(context).addPayload(message);
            }
        }
    }

    private static MessageStore getMessageStore(Context context) {
        return ApptentiveDatabase.getInstance(context);
    }

    public static int getUnreadMessageCount(Context context) {
        return getMessageStore(context).getUnreadMessageCount();
    }

    // Listeners

    public interface OnSentMessageListener {
        public void onSentMessage(Message message);
    }

    public static void setSentMessageListener(OnSentMessageListener onSentMessageListener) {
        sentMessageListener = onSentMessageListener;
    }

    public interface OnNewMessagesListener {
        public void onMessagesUpdated();
    }

    public static void setInternalOnMessagesUpdatedListener(OnNewMessagesListener listener) {
        internalNewMessagesListener = listener;
    }

    public static void setHostUnreadMessagesListener(UnreadMessagesListener listener) {
        hostUnreadMessagesListener = listener;
    }

    public static void notifyHostUnreadMessagesListener(int unreadMessages) {
        if (hostUnreadMessagesListener != null) {
            hostUnreadMessagesListener.onUnreadMessageCountChanged(unreadMessages);
        }
    }
}