本地化之章!
往期传送门:
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
真没想到这东西居然还会写到第七篇,很多亲们的反馈和鼓励给了我很大的动力啊,最近正好朋友也在做这个东西,但是我们用一样的库和后端做的东西居然不一样(他用这个做了联网弹幕!images/loading.gif' data-original="http://img.baidu.com/hi/jx2/j_0059.gif" />),不过确实发现了一些问题比如asmack的库内容参差不齐,很多提供方法都不一样,看来使用者们都或多或少的对源码进行了一些修改,都变得乱糟糟的呢!
这里就提供一下我自己用的asmack库吧,省的大家用的不一样:http://files.cnblogs.com/files/lfkdsk/asmack.zip
这次的博文先从完成的效果开始吧,这个并不是最终稿,因为虽然完成了很多的功能啊,但是还有一些问题,比如接收数据没用广播啊,监听的ChatListener没放在server里啊,好友系统并不完善啊,很多的东西还没有完成,到时候还要根据这些东西进行一些修改,但是现在需要的功能已经够用了,接着的那些东西也不过是要应用asmack库里的东西而已了,好了先上效果图:
(1.首先登录界面增加了Ip的选项,更具有Spark的android版的感觉,通用性强了,不过我之后要是想上线让大家用可能会删掉)
(2.现在不打开具体的聊天窗口,程序也不会蹦了,因为原来是直接向listview里面添加数据,可是listview还没初始化所以会崩)
(3.打开具体的useractivity就会取出原来的数据然后还有新打印的出来的)
(4.信息由于是走数据库了,所以分发也不会想原来一样出错了)
(5.我不想用传统的通知栏,那个用户能禁用,哈哈哈哈哈哈哈,我用了定制的Toast,在桌面的时候接到消息就会弹出一个Toast提示!)
好了这就是我们本次要达成的效果,让我们一个一个来!
1.首先从主界面的输入IP开始:
1 <TableRow> 2 <TextView 3 android:textColor="#ffc2c6c6" 4 android:layout_height="wrap_content" 5 android:text="Ip"/> 6 <EditText 7 android:id="@+id/login_ip" 8 android:hint="Input your Ip" 9 android:maxLines="1"10 android:layout_height="wrap_content"11 />12 </TableRow>
先在TableLayout里添加。
静态数据类里添加:
1 //ip名称2 public static String My_Ip = "";
主活动的添加:
ip = (EditText) findViewById(R.id.login_ip);
check_init()函数里添加:
1 private void checkbox_init() {//checkbox判断函数 2 //判断记住密码多选框的状态 3 if(sp.getBoolean("ISCHECK", false)) 4 { 5 //设置默认是记录密码状态 6 check_save.setChecked(true); 7 ip.setText(sp.getString("USER_IP", "")); 8 name.setText(sp.getString("USER_NAME","")); 9 password.setText(sp.getString("PASSWORD",""));10 //判断自动登陆多选框状态11 if(sp.getBoolean("AUTO_ISCHECK", false))12 {13 //设置默认是自动登录状态14 check_auto.setChecked(true);15 //跳转界面16 //account=sp.getString("USER_NAME","");17 //pwd=sp.getString("PASSWORD","");18 Log.i("======================"+account,pwd+"===================================");19 accountLogin();20 }21 }22 }23 private void setCheck_save(){24 if(check_save.isChecked())25 {26 //记住用户名、密码、27 editor = sp.edit();28 editor.putString("USER_IP", user.My_Ip);29 editor.putString("USER_NAME", account);30 editor.putString("PASSWORD",pwd);31 editor.apply();32 }33 }
这个是把Ip添加进记录。
修改登录的方法:
1 private void accountLogin() { 2 new Thread() { 3 public void run() { 4 user.My_Ip = ((EditText)findViewById(R.id.login_ip)) 5 .getText().toString(); 6 account = ((EditText) findViewById(R.id.login_name)) 7 .getText().toString(); 8 pwd = ((EditText) findViewById(R.id.login_password)).getText() 9 .toString();10 boolean is = ConnecMethod.login(account, pwd);11 if (is) {12 insHandler.sendEmptyMessage(1);13 // 将用户名保存14 user.UserName = account+"@lfkdsk/Spark 2.6.3";15 user.UserName_= account;16 setCheck_save();17 } else {18 insHandler.sendEmptyMessage(0);19 }20 }21 }.start();22 }
但是要是逐层的为函数添加参数,然后无限的传参也是一种不太现实的方法,所以我们在XMpp连接的地方直接调用静态存储的IP:
1 public static boolean openConnection() { 2 try { 3 connConfig = new ConnectionConfiguration(user.My_Ip, 5222); 4 // 设置登录状态为离线 5 connConfig.setSendPresence(false); 6 // 断网重连 7 connConfig.setReconnectionAllowed(true); 8 con = new XMPPConnection(connConfig); 9 con.connect();10 return true;11 } catch (Exception e) {12 13 }14 return false;15 }
这样我们登陆的时候就能手动指定ip或者是域名了,增强了通用性。
2.本地化数据的具体操作:
1.新建一个类作为本地数据库的模版:
1 package com.lfk.webim.appli; 2 3 import android.util.Log; 4 5 /** 6 * Created by Administrator on 2015/5/26. 7 */ 8 public class TalkLogs { 9 private String ID = "_id"; //数据库主键,自增10 private String With_Id ="with_id"; //和谁聊天11 private String Logs = "talklogs"; //聊天记录12 private String If_read = "_ifread"; //是否已读13 private String dbname; //数据表名---为用户名,即user.UserName_14 private String CREAT_DB = ""; //数据库新建的语句15 16 public TalkLogs(String dbname){17 this.dbname = dbname;18 giveanameto(dbname);19 Log.e("dbname=====", this.dbname);20 Log.e("dbname参数=====",dbname);21 }22 private void giveanameto(String dbname){23 CREAT_DB = "CREATE TABLE if not exists "+dbname+"("24 +this.ID +" integer primary key autoincrement,"25 +this.With_Id+","26 +this.If_read+" integer,"27 + this.Logs+")";28 }29 public String returnAString(){30 Log.e("CREAT_DB===========",CREAT_DB);31 return CREAT_DB;32 }33 }
1 package com.lfk.webim.appli; 2 3 import android.content.Context; 4 import android.database.sqlite.SQLiteDatabase; 5 import android.database.sqlite.SQLiteOpenHelper; 6 import android.widget.Toast; 7 8 /** 9 * Created by Administrator on 2015/5/25.10 */11 public class SQLiteHelper extends SQLiteOpenHelper {12 private Context mcontext;13 public SQLiteHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {14 super(context, name, factory, version);15 mcontext = context;16 }17 @Override18 public void onCreate(SQLiteDatabase db) {19 //db.execSQL(CREAT_DB);20 Toast.makeText(mcontext, "succeed collect!", Toast.LENGTH_SHORT).show();21 }22 23 @Override24 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {25 }26 }
写一个空的SQLiteHelper,把表放在后面。
代码里做了详细的注释,类里面传入用户名,返回新建表的String语句。
1 public void CreateNewTable(){2 sqLiteHelper = new SQLiteHelper(this,"user_logs.db",null,1); //新建.db文件3 sqLiteDatabase = sqLiteHelper.getWritableDatabase(); 4 TalkLogs talklog = new TalkLogs(user.UserName_); //获取新建表的语句5 sqLiteDatabase.execSQL(talklog.returnAString()); //新建表6 Toast.makeText(friend.this, user.UserName_+" Create success",Toast.LENGTH_SHORT).show();7 Log.e(user.UserName_, "success!!!");8 //sqLiteDatabase.close();9 }
在friend的activity里面,新建该方法,每次进入朋友界面,新建以用户名为名的表,因为用的SQL语句写了if exist 所以已有的不会新建。
1 final ClientConServer server = new ClientConServer(this,mhandler,this.sqLiteDatabase);
对工具类进行实例化,可以解决静态方法不能用在非静态上下文的问题,这里传入context,handler,和数据库,数据库是为了防止打开重复,传入handler是为了桌面Toast
2.修改后的friend活动:
1 package com.lfk.webim; 2 3 import android.content.Intent; 4 import android.database.sqlite.SQLiteDatabase; 5 import android.os.Bundle; 6 import android.os.Handler; 7 import android.support.v4.widget.SwipeRefreshLayout; 8 import android.util.Log; 9 import android.view.Gravity; 10 import android.view.KeyEvent; 11 import android.view.LayoutInflater; 12 import android.view.View; 13 import android.view.ViewGroup; 14 import android.widget.AdapterView; 15 import android.widget.ArrayAdapter; 16 import android.widget.ImageView; 17 import android.widget.ListView; 18 import android.widget.TextView; 19 import android.widget.Toast; 20 21 import com.lfk.webim.appli.BaseActivity; 22 import com.lfk.webim.appli.SQLiteHelper; 23 import com.lfk.webim.appli.TalkLogs; 24 import com.lfk.webim.appli.user; 25 import com.lfk.webim.server.Myserver; 26 import com.lfk.webim.server.connect; 27 28 29 public class friend extends BaseActivity { 30 public static ArrayAdapter<String> mArrayAdapter; 31 public SwipeRefreshLayout swipeLayout; 32 private SQLiteDatabase sqLiteDatabase; 33 private SQLiteHelper sqLiteHelper; 34 @Override 35 protected void onCreate(Bundle savedInstanceState) { 36 super.onCreate(savedInstanceState); 37 setContentView(R.layout.activity_friend); 38 39 CreateNewTable(); 40 final ClientConServer server = new ClientConServer(this,mhandler,this.sqLiteDatabase); 41 42 swipeLayout = (SwipeRefreshLayout)findViewById(R.id.swipe_refresh); 43 TextView textView=(TextView)findViewById(R.id.name); 44 textView.setText(user.UserName_ + "的朋友"); 45 46 Intent intentServer= new Intent(this, Myserver.class); 47 startService(intentServer); 48 49 final ListView listView=(ListView)findViewById(R.id.friend_list); 50 mArrayAdapter= new ArrayAdapter<String>(this, R.layout.list_item); 51 listView.setAdapter(mArrayAdapter); 52 53 //server.getFriends(); 54 //server.getChat(); 55 56 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 57 @Override 58 public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, 59 long arg3) { 60 String temp = (String) ((TextView) arg1).getText(); 61 Intent intent = new Intent(); 62 String temper = temp + "@lfkdsk/Smack"; 63 Log.e(temp + "================", temper); 64 user.FromName = temper; 65 user.FromName_ = temp; 66 intent.putExtra("FromName", temper); 67 intent.setClass(friend.this, useractivity.class); 68 startActivity(intent); 69 Toast.makeText(getApplicationContext(), 70 "Chat with " + temp, 71 Toast.LENGTH_SHORT).show(); 72 mArrayAdapter.notifyDataSetChanged(); 73 } 74 }); 75 76 swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { 77 @Override 78 public void onRefresh() { 79 new Handler().postDelayed(new Runnable() {//延迟跳转=-= 80 public void run() { 81 swipeLayout.setRefreshing(true); 82 mArrayAdapter.clear(); 83 server.getFriends(); 84 swipeLayout.setRefreshing(false); 85 } 86 }, 500); 87 } 88 }); 89 } 90 91 public void CreateNewTable(){ 92 sqLiteHelper = new SQLiteHelper(this,"user_logs.db",null,1); //新建.db文件 93 sqLiteDatabase = sqLiteHelper.getWritableDatabase(); 94 TalkLogs talklog = new TalkLogs(user.UserName_); //获取新建表的语句 95 sqLiteDatabase.execSQL(talklog.returnAString()); //新建表 96 Toast.makeText(friend.this, user.UserName_+" Create success",Toast.LENGTH_SHORT).show(); 97 Log.e(user.UserName_, "success!!!"); 98 //sqLiteDatabase.close(); 99 }100 public Handler mhandler = new Handler()101 {102 public void handleMessage(android.os.Message message)103 {104 switch (message.what) {105 case 0:106 Bundle bundle = (Bundle)message.obj; //桌面Toast的解决方法107 String s1 = bundle.getString("name");108 String s2 = bundle.getString("text");109 showCustomToast(s1,s2);110 break;111 case 1: {112 String temp = (String) message.obj;113 friend.mArrayAdapter.add(temp);114 break;115 }116 }117 }118 };119 protected void onDestroy()120 {121 super.onDestroy();122 connect.closeConnection();123 Intent stopintent=new Intent(this, Myserver.class);124 stopService(stopintent);125 }126 private long exitTime = 0;127 @Override128 public boolean onKeyDown(int keyCode, KeyEvent event) {129 if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){130 Intent home = new Intent(Intent.ACTION_MAIN);131 home.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);132 home.addCategory(Intent.CATEGORY_HOME);133 startActivity(home);134 return true;135 }136 return super.onKeyDown(keyCode, event);137 }138 public void showCustomToast(String s1, String s2) {//新建显示TOAST139 // 通用的布局加载器140 LayoutInflater inflater = getLayoutInflater();141 // 加载根容器,方便用于后面的view的定位142 View layout = inflater.inflate(R.layout.toast_view, (ViewGroup)findViewById(R.id.llToast));143 // 设置图片的源文件144 ImageView image = (ImageView) layout.findViewById(R.id.tvImageToast);145 image.setImageResource(R.drawable.toast_image);146 // 设置title及内容147 TextView title = (TextView) layout.findViewById(R.id.tvTitleToast);148 title.setText(s1);149 TextView text = (TextView) layout.findViewById(R.id.tvTextToast);150 text.setText(s2);151 Toast tempToast = new Toast(getApplicationContext());152 // 设置位置153 tempToast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER, 0, 0);154 // 设置显示时间155 tempToast.setDuration(Toast.LENGTH_SHORT);156 tempToast.setView(layout);157 tempToast.show();158 }159 }
friend活动
3.工具类进行了很大的修改,详细讲解:
1 package com.lfk.webim; 2 3 import android.app.ActivityManager; 4 import android.content.ComponentName; 5 import android.content.ContentValues; 6 import android.content.Context; 7 import android.content.Intent; 8 import android.content.pm.PackageManager; 9 import android.content.pm.ResolveInfo; 10 import android.database.Cursor; 11 import android.database.sqlite.SQLiteDatabase; 12 import android.os.Bundle; 13 import android.os.Handler; 14 import android.util.Log; 15 16 import com.lfk.webim.appli.user; 17 import com.lfk.webim.server.connect; 18 19 import org.jivesoftware.smack.Chat; 20 import org.jivesoftware.smack.ChatManager; 21 import org.jivesoftware.smack.ChatManagerListener; 22 import org.jivesoftware.smack.MessageListener; 23 import org.jivesoftware.smack.Roster; 24 import org.jivesoftware.smack.RosterEntry; 25 import org.jivesoftware.smack.RosterGroup; 26 import org.jivesoftware.smack.packet.Message; 27 28 import java.util.ArrayList; 29 import java.util.Collection; 30 import java.util.List; 31 32 33 public class ClientConServer { 34 private Context context; 35 private Handler handlers; 36 private SQLiteDatabase sqLiteDatabase; 37 38 ClientConServer(Context context,Handler handler,SQLiteDatabase sqLiteDatabase){ 39 this.context = context; 40 this.handlers = handler; 41 this.sqLiteDatabase = sqLiteDatabase; 42 getFriends(); 43 getChat(); 44 System.out.print(isAppForground(context)); 45 } 46 //这里收到消息 47 private Handler handler = new Handler(){ 48 public void handleMessage(android.os.Message m) { 49 Message msg = new Message(); 50 msg = (Message) m.obj; 51 //把从服务器获得的消息通过发送 52 String[] message = new String[]{ msg.getFrom(), msg.getBody()}; 53 System.out.println("==========收到消息 From==========="+ message[0]); 54 System.out.println("==========收到消息 Body===========" + message[1]); 55 String s = msg.getFrom(); 56 String s1 = s.split("@")[0]; 57 ContentValues values = new ContentValues(); 58 if(message[1]!=null) { 59 if (user.UserName.equals(message[0])) { 60 values.put("with_id",s1); 61 values.put("talklogs", "ME: " + msg.getBody()); 62 values.put("_ifread",0); 63 Log.e("存入:", "ME: " + msg.getBody()); 64 sqLiteDatabase.insert("\"" + user.UserName_ + "\"", null, values); 65 values.clear(); 66 } else { 67 values.put("with_id", s1); 68 values.put("talklogs", s1 + "说:" + msg.getBody()); 69 values.put("_ifread", 0); 70 Log.e("存入:", s1 + "说:" + msg.getBody()); 71 sqLiteDatabase.insert("\"" + user.UserName_ + "\"", null, values); 72 addUnread(values,s1); 73 } 74 if(isHome(context)){ 75 sendToast(msg,s1); 76 } 77 } 78 } 79 }; 80 public void getFriends(){ 81 //获取用户组、成员信息 82 System.out.println("--------find start----------"); 83 Roster roster = connect.con.getRoster(); 84 Collection<RosterGroup> entriesGroup = roster.getGroups(); 85 System.out.println("team:" + entriesGroup.size()); 86 for(RosterGroup group: entriesGroup){ 87 Collection<RosterEntry> entries = group.getEntries(); 88 int temp=group.getEntryCount(); 89 System.out.println("--------groupnumber--------" + "\n" + temp); 90 System.out.println("--------groupName----------" + "\n" + group.getName()); 91 for (RosterEntry entry : entries) { 92 System.out.println("name:"+entry.getName()); 93 String string2 = entry.getName(); 94 android.os.Message message_list = new android.os.Message(); 95 message_list.obj = string2; 96 message_list.what = 1; 97 handlers.sendMessage(message_list); 98 } 99 }100 System.out.println("--------find end--------");101 }102 private void addUnread(ContentValues values,String s1){103 if (isAppForground(context)&& s1.equals(user.FromName_)) {104 Cursor cursor = sqLiteDatabase.rawQuery("Select * From "+user.UserName_+" where with_id ="+"\""+user.FromName_+"\""+"And _ifread ="+0,null);105 if(cursor.moveToFirst()) {106 do {107 String talklogs = cursor.getString(cursor.getColumnIndex("talklogs"));108 useractivity.mConversationArrayAdapter.add(talklogs);109 Log.e(talklogs, "================");110 }while (cursor.moveToNext());111 }112 if(!isAppForground(context))113 useractivity.mConversationArrayAdapter.notifyDataSetChanged();114 cursor.close();115 }116 values.clear();117 }118 private void sendToast(Message msg,String s1){119 android.os.Message message_send = new android.os.Message();120 Bundle bundle = new Bundle();121 bundle.putString("name",s1);122 bundle.putString("text",msg.getBody());123 message_send.obj = bundle;124 message_send.what = 0;125 handlers.sendMessage(message_send);126 }127 private void getChat(){128 //在登陆以后应该建立一个监听消息的**,用来监听收到的消息:129 ChatManager chatManager = connect.con.getChatManager();130 chatManager.addChatListener(new MyChatManagerListener());131 }132 /** message listener*/133 class MyChatManagerListener implements ChatManagerListener {134 public void chatCreated(Chat chat, boolean arg1) {135 chat.addMessageListener(new MessageListener(){136 @Override137 public void processMessage(Chat chat, Message msg) {138 android.os.Message m = handler.obtainMessage();139 m.obj = msg;140 m.sendToTarget();141 }142 });143 }144 }145 public boolean isAppForground(Context mContext) {146 ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);147 List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);148 if (!tasks.isEmpty()) {149 ComponentName topActivity = tasks.get(0).topActivity;150 if (!topActivity.getPackageName().equals(mContext.getPackageName())) {151 return false;152 }153 }154 return true;155 }156 public boolean isHome(Context mContext){157 ActivityManager mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);158 List<ActivityManager.RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);159 return getHomes(mContext).contains(rti.get(0).topActivity.getPackageName());160 }161 /**162 * 获得属于桌面的应用的应用包名称163 * @return 返回包含所有包名的字符串列表164 */165 private List<String> getHomes(Context mContext) {166 List<String> names = new ArrayList<String>();167 PackageManager packageManager = mContext.getPackageManager();168 //属性169 Intent intent = new Intent(Intent.ACTION_MAIN);170 intent.addCategory(Intent.CATEGORY_HOME);171 List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intent,172 PackageManager.MATCH_DEFAULT_ONLY);173 for(ResolveInfo ri : resolveInfo){174 names.add(ri.activityInfo.packageName);175 System.out.println(ri.activityInfo.packageName);176 }177 return names;178 }179 }
工具类
1 ClientConServer(Context context,Handler handler,SQLiteDatabase sqLiteDatabase){2 this.context = context;3 this.handlers = handler;4 this.sqLiteDatabase = sqLiteDatabase;5 getFriends();6 getChat();7 System.out.print(isAppForground(context));8 }
3.1构造函数,用于实例化。
1 private void addUnread(ContentValues values,String s1){ 2 if (isAppForground(context)&& s1.equals(user.FromName_)) { 3 Cursor cursor = sqLiteDatabase.rawQuery("Select * From "+user.UserName_+" where with_id ="+"\""+user.FromName_+"\""+"And _ifread ="+0,null); 4 if(cursor.moveToFirst()) { 5 do { 6 String talklogs = cursor.getString(cursor.getColumnIndex("talklogs")); 7 useractivity.mConversationArrayAdapter.add(talklogs); 8 Log.e(talklogs, "================"); 9 }while (cursor.moveToNext());10 }11 if(!isAppForground(context))12 useractivity.mConversationArrayAdapter.notifyDataSetChanged();13 cursor.close();14 }15 values.clear();16 }
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就是重要的消息分发机制:
1 private Handler handler = new Handler(){ 2 public void handleMessage(android.os.Message m) { 3 Message msg = new Message(); 4 msg = (Message) m.obj; 5 //把从服务器获得的消息通过发送 6 String[] message = new String[]{ msg.getFrom(), msg.getBody()}; 7 System.out.println("==========收到消息 From==========="+ message[0]); 8 System.out.println("==========收到消息 Body===========" + message[1]); 9 String s = msg.getFrom();10 String s1 = s.split("@")[0];11 ContentValues values = new ContentValues();12 if(message[1]!=null) {13 if (user.UserName.equals(message[0])) {14 values.put("with_id",s1);15 values.put("talklogs", "ME: " + msg.getBody());16 values.put("_ifread",0);17 Log.e("存入:", "ME: " + msg.getBody());18 sqLiteDatabase.insert("\"" + user.UserName_ + "\"", null, values);19 values.clear();20 } else {21 values.put("with_id", s1);22 values.put("talklogs", s1 + "说:" + msg.getBody());23 values.put("_ifread", 0);24 Log.e("存入:", s1 + "说:" + msg.getBody());25 sqLiteDatabase.insert("\"" + user.UserName_ + "\"", null, values);26 addUnread(values,s1);27 }28 if(isHome(context)){29 sendToast(msg,s1);30 }31 }32 }33 };
4.改进后的聊天界面:
1 package com.lfk.webim; 2 3 import android.content.ContentValues; 4 import android.database.Cursor; 5 import android.database.sqlite.SQLiteDatabase; 6 import android.os.Bundle; 7 import android.os.Environment; 8 import android.os.Handler; 9 import android.util.Log; 10 import android.view.View; 11 import android.widget.ArrayAdapter; 12 import android.widget.Button; 13 import android.widget.EditText; 14 import android.widget.ListView; 15 import android.widget.TextView; 16 import android.widget.Toast; 17 18 import com.lfk.webim.appli.BaseActivity; 19 import com.lfk.webim.appli.user; 20 import com.lfk.webim.server.connect; 21 22 import org.jivesoftware.smack.Chat; 23 import org.jivesoftware.smack.ChatManager; 24 import org.jivesoftware.smack.MessageListener; 25 import org.jivesoftware.smack.XMPPConnection; 26 import org.jivesoftware.smack.XMPPException; 27 import org.jivesoftware.smack.packet.Message; 28 29 import java.io.File; 30 31 public class useractivity extends BaseActivity { 32 private ListView listView; 33 public static ArrayAdapter<String> mConversationArrayAdapter; 34 private ClientConServer server; 35 private SQLiteDatabase database; 36 @Override 37 protected void onCreate(Bundle savedInstanceState) { 38 super.onCreate(savedInstanceState); 39 setContentView(R.layout.useractivity); 40 41 getActionBar().setDisplayHomeAsUpEnabled(true); 42 43 //server = (ClientConServer)getIntent().getSerializableExtra("ClientConServer"); 44 45 listView = (ListView) findViewById(R.id.in); 46 TextView textView = (TextView) findViewById(R.id.username); 47 textView.setText("Talk with "+user.FromName_); 48 49 mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message); 50 listView.setAdapter(mConversationArrayAdapter); 51 52 OpenDatabase(); 53 54 //server = new ClientConServer(mhandle); 55 56 Button button = (Button)findViewById(R.id.button_send); 57 58 button.setOnClickListener(new View.OnClickListener() { 59 @Override 60 public void onClick(View v) { 61 EditText input = (EditText) findViewById(R.id.edit_text_out); 62 final String content = input.getText().toString(); 63 String string = "ME" + ":" + content; 64 android.os.Message mm = new android.os.Message(); 65 mm.what = 0; 66 mm.obj = content; 67 try { 68 XMPPConnection connection = connect.getConnection(); 69 ChatManager cm = connection.getChatManager(); 70 Chat chat = cm.createChat(user.FromName, new MessageListener() { 71 @Override 72 public void processMessage(Chat chat, Message msg) { 73 msg.setBody(content); 74 Log.i("---", msg.getFrom() + "说:" + msg.getBody()); 75 //添加消息到聊天窗口 76 } 77 }); 78 if (content.equals("")) { 79 mm.what = 1; 80 mhandle.handleMessage(mm); 81 } else { 82 mhandle.handleMessage(mm); 83 chat.sendMessage(content); 84 } 85 input.setText(""); 86 } catch (XMPPException e) { 87 e.printStackTrace(); 88 } 89 } 90 91 }); 92 } 93 public Handler mhandle = new Handler() { 94 public void handleMessage(android.os.Message m) { 95 switch (m.what) { 96 case 1: 97 Toast.makeText(useractivity.this, "不能发送空消息", Toast.LENGTH_SHORT).show(); 98 break; 99 case 0:100 String respond = (String) m.obj;101 Log.i("---", respond);102 ContentValues values = new ContentValues();103 values.put("with_id",user.FromName_);104 values.put("talklogs","ME: "+respond);105 values.put("_ifread",0);106 Log.e("存入:", "ME: " + respond);107 database.insert("\"" + user.UserName_ + "\"", null, values);108 values.clear();109 mConversationArrayAdapter.add("ME: "+respond);110 mConversationArrayAdapter.notifyDataSetChanged();111 break;112 case 2:113 //addTheListview();114 break;115 }116 }117 };118 private void OpenDatabase(){119 String DB_NAME = "user_logs.db"; //保存的数据库文件名120 String PACKAGE_NAME = "com.lfk.webim";// 应用的包名121 String DB_PATH = "/data"122 + Environment.getDataDirectory().getAbsolutePath() +"/"123 + PACKAGE_NAME+ "/databases"; // 在手机里存放数据库的位置124 File myDataPath = new File(DB_PATH);125 String dbfile = myDataPath+"/"+DB_NAME;126 database = SQLiteDatabase.openOrCreateDatabase(dbfile, null);127 if(!checkColumnExist1(database,user.UserName_,user.FromName_)){128 Cursor cursor = database.rawQuery("Select * From "+user.UserName_+" where with_id ="+"\""+user.FromName_+"\"",null);129 if(cursor.moveToFirst()) {130 do {131 String talklogs = cursor.getString(cursor.getColumnIndex("talklogs"));132 mConversationArrayAdapter.add(talklogs);133 Log.e(talklogs, "================");134 }while (cursor.moveToNext());135 }136 database.execSQL("UPDATE "+user.UserName_+" SET _ifread = 1 "+"Where with_id ="+"\""+user.FromName_+"\"");137 cursor.close();138 //database.close();139 }140 }141 public static boolean checkColumnExist1(SQLiteDatabase db, String tableName, String columnName) {142 boolean result = false ;143 Cursor cursor = null ;144 try{145 //查询一行146 cursor = db.rawQuery( "SELECT * FROM " + tableName + " LIMIT 0", null );147 result = cursor != null && cursor.getColumnIndex(columnName) != -1 ;148 }catch (Exception e){149 Log.e("","checkColumnExists1..." + e.getMessage()) ;150 }finally{151 if(null != cursor && !cursor.isClosed()){152 cursor.close() ;153 }154 }155 return result ;156 }157 }
聊天活动
1 private void OpenDatabase(){ 2 String DB_NAME = "user_logs.db"; //保存的数据库文件名 3 String PACKAGE_NAME = "com.lfk.webim";// 应用的包名 4 String DB_PATH = "/data" 5 + Environment.getDataDirectory().getAbsolutePath() +"/" 6 + PACKAGE_NAME+ "/databases"; // 在手机里存放数据库的位置 7 File myDataPath = new File(DB_PATH); 8 String dbfile = myDataPath+"/"+DB_NAME; 9 database = SQLiteDatabase.openOrCreateDatabase(dbfile, null);10 if(!checkColumnExist1(database,user.UserName_,user.FromName_)){11 Cursor cursor = database.rawQuery("Select * From "+user.UserName_+" where with_id ="+"\""+user.FromName_+"\"",null);12 if(cursor.moveToFirst()) {13 do {14 String talklogs = cursor.getString(cursor.getColumnIndex("talklogs"));15 mConversationArrayAdapter.add(talklogs);16 Log.e(talklogs, "================");17 }while (cursor.moveToNext());18 }19 database.execSQL("UPDATE "+user.UserName_+" SET _ifread = 1 "+"Where with_id ="+"\""+user.FromName_+"\"");20 cursor.close();21 //database.close();22 }23 }
每次进入都先打开数据库,并且把所有的聊天对应的人的数据库信息取出来,然后把所有的已读标志设为1;
1 public static boolean checkColumnExist1(SQLiteDatabase db, String tableName, String columnName) { 2 boolean result = false ; 3 Cursor cursor = null ; 4 try{ 5 //查询一行 6 cursor = db.rawQuery( "SELECT * FROM " + tableName + " LIMIT 0", null ); 7 result = cursor != null && cursor.getColumnIndex(columnName) != -1 ; 8 }catch (Exception e){ 9 Log.e("","checkColumnExists1..." + e.getMessage()) ;10 }finally{11 if(null != cursor && !cursor.isClosed()){12 cursor.close() ;13 }14 }15 return result ;16 }
这里用到了一个方法,用来判断表里有没有你的这个字段,如果没有就不用添加到listview里,否则你没和他聊过会崩!!
1 public Handler mhandle = new Handler() { 2 public void handleMessage(android.os.Message m) { 3 switch (m.what) { 4 case 1: 5 Toast.makeText(useractivity.this, "不能发送空消息", Toast.LENGTH_SHORT).show(); 6 break; 7 case 0: 8 String respond = (String) m.obj; 9 Log.i("---", respond);10 ContentValues values = new ContentValues();11 values.put("with_id",user.FromName_);12 values.put("talklogs","ME: "+respond);13 values.put("_ifread",0);14 Log.e("存入:", "ME: " + respond);15 database.insert("\"" + user.UserName_ + "\"", null, values);16 values.clear();17 mConversationArrayAdapter.add("ME: "+respond);18 mConversationArrayAdapter.notifyDataSetChanged();19 break;20 case 2:21 //addTheListview();22 break;23 }24 }25 };
在自己发送消息的时候,存入数据库,然后添加到listview里面。
3.桌面显示的Toast:
1 <? 2 <LinearLayout 3 android:id="@+id/llToast" 4 android:layout_width="wrap_content" 5 android:layout_height="wrap_content" 6 android:background="#ffffffff" 7 android:orientation="vertical" > 8 9 <TextView10 android:id="@+id/tvTitleToast"11 android:layout_width="match_parent"12 android:layout_height="wrap_content"13 android:layout_margin="1dip"14 android:background="#bb000000"15 android:gravity="center"16 android:text="Title"17 android:textColor="#ffffffff" />18 19 <LinearLayout20 android:id="@+id/llToastContent"21 android:layout_width="wrap_content"22 android:layout_height="wrap_content"23 android:layout_marginBottom="1dip"24 android:layout_marginLeft="1dip"25 android:layout_marginRight="1dip"26 android:background="#44000000"27 android:orientation="vertical"28 android:padding="15dip" >29 30 <ImageView31 android:id="@+id/tvImageToast"32 android:layout_width="wrap_content"33 android:layout_height="wrap_content"34 android:layout_gravity="center"35 android:contentDescription="@string/hello_world"36 android:src='/images/loading.gif' data-original="@drawable/toast_image" />37 38 <TextView39 android:id="@+id/tvTextToast"40 android:layout_width="128dp"41 android:layout_height="wrap_content"42 android:gravity="center"43 android:paddingLeft="10dip"44 android:paddingRight="10dip"45 android:singleLine="false"46 android:text="自定义显示语句"47 android:textColor="#ff000000" />48 </LinearLayout>49 50 </LinearLayout>
1.添加一个toast的布局文件,写出来的样子是这样的:
2.friend里面添加一个方法进行处理:
1 public void showCustomToast(String s1, String s2) {//新建显示TOAST 2 // 通用的布局加载器 3 LayoutInflater inflater = getLayoutInflater(); 4 // 加载根容器,方便用于后面的view的定位 5 View layout = inflater.inflate(R.layout.toast_view, (ViewGroup)findViewById(R.id.llToast)); 6 // 设置图片的源文件 7 ImageView image = (ImageView) layout.findViewById(R.id.tvImageToast); 8 image.setImageResource(R.drawable.toast_image); 9 // 设置title及内容10 TextView title = (TextView) layout.findViewById(R.id.tvTitleToast);11 title.setText(s1);12 TextView text = (TextView) layout.findViewById(R.id.tvTextToast);13 text.setText(s2);14 Toast tempToast = new Toast(getApplicationContext());15 // 设置位置16 tempToast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER, 0, 0);17 // 设置显示时间18 tempToast.setDuration(Toast.LENGTH_SHORT);19 tempToast.setView(layout);20 tempToast.show();21 }22 }
3.显示:
刚才在friend里面我们对工具类进行了实例化,传入了handler,就是要在工具类用handler回调,用friend的handler进行处理:
1 if(isHome(context)){2 sendToast(msg,s1);3 }
如果在桌面:
1 private void sendToast(Message msg,String s1){2 android.os.Message message_send = new android.os.Message();3 Bundle bundle = new Bundle();4 bundle.putString("name",s1);5 bundle.putString("text",msg.getBody());6 message_send.obj = bundle;7 message_send.what = 0;8 handlers.sendMessage(message_send);9 }
打包名字,信息发到friend的handler里去。
1 public Handler mhandler = new Handler() 2 { 3 public void handleMessage(android.os.Message message) 4 { 5 switch (message.what) { 6 case 0: 7 Bundle bundle = (Bundle)message.obj; //桌面Toast的解决方法 8 String s1 = bundle.getString("name"); 9 String s2 = bundle.getString("text");10 showCustomToast(s1,s2);11 break;12 case 1: {13 String temp = (String) message.obj;14 friend.mArrayAdapter.add(temp);15 break;16 }17 }18 }19 };
friend的Handler里处理一下,就能显示出来了。
这一次就说这么多吧,整个Demo已经能像正常的IM应用一样使用了,还有一些自己的修改方法,在下一篇的后续里会增加加好友啊,
加组,转入server里的一系列方法,敬请期待!
喜欢就点赞吧!!!
原标题:openfire+asmack搭建的安卓即时通讯(七) 15.5.27
关键词: