package com.smartisanos.sidebar.util;
import android.content.ActivityNotFoundException;
import android.content.ClipDescription;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.Bitmap;
import android.view.DragEvent;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.smartisanos.sidebar.R;
public class WechatContact extends ContactItem {
private static final LOG log = LOG.getInstance(WechatContact.class);
public static final String PKG_NAME = "com.tencent.mm";
private String mIntent;
private int mUid;
public WechatContact(Context context, String name, String intent, Bitmap icon) {
super(context, icon, name);
mIntent = intent;
}
public int getUserId() {
return mUid;
}
public void setUserId(int id) {
mUid = id;
}
@Override
public boolean acceptDragEvent(Context context, DragEvent event) {
if (event.getClipDescription().getMimeTypeCount() <= 0) {
return false;
}
String mimeType = event.getClipDescription().getMimeType(0);
if (ClipDescription.MIMETYPE_TEXT_PLAIN.equals(mimeType)) {
return true;
}
return false;
}
@Override
public boolean handleDragEvent(Context context, DragEvent event) {
Tracker.dragSuccess(1, PKG_NAME);
boolean sret = super.handleDragEvent(context, event);
if(sret){
return true;
}
if(event.getClipData().getItemCount() <= 0){
return false;
}
Intent intent = null;
try {
intent = Intent.parseUri(mIntent, 0);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("wechat_text", event.getClipData().getItemAt(0).getText().toString());
} catch (URISyntaxException e) {
e.printStackTrace();
}
if (intent == null) {
//lose intent
return false;
}
log.error("start with uid ["+mUid+"]");
try {
LaunchApp.start(mContext, intent, true, PKG_NAME, mUid);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
public boolean openUI(Context context) {
Tracker.onClick(Tracker.EVENT_CLICK_CONTACTS, "contacts_type", "0");
Intent intent = null;
try {
intent = Intent.parseUri(mIntent, 0);
} catch (URISyntaxException e) {
e.printStackTrace();
return false;
}
try {
LaunchApp.start(mContext, intent, true, PKG_NAME, mUid);
return true;
} catch (ActivityNotFoundException e) {
// NA
}
return false;
}
public static void removeDoppelgangerShortcut(Context context) {
// String where = DatabaseHelper.UID + "=" + UserPackage.USER_DOPPELGANGER;
// DatabaseHelper.getInstance(context).remove(where);
}
@Override
public void save() {
DatabaseHelper.getInstance(mContext).update(this);
}
@Override
public void deleteFromDatabase() {
DatabaseHelper.getInstance(mContext).remove(this);
}
@Override
public int getTypeIcon() {
return R.drawable.contact_icon_wechat;
}
@Override
public String getPackageName() {
return PKG_NAME;
}
@Override
public boolean sameContact(ContactItem ci) {
if (ci == null) {
return false;
}
if (mIntent == null) {
return false;
}
if (ci instanceof WechatContact) {
WechatContact wc = (WechatContact) ci;
if (mIntent.equals(wc.mIntent)) {
return true;
}
}
return false;
}
public static List<ContactItem> getContacts(Context context){
return DatabaseHelper.getInstance(context).list();
}
public static final class DatabaseHelper extends SQLiteOpenHelper {
private static final int DB_VERSION = 2;
private static final String DB_NAME = "wechat_contacts";
private volatile static DatabaseHelper sInstance;
public synchronized static DatabaseHelper getInstance(Context context){
if(sInstance == null){
synchronized(DatabaseHelper.class){
if(sInstance == null){
sInstance = new DatabaseHelper(context);
}
}
}
return sInstance;
}
public static final String TABLE_NAME = "contacts";
public static final String ID = "_id";
public static final String DISPLAY_NAME = "display_name";
public static final String WEIGHT = "weight";
public static final String LAUNCH_INTENT = "launchIntent";
public static final String AVATAR = "avatar";
public static final String UID = "user_id";
public static final String[] columns = new String[] {ID, DISPLAY_NAME, WEIGHT, UID, LAUNCH_INTENT, AVATAR};
private static final Map<String, String> columnProps = new HashMap<String, String>();
static {
columnProps.put(ID, "INTEGER PRIMARY KEY");
columnProps.put(DISPLAY_NAME, "TEXT");
columnProps.put(WEIGHT, "INTEGER");
columnProps.put(UID, "INTEGER");
columnProps.put(LAUNCH_INTENT, "TEXT");
columnProps.put(AVATAR, "BLOB");
}
private Context mContext;
private DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = generateCreateSQL(TABLE_NAME, columns, columnProps);
db.execSQL(sql);
}
private static String generateCreateSQL(String table, String[] columns, Map<String, String> props) {
StringBuffer buffer = new StringBuffer();
buffer.append("CREATE TABLE IF NOT EXISTS " + table + " (");
for (int i = 0; i < columns.length; i++) {
String column = columns[i];
String prop = props.get(column);
buffer.append(column);
buffer.append(" ");
buffer.append(prop);
if (i != (columns.length - 1)) {
buffer.append(", ");
}
}
buffer.append(");");
return buffer.toString();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
log.error("update db to version => old ["+oldVersion+"] new ["+newVersion+"]");
//to version 2
for (int i = oldVersion; i < newVersion; i++) {
int version = oldVersion + 1;
upgradeTo(db, version);
}
}
private void upgradeTo(SQLiteDatabase db, int version) {
log.error("upgradeTo => " + version);
switch (version) {
case 2 : {
String sql = generateCreateSQL(TABLE_NAME, columns, columnProps);
String[] oldColumns = new String[] {ID, DISPLAY_NAME, WEIGHT, LAUNCH_INTENT, AVATAR};
boolean success = formatTable(db, TABLE_NAME, oldColumns, sql);
log.error("formatTable ["+TABLE_NAME+"] => " + success);
break;
}
}
}
/**
* merge data from old table to new table.
* make sure table name won't change and column name & type is same with old table
* @param tableName
* @param columns backup data columns
* @param createSql sql for create table
*/
public static boolean formatTable(SQLiteDatabase db, final String tableName, final String[] columns, String createSql) {
boolean success = true;
db.beginTransaction();
try {
success = formatTableImpl(db, tableName, columns, createSql);
db.setTransactionSuccessful();
} catch (Exception e) {
success = false;
e.printStackTrace();
} finally {
try {
db.endTransaction();
} catch (Exception e) {
success = false;
e.printStackTrace();
}
}
return success;
}
private static final String DROP_TABLE_SQL_PREFIX = "DROP TABLE IF EXISTS ";
public static String dropTableSql(String tableName) {
return DROP_TABLE_SQL_PREFIX + tableName;
}
/**
* merge data from old table to new table.
* make sure table name won't change and column name & type is same with old table
* @param tableName
* @param columns backup data columns
* @param createSql sql for create table
*/
private static boolean formatTableImpl(SQLiteDatabase db, final String tableName, final String[] columns, String createSql) {
if (tableName == null) {
log.error("mergeTable return by tableName is null");
return false;
}
if (columns == null || columns.length == 0) {
log.error("mergeTable return by columns is empty");
return false;
}
// rename old table
String oldTableName = tableName + "_old";
String renameTableSql = "ALTER TABLE " + tableName + " RENAME TO " + oldTableName;
db.execSQL(renameTableSql);
// create table with format
db.execSQL(createSql);
// merge data to new table
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < columns.length; i++) {
buffer.append(columns[i]);
if (i != (columns.length - 1)) {
buffer.append(", ");
}
}
String mergeColumns = buffer.toString();
String mergeSql = "INSERT INTO " + tableName + " (" + mergeColumns +
") SELECT " + mergeColumns + " FROM " + oldTableName;
db.execSQL(mergeSql);
// drop tmp table
db.execSQL(dropTableSql(oldTableName));
return true;
}
private long getRecordId(WechatContact info) {
ThreadVerify.verify(false);
String launchIntent = info.mIntent;
String where = LAUNCH_INTENT + "='"+launchIntent+"'";
Cursor cursor = null;
try {
cursor = getReadableDatabase().query(TABLE_NAME, null, where, null, null, null, null);
if (cursor.moveToFirst()) {
int index = cursor.getColumnIndex(ID);
return cursor.getInt(index);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
return -1;
}
public long update(WechatContact info) {
ThreadVerify.verify(false);
long recordId = getRecordId(info);
long result = -1;
ContentValues cv = new ContentValues();
cv.put(UID, info.mUid);
cv.put(DISPLAY_NAME, info.mDisplayName.toString());
cv.put(WEIGHT, info.getIndex());
cv.put(LAUNCH_INTENT, info.mIntent);
cv.put(AVATAR, BitmapUtils.Drawable2Bytes(info.getAvatar()));
if (recordId > 0) {
//update
String whereCase = ID + "=" + recordId;
result = getWritableDatabase().update(TABLE_NAME, cv, whereCase, null);
} else {
//insert
result = getWritableDatabase().insert(TABLE_NAME, null, cv);
}
return result;
}
public boolean remove(WechatContact info) {
ThreadVerify.verify(false);
long recordId = getRecordId(info);
if (recordId > 0) {
String where = ID + "=" + recordId;
return remove(where);
}
return false;
}
public boolean remove(String where) {
ThreadVerify.verify(false);
try {
SQLiteDatabase db = getWritableDatabase();
int affectedRow = db.delete(TABLE_NAME, where, null);
if (affectedRow > 0) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public List<ContactItem> list() {
ThreadVerify.verify(false);
List<ContactItem> list = new ArrayList<ContactItem>();
Cursor cursor = null;
try {
cursor = getReadableDatabase().query(TABLE_NAME, null, null, null, null, null, null);
if (cursor.moveToFirst()) {
int nameIndex = cursor.getColumnIndex(DISPLAY_NAME);
int weightIndex = cursor.getColumnIndex(WEIGHT);
int intentIndex = cursor.getColumnIndex(LAUNCH_INTENT);
int avatarIndex = cursor.getColumnIndex(AVATAR);
int uidIndex = cursor.getColumnIndex(UID);
do {
String name = cursor.getString(nameIndex);
int weight = cursor.getInt(weightIndex);
String intent = cursor.getString(intentIndex);
int uid = cursor.getInt(uidIndex);
byte[] avatar = cursor.getBlob(avatarIndex);
Bitmap icon = BitmapUtils.Bytes2Bitmap(avatar);
WechatContact contact = new WechatContact(mContext, name, intent, icon);
contact.setUserId(uid);
contact.setIndex(weight);
list.add(contact);
} while (cursor.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
return list;
}
}
}