openfire+asmack搭建的安卓即时通讯(七) 15.5.27

时间:2021-09-27 03:16:01

本地化之章!

 往期传送门:

  1.http://www.cnblogs.com/lfk-dsk/p/4398943.html

  2.http://www.cnblogs.com/lfk-dsk/p/4411625.html

  3.http://www.cnblogs.com/lfk-dsk/p/4412126.html

  4.http://www.cnblogs.com/lfk-dsk/p/4413693.html

  5.http://www.cnblogs.com/lfk-dsk/p/4419418.html

  6.http://www.cnblogs.com/lfk-dsk/p/4433319.html

真没想到这东西居然还会写到第七篇,很多亲们的反馈和鼓励给了我很大的动力啊,最近正好朋友也在做这个东西,但是我们用一样的库和后端做的东西居然不一样(他用这个做了联网弹幕!openfire+asmack搭建的安卓即时通讯(七) 15.5.27),不过确实发现了一些问题比如asmack的库内容参差不齐,很多提供方法都不一样,看来使用者们都或多或少的对源码进行了一些修改,都变得乱糟糟的呢!

这里就提供一下我自己用的asmack库吧,省的大家用的不一样:http://files.cnblogs.com/files/lfkdsk/asmack.zip

这次的博文先从完成的效果开始吧,这个并不是最终稿,因为虽然完成了很多的功能啊,但是还有一些问题,比如接收数据没用广播啊,监听的ChatListener没放在server里啊,好友系统并不完善啊,很多的东西还没有完成,到时候还要根据这些东西进行一些修改,但是现在需要的功能已经够用了,接着的那些东西也不过是要应用asmack库里的东西而已了,好了先上效果图:

openfire+asmack搭建的安卓即时通讯(七) 15.5.27

(1.首先登录界面增加了Ip的选项,更具有Spark的android版的感觉,通用性强了,不过我之后要是想上线让大家用可能会删掉)

openfire+asmack搭建的安卓即时通讯(七) 15.5.27

(2.现在不打开具体的聊天窗口,程序也不会蹦了,因为原来是直接向listview里面添加数据,可是listview还没初始化所以会崩)

openfire+asmack搭建的安卓即时通讯(七) 15.5.27

(3.打开具体的useractivity就会取出原来的数据然后还有新打印的出来的)

openfire+asmack搭建的安卓即时通讯(七) 15.5.27

(4.信息由于是走数据库了,所以分发也不会想原来一样出错了)                                                                                                               

                                                      openfire+asmack搭建的安卓即时通讯(七) 15.5.27

(5.我不想用传统的通知栏,那个用户能禁用,哈哈哈哈哈哈哈,我用了定制的Toast,在桌面的时候接到消息就会弹出一个Toast提示!)

好了这就是我们本次要达成的效果,让我们一个一个来!

1.首先从主界面的输入IP开始:

  <TableRow>
<TextView
android:textColor="#ffc2c6c6"
android:layout_height="wrap_content"
android:text="Ip"/>
<EditText
android:id="@+id/login_ip"
android:hint="Input your Ip"
android:maxLines="1"
android:layout_height="wrap_content"
/>
</TableRow>

先在TableLayout里添加。

静态数据类里添加:

     //ip名称
public static String My_Ip = "";

主活动的添加:

ip = (EditText) findViewById(R.id.login_ip);

check_init()函数里添加:

  private void checkbox_init() {//checkbox判断函数
//判断记住密码多选框的状态
if(sp.getBoolean("ISCHECK", false))
{
//设置默认是记录密码状态
check_save.setChecked(true);
ip.setText(sp.getString("USER_IP", ""));
name.setText(sp.getString("USER_NAME",""));
password.setText(sp.getString("PASSWORD",""));
//判断自动登陆多选框状态
if(sp.getBoolean("AUTO_ISCHECK", false))
{
//设置默认是自动登录状态
check_auto.setChecked(true);
//跳转界面
//account=sp.getString("USER_NAME","");
//pwd=sp.getString("PASSWORD","");
Log.i("======================"+account,pwd+"===================================");
accountLogin();
}
}
}
private void setCheck_save(){
if(check_save.isChecked())
{
//记住用户名、密码、
editor = sp.edit();
editor.putString("USER_IP", user.My_Ip);
editor.putString("USER_NAME", account);
editor.putString("PASSWORD",pwd);
editor.apply();
}
}

这个是把Ip添加进记录。

修改登录的方法:

    private void accountLogin() {
new Thread() {
public void run() {
user.My_Ip = ((EditText)findViewById(R.id.login_ip))
.getText().toString();
account = ((EditText) findViewById(R.id.login_name))
.getText().toString();
pwd = ((EditText) findViewById(R.id.login_password)).getText()
.toString();
boolean is = ConnecMethod.login(account, pwd);
if (is) {
insHandler.sendEmptyMessage(1);
// 将用户名保存
user.UserName = account+"@lfkdsk/Spark 2.6.3";
user.UserName_= account;
setCheck_save();
} else {
insHandler.sendEmptyMessage(0);
}
}
}.start();
}

  但是要是逐层的为函数添加参数,然后无限的传参也是一种不太现实的方法,所以我们在XMpp连接的地方直接调用静态存储的IP:

     public static boolean openConnection() {
try {
connConfig = new ConnectionConfiguration(user.My_Ip, 5222);
// 设置登录状态为离线
connConfig.setSendPresence(false);
// 断网重连
connConfig.setReconnectionAllowed(true);
con = new XMPPConnection(connConfig);
con.connect();
return true;
} catch (Exception e) { }
return false;
}

  这样我们登陆的时候就能手动指定ip或者是域名了,增强了通用性。

   2.本地化数据的具体操作:

  1.新建一个类作为本地数据库的模版:

 package com.lfk.webim.appli;

 import android.util.Log;

 /**
* Created by Administrator on 2015/5/26.
*/
public class TalkLogs {
private String ID = "_id"; //数据库主键,自增
private String With_Id ="with_id"; //和谁聊天
private String Logs = "talklogs"; //聊天记录
private String If_read = "_ifread"; //是否已读
private String dbname; //数据表名---为用户名,即user.UserName_
private String CREAT_DB = ""; //数据库新建的语句 public TalkLogs(String dbname){
this.dbname = dbname;
giveanameto(dbname);
Log.e("dbname=====", this.dbname);
Log.e("dbname参数=====",dbname);
}
private void giveanameto(String dbname){
CREAT_DB = "CREATE TABLE if not exists "+dbname+"("
+this.ID +" integer primary key autoincrement,"
+this.With_Id+","
+this.If_read+" integer,"
+ this.Logs+")";
}
public String returnAString(){
Log.e("CREAT_DB===========",CREAT_DB);
return CREAT_DB;
}
}
 package com.lfk.webim.appli;

 import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast; /**
* Created by Administrator on 2015/5/25.
*/
public class SQLiteHelper extends SQLiteOpenHelper {
private Context mcontext;
public SQLiteHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mcontext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
//db.execSQL(CREAT_DB);
Toast.makeText(mcontext, "succeed collect!", Toast.LENGTH_SHORT).show();
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}

  写一个空的SQLiteHelper,把表放在后面。

  代码里做了详细的注释,类里面传入用户名,返回新建表的String语句。

     public void CreateNewTable(){
sqLiteHelper = new SQLiteHelper(this,"user_logs.db",null,1); //新建.db文件
sqLiteDatabase = sqLiteHelper.getWritableDatabase();
TalkLogs talklog = new TalkLogs(user.UserName_); //获取新建表的语句
sqLiteDatabase.execSQL(talklog.returnAString()); //新建表
Toast.makeText(friend.this, user.UserName_+" Create success",Toast.LENGTH_SHORT).show();
Log.e(user.UserName_, "success!!!");
//sqLiteDatabase.close();
}

  在friend的activity里面,新建该方法,每次进入朋友界面,新建以用户名为名的表,因为用的SQL语句写了if exist 所以已有的不会新建。

 final ClientConServer server = new ClientConServer(this,mhandler,this.sqLiteDatabase);

  对工具类进行实例化,可以解决静态方法不能用在非静态上下文的问题,这里传入context,handler,和数据库,数据库是为了防止打开重复,传入handler是为了桌面Toast

  2.修改后的friend活动:

 package com.lfk.webim;

 import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast; import com.lfk.webim.appli.BaseActivity;
import com.lfk.webim.appli.SQLiteHelper;
import com.lfk.webim.appli.TalkLogs;
import com.lfk.webim.appli.user;
import com.lfk.webim.server.Myserver;
import com.lfk.webim.server.connect; public class friend extends BaseActivity {
public static ArrayAdapter<String> mArrayAdapter;
public SwipeRefreshLayout swipeLayout;
private SQLiteDatabase sqLiteDatabase;
private SQLiteHelper sqLiteHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_friend); CreateNewTable();
final ClientConServer server = new ClientConServer(this,mhandler,this.sqLiteDatabase); swipeLayout = (SwipeRefreshLayout)findViewById(R.id.swipe_refresh);
TextView textView=(TextView)findViewById(R.id.name);
textView.setText(user.UserName_ + "的朋友"); Intent intentServer= new Intent(this, Myserver.class);
startService(intentServer); final ListView listView=(ListView)findViewById(R.id.friend_list);
mArrayAdapter= new ArrayAdapter<String>(this, R.layout.list_item);
listView.setAdapter(mArrayAdapter); //server.getFriends();
//server.getChat(); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
String temp = (String) ((TextView) arg1).getText();
Intent intent = new Intent();
String temper = temp + "@lfkdsk/Smack";
Log.e(temp + "================", temper);
user.FromName = temper;
user.FromName_ = temp;
intent.putExtra("FromName", temper);
intent.setClass(friend.this, useractivity.class);
startActivity(intent);
Toast.makeText(getApplicationContext(),
"Chat with " + temp,
Toast.LENGTH_SHORT).show();
mArrayAdapter.notifyDataSetChanged();
}
}); swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {//延迟跳转=-=
public void run() {
swipeLayout.setRefreshing(true);
mArrayAdapter.clear();
server.getFriends();
swipeLayout.setRefreshing(false);
}
}, 500);
}
});
} public void CreateNewTable(){
sqLiteHelper = new SQLiteHelper(this,"user_logs.db",null,1); //新建.db文件
sqLiteDatabase = sqLiteHelper.getWritableDatabase();
TalkLogs talklog = new TalkLogs(user.UserName_); //获取新建表的语句
sqLiteDatabase.execSQL(talklog.returnAString()); //新建表
Toast.makeText(friend.this, user.UserName_+" Create success",Toast.LENGTH_SHORT).show();
Log.e(user.UserName_, "success!!!");
//sqLiteDatabase.close();
}
public Handler mhandler = new Handler()
{
public void handleMessage(android.os.Message message)
{
switch (message.what) {
case 0:
Bundle bundle = (Bundle)message.obj; //桌面Toast的解决方法
String s1 = bundle.getString("name");
String s2 = bundle.getString("text");
showCustomToast(s1,s2);
break;
case 1: {
String temp = (String) message.obj;
friend.mArrayAdapter.add(temp);
break;
}
}
}
};
protected void onDestroy()
{
super.onDestroy();
connect.closeConnection();
Intent stopintent=new Intent(this, Myserver.class);
stopService(stopintent);
}
private long exitTime = 0;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){
Intent home = new Intent(Intent.ACTION_MAIN);
home.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
home.addCategory(Intent.CATEGORY_HOME);
startActivity(home);
return true;
}
return super.onKeyDown(keyCode, event);
}
public void showCustomToast(String s1, String s2) {//新建显示TOAST
// 通用的布局加载器
LayoutInflater inflater = getLayoutInflater();
// 加载根容器,方便用于后面的view的定位
View layout = inflater.inflate(R.layout.toast_view, (ViewGroup)findViewById(R.id.llToast));
// 设置图片的源文件
ImageView image = (ImageView) layout.findViewById(R.id.tvImageToast);
image.setImageResource(R.drawable.toast_image);
// 设置title及内容
TextView title = (TextView) layout.findViewById(R.id.tvTitleToast);
title.setText(s1);
TextView text = (TextView) layout.findViewById(R.id.tvTextToast);
text.setText(s2);
Toast tempToast = new Toast(getApplicationContext());
// 设置位置
tempToast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER, 0, 0);
// 设置显示时间
tempToast.setDuration(Toast.LENGTH_SHORT);
tempToast.setView(layout);
tempToast.show();
}
}

friend活动

   3.工具类进行了很大的修改,详细讲解:

 package com.lfk.webim;

 import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log; import com.lfk.webim.appli.user;
import com.lfk.webim.server.connect; import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.packet.Message; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; public class ClientConServer {
private Context context;
private Handler handlers;
private SQLiteDatabase sqLiteDatabase; ClientConServer(Context context,Handler handler,SQLiteDatabase sqLiteDatabase){
this.context = context;
this.handlers = handler;
this.sqLiteDatabase = sqLiteDatabase;
getFriends();
getChat();
System.out.print(isAppForground(context));
}
//这里收到消息
private Handler handler = new Handler(){
public void handleMessage(android.os.Message m) {
Message msg = new Message();
msg = (Message) m.obj;
//把从服务器获得的消息通过发送
String[] message = new String[]{ msg.getFrom(), msg.getBody()};
System.out.println("==========收到消息 From==========="+ message[0]);
System.out.println("==========收到消息 Body===========" + message[1]);
String s = msg.getFrom();
String s1 = s.split("@")[0];
ContentValues values = new ContentValues();
if(message[1]!=null) {
if (user.UserName.equals(message[0])) {
values.put("with_id",s1);
values.put("talklogs", "ME: " + msg.getBody());
values.put("_ifread",0);
Log.e("存入:", "ME: " + msg.getBody());
sqLiteDatabase.insert("\"" + user.UserName_ + "\"", null, values);
values.clear();
} else {
values.put("with_id", s1);
values.put("talklogs", s1 + "说:" + msg.getBody());
values.put("_ifread", 0);
Log.e("存入:", s1 + "说:" + msg.getBody());
sqLiteDatabase.insert("\"" + user.UserName_ + "\"", null, values);
addUnread(values,s1);
}
if(isHome(context)){
sendToast(msg,s1);
}
}
}
};
public void getFriends(){
//获取用户组、成员信息
System.out.println("--------find start----------");
Roster roster = connect.con.getRoster();
Collection<RosterGroup> entriesGroup = roster.getGroups();
System.out.println("team:" + entriesGroup.size());
for(RosterGroup group: entriesGroup){
Collection<RosterEntry> entries = group.getEntries();
int temp=group.getEntryCount();
System.out.println("--------groupnumber--------" + "\n" + temp);
System.out.println("--------groupName----------" + "\n" + group.getName());
for (RosterEntry entry : entries) {
System.out.println("name:"+entry.getName());
String string2 = entry.getName();
android.os.Message message_list = new android.os.Message();
message_list.obj = string2;
message_list.what = 1;
handlers.sendMessage(message_list);
}
}
System.out.println("--------find end--------");
}
private void addUnread(ContentValues values,String s1){
if (isAppForground(context)&& s1.equals(user.FromName_)) {
Cursor cursor = sqLiteDatabase.rawQuery("Select * From "+user.UserName_+" where with_id ="+"\""+user.FromName_+"\""+"And _ifread ="+0,null);
if(cursor.moveToFirst()) {
do {
String talklogs = cursor.getString(cursor.getColumnIndex("talklogs"));
useractivity.mConversationArrayAdapter.add(talklogs);
Log.e(talklogs, "================");
}while (cursor.moveToNext());
}
if(!isAppForground(context))
useractivity.mConversationArrayAdapter.notifyDataSetChanged();
cursor.close();
}
values.clear();
}
private void sendToast(Message msg,String s1){
android.os.Message message_send = new android.os.Message();
Bundle bundle = new Bundle();
bundle.putString("name",s1);
bundle.putString("text",msg.getBody());
message_send.obj = bundle;
message_send.what = 0;
handlers.sendMessage(message_send);
}
private void getChat(){
//在登陆以后应该建立一个监听消息的监听器,用来监听收到的消息:
ChatManager chatManager = connect.con.getChatManager();
chatManager.addChatListener(new MyChatManagerListener());
}
/** message listener*/
class MyChatManagerListener implements ChatManagerListener {
public void chatCreated(Chat chat, boolean arg1) {
chat.addMessageListener(new MessageListener(){
@Override
public void processMessage(Chat chat, Message msg) {
android.os.Message m = handler.obtainMessage();
m.obj = msg;
m.sendToTarget();
}
});
}
}
public boolean isAppForground(Context mContext) {
ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
if (!topActivity.getPackageName().equals(mContext.getPackageName())) {
return false;
}
}
return true;
}
public boolean isHome(Context mContext){
ActivityManager mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);
return getHomes(mContext).contains(rti.get(0).topActivity.getPackageName());
}
/**
* 获得属于桌面的应用的应用包名称
* @return 返回包含所有包名的字符串列表
*/
private List<String> getHomes(Context mContext) {
List<String> names = new ArrayList<String>();
PackageManager packageManager = mContext.getPackageManager();
//属性
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
for(ResolveInfo ri : resolveInfo){
names.add(ri.activityInfo.packageName);
System.out.println(ri.activityInfo.packageName);
}
return names;
}
}

工具类

 ClientConServer(Context context,Handler handler,SQLiteDatabase sqLiteDatabase){
this.context = context;
this.handlers = handler;
this.sqLiteDatabase = sqLiteDatabase;
getFriends();
getChat();
System.out.print(isAppForground(context));
}

  3.1构造函数,用于实例化。

  private void addUnread(ContentValues values,String s1){
if (isAppForground(context)&& s1.equals(user.FromName_)) {
Cursor cursor = sqLiteDatabase.rawQuery("Select * From "+user.UserName_+" where with_id ="+"\""+user.FromName_+"\""+"And _ifread ="+0,null);
if(cursor.moveToFirst()) {
do {
String talklogs = cursor.getString(cursor.getColumnIndex("talklogs"));
useractivity.mConversationArrayAdapter.add(talklogs);
Log.e(talklogs, "================");
}while (cursor.moveToNext());
}
if(!isAppForground(context))
useractivity.mConversationArrayAdapter.notifyDataSetChanged();
cursor.close();
}
values.clear();
}

  3.2搜索所有与我聊天的人的记录,并且为未读。

public boolean isAppForground(Context mContext) {
ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
if (!topActivity.getPackageName().equals(mContext.getPackageName())) {
return false;
}
}
return true;
}
public boolean isHome(Context mContext){
ActivityManager mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);
return getHomes(mContext).contains(rti.get(0).topActivity.getPackageName());
}
/**
* 获得属于桌面的应用的应用包名称
* @return 返回包含所有包名的字符串列表
*/
private List<String> getHomes(Context mContext) {
List<String> names = new ArrayList<String>();
PackageManager packageManager = mContext.getPackageManager();
//属性
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
for(ResolveInfo ri : resolveInfo){
names.add(ri.activityInfo.packageName);
System.out.println(ri.activityInfo.packageName);
}
return names;
}
}

  3.3判断现在栈顶的活动是什么?还有是否在桌面。

  3.4消息的分发机制

  这里需要讲解一下我的聊天机制,ChatListener接收数据,然后存入数据库,如果现在的栈顶活动为朋友界面(有一个判断),就默默的存进去,如果是聊天界面就把所有数据库里的取出来,把所有的消息都设为已读(_ifread=1),放在listview里,

然后如果有新消息的话,就用3.1的方法把所有的_ifread的消息取出来,即时的显示在listview里面,如果现在为桌面,就把东西存入然后再Toast出来。

  所以handler就是重要的消息分发机制:

  private  Handler handler = new Handler(){
public void handleMessage(android.os.Message m) {
Message msg = new Message();
msg = (Message) m.obj;
//把从服务器获得的消息通过发送
String[] message = new String[]{ msg.getFrom(), msg.getBody()};
System.out.println("==========收到消息 From==========="+ message[0]);
System.out.println("==========收到消息 Body===========" + message[1]);
String s = msg.getFrom();
String s1 = s.split("@")[0];
ContentValues values = new ContentValues();
if(message[1]!=null) {
if (user.UserName.equals(message[0])) {
values.put("with_id",s1);
values.put("talklogs", "ME: " + msg.getBody());
values.put("_ifread",0);
Log.e("存入:", "ME: " + msg.getBody());
sqLiteDatabase.insert("\"" + user.UserName_ + "\"", null, values);
values.clear();
} else {
values.put("with_id", s1);
values.put("talklogs", s1 + "说:" + msg.getBody());
values.put("_ifread", 0);
Log.e("存入:", s1 + "说:" + msg.getBody());
sqLiteDatabase.insert("\"" + user.UserName_ + "\"", null, values);
addUnread(values,s1);
}
if(isHome(context)){
sendToast(msg,s1);
}
}
}
};

  4.改进后的聊天界面:

 package com.lfk.webim;

 import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast; import com.lfk.webim.appli.BaseActivity;
import com.lfk.webim.appli.user;
import com.lfk.webim.server.connect; import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message; import java.io.File; public class useractivity extends BaseActivity {
private ListView listView;
public static ArrayAdapter<String> mConversationArrayAdapter;
private ClientConServer server;
private SQLiteDatabase database;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.useractivity); getActionBar().setDisplayHomeAsUpEnabled(true); //server = (ClientConServer)getIntent().getSerializableExtra("ClientConServer"); listView = (ListView) findViewById(R.id.in);
TextView textView = (TextView) findViewById(R.id.username);
textView.setText("Talk with "+user.FromName_); mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);
listView.setAdapter(mConversationArrayAdapter); OpenDatabase(); //server = new ClientConServer(mhandle); Button button = (Button)findViewById(R.id.button_send); button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EditText input = (EditText) findViewById(R.id.edit_text_out);
final String content = input.getText().toString();
String string = "ME" + ":" + content;
android.os.Message mm = new android.os.Message();
mm.what = 0;
mm.obj = content;
try {
XMPPConnection connection = connect.getConnection();
ChatManager cm = connection.getChatManager();
Chat chat = cm.createChat(user.FromName, new MessageListener() {
@Override
public void processMessage(Chat chat, Message msg) {
msg.setBody(content);
Log.i("---", msg.getFrom() + "说:" + msg.getBody());
//添加消息到聊天窗口
}
});
if (content.equals("")) {
mm.what = 1;
mhandle.handleMessage(mm);
} else {
mhandle.handleMessage(mm);
chat.sendMessage(content);
}
input.setText("");
} catch (XMPPException e) {
e.printStackTrace();
}
} });
}
public Handler mhandle = new Handler() {
public void handleMessage(android.os.Message m) {
switch (m.what) {
case 1:
Toast.makeText(useractivity.this, "不能发送空消息", Toast.LENGTH_SHORT).show();
break;
case 0:
String respond = (String) m.obj;
Log.i("---", respond);
ContentValues values = new ContentValues();
values.put("with_id",user.FromName_);
values.put("talklogs","ME: "+respond);
values.put("_ifread",0);
Log.e("存入:", "ME: " + respond);
database.insert("\"" + user.UserName_ + "\"", null, values);
values.clear();
mConversationArrayAdapter.add("ME: "+respond);
mConversationArrayAdapter.notifyDataSetChanged();
break;
case 2:
//addTheListview();
break;
}
}
};
private void OpenDatabase(){
String DB_NAME = "user_logs.db"; //保存的数据库文件名
String PACKAGE_NAME = "com.lfk.webim";// 应用的包名
String DB_PATH = "/data"
+ Environment.getDataDirectory().getAbsolutePath() +"/"
+ PACKAGE_NAME+ "/databases"; // 在手机里存放数据库的位置
File myDataPath = new File(DB_PATH);
String dbfile = myDataPath+"/"+DB_NAME;
database = SQLiteDatabase.openOrCreateDatabase(dbfile, null);
if(!checkColumnExist1(database,user.UserName_,user.FromName_)){
Cursor cursor = database.rawQuery("Select * From "+user.UserName_+" where with_id ="+"\""+user.FromName_+"\"",null);
if(cursor.moveToFirst()) {
do {
String talklogs = cursor.getString(cursor.getColumnIndex("talklogs"));
mConversationArrayAdapter.add(talklogs);
Log.e(talklogs, "================");
}while (cursor.moveToNext());
}
database.execSQL("UPDATE "+user.UserName_+" SET _ifread = 1 "+"Where with_id ="+"\""+user.FromName_+"\"");
cursor.close();
//database.close();
}
}
public static boolean checkColumnExist1(SQLiteDatabase db, String tableName, String columnName) {
boolean result = false ;
Cursor cursor = null ;
try{
//查询一行
cursor = db.rawQuery( "SELECT * FROM " + tableName + " LIMIT 0", null );
result = cursor != null && cursor.getColumnIndex(columnName) != -1 ;
}catch (Exception e){
Log.e("","checkColumnExists1..." + e.getMessage()) ;
}finally{
if(null != cursor && !cursor.isClosed()){
cursor.close() ;
}
}
return result ;
}
}

聊天活动

     private void OpenDatabase(){
String DB_NAME = "user_logs.db"; //保存的数据库文件名
String PACKAGE_NAME = "com.lfk.webim";// 应用的包名
String DB_PATH = "/data"
+ Environment.getDataDirectory().getAbsolutePath() +"/"
+ PACKAGE_NAME+ "/databases"; // 在手机里存放数据库的位置
File myDataPath = new File(DB_PATH);
String dbfile = myDataPath+"/"+DB_NAME;
database = SQLiteDatabase.openOrCreateDatabase(dbfile, null);
if(!checkColumnExist1(database,user.UserName_,user.FromName_)){
Cursor cursor = database.rawQuery("Select * From "+user.UserName_+" where with_id ="+"\""+user.FromName_+"\"",null);
if(cursor.moveToFirst()) {
do {
String talklogs = cursor.getString(cursor.getColumnIndex("talklogs"));
mConversationArrayAdapter.add(talklogs);
Log.e(talklogs, "================");
}while (cursor.moveToNext());
}
database.execSQL("UPDATE "+user.UserName_+" SET _ifread = 1 "+"Where with_id ="+"\""+user.FromName_+"\"");
cursor.close();
//database.close();
}
}

  每次进入都先打开数据库,并且把所有的聊天对应的人的数据库信息取出来,然后把所有的已读标志设为1;

  

     public static boolean checkColumnExist1(SQLiteDatabase db, String tableName, String columnName) {
boolean result = false ;
Cursor cursor = null ;
try{
//查询一行
cursor = db.rawQuery( "SELECT * FROM " + tableName + " LIMIT 0", null );
result = cursor != null && cursor.getColumnIndex(columnName) != -1 ;
}catch (Exception e){
Log.e("","checkColumnExists1..." + e.getMessage()) ;
}finally{
if(null != cursor && !cursor.isClosed()){
cursor.close() ;
}
}
return result ;
}

  这里用到了一个方法,用来判断表里有没有你的这个字段,如果没有就不用添加到listview里,否则你没和他聊过会崩!!

     public Handler mhandle = new Handler() {
public void handleMessage(android.os.Message m) {
switch (m.what) {
case 1:
Toast.makeText(useractivity.this, "不能发送空消息", Toast.LENGTH_SHORT).show();
break;
case 0:
String respond = (String) m.obj;
Log.i("---", respond);
ContentValues values = new ContentValues();
values.put("with_id",user.FromName_);
values.put("talklogs","ME: "+respond);
values.put("_ifread",0);
Log.e("存入:", "ME: " + respond);
database.insert("\"" + user.UserName_ + "\"", null, values);
values.clear();
mConversationArrayAdapter.add("ME: "+respond);
mConversationArrayAdapter.notifyDataSetChanged();
break;
case 2:
//addTheListview();
break;
}
}
};

  在自己发送消息的时候,存入数据库,然后添加到listview里面。

  3.桌面显示的Toast:

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/llToast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffffff"
android:orientation="vertical" > <TextView
android:id="@+id/tvTitleToast"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="1dip"
android:background="#bb000000"
android:gravity="center"
android:text="Title"
android:textColor="#ffffffff" /> <LinearLayout
android:id="@+id/llToastContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="1dip"
android:layout_marginLeft="1dip"
android:layout_marginRight="1dip"
android:background="#44000000"
android:orientation="vertical"
android:padding="15dip" > <ImageView
android:id="@+id/tvImageToast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:contentDescription="@string/hello_world"
android:src="@drawable/toast_image" /> <TextView
android:id="@+id/tvTextToast"
android:layout_width="128dp"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:singleLine="false"
android:text="自定义显示语句"
android:textColor="#ff000000" />
</LinearLayout> </LinearLayout>

  1.添加一个toast的布局文件,写出来的样子是这样的:  

    openfire+asmack搭建的安卓即时通讯(七) 15.5.27

  2.friend里面添加一个方法进行处理:

     public void showCustomToast(String s1, String s2) {//新建显示TOAST
// 通用的布局加载器
LayoutInflater inflater = getLayoutInflater();
// 加载根容器,方便用于后面的view的定位
View layout = inflater.inflate(R.layout.toast_view, (ViewGroup)findViewById(R.id.llToast));
// 设置图片的源文件
ImageView image = (ImageView) layout.findViewById(R.id.tvImageToast);
image.setImageResource(R.drawable.toast_image);
// 设置title及内容
TextView title = (TextView) layout.findViewById(R.id.tvTitleToast);
title.setText(s1);
TextView text = (TextView) layout.findViewById(R.id.tvTextToast);
text.setText(s2);
Toast tempToast = new Toast(getApplicationContext());
// 设置位置
tempToast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER, 0, 0);
// 设置显示时间
tempToast.setDuration(Toast.LENGTH_SHORT);
tempToast.setView(layout);
tempToast.show();
}
}

  3.显示:

   刚才在friend里面我们对工具类进行了实例化,传入了handler,就是要在工具类用handler回调,用friend的handler进行处理:

  

 if(isHome(context)){
sendToast(msg,s1);
}

  如果在桌面:

 private void sendToast(Message msg,String s1){
android.os.Message message_send = new android.os.Message();
Bundle bundle = new Bundle();
bundle.putString("name",s1);
bundle.putString("text",msg.getBody());
message_send.obj = bundle;
message_send.what = 0;
handlers.sendMessage(message_send);
}

  打包名字,信息发到friend的handler里去。

  

  public  Handler mhandler = new Handler()
{
public void handleMessage(android.os.Message message)
{
switch (message.what) {
case 0:
Bundle bundle = (Bundle)message.obj; //桌面Toast的解决方法
String s1 = bundle.getString("name");
String s2 = bundle.getString("text");
showCustomToast(s1,s2);
break;
case 1: {
String temp = (String) message.obj;
friend.mArrayAdapter.add(temp);
break;
}
}
}
};

  friend的Handler里处理一下,就能显示出来了。

  这一次就说这么多吧,整个Demo已经能像正常的IM应用一样使用了,还有一些自己的修改方法,在下一篇的后续里会增加加好友啊,

加组,转入server里的一系列方法,敬请期待!

   喜欢就点赞吧!!!