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

    本地化之章!

 往期传送门:

  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

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

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

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

    

blob.png

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

   

blob.png

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

blob.png

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

blob.png

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

                                                      blob.png    

(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     @Override
18     public void onCreate(SQLiteDatabase db) {
19         //db.execSQL(CREAT_DB);
20         Toast.makeText(mcontext, "succeed collect!", Toast.LENGTH_SHORT).show();
21     }
22 
23     @Override
24     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     @Override
128     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) {//新建显示TOAST
139         // 通用的布局加载器
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                 @Override
137                 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 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 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     <TextView
10         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     <LinearLayout
20         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         <ImageView
31             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="@drawable/toast_image" />
37 
38         <TextView
39             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里的一系列方法,敬请期待!

   喜欢就点赞吧!!!

  

posted @ 2015-05-27 21:29  刘丰恺  阅读(1384)  评论(0编辑  收藏  举报