📄 chatview.java
字号:
/* * Copyright (C) 2008 Esmertec AG. * Copyright (C) 2008 The Android Open Source Project * * 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.android.im.app;import java.util.ArrayList;import java.util.Date;import java.util.Map;import android.app.Activity;import android.app.AlertDialog;import android.content.AsyncQueryHandler;import android.content.ContentResolver;import android.content.ContentUris;import android.content.ContentValues;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.content.res.Resources;import android.database.ContentObserver;import android.database.Cursor;import android.database.CursorIndexOutOfBoundsException;import android.database.DataSetObserver;import android.database.CharArrayBuffer;import android.graphics.Typeface;import android.net.Uri;import android.os.Bundle;import android.os.Message;import android.os.RemoteException;import android.provider.Im;import android.text.TextUtils;import android.text.style.StyleSpan;import android.text.style.URLSpan;import android.util.AttributeSet;import android.util.Log;import android.view.KeyEvent;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.AbsListView;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.Button;import android.widget.CursorAdapter;import android.widget.EditText;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.TextView;import android.widget.AbsListView.OnScrollListener;import android.widget.AdapterView.OnItemClickListener;import com.android.im.IChatListener;import com.android.im.IChatSession;import com.android.im.IChatSessionListener;import com.android.im.IChatSessionManager;import com.android.im.IContactList;import com.android.im.IContactListListener;import com.android.im.IContactListManager;import com.android.im.IImConnection;import com.android.im.R;import com.android.im.app.adapter.ChatListenerAdapter;import com.android.im.app.adapter.ChatSessionListenerAdapter;import com.android.im.engine.Contact;import com.android.im.engine.ImConnection;import com.android.im.engine.ImErrorInfo;import com.android.im.plugin.BrandingResourceIDs;public class ChatView extends LinearLayout { // This projection and index are set for the query of active chats static final String[] CHAT_PROJECTION = { Im.Contacts._ID, Im.Contacts.ACCOUNT, Im.Contacts.PROVIDER, Im.Contacts.USERNAME, Im.Contacts.NICKNAME, Im.Contacts.TYPE, Im.Presence.PRESENCE_STATUS, Im.Chats.LAST_UNREAD_MESSAGE, }; static final int CONTACT_ID_COLUMN = 0; static final int ACCOUNT_COLUMN = 1; static final int PROVIDER_COLUMN = 2; static final int USERNAME_COLUMN = 3; static final int NICKNAME_COLUMN = 4; static final int TYPE_COLUMN = 5; static final int PRESENCE_STATUS_COLUMN = 6; static final int LAST_UNREAD_MESSAGE_COLUMN = 7; static final String[] INVITATION_PROJECT = { Im.Invitation._ID, Im.Invitation.PROVIDER, Im.Invitation.SENDER, }; static final int INVITATION_ID_COLUMN = 0; static final int INVITATION_PROVIDER_COLUMN = 1; static final int INVITATION_SENDER_COLUMN = 2; static final StyleSpan STYLE_BOLD = new StyleSpan(Typeface.BOLD); Markup mMarkup; Activity mScreen; ImApp mApp; SimpleAlertHandler mHandler; Cursor mCursor; private ImageView mStatusIcon; private TextView mTitle; /*package*/ListView mHistory; EditText mEdtInput; private Button mSendButton; private View mStatusWarningView; private ImageView mWarningIcon; private TextView mWarningText; private MessageAdapter mMessageAdapter; private IChatSessionManager mChatSessionMgr; private IChatSessionListener mChatSessionListener; private IChatSession mChatSession; private long mChatId; int mType; String mNickName; String mUserName; long mProviderId; long mAccountId; long mInvitationId; private int mPresenceStatus; private int mViewType; private static final int VIEW_TYPE_CHAT = 1; private static final int VIEW_TYPE_INVITATION = 2; private static final int VIEW_TYPE_SUBSCRIPTION = 3; private static final long SHOW_TIME_STAMP_INTERVAL = 60 * 1000; // 1 minute private static final int QUERY_TOKEN = 10; // Async QueryHandler private final class QueryHandler extends AsyncQueryHandler { public QueryHandler(Context context) { super(context.getContentResolver()); } @Override protected void onQueryComplete(int token, Object cookie, Cursor c) { Cursor cursor = new DeltaCursor(c); if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){ log("onQueryComplete: cursor.count=" + cursor.getCount()); } mMessageAdapter.changeCursor(cursor); } } private QueryHandler mQueryHandler; private class RequeryCallback implements Runnable { public void run() { if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){ log("RequeryCallback"); } requeryCursor(); } } private RequeryCallback mRequeryCallback = null; private OnItemClickListener mOnItemClickListener = new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if (!(view instanceof MessageView)) { return; } URLSpan[] links = ((MessageView)view).getMessageLinks(); if (links.length == 0){ return; } final ArrayList<String> linkUrls = new ArrayList<String>(links.length); for (URLSpan u : links) { linkUrls.add(u.getURL()); } ArrayAdapter<String> a = new ArrayAdapter<String>(mScreen, android.R.layout.select_dialog_item, linkUrls); AlertDialog.Builder b = new AlertDialog.Builder(mScreen); b.setTitle(R.string.select_link_title); b.setCancelable(true); b.setAdapter(a, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { Uri uri = Uri.parse(linkUrls.get(which)); Intent intent = new Intent(Intent.ACTION_VIEW, uri); intent.addCategory(Intent.CATEGORY_BROWSABLE); mScreen.startActivity(intent); } }); b.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); b.show(); } }; private IChatListener mChatListener = new ChatListenerAdapter() { @Override public void onIncomingMessage(IChatSession ses, com.android.im.engine.Message msg) { scheduleRequery(0); } @Override public void onContactJoined(IChatSession ses, Contact contact) { scheduleRequery(0); } @Override public void onContactLeft(IChatSession ses, Contact contact) { scheduleRequery(0); } @Override public void onSendMessageError(IChatSession ses, com.android.im.engine.Message msg, ImErrorInfo error) { scheduleRequery(0); } }; private Runnable mUpdateChatCallback = new Runnable() { public void run() { if (mCursor.requery() && mCursor.moveToFirst()) { updateChat(); } } }; private IContactListListener mContactListListener = new IContactListListener.Stub () { public void onAllContactListsLoaded() { } public void onContactChange(int type, IContactList list, Contact contact){ } public void onContactError(int errorType, ImErrorInfo error, String listName, Contact contact) { } public void onContactsPresenceUpdate(Contact[] contacts) { if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)) { log("onContactsPresenceUpdate()"); } for (Contact c : contacts) { if (c.getAddress().getFullName().equals(mUserName)) { mHandler.post(mUpdateChatCallback); scheduleRequery(0); break; } } } }; static final void log(String msg) { Log.d(ImApp.LOG_TAG, "<ChatView> " +msg); } public ChatView(Context context, AttributeSet attrs) { super(context, attrs); mScreen = (Activity) context; mApp = ImApp.getApplication(mScreen); mHandler = new ChatViewHandler(); } void registerForConnEvents() { mApp.registerForConnEvents(mHandler); } void unregisterForConnEvents() { mApp.unregisterForConnEvents(mHandler); } @Override protected void onFinishInflate() { mStatusIcon = (ImageView) findViewById(R.id.statusIcon); mTitle = (TextView) findViewById(R.id.title); mHistory = (ListView) findViewById(R.id.history); mEdtInput = (EditText) findViewById(R.id.edtInput); mSendButton = (Button)findViewById(R.id.btnSend); mHistory.setOnItemClickListener(mOnItemClickListener); mStatusWarningView = findViewById(R.id.warning); mWarningIcon = (ImageView)findViewById(R.id.warningIcon); mWarningText = (TextView)findViewById(R.id.warningText); Button acceptInvitation = (Button)findViewById(R.id.btnAccept); Button declineInvitation= (Button)findViewById(R.id.btnDecline); Button approveSubscription = (Button)findViewById(R.id.btnApproveSubscription); Button declineSubscription = (Button)findViewById(R.id.btnDeclineSubscription); acceptInvitation.setOnClickListener(new OnClickListener() { public void onClick(View v) { acceptInvitation(); } }); declineInvitation.setOnClickListener(new OnClickListener() { public void onClick(View v) { declineInvitation(); } }); approveSubscription.setOnClickListener(new OnClickListener(){ public void onClick(View v) { approveSubscription(); } }); declineSubscription.setOnClickListener(new OnClickListener(){ public void onClick(View v) { declineSubscription(); } }); mEdtInput.setOnKeyListener(new OnKeyListener(){ public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN) { switch (keyCode) { case KeyEvent.KEYCODE_DPAD_CENTER: sendMessage(); return true; case KeyEvent.KEYCODE_ENTER: if (event.isAltPressed()) { mEdtInput.append("\n"); } else { sendMessage(); } return true; } } return false; } }); mSendButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { sendMessage(); } }); } public void onResume(){ if (mViewType == VIEW_TYPE_CHAT) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -