📄 imapp.java
字号:
/* * Copyright (C) 2007-2008 Esmertec AG. * Copyright (C) 2007-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 android.app.Activity;import android.app.Application;import android.content.ComponentName;import android.content.ContentResolver;import android.content.ContentUris;import android.content.ContentValues;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.content.res.Resources;import android.database.Cursor;import android.net.Uri;import android.os.Broadcaster;import android.os.Handler;import android.os.IBinder;import android.os.Message;import android.os.RemoteException;import android.provider.Im;import android.util.Log;import com.android.im.IConnectionCreationListener;import com.android.im.IImConnection;import com.android.im.IRemoteImService;import com.android.im.R;import com.android.im.app.adapter.ConnectionListenerAdapter;import com.android.im.engine.ImConnection;import com.android.im.engine.ImErrorInfo;import com.android.im.plugin.BrandingResourceIDs;import com.android.im.plugin.ImPluginInfo;import com.android.im.service.ImServiceConstants;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;public class ImApp extends Application { public static final String LOG_TAG = "ImApp"; public static final String EXTRA_INTENT_SEND_TO_USER = "Send2_U"; public static final String EXTRA_INTENT_PASSWORD = "password"; private static ImApp sImApp; IRemoteImService mImService; HashMap<Long, IImConnection> mConnections; MyConnListener mConnectionListener; HashMap<Long, ProviderDef> mProviders; Broadcaster mBroadcaster; /** A queue of messages that are waiting to be sent when service is connected.*/ ArrayList<Message> mQueue = new ArrayList<Message>(); /** A flag indicates that we have called to start the service.*/ private boolean mServiceStarted; private Context mApplicationContext; private Resources mPrivateResources; private HashMap<Long, BrandingResources> mBrandingResources; private BrandingResources mDefaultBrandingResources; public static final int EVENT_SERVICE_CONNECTED = 100; public static final int EVENT_CONNECTION_CREATED = 150; public static final int EVENT_CONNECTION_LOGGING_IN = 200; public static final int EVENT_CONNECTION_LOGGED_IN = 201; public static final int EVENT_CONNECTION_LOGGING_OUT = 202; public static final int EVENT_CONNECTION_DISCONNECTED = 203; public static final int EVENT_CONNECTION_SUSPENDED = 204; public static final int EVENT_USER_PRESENCE_UPDATED = 300; public static final int EVENT_UPDATE_USER_PRESENCE_ERROR = 301; private static final String[] PROVIDER_PROJECTION = { Im.Provider._ID, Im.Provider.NAME, Im.Provider.FULLNAME, Im.Provider.SIGNUP_URL, }; private static final String[] ACCOUNT_PROJECTION = { Im.Account._ID, Im.Account.PROVIDER, Im.Account.NAME, Im.Account.USERNAME, Im.Account.PASSWORD, }; static final void log(String log) { Log.d(LOG_TAG, log); } public static ImApp getApplication(Activity activity) { // TODO should this be synchronized? if (sImApp == null) { initialize(activity); } return sImApp; } /** * Initialize performs the manual ImApp instantiation and initialization. When the * ImApp is started first in the process, the ImApp public constructor should be called, * and sImApp initialized. So calling initialize() later should have no effect. However, * if another application runs in the same process and is started first, the ImApp * application object won't be instantiated, and we need to call initialize() manually to * instantiate and initialize it. */ private static void initialize(Activity activity) { // construct the TalkApp manually and call onCreate(). sImApp = new ImApp(); sImApp.mApplicationContext = activity.getApplication(); sImApp.mPrivateResources = activity.getResources(); sImApp.onCreate(); } @Override public Resources getResources() { if (mApplicationContext == this) { return super.getResources(); } return mPrivateResources; } @Override public ContentResolver getContentResolver() { if (mApplicationContext == this) { return super.getContentResolver(); } return mApplicationContext.getContentResolver(); } public ImApp() { super(); mConnections = new HashMap<Long, IImConnection>(); mApplicationContext = this; sImApp = this; } @Override public void onCreate() { super.onCreate(); mBroadcaster = new Broadcaster(); loadDefaultBrandingRes(); mBrandingResources = new HashMap<Long, BrandingResources>(); } @Override public void onTerminate() { stopImServiceIfInactive(); if (mImService != null) { try { mImService.removeConnectionCreatedListener(mConnCreationListener); } catch (RemoteException e) { Log.w(LOG_TAG, "failed to remove ConnectionCreatedListener"); } } super.onTerminate(); } public synchronized void startImServiceIfNeed() { if(!mServiceStarted) { if(Log.isLoggable(LOG_TAG, Log.DEBUG)) log("start ImService"); Intent serviceIntent = new Intent(); serviceIntent.setComponent(ImServiceConstants.IM_SERVICE_COMPONENT); mApplicationContext.startService(serviceIntent); mApplicationContext.bindService(serviceIntent, mImServiceConn, Context.BIND_AUTO_CREATE); mServiceStarted = true; mConnectionListener = new MyConnListener(new Handler()); } } public synchronized void stopImServiceIfInactive() { boolean hasActiveConnection = true; synchronized (mConnections) { hasActiveConnection = !mConnections.isEmpty(); } if (!hasActiveConnection && mServiceStarted) { if (Log.isLoggable(LOG_TAG, Log.DEBUG)) log("stop ImService because there's no active connections"); if(mImService != null) { mApplicationContext.unbindService(mImServiceConn); mImService = null; } Intent intent = new Intent(); intent.setComponent(ImServiceConstants.IM_SERVICE_COMPONENT); mApplicationContext.stopService(intent); mServiceStarted = false; } } private ServiceConnection mImServiceConn = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { if(Log.isLoggable(LOG_TAG, Log.DEBUG)) log("service connected"); mImService = IRemoteImService.Stub.asInterface(service); fetchActiveConnections(); loadBrandingResources(); synchronized (mQueue) { for (Message msg : mQueue) { msg.sendToTarget(); } mQueue.clear(); } Message msg = Message.obtain(null, EVENT_SERVICE_CONNECTED); mBroadcaster.broadcast(msg); } public void onServiceDisconnected(ComponentName className) { if(Log.isLoggable(LOG_TAG, Log.DEBUG)) log("service disconnected"); mConnections.clear(); mImService = null; } }; public boolean serviceConnected() { return mImService != null; } public static long insertOrUpdateAccount(ContentResolver cr, long providerId, String userName, String pw) { String selection = Im.Account.PROVIDER + "=? AND " + Im.Account.USERNAME + "=?"; String[] selectionArgs = {Long.toString(providerId), userName }; Cursor c = cr.query(Im.Account.CONTENT_URI, ACCOUNT_PROJECTION, selection, selectionArgs, null); if (c != null && c.moveToFirst()) { // Update the password c.updateString(c.getColumnIndexOrThrow(Im.Account.PASSWORD), pw); c.commitUpdates(); long id = c.getLong(c.getColumnIndexOrThrow(Im.Account._ID)); c.close(); return id; } else { ContentValues values = new ContentValues(4); values.put(Im.Account.PROVIDER, providerId); values.put(Im.Account.NAME, userName); values.put(Im.Account.USERNAME, userName); values.put(Im.Account.PASSWORD, pw); Uri result = cr.insert(Im.Account.CONTENT_URI, values); return ContentUris.parseId(result); } } private void loadImProviderSettings() { if (mProviders != null) { return; } mProviders = new HashMap<Long, ProviderDef>(); ContentResolver cr = getContentResolver(); Cursor c = cr.query(Im.Provider.CONTENT_URI, PROVIDER_PROJECTION, null, null, null); if (c == null) { return; } while (c.moveToNext()) { long id = c.getLong(0); String providerName = c.getString(1); String fullName = c.getString(2); String signUpUrl = c.getString(3); mProviders.put(id, new ProviderDef(id, providerName, fullName, signUpUrl)); } c.close(); } private void loadDefaultBrandingRes() { HashMap<Integer, Integer> resMapping = new HashMap<Integer, Integer>(); resMapping.put(BrandingResourceIDs.DRAWABLE_LOGO, R.drawable.imlogo_s); resMapping.put(BrandingResourceIDs.DRAWABLE_PRESENCE_ONLINE, android.R.drawable.presence_online); resMapping.put(BrandingResourceIDs.DRAWABLE_PRESENCE_AWAY, android.R.drawable.presence_away); resMapping.put(BrandingResourceIDs.DRAWABLE_PRESENCE_BUSY, android.R.drawable.presence_busy); resMapping.put(BrandingResourceIDs.DRAWABLE_PRESENCE_INVISIBLE, android.R.drawable.presence_invisible); resMapping.put(BrandingResourceIDs.DRAWABLE_PRESENCE_OFFLINE, android.R.drawable.presence_offline); resMapping.put(BrandingResourceIDs.DRAWABLE_BLOCK, R.drawable.ic_im_block); resMapping.put(BrandingResourceIDs.STRING_ARRAY_SMILEY_NAMES, R.array.default_smiley_names); resMapping.put(BrandingResourceIDs.STRING_ARRAY_SMILEY_TEXTS, R.array.default_smiley_texts); resMapping.put(BrandingResourceIDs.STRING_PRESENCE_AVAILABLE, R.string.presence_available); resMapping.put(BrandingResourceIDs.STRING_PRESENCE_BUSY, R.string.presence_busy); resMapping.put(BrandingResourceIDs.STRING_PRESENCE_AWAY, R.string.presence_away); resMapping.put(BrandingResourceIDs.STRING_PRESENCE_IDLE, R.string.presence_idle); resMapping.put(BrandingResourceIDs.STRING_PRESENCE_OFFLINE, R.string.presence_offline); resMapping.put(BrandingResourceIDs.STRING_PRESENCE_INVISIBLE, R.string.presence_invisible); resMapping.put(BrandingResourceIDs.STRING_LABEL_USERNAME, R.string.label_username);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -