首页 > 代码库 > android 练习之路 (八)

android 练习之路 (八)

项目的github地址:https://github.com/Qunter/SearchAndCall

------------------------------------------------------------------------

图稍后再上,自带的虚拟机没办法初始化融云的服务,也是醉

今天使用Bmob来实现好友关系的存储,融云的IM来实现好友间的聊天

先做好准备工作,融云的依赖添加好,首先是下最新的kit包,然后导入两个module,并且添加依赖

技术分享

    //融云IM依赖
    compile project(‘:IMKit‘)

这里还有一些相关的设置,暂且不说,官网上有文档

这还不算完,因为这个程序里我们没有后台(竞赛提交作品要能直接演示,当然了,客观原因是我也不是很喜欢挂后台,挺麻烦的),所以我们得在客户端里实现后台的功能,所以我们需要导入一些融云的工具类

它们在哪下载呢,可以下载一个java的融云的后台demo,然后把其中的io.rong包复制过来,粘贴到项目里

技术分享

这就算把先头工作做的差不多了,然后一步一步来

还是类似上一个活动模块的布局样式

activity_friend_info_fragm.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.design.widget.TabLayout
        android:id="@+id/friendTabLayout"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        app:tabIndicatorColor="@android:color/black"/>
    <android.support.v4.view.ViewPager
        android:id="@+id/friendViewPaper"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>
</LinearLayout>

布局完了就是跟一个Activity

FriendInfoFragmActivity.java

public class FriendInfoFragmActivity extends Fragment {
    public static FriendInfoFragmActivity newInstance() {
        return new FriendInfoFragmActivity();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.activity_friend_info_fragm, container, false);
        //Fragment+ViewPager+FragmentViewPager组合的使用
        ViewPager viewPager = (ViewPager) view.findViewById(R.id.friendViewPaper);
        FriendPagerAdapter adapter = new FriendPagerAdapter(getActivity().getSupportFragmentManager(), getContext());
        viewPager.setAdapter(adapter);
        //TabLayout
        TabLayout tabLayout = (TabLayout) view.findViewById(R.id.friendTabLayout);
        tabLayout.setupWithViewPager(viewPager);
        return view;
    }
}

接着是建一个viewpager的adapter

FriendPagerAdapter.java

public class FriendPagerAdapter extends FragmentPagerAdapter {
    public final int COUNT = 2;
    private String[] titles = new String[]{"消息列表", "我的好友"};
    private Context context;
    private Fragment conversationList;
    private Fragment conversationFragment = null;
    public FriendPagerAdapter(FragmentManager fm, Context context) {
        super(fm);
        this.context = context;
    }

    @Override
    public Fragment getItem(int position) {
        if(position==0){
            conversationList = initConversationList();//获取融云会话列表的对象
            return conversationList;
        }else if(position==1){
            return FriendPageFragment.newInstance();
        }
        return null;
    }

    @Override
    public int getCount() {
        return COUNT;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return titles[position];
    }
    private Fragment initConversationList() {

        /**
         * appendQueryParameter对具体的会话列表做展示
         */
        if (conversationFragment == null) {
            ConversationListFragment listFragment = new ConversationListFragment();
            Uri uri = Uri.parse("rong://" + context.getPackageName()).buildUpon()
                    .appendPath("conversationList")
                    .appendQueryParameter(Conversation.ConversationType.PRIVATE.getName(), "false")//设置私聊会话是否聚合显示
                    .appendQueryParameter(Conversation.ConversationType.GROUP.getName(), "true")
                    // .appendQueryParameter(Conversation.ConversationType.PUBLIC_SERVICE.getName(), "false")//公共服务号
                    //.appendQueryParameter(Conversation.ConversationType.APP_PUBLIC_SERVICE.getName(), "false")//公共服务号
                    .appendQueryParameter(Conversation.ConversationType.DISCUSSION.getName(), "false")//设置私聊会话是否聚合显示
                    .appendQueryParameter(Conversation.ConversationType.SYSTEM.getName(), "false")//设置私聊会是否聚合显示
                    .build();
            listFragment.setUri(uri);
            return listFragment;
        } else {
            return conversationFragment;
        }
    }
}

左边是消息列表,这个用融云的消息列表,右边是好友列表,就需要我们自己定义了

从左至右吧

融云的消息列表

activity_conversation.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#000">

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_margin="15dp"
            android:text="rongCloud"
            android:textColor="#fff"
            android:textSize="18sp" />

    </LinearLayout>
    <fragment
        android:id="@+id/conversation"
        android:name="io.rong.imkit.fragment.ConversationFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


</LinearLayout>

然后是Activity

(不是我说,这个命名是真的有毒,这个类是从融云提供的demo上摘下来的,不过反正是他们内部实现的东西,先不改得了,忙完这两天再一起弄)

public class ConversationActivity extends FragmentActivity {

    private TextView mName;
    //private ImageView mPersionInformationIv;
    private Conversation.ConversationType mConversationType;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_conversation);
        Intent intent = getIntent();
        mConversationType = Conversation.ConversationType.valueOf(intent.getData().getLastPathSegment().toUpperCase(Locale.getDefault()));
        //Log.e("log", mConversationType.getName());
        mName = (TextView) findViewById(R.id.name);
        /*
        mPersionInformationIv = (ImageView) findViewById(R.id.persionInformationIv);
        if(mConversationType.getName().equals("private")){
            mPersionInformationIv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent mIntent = new Intent(getApplicationContext(),UserInformationPage.class);
                    Bundle bundle=new Bundle();
                    bundle.putString("userNickName", getIntent().getData().getQueryParameter("title"));
                    mIntent.putExtras(bundle);
                    startActivity(mIntent);
                }
            });
        }else if(mConversationType.getName().equals("discussion")){
            mPersionInformationIv.setVisibility(View.GONE);
        }
        */
        String sId = getIntent().getData().getQueryParameter("targetId");//targetId:单聊即对方ID,群聊即群组ID
        String sName = getIntent().getData().getQueryParameter("title");//获取昵称
        if (!TextUtils.isEmpty(sName)){
            mName.setText(sName);
        }else {
//            sId
            //TODO 拿到id 去请求自己服务端
        }
    }
}

然后这个界面注册的方式不一样,这里也贴一下,其实官方文档有写

     <!--会话界面-->
        <activity
            android:name=".activity.ConversationActivity"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="stateHidden|adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />

                <data
                    android:host="com.qunter.searchcall"
                    android:pathPrefix="/conversation/"
                    android:scheme="rong" />
            </intent-filter>
        </activity>

 然后就是好友列表的实现

activity_friend_list.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swipe_refresh_friend"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_friend"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:overScrollMode="never"
        android:scrollbars="vertical" />
</android.support.v4.widget.SwipeRefreshLayout>

item_friend_info.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView android:id="@+id/friend_card_view"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:layout_marginBottom="2dp"
    android:layout_marginTop="2dp"
    android:clickable="true"
    app:cardBackgroundColor="@color/card_view_background_dark"
    app:cardCornerRadius="0dp"
    app:cardElevation="2dp">

    <LinearLayout
        android:id="@+id/item_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/item_useravatar"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_marginLeft="30dp"
            android:layout_marginRight="10dp"
            android:scaleType="fitCenter"
            android:src="@drawable/account_avatar" />
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <TextView
                android:id="@+id/item_username"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:layout_marginEnd="10dp"
                android:lineSpacingExtra="2dp"
                android:maxLines="1"
                android:padding="2dp"
                android:textColor="@color/font_normal"
                android:textSize="18sp" />
        </RelativeLayout>


    </LinearLayout>
</android.support.v7.widget.CardView>

左边直接new一个融云的会话列表就行,但是右边需要自己写

FriendPageFragment.java

public class FriendPageFragment extends Fragment implements RongIM.UserInfoProvider{
    private SwipeRefreshLayout friendSwipeRefreshLayout;
    private FriendInfoListAdapter adapter;
    private List<UserInfo> loginUserFriendInfoList;
    private List<Friend> loginUserFriendRongList;
    private RecyclerView friendRecyclerView;
    private String loginUserFriendObjectID="";
    private final int GETLOGINUSERFRIENDOBJECTID=0x00,GETLOGINUSERFRIENDLIST=0x01,FRIENDINFORMATIONLISTDOWNOVER=0x02;
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case GETLOGINUSERFRIENDOBJECTID:
                    getLoginUserFriendObjectID();
                    break;
                case GETLOGINUSERFRIENDLIST:
                    getLoginUserFriendList();
                    break;
                case FRIENDINFORMATIONLISTDOWNOVER:
                    loadFriendRecycleView();
                    initUserInfo();
                    friendSwipeRefreshLayout.setRefreshing(false);
                    break;

            }
        }
    };
    public static FriendPageFragment newInstance() {
        FriendPageFragment fragment = new FriendPageFragment();
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.activity_friend_list,container,false);
        friendSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh_friend);
        friendSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                handler.sendEmptyMessage(GETLOGINUSERFRIENDLIST);
            }
        });
        friendRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_friend);
        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
        friendRecyclerView.setLayoutManager(layoutManager);
        handler.sendEmptyMessage(GETLOGINUSERFRIENDOBJECTID);
        return view;
    }
    /**
     * 获取用户好友列表的数据库表单中ID
     */
    private void getLoginUserFriendObjectID(){
        final BmobQuery<UserFriend> userObjectIDQuery = new BmobQuery<UserFriend>();
        userObjectIDQuery.addWhereEqualTo("userID", BmobUser.getCurrentUser(UserInfo.class).getUserPhone());
        userObjectIDQuery.findObjects(new FindListener<UserFriend>() {
            @Override
            public void done(List<UserFriend> object, BmobException e) {
                if(e==null){
                    loginUserFriendObjectID =object.get(0).getObjectId();
                    //Toast.makeText(getContext(), "loginUserFriendObjectID"+loginUserFriendObjectID, Toast.LENGTH_SHORT).show();
                    handler.sendEmptyMessage(GETLOGINUSERFRIENDLIST);
                }else{
                }
            }
        });

    }
    /**
     *获取用户好友列表数据
     */
    private void getLoginUserFriendList(){
        UserFriend userFriend = new UserFriend();
        // 查询好友列表内的所有用户,因此查询的是用户表
        BmobQuery<UserInfo> userFriendQuery = new BmobQuery<UserInfo>();
        userFriend.setObjectId(loginUserFriendObjectID);
        //userFriend是UserFriend表中的字段,用来存储所有该用户的好友关系的用户
        userFriendQuery.addWhereRelatedTo("userFriend", new BmobPointer(userFriend));
        userFriendQuery.findObjects(new FindListener<UserInfo>() {
            @Override
            public void done(List<UserInfo> object,BmobException e) {
                if(e==null){
                    loginUserFriendInfoList=object;
                    Log.e("taggg", loginUserFriendInfoList.size()+"" );
                    Log.e("taggg", loginUserFriendInfoList.get(0).getUserNickname()+"" );
                    //Toast.makeText(getContext(), "成功加载好友列表数据"+userFriendInformationList.size(), Toast.LENGTH_SHORT).show();
                    handler.sendEmptyMessage(FRIENDINFORMATIONLISTDOWNOVER);
                }else{
                    Toast.makeText(getContext(), "加载好友列表数据失败"+e, Toast.LENGTH_SHORT).show();
                }
            }

        });
    }
    /**
     * 加载好友信息至RecycleView
     */
    private void loadFriendRecycleView(){
        adapter = new FriendInfoListAdapter(getContext(),loginUserFriendInfoList,friendRecyclerView);
        adapter.setOnItemClickListener(new FriendInfoListAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                RongIM.getInstance().startPrivateChat(getContext(), loginUserFriendInfoList.get(position).getUserPhone(), loginUserFriendInfoList.get(position).getUserNickname());
            }
        });
        friendRecyclerView.setAdapter(adapter);
    }
    /**
     * 储存好友相关信息:id,昵称,token
     */
    private void initUserInfo() {
        loginUserFriendRongList = new ArrayList<Friend>();
        loginUserFriendRongList.add(new Friend(BmobUser.getCurrentUser(UserInfo.class).getUserPhone(),BmobUser.getCurrentUser(UserInfo.class).getUserNickname(),BmobUser.getCurrentUser(UserInfo.class).getUserAvatar()));
        for(UserInfo userFriendInfo:loginUserFriendInfoList){
            //好友内容为:id,昵称,头像url
            loginUserFriendRongList.add(new Friend(userFriendInfo.getUserPhone(),userFriendInfo.getUserNickname(),userFriendInfo.getUserAvatar()));
        }
        RongIM.setUserInfoProvider(this, true);
    }
    @Override
    public io.rong.imlib.model.UserInfo getUserInfo(String s) {
        for (Friend i : loginUserFriendRongList) {
            if (i.getUserId().equals(s)) {
                //Log.e(TAG, i.getPortraitUri());
                return new io.rong.imlib.model.UserInfo(i.getUserId(), i.getName(), Uri.parse(i.getPortraitUri()));
            }
        }
        return null;
    }
}

然后就需要写一个RecycleView的Adapter了

FriendInfoListAdapter.java

public class FriendInfoListAdapter extends RecyclerView.Adapter<FriendInfoListAdapter.ViewHolder>{
    private List<UserInfo> loginUserFriendInfoList;
    private Context context;
    private RecyclerView recyclerView;
    private OnItemClickListener onItemClickListener;

    static class ViewHolder extends RecyclerView.ViewHolder{
        private ImageView userAvatarImg;
        private TextView userNameTv;
        public ViewHolder(View view){
            super(view);
            userAvatarImg = (ImageView) view.findViewById(R.id.item_useravatar);
            userNameTv = (TextView) view.findViewById(R.id.item_username);
        }
    }
    public FriendInfoListAdapter(Context context,List<UserInfo> loginUserFriendInfoList,RecyclerView recyclerView){
        this.context = context;
        this.loginUserFriendInfoList = loginUserFriendInfoList;
        this.recyclerView = recyclerView;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_friend_info,parent,false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(final FriendInfoListAdapter.ViewHolder holder, final int position) {
        holder.setIsRecyclable(false);
        final UserInfo friendInfo = loginUserFriendInfoList.get(position);
        Glide.with(context).load(friendInfo.getUserAvatar()).bitmapTransform(new CropCircleTransformation(context)).into(holder.userAvatarImg);
        holder.userNameTv.setText(friendInfo.getUserNickname());
        if(onItemClickListener != null){
            //为ItemView设置监听器
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = holder.getLayoutPosition();
                    onItemClickListener.onItemClick(holder.itemView,position);
                }
            });
        }
    }
    @Override
    public int getItemCount() {
        return loginUserFriendInfoList.size();
    }
    /**
     * 点击事件接口
     */
    public interface OnItemClickListener{
        void onItemClick(View view, int position);
    }

    /**
     * 设置点击事件方法
     */
    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemClickListener = onItemClickListener;
    }
}

然后回头看一眼,首先在MainActivity里应该初始化融云的服务

        RongIM.init(this);
        initUserToken(); 
   /**
     * 获取融云所需userID及token
     */
    private void initUserToken(){
        UserInfo loginUser = BmobUser.getCurrentUser(UserInfo.class);
        userID = loginUser.getUserPhone();
        connectRongServer(loginUser.getRongToken());
    }

    /**
     * 初始化登录用户的融云服务
     */
    private void connectRongServer(String token) {

        RongIM.connect(token, new RongIMClient.ConnectCallback() {
            @Override
            public void onSuccess(String userId) {
                if (userId.equals(userID)){
                    Toast.makeText(getApplicationContext(), userID+"成功连接", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(getApplicationContext(), userID+"连接失败", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void one rror(RongIMClient.ErrorCode errorCode) {
                // Log.e("onError", "onError userid:" + errorCode.getValue());//获取错误的错误码
                Toast.makeText(getApplicationContext(), "Error", Toast.LENGTH_SHORT).show();
                Log.e("MainActivity", "connect failure errorCode is : " + errorCode.getValue());
            }


            @Override
            public void onTokenIncorrect() {
                Toast.makeText(getApplicationContext(), "TokenError", Toast.LENGTH_SHORT).show();
                Log.e("MainActivity", "token is error ,please check token and appkey");
            }
        });

    }

实体类也需要完善一下了,我们现在还有很多其他需要的字段,以及融云所需的好友实体

UserInfo.java

public class UserInfo extends BmobUser {
    private String userNickname;
    private String userPhone;
    private String rongToken;
    //用户头像,先设置初始头像
    private String userAvatar="http://bmob-cdn-8854.b0.upaiyun.com/2017/01/21/910615c0405f9bd280350b57f8dc180c.png";

    public String getUserNickname() {
        return userNickname;
    }

    public void setUserNickname(String userNickname) {
        this.userNickname = userNickname;
    }

    public String getUserPhone() {
        return userPhone;
    }

    public void setUserPhone(String userPhone) {
        this.userPhone = userPhone;
    }

    public String getRongToken() {
        return rongToken;
    }

    public void setRongToken(String rongToken) {
        this.rongToken = rongToken;
    }

    public String getUserAvatar() {
        return userAvatar;
    }

    public void setUserAvatar(String userAvatar) {
        this.userAvatar = userAvatar;
    }
}

UserFriend.java

public class UserFriend extends BmobObject {
    private String userID;
    private BmobRelation userFriend;


    public BmobRelation getUserFriend() {
        return userFriend;
    }

    public void setUserFriend(BmobRelation userFriend) {
        this.userFriend = userFriend;
    }

    public String getUserID() {
        return userID;
    }

    public void setUserID(String userID) {
        this.userID = userID;
    }
}

Friend.java

public class Friend {

    private String userId;
    private String name;
    private String portraitUri;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPortraitUri() {
        return portraitUri;
    }

    public void setPortraitUri(String portraitUri) {
        this.portraitUri = portraitUri;
    }

    public Friend(String userId, String name, String portraitUri) {
        this.userId = userId;
        this.name = name;
        this.portraitUri = portraitUri;
    }
}

行,然后把注册类完善一下

RegisterActivity.java

public class RegisterActivity extends BaseActivity implements View.OnClickListener{
    private EditText usernameEt,passwordEt,userPhoneEt,userNicknameEt;
    private Button registerBtn,loginBtn;
    private UserInfo userInformation;
    private String rongToken="",userID="";
    private final int ISREGISTER=0x00,GETRONGTOKEN=0x01,ALLSUCCESS=0x02,FAIL=0x03,BUILDUSERFRIENDLIST=0x04;
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case ISREGISTER:
                    isRegister();
                    break;
                case GETRONGTOKEN:
                    new getRongToken(userPhoneEt.getText().toString().trim(),userNicknameEt.getText().toString().trim()).start();
                    break;
                case BUILDUSERFRIENDLIST:
                    buildUserFriendList();
                    break;
                case ALLSUCCESS:
                    register();
                    break;
                case FAIL:
                    Toast.makeText(RegisterActivity.this,"获取Token失败  请检查网络和账号后重试", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    };
    @Override
    protected void initVariablesAndService() {
        setIfImmersive(true);
        Bmob.initialize(this,"8da888d03200ff2f6b403d064b805d60");
    }

    @Override
    protected void initViews(Bundle savedInstanceState) {
        setContentView(R.layout.activity_register);
        usernameEt = (EditText) findViewById(R.id.register_usernameEt);
        passwordEt = (EditText) findViewById(R.id.register_passwordEt);
        userPhoneEt = (EditText) findViewById(R.id.register_userPhoneEt);
        userNicknameEt = (EditText) findViewById(R.id.register_userNicknameEt);
        registerBtn = (Button) findViewById(R.id.register_registerBtn);
        registerBtn.setOnClickListener(this);
        loginBtn = (Button) findViewById(R.id.register_loginBtn);
        loginBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.register_registerBtn:
                userID = userPhoneEt.getText().toString().trim();
                handler.sendEmptyMessage(ISREGISTER);
                break;
            case R.id.register_loginBtn:
                startActivity(LoginActivity.class);
                this.finish();
                break;
        }
    }
    /**
     * 判断账号是否已被注册
     */
    private void isRegister(){
        String username = usernameEt.getText().toString().trim();
        BmobQuery<UserInfo> query = new BmobQuery<UserInfo>();
        query.addWhereEqualTo("username",username);
        query.findObjects(new FindListener<UserInfo>() {
            @Override
            public void done(List<UserInfo> list, BmobException e) {
                if (e==null&&list.size()==0){
                    handler.sendEmptyMessage(GETRONGTOKEN);
                }else {
                    Toast.makeText(RegisterActivity.this,"您的账号已被使用  请更换", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
    /**
     * 注册账号至bmob
     */
    private void register(){
        userInformation = new UserInfo();
        userInformation.setUsername(usernameEt.getText().toString().trim());
        userInformation.setPassword(passwordEt.getText().toString().trim());
        userInformation.setUserPhone(userPhoneEt.getText().toString().trim());
        userInformation.setUserNickname(userNicknameEt.getText().toString().trim());
        userInformation.setRongToken(rongToken);
        userInformation.signUp(new SaveListener<UserInfo>() {
            @Override
            public void done(UserInfo s, BmobException e) {
                if(e==null){
                    Toast.makeText(RegisterActivity.this,"注册成功", Toast.LENGTH_SHORT).show();
                    userInformation.login(new SaveListener<UserInfo>() {
                        @Override
                        public void done(UserInfo userInfo, BmobException e) {
                            if(e==null){
                                Toast.makeText(RegisterActivity.this,"登录成功", Toast.LENGTH_SHORT).show();
                                startActivity(MainActivity.class);
                                RegisterActivity.this.finish();
                            }
                        }
                    });
                }else{
                    Log.e("失败代码",e.toString());
                }

            }
        });
    }
    class getRongToken extends Thread{
        String userId;//定义线程内变量
        String name;
        User rongAppInformation = new User("cpj2xarlc68cn", "9gRSABvb08W3YC");//融云APP信息
        String Token = "";
        public getRongToken(String userId, String name){//定义带参数的构造函数,达到初始化线程内变量的值
            this.userId=userId;
            this.name=name;
        }
        @Override
        public void run() {
            try {
                //使用默认头像,但函数需要三参
                Token=rongAppInformation.getToken(userId,name,"http://bmob-cdn-8854.b0.upaiyun.com/2017/01/21/910615c0405f9bd280350b57f8dc180c.png").getToken();
                rongToken=Token ;//消息内容
                handler.sendEmptyMessage(BUILDUSERFRIENDLIST);
            } catch (Exception e) {
                e.printStackTrace();
                handler.sendEmptyMessage(FAIL);
            }
        }
    }
    /**
     * 如果用户此前没有生成好友列表的情况下,执行方法生成好友列表
     */
    private void buildUserFriendList(){
        String loginUserID = userID;
        UserFriend userFriend = new UserFriend();
        userFriend.setUserID(loginUserID);
        BmobRelation relation = new BmobRelation();
        userFriend.setUserFriend(relation);
        userFriend.save(new SaveListener<String>() {
            @Override
            public void done(String s, BmobException e) {
                if(e==null){
                    //Toast.makeText(getApplicationContext(), "执行", Toast.LENGTH_SHORT).show();
                    handler.sendEmptyMessage(ALLSUCCESS);
                }else{
                    //Toast.makeText(getApplicationContext(), e+"错误", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

然后还是要加个添加好友的页面,样式大概就先做到和之前的那个添加活动差不多吧

activity_friend_add.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:theme="@style/Theme.AppCompat.Light">
            <ImageView
                android:id="@+id/friend_add_backBtn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="left"
                android:src="@drawable/ic_arrow_back_black_36dp"/>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="添加好友"
                android:textSize="22sp"
                android:textColor="#dd000000" />
        </android.support.v7.widget.Toolbar>
    </android.support.design.widget.AppBarLayout>
    <LinearLayout
        android:id="@+id/friend_add_linearlayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <EditText
            android:id="@+id/friend_addEt"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:hint="请输入搜索用户的昵称"
            android:inputType="text" />
        <Button
            android:id="@+id/friend_addBtn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="搜索"/>
    </LinearLayout>

</LinearLayout>

FriendAddActivity.java

public class FriendAddActivity extends BaseActivity implements View.OnClickListener{
    private EditText friendAddEt;
    private TextView friendAddTv;
    private ImageView friendAddBackBtn;
    private LinearLayout friendAddLinLayout,friendAddAskView;
    private String loginUserFriendObjectID="",loginUserFriendFriendObjectID="";
    private UserInfo searchUser;
    private String searchUserAvatarUrl="",searchUserNickname="";
    //用于标记是否已显示用户信息
    private int flag = 0;
    final int ADDFRIENDASK = 0x00, DELFRIENDASK = 0x01, IFGETFRIENDLIST = 0x02, SEARCHUSERINFO = 0x03 ,SAVEUSERFRIENDLIST=0x04,GETFRIENDFRIENDOBJECT=0x05,SAVEFRIENDFRIENDLIST=0x06;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case IFGETFRIENDLIST:
                    searchUserFriendObjectId();
                    break;
                case SEARCHUSERINFO:
                    searchUserInfo(friendAddEt.getText().toString());
                    break;
                case ADDFRIENDASK:
                    if (flag == 1) {
                        friendAddLinLayout.removeView(friendAddAskView);
                        flag = 0;
                    }
                    friendAddLinLayout.addView(addFriendAddAskView(searchUserAvatarUrl, searchUserNickname));
                    flag = 1;
                    break;
                case SAVEUSERFRIENDLIST:
                    addFriend();
                    break;
                case DELFRIENDASK:
                    friendAddLinLayout.removeView(friendAddAskView);
                    break;
                case GETFRIENDFRIENDOBJECT:
                    searchFriendFriendInformation();
                    break;
                case SAVEFRIENDFRIENDLIST:
                    saveFriendFriendList();
                    break;
            }
        }
    };
    @Override
    protected void initVariablesAndService() {

    }
    @Override
    protected void initViews(Bundle savedInstanceState) {
        setContentView(R.layout.activity_friend_add);
        friendAddEt = (EditText) findViewById(R.id.friend_addEt);
        friendAddTv = (TextView) findViewById(R.id.friend_addBtn);
        friendAddBackBtn = (ImageView) findViewById(R.id.friend_add_backBtn);
        friendAddLinLayout = (LinearLayout) findViewById(R.id.friend_add_linearlayout);

        friendAddTv.setOnClickListener(this);
        friendAddBackBtn.setOnClickListener(this);
        handler.sendEmptyMessage(IFGETFRIENDLIST);
    }
    /**
     * bmob查询登录用户好友表ID
     */
    private void searchUserFriendObjectId() {
        final BmobQuery<UserFriend> query = new BmobQuery<UserFriend>();
        query.addWhereEqualTo("userID", BmobUser.getCurrentUser(UserInfo.class).getUserPhone());
        query.findObjects(new FindListener<UserFriend>() {
            @Override
            public void done(List<UserFriend> object, BmobException e) {
                if (e == null) {
                    loginUserFriendObjectID = object.get(0).getObjectId();
                }
            }
        });
    }
    /**
     * bmob查询某用户信息
     */
    private void searchUserInfo(String userNickname) {
        BmobQuery<UserInfo> query = new BmobQuery<UserInfo>();
        query.addWhereEqualTo("userNickname", userNickname);
        query.findObjects(new FindListener<UserInfo>() {
            @Override
            public void done(List<UserInfo> object, BmobException e) {
                if (e == null) {
                    searchUser = object.get(0);
                    searchUserAvatarUrl = searchUser.getUserAvatar();
                    searchUserNickname = searchUser.getUserNickname();
                    handler.sendEmptyMessage(ADDFRIENDASK);
                    //Toast.makeText(getApplicationContext(), user.getNickName()+"查询成功", Toast.LENGTH_SHORT).show();
                } else {
                    //Toast.makeText(getApplicationContext(), "查询失败"+e, Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
    /**
     * 动态生成是否添加好友(显示用户信息)的控件
     */
    private LinearLayout addFriendAddAskView(String searchUserAvatarUrl, String searchUserNickname) {
        friendAddAskView = new LinearLayout(this);
        friendAddAskView.setOrientation(LinearLayout.HORIZONTAL);
        LinearLayout.LayoutParams llparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        friendAddAskView.setLayoutParams(llparams);
        ImageView touxiang = new ImageView(this);
        Glide.with(getApplicationContext()).load(searchUserAvatarUrl).into(touxiang);
        LinearLayout.LayoutParams txparams = new LinearLayout.LayoutParams(100, 100);
        txparams.setMargins(30, 15, 15, 15);
        touxiang.setLayoutParams(txparams);
        LinearLayout.LayoutParams unparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        unparams.setMargins(30, 0, 30, 0);
        TextView userName = new TextView(this);
        userName.setText(searchUserNickname);
        userName.setLayoutParams(unparams);
        userName.setGravity(Gravity.CENTER_VERTICAL);
        LinearLayout.LayoutParams btnparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        btnparams.setMargins(30, 0, 30, 0);
        Button add = new Button(this);
        //add.setBackgroundResource(R.drawable.background_button);
        add.setTextColor(Color.WHITE);
        add.setGravity(Gravity.CENTER);
        add.setText("添加好友");
        add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                handler.sendEmptyMessage(SAVEUSERFRIENDLIST);
            }
        });
        add.setLayoutParams(btnparams);
        Button noAdd = new Button(this);
        //noAdd.setBackgroundResource(R.drawable.background_button);
        noAdd.setTextColor(Color.WHITE);
        noAdd.setGravity(Gravity.CENTER);
        noAdd.setText("取消");
        noAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                handler.sendEmptyMessage(DELFRIENDASK);
            }
        });
        noAdd.setLayoutParams(btnparams);
        friendAddAskView.addView(touxiang);
        friendAddAskView.addView(userName);
        friendAddAskView.addView(add);
        friendAddAskView.addView(noAdd);
        return friendAddAskView;
    }
    /**
     * 储存登录用户好友关系
     */
    private void addFriend(){
        UserFriend userFriend = new UserFriend();
        userFriend.setObjectId(loginUserFriendObjectID);
        BmobRelation relation = new BmobRelation();
        //将当前用户添加到多对多关联中
        relation.add(searchUser);
        //多对多关联指向`post`的`likes`字段
        userFriend.setUserFriend(relation);
        userFriend.update(new UpdateListener() {
            @Override
            public void done(BmobException e) {
                if (e == null) {
                    //Toast.makeText(getApplicationContext(), "更新登录用户好友列表成功", Toast.LENGTH_SHORT).show();
                    handler.sendEmptyMessage(GETFRIENDFRIENDOBJECT);
                } else {
                    //Toast.makeText(getApplicationContext(), e+"添加失败", Toast.LENGTH_SHORT).show();
                    Toast.makeText(getApplicationContext(), loginUserFriendObjectID, Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
    /**
     * bmob查询想添加为好友的用户的好友信息
     */
    private void searchFriendFriendInformation() {
        final BmobQuery<UserFriend> query = new BmobQuery<UserFriend>();
        query.addWhereEqualTo("userID", searchUser.getUserPhone());
        query.findObjects(new FindListener<UserFriend>() {
            @Override
            public void done(List<UserFriend> object, BmobException e) {
                if (e == null) {
                    loginUserFriendFriendObjectID = object.get(0).getObjectId();
                    handler.sendEmptyMessage(SAVEFRIENDFRIENDLIST);
                } else {

                }
            }
        });
    }
    /**
     * 储存好友用户好友关系
     */
    private void saveFriendFriendList(){
        UserFriend userFriend = new UserFriend();
        userFriend.setObjectId(loginUserFriendFriendObjectID);
        BmobRelation relation = new BmobRelation();
        //将当前用户添加到多对多关联中
        relation.add(BmobUser.getCurrentUser(UserInfo.class));
        //多对多关联指向`post`的`likes`字段
        userFriend.setUserFriend(relation);
        userFriend.update(new UpdateListener() {
            @Override
            public void done(BmobException e) {
                if (e == null) {
                    Toast.makeText(getApplicationContext(), "成功添加好友", Toast.LENGTH_SHORT).show();
                    finish();
                } else {
                    //Toast.makeText(getApplicationContext(), e+"添加失败", Toast.LENGTH_SHORT).show();
                    Log.e("错误",e+"" );
                    Toast.makeText(getApplicationContext(), e+"", Toast.LENGTH_SHORT).show();
                }
            }

        });
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.friend_addBtn:
                handler.sendEmptyMessage(SEARCHUSERINFO);
                break;
            case R.id.friend_add_backBtn:
                finish();
                break;
        }
    }
}

行,先告一段落吧,快凌晨了,赶着去github上传一下代码,不然今天的绿点又没了(笑)

android 练习之路 (八)