Java tutorial
/* * Copyright (C) 2014 ChatWing * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.chatwingsdk.managers; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarActivity; import android.text.TextUtils; import android.view.Menu; import android.view.MenuItem; import android.webkit.WebView; import com.chatwingsdk.Constants; import com.chatwingsdk.R; import com.chatwingsdk.contentproviders.ChatWingContentProvider; import com.chatwingsdk.events.internal.ChatBoxUnreadCountChangedEvent; import com.chatwingsdk.events.internal.CurrentCommunicationEvent; import com.chatwingsdk.events.internal.TouchUserInfoEvent; import com.chatwingsdk.fragments.CommunicationMessagesFragment; import com.chatwingsdk.pojos.Message; import com.chatwingsdk.services.SyncCommunicationBoxesIntentService; import com.chatwingsdk.tables.ChatBoxTable; import com.chatwingsdk.tables.ConversationTable; import com.chatwingsdk.utils.JsonConstantsProvider; import com.chatwingsdk.utils.LogUtils; import com.google.gson.Gson; import com.squareup.otto.Bus; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; /** * Created by cuongthai on 14/04/2014. */ public abstract class CommunicationModeManager { private static final String EXTRA_OPENING_VIDEO_URL = "opening_video_url"; private final Bus mBus; protected final Delegate mActivityDelegate; protected final UserManager mUserManager; protected CharSequence mOriginalTitle; protected CharSequence mTitle; private String mOpeningVideoUrl; private boolean mIsRegisteredToBus; protected boolean mIsActive; public CommunicationModeManager(Bus bus, Delegate delegate, UserManager userManager) { mBus = bus; mActivityDelegate = delegate; mUserManager = userManager; mIsRegisteredToBus = false; mIsActive = false; } protected void onCurrentCommunicationChanged(CurrentCommunicationEvent event) { switch (event.getStatus()) { case REMOVED: case LOADING: mActivityDelegate.setContentShown(false); break; case LOADED: mActivityDelegate.setContentShown(true); break; } } public abstract void logout(); public abstract void reloadCurrentBox(); public abstract ActionBarDrawerToggle getDrawerToggleListener(); public abstract int getResourceStringNoCommunicationBox(); public boolean isCommunicationBoxDrawerOpening() { return mActivityDelegate.getDrawerLayout().isDrawerOpen(getCommunicationBoxDrawerGravity()); } public boolean onCreateOptionsMenu(Menu menu) { ActionBarActivity activity = mActivityDelegate.getActivity(); activity.getMenuInflater().inflate(R.menu.main_menu, menu); return true; } public boolean onPrepareOptionsMenu(Menu menu) { return false; } public abstract boolean onOptionsItemSelected(MenuItem item); public abstract boolean isSecondaryDrawerOpening(); public abstract boolean isInCurrentCommunicationBox(Message message); public boolean processMessageNotInCurrentCommunicationBox(Message message) { Uri uri; String unreadColumn; if (message.isPrivate()) { uri = ChatWingContentProvider.getConversationWithIdUri(message.getConversationID()); unreadColumn = ConversationTable.UNREAD_COUNT; } else { uri = ChatWingContentProvider.getChatBoxWithIdUri(message.getChatBoxId()); unreadColumn = ChatBoxTable.UNREAD_COUNT; } ActionBarActivity activity = mActivityDelegate.getActivity(); ContentResolver contentResolver = activity.getContentResolver(); // Get unread count of the correct chat box. Cursor cursor = null; int unreadCount = -1; try { cursor = contentResolver.query(uri, new String[] { unreadColumn }, null, null, null); if (cursor.getCount() > 0 && cursor.moveToFirst()) { unreadCount = cursor.getInt(cursor.getColumnIndex(unreadColumn)); } // else { // The chat box is not available in the DB. // TODO: may create the chat box or trigger a sync operation. // } } finally { if (cursor != null && !cursor.isClosed()) { cursor.close(); } } if (unreadCount == -1) { // 1. Something was wrong (the chat box id is invalid // or can't query the chat box from DB). // Let's stop. // 2. Conversation not found. There might be a case client received // a msg but there is not conversation created beforehand. We can // just ignore that and wait for "remote_unread" if (message.isPrivate()) { Intent intent = new Intent(activity, SyncCommunicationBoxesIntentService.class); intent.putExtra(SyncCommunicationBoxesIntentService.UPDATE_CATEGORIES_FLAG, false); intent.putExtra(SyncCommunicationBoxesIntentService.UPDATE_CONVERSATION_FLAG, true); activity.startService(intent); } return false; } // Increase unread count in DB if (message.isPrivate()) { return updateConversationUnreadCount(message.getConversationID(), ++unreadCount); } else { return updateChatBoxUnreadCountInDB(message.getChatBoxId(), ++unreadCount); } } protected boolean updateChatBoxUnreadCountInDB(int chatBoxId, int unreadCount) { Uri uri = ChatWingContentProvider.getChatBoxWithIdUri(chatBoxId); ContentValues contentValues = new ContentValues(); contentValues.put(ChatBoxTable.UNREAD_COUNT, unreadCount); ContentResolver contentResolver = mActivityDelegate.getActivity().getContentResolver(); int updated = contentResolver.update(uri, contentValues, null, null); if (updated == 1) { LogUtils.v("Update unread count. New Unread count: " + unreadCount); mBus.post(new ChatBoxUnreadCountChangedEvent(chatBoxId)); contentResolver.notifyChange(ChatWingContentProvider.getAggregatedCategoriesUri(), null); return true; } else { LogUtils.e("Failed to update unread count."); return false; } } protected boolean updateConversationUnreadCount(String conversationId, int unreadCount) { Uri uri = ChatWingContentProvider.getConversationWithIdUri(conversationId); ContentValues contentValues = new ContentValues(); contentValues.put(ConversationTable.UNREAD_COUNT, unreadCount); contentValues.put(ConversationTable.DATE_UPDATED, System.currentTimeMillis()); int updated = mActivityDelegate.getActivity().getContentResolver().update(uri, contentValues, null, null); if (updated == 1) { return true; } else { LogUtils.e("Failed to update unread count."); return false; } } public static interface Delegate { public void handle(Exception exception, int errorMessageResId); public ActionBarActivity getActivity(); public CommunicationMessagesFragment getCommunicationMessagesFragment(); public void setProgressText(int resId, boolean showProgressBar); public void setContentShown(boolean show); public DrawerLayout getDrawerLayout(); public void ensureWebViewAndSubscribeToChannels(); } /** * Required methods for {@link com.chatwingsdk.activities.CommunicationActivity} * we try to have separate handlers for ChatMode or ConversationMode. */ public abstract void onPostResume(); public abstract void onDestroy(); public void onCreate(Bundle savedInstanceState) { if (savedInstanceState != null) { if (savedInstanceState.containsKey(EXTRA_OPENING_VIDEO_URL)) { mOpeningVideoUrl = savedInstanceState.getString(EXTRA_OPENING_VIDEO_URL); } } } protected void invalidateOptionsMenu() { mActivityDelegate.getActivity().invalidateOptionsMenu(); } public void onActivityResult(int requestCode, int resultCode, Intent data) { if (!mIsActive) { return; } } public void onResume() { registerToBus(); } public void onPause() { unregisterToBus(); } public void onSaveInstanceState(Bundle outState) { if (!TextUtils.isEmpty(mOpeningVideoUrl)) { outState.putString(EXTRA_OPENING_VIDEO_URL, mOpeningVideoUrl); } } public void activate() { mIsActive = true; registerToBus(); mOriginalTitle = mTitle = mActivityDelegate.getActivity().getTitle(); mActivityDelegate.setProgressText(getResourceStringNoCommunicationBox(), false); setSubTitle(null); openCommunicationBoxDrawer(); invalidateOptionsMenu(); } public void deactivate() { mIsActive = false; unregisterToBus(); } protected String getString(int id) { return mActivityDelegate.getActivity().getString(id); } protected void setTitle(String title) { mTitle = title; mActivityDelegate.getActivity().getSupportActionBar().setTitle(title); } protected void setSubTitle(String subTitle) { if (Constants.SHOW_CHAT_BOX_URL) { mActivityDelegate.getActivity().getSupportActionBar().setSubtitle(subTitle); } else { mActivityDelegate.getActivity().getSupportActionBar().setSubtitle(null); } } public Map<String, String> getEmoticons() { return new Gson().fromJson(JsonConstantsProvider.DEFAULT_COMMUNICATION_EMOTION_JSON, HashMap.class); } public void openCommunicationBoxDrawer() { mActivityDelegate.getDrawerLayout().openDrawer(getCommunicationBoxDrawerGravity()); mActivityDelegate.getActivity().invalidateOptionsMenu(); } protected abstract int getCommunicationBoxDrawerGravity(); private void registerToBus() { if (mIsActive && !mIsRegisteredToBus) { mBus.register(this); mIsRegisteredToBus = true; } } private void unregisterToBus() { if (mIsRegisteredToBus) { mBus.unregister(this); mIsRegisteredToBus = false; } } public void subscribeToChannels(WebView mWebView) { if (mWebView == null) { return; } subscribeToChatBoxChannels(mWebView); subscribeToConversationChannels(mWebView); } private void subscribeToChatBoxChannels(WebView mWebView) { // Query for chat box keys Uri chatBoxesUri = ChatWingContentProvider.getChatBoxesUri(); ArrayList<String> fayeChannels = new ArrayList<String>(); Cursor c = null; try { c = mActivityDelegate.getActivity().getContentResolver().query(chatBoxesUri, new String[] { ChatBoxTable.FAYE_CHANNEL }, null, null, null); if (c.getCount() > 0 && c.moveToFirst()) { int fayeChannelIndex = c.getColumnIndex(ChatBoxTable.FAYE_CHANNEL); do { // We can subscribe to each chat box here, // but it can take a lot of time and holding the Cursor for // that long is not a good idea. So, to be safe, // let's get all chat box keys first and subscribe later. String fayeChannel = c.getString(fayeChannelIndex); fayeChannels.add(fayeChannel); } while (c.moveToNext()); } } finally { if (c != null && !c.isClosed()) { c.close(); } } // Subscribe to all of them for (String fayeChannel : fayeChannels) { String js = String.format("javascript:subscribe('%s')", fayeChannel); mWebView.loadUrl(js); } } private void subscribeToConversationChannels(WebView mWebView) { if (mUserManager.getCurrentUser() == null) { return; } String js = String.format("javascript:subscribe('/user/%s')", mUserManager.getCurrentUser().getId()); mWebView.loadUrl(js); } }