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库吧,省的大家用的不一样:http://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的布局文件,写出来的样子是这样的:  

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

  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)