Kaynağa Gözat

添加登录方式切换,修复聊天选人的bug等问题

fancy 6 yıl önce
ebeveyn
işleme
6984c6bd9c

+ 1 - 1
o2android/app/build.gradle

@@ -107,7 +107,7 @@ android {
     buildTypes {
         debug {
             signingConfig signingConfigs.debug
-            buildConfigField "Boolean", "InnerServer", "true"
+            buildConfigField "Boolean", "InnerServer", "false"
             buildConfigField "Boolean", "LOG_ENABLE", "true"
             buildConfigField "Boolean", "LOG_FILE", "true"
             manifestPlaceholders = [JPUSH_PKGNAME      : defaultConfig.applicationId,

+ 56 - 14
o2android/app/src/main/java/jiguang/chat/activity/ChatDetailActivity.java

@@ -16,8 +16,15 @@ import com.wugang.activityresult.library.ActivityResult;
 
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.R;
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.organization.ContactPickerActivity;
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.api.RetrofitClient;
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.api.service.OrgAssembleExpressService;
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.ApiResponse;
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.main.identity.IdentityLevelForm;
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.main.person.PersonJson;
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.main.unit.UnitJson;
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.vo.ContactPickerResult;
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.vo.O2PersonPickerResultItem;
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.StringUtil;
 
 import java.io.File;
 import java.lang.ref.WeakReference;
@@ -36,6 +43,11 @@ import jiguang.chat.application.JGApplication;
 import jiguang.chat.controller.ChatDetailController;
 import jiguang.chat.utils.ToastUtil;
 import jiguang.chat.view.ChatDetailView;
+import rx.Observable;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.functions.Action1;
+import rx.functions.Func1;
+import rx.schedulers.Schedulers;
 
 /**
  * Created by ${chenyn} on 2017/4/21.
@@ -218,10 +230,41 @@ public class ChatDetailActivity extends BaseActivity {
      * 从ContactsActivity中选择朋友加入到群组中
      */
     public void showContacts(Long group) {
+        OrgAssembleExpressService service = RetrofitClient.Companion.instance().assembleExpressApi();
+        RetrofitClient.Companion.instance().assemblePersonalApi().getCurrentPersonInfo()
+                .subscribeOn(Schedulers.io())
+                .flatMap((Func1<ApiResponse<PersonJson>, Observable<ApiResponse<UnitJson>>>) personJsonApiResponse -> {
+                    PersonJson personJson = personJsonApiResponse.getData();
+                    if (personJson!=null && !personJson.getWoIdentityList().isEmpty()) {
+                        String identity = personJson.getWoIdentityList().get(0).getDistinguishedName();
+                        IdentityLevelForm form = new IdentityLevelForm(identity, 1);
+                        return service.unitByIdentityAndLevel(form);
+                    }else  {
+                        return  Observable.just(new ApiResponse<UnitJson>());
+                    }
+                })
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(unitJsonApiResponse -> {
+                        if (unitJsonApiResponse.getData() != null) {
+                            openChooseUser(unitJsonApiResponse.getData().getDistinguishedName());
+                        }else {
+                            openChooseUser(null);
+                        }
+                }, error -> openChooseUser(null));
+
+
+
+    }
+
+    private void openChooseUser(String topOrg) {
         ArrayList<String> modes = new ArrayList<>();
         modes.add("personPicker");
+        ArrayList<String> topList = new ArrayList<>();
+        if (!TextUtils.isEmpty(topOrg)) {
+            topList.add(topOrg);
+        }
         Bundle bundle1 = ContactPickerActivity.Companion.startPickerBundle(modes,
-                new ArrayList<>(),
+                topList,
                 "",
                 0,
                 true,
@@ -234,21 +277,20 @@ public class ChatDetailActivity extends BaseActivity {
                 .className(ContactPickerActivity.class)
                 .params(bundle1)
                 .greenChannel().forResult((resultCode, data) -> {
-                    if (data != null) {
-                        ContactPickerResult result = data.getParcelableExtra(ContactPickerActivity.CONTACT_PICKED_RESULT);
-                        if (result != null) {
-                            ArrayList<O2PersonPickerResultItem> users = result.getUsers();
-                            if (users.size() != 0) {
-                                ArrayList<String> list = new ArrayList<>();
-                                for (int i = 0; i < users.size(); i++) {
-                                    list.add(users.get(i).getDistinguishedName());
-                                }
-                                mChatDetailController.addMembersToGroup(list);
-                            }
+            if (data != null) {
+                ContactPickerResult result = data.getParcelableExtra(ContactPickerActivity.CONTACT_PICKED_RESULT);
+                if (result != null) {
+                    ArrayList<O2PersonPickerResultItem> users = result.getUsers();
+                    if (users.size() != 0) {
+                        ArrayList<String> list = new ArrayList<>();
+                        for (int i = 0; i < users.size(); i++) {
+                            list.add(users.get(i).getId());
                         }
+                        mChatDetailController.addMembersToGroup(list);
                     }
-                });
-
+                }
+            }
+        });
     }
 
 

+ 44 - 0
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/base/BaseMVPActivity.kt

@@ -8,9 +8,18 @@ import android.widget.TextView
 import com.wugang.activityresult.library.ActivityResult
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.R
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.organization.ContactPickerActivity
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.api.RetrofitClient
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.ApiResponse
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.main.identity.IdentityLevelForm
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.main.unit.UnitJson
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.vo.ContactPickerResult
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.ImmersedStatusBarUtils
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.XLog
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.o2Subscribe
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.widgets.dialog.LoadingDialog
+import rx.Observable
+import rx.android.schedulers.AndroidSchedulers
+import rx.schedulers.Schedulers
 
 
 /**
@@ -114,4 +123,39 @@ abstract class BaseMVPActivity<in V: BaseView, T: BasePresenter<V>>: AppCompatAc
                 }
     }
 
+    fun getCurrentIdentityUnit(callback:(String?)-> Unit) {
+        val expressService = RetrofitClient.instance().assembleExpressApi()
+        val personalService = RetrofitClient.instance().assemblePersonalApi()
+        personalService.getCurrentPersonInfo()
+                .subscribeOn(Schedulers.io())
+                .flatMap { unitResponse ->
+                    val person = unitResponse.data
+                    if (person != null) {
+                        val identityList = person.woIdentityList
+                        if (identityList.isNotEmpty()) {
+                            val identity = identityList[0]
+                            val form = IdentityLevelForm(identity = identity.distinguishedName, level = 1)
+                            expressService.unitByIdentityAndLevel(form)
+                        } else {
+                            Observable.just(ApiResponse<UnitJson>())
+                        }
+                    } else {
+                        Observable.just(ApiResponse<UnitJson>())
+                    }
+                }.observeOn(AndroidSchedulers.mainThread())
+                .o2Subscribe {
+                    onNext { unitJsonApiResponse ->
+                        if (unitJsonApiResponse.data != null) {
+                            callback(unitJsonApiResponse.data.distinguishedName)
+                        }else {
+                            callback(null)
+                        }
+                    }
+                    onError{ e, _ ->
+                        XLog.error("", e)
+                        callback(null)
+                    }
+                }
+    }
+
 }

+ 93 - 13
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/login/LoginActivity.kt

@@ -4,6 +4,7 @@ import android.content.Context
 import android.media.AudioManager
 import android.media.MediaPlayer
 import android.os.Bundle
+import android.support.v4.content.ContextCompat
 import android.text.InputType
 import android.text.TextUtils
 import android.view.KeyEvent
@@ -27,9 +28,11 @@ import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.biometric.OnBiometryAuthCallb
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.goThenKill
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.gone
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.visible
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.widgets.BottomSheetMenu
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.widgets.CountDownButtonHelper
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.widgets.dialog.O2DialogSupport
 import java.io.IOException
+import kotlin.math.log
 
 
 /**
@@ -80,11 +83,13 @@ class LoginActivity: BaseMVPActivity<LoginContract.View, LoginContract.Presenter
     private var mediaPlayer: MediaPlayer? = null
     private var playBeep: Boolean = false
 
+    private var loginType = 0 // 0默认的用户名验证码登录 1用户名密码登录
+    private var canBioAuth = false //是否有指纹认证
+
 
     override fun afterSetContentView(savedInstanceState: Bundle?) {
         receivePhone = intent.extras?.getString(REQUEST_PHONE_KEY) ?: ""
-        //是否开启了指纹识别登录
-        checkBioAuthLogin()
+
 
         setDefaultLogo()
         login_edit_username_id.setText(receivePhone)
@@ -118,13 +123,16 @@ class LoginActivity: BaseMVPActivity<LoginContract.View, LoginContract.Presenter
         tv_user_fallback_btn.setOnClickListener(this)
         tv_bioauth_btn.setOnClickListener(this)
 
-
+        //是否开启了指纹识别登录
+        checkBioAuthLogin()
         if (BuildConfig.InnerServer) {
             login_edit_password_id.setHint(R.string.activity_login_password)
             login_edit_password_id.inputType = InputType.TYPE_TEXT_VARIATION_PASSWORD
             button_login_phone_code.gone()
             tv_rebind_btn.gone()
+            tv_bioauth_btn.gone()
         }else {
+            tv_bioauth_btn.visible()
             login_edit_password_id.setHint(R.string.login_code)
             login_edit_password_id.inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL
             button_login_phone_code.visible()
@@ -178,7 +186,7 @@ class LoginActivity: BaseMVPActivity<LoginContract.View, LoginContract.Presenter
                 userFallback()
             }
             R.id.tv_bioauth_btn -> {
-                showBiometryAuthUI()
+                showChangeLoginTypeMenu()
             }
             R.id.btn_bio_auth_login ->{
                 bioAuthLogin()
@@ -197,6 +205,42 @@ class LoginActivity: BaseMVPActivity<LoginContract.View, LoginContract.Presenter
         }
     }
 
+    //切换登录方式
+    private fun showChangeLoginTypeMenu() {
+        val listItems = ArrayList<String>()
+        val title = if(loginType == 0) "密码登录" else "验证码登录"
+        listItems.add(title)
+        if (canBioAuth) {
+            listItems.add("指纹识别登录")
+        }
+        BottomSheetMenu(this)
+                .setTitle("切换登录方式")
+                .setItems(listItems, ContextCompat.getColor(this, R.color.z_color_text_primary)) { index ->
+                    if (index == 0) {
+                        changeLoginType()
+                    }else if (index == 1) {
+                        showBiometryAuthUI()
+                    }
+                }
+                .show()
+
+
+    }
+    private  fun changeLoginType() {
+        if (loginType == 0) {
+            login_edit_password_id.setHint(R.string.activity_login_password)
+            login_edit_password_id.inputType = InputType.TYPE_TEXT_VARIATION_PASSWORD
+            button_login_phone_code.gone()
+            loginType = 1
+        }else {
+            login_edit_password_id.setHint(R.string.login_code)
+            login_edit_password_id.inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL
+            button_login_phone_code.visible()
+            button_login_phone_code.setOnClickListener(this)
+            loginType = 0
+        }
+    }
+
 
     override fun loginSuccess(data: AuthenticationInfoJson) {
         if (login_main_biometry.visibility == View.VISIBLE) {
@@ -226,9 +270,13 @@ class LoginActivity: BaseMVPActivity<LoginContract.View, LoginContract.Presenter
         }
         if (TextUtils.isEmpty(code)) {
             val label = if(BuildConfig.InnerServer){
-                getString(R.string.login_code)
-            }else {
                 getString(R.string.activity_login_password)
+            }else {
+                if (loginType == 0) {
+                    getString(R.string.login_code)
+                }else {
+                    getString(R.string.activity_login_password)
+                }
             }
             XToast.toastShort(this, "$label 不能为空!")
             return
@@ -237,7 +285,11 @@ class LoginActivity: BaseMVPActivity<LoginContract.View, LoginContract.Presenter
         if (BuildConfig.InnerServer) {
             mPresenter.loginByPassword(credential, code)
         }else {
-            mPresenter.login(credential, code)
+            if (loginType == 0) {
+                mPresenter.login(credential, code)
+            }else {
+                mPresenter.loginByPassword(credential, code)
+            }
         }
     }
 
@@ -268,11 +320,21 @@ class LoginActivity: BaseMVPActivity<LoginContract.View, LoginContract.Presenter
      * 是否开启了指纹识别登录
      */
     private fun checkBioAuthLogin() {
-        val userId = O2SDKManager.instance().prefs().getString(BioConstants.O2_bio_auth_user_id_prefs_key, "") ?: ""
+        val bioAuthUser = O2SDKManager.instance().prefs().getString(BioConstants.O2_bio_auth_user_id_prefs_key, "") ?: ""
+        var userId = ""
+        //判断是否当前绑定的服务器的
+        if (bioAuthUser.isNotBlank()) {
+            val array = bioAuthUser.split("^^")
+            if (array.isNotEmpty() && array.size == 2) {
+                val unitId = O2SDKManager.instance().prefs().getString(O2.PRE_BIND_UNIT_ID_KEY, "") ?: ""
+                if (array[0] == unitId) {
+                    userId = array[1]
+                }
+            }
+        }
         if (userId.isNotEmpty()) {
-            tv_bioauth_btn.visible()
-            login_form_scroll_id.gone()
-            login_main_biometry.visible()
+            canBioAuth = true
+            showBiometryAuthUI()
         }else {
             login_form_scroll_id.visible()
             login_main_biometry.gone()
@@ -303,7 +365,8 @@ class LoginActivity: BaseMVPActivity<LoginContract.View, LoginContract.Presenter
         if(!bioManager.isBiometricPromptEnable()){
             XToast.toastShort(this, "指纹识别模块未启用,请检查手机是否开启")
         }else {
-            val userId = O2SDKManager.instance().prefs().getString(BioConstants.O2_bio_auth_user_id_prefs_key, "") ?: ""
+
+
             bioManager.authenticate(object : OnBiometryAuthCallback{
                 override fun onUseFallBack() {
                     XLog.error("点击了《其他方式》按钮。。。。。")
@@ -312,7 +375,24 @@ class LoginActivity: BaseMVPActivity<LoginContract.View, LoginContract.Presenter
 
                 override fun onSucceeded() {
                     showLoadingDialog()
-                    mPresenter.ssoLogin(userId)
+                    val bioAuthUser = O2SDKManager.instance().prefs().getString(BioConstants.O2_bio_auth_user_id_prefs_key, "") ?: ""
+                    var userId = ""
+                    //判断是否当前绑定的服务器的
+                    if (bioAuthUser.isNotBlank()) {
+                        val array = bioAuthUser.split("^^")
+                        if (array.isNotEmpty() && array.size == 2) {
+                            val unitId = O2SDKManager.instance().prefs().getString(O2.PRE_BIND_UNIT_ID_KEY, "") ?: ""
+                            if (array[0] == unitId) {
+                                userId = array[1]
+                            }
+                        }
+                    }
+                    if (userId.isBlank()) {
+                        XLog.error("用户名为空 无法登录。。。。")
+                        XToast.toastShort(this@LoginActivity, "服务器验证登录失败,请尝试使用其它方式登录")
+                    }else {
+                        mPresenter.ssoLogin(userId)
+                    }
                 }
 
                 override fun onFailed() {

+ 146 - 19
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/NewsFragment.kt

@@ -17,6 +17,7 @@ import android.view.MenuItem
 import android.view.View
 import android.widget.AdapterView
 import cn.jpush.im.android.api.JMessageClient
+import cn.jpush.im.android.api.callback.CreateGroupCallback
 import cn.jpush.im.android.api.callback.GetAvatarBitmapCallback
 import cn.jpush.im.android.api.enums.ConversationType
 import cn.jpush.im.android.api.event.*
@@ -24,24 +25,25 @@ import cn.jpush.im.android.api.model.Conversation
 import cn.jpush.im.android.api.model.GroupInfo
 import cn.jpush.im.android.api.model.UserInfo
 import cn.jpush.im.android.eventbus.EventBus
+import cn.jpush.im.api.BasicCallback
 import jiguang.chat.activity.ChatActivity
+import jiguang.chat.application.JGApplication
 import kotlinx.android.synthetic.main.fragment_main_news.*
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.O2App
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.O2SDKManager
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.R
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BaseMVPViewPagerFragment
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.openim.IMTribeCreateActivity
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.organization.ContactPickerActivity
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.im.*
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.vo.O2PersonPickerResultItem
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.XLog
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.XToast
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.go
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.gone
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.visible
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.widgets.dialog.O2DialogSupport
 import org.jetbrains.anko.doAsync
 import org.jetbrains.anko.uiThread
 import java.util.*
+import kotlin.collections.ArrayList
 
 /**
  * Created by fancylou on 10/9/17.
@@ -211,25 +213,22 @@ class NewsFragment : BaseMVPViewPagerFragment<NewsContract.View, NewsContract.Pr
 
     override fun onOptionsItemSelected(item: MenuItem?): Boolean {
         when (item?.itemId) {
+            R.id.menu_single_create -> {
+                XLog.info("创建单聊。。。。。。。。。。。。。。。。。。。。。。。。。。。")
+                if (isLogin) {
+                    (activity as MainActivity).getCurrentIdentityUnit { topOrg ->
+                        chooseSinglePerson(topOrg)
+                    }
+                } else {
+                    XToast.toastShort(activity, "聊天服务器未登录成功,无法发起聊天!")
+                }
+                return true
+            }
             R.id.menu_tribe_create -> {
                 XLog.info("创建群聊。。。。。。。。。。。。。。。。。。。。。。。。。。。")
                 if (isLogin) {
-                    try {
-                        val bundle = ContactPickerActivity.startPickerBundle(
-                                arrayListOf("personPicker"),
-                                multiple = true,
-                                initUserList = arrayListOf(O2SDKManager.instance().distinguishedName)
-                        )
-                        (activity as MainActivity).contactPicker(bundle) { result ->
-                            if (result != null) {
-                                val list = ArrayList<String>()
-                                val users = result.users
-                                users.map { list.add(it.distinguishedName) }
-                                activity.go<IMTribeCreateActivity>(IMTribeCreateActivity.startCreate(list))
-                            }
-                        }
-
-                    } catch (e: Exception) {
+                    (activity as MainActivity).getCurrentIdentityUnit { topOrg ->
+                        chooseMultiPerson(topOrg)
                     }
                 } else {
                     XToast.toastShort(activity, "聊天服务器未登录成功,无法发起聊天!")
@@ -240,6 +239,53 @@ class NewsFragment : BaseMVPViewPagerFragment<NewsContract.View, NewsContract.Pr
         return super.onOptionsItemSelected(item)
     }
 
+    private fun chooseSinglePerson(topOrg: String?) {
+        try {
+            val topList = ArrayList<String>()
+            if (!TextUtils.isEmpty(topOrg)) {
+                topList.add(topOrg!!)
+            }
+            val bundle = ContactPickerActivity.startPickerBundle(
+                    arrayListOf("personPicker"),
+                    topUnitList =  topList,
+                    multiple = false,
+                    maxNumber = 1
+            )
+            (activity as MainActivity).contactPicker(bundle) { result ->
+                if (result != null) {
+                    val users = result.users
+                    if (users.isNotEmpty()) {
+                        createSingleChat(users)
+                    }
+                }
+            }
+        } catch (e: Exception) {
+        }
+    }
+
+    private fun chooseMultiPerson(topOrg: String?) {
+        try {
+            val topList = ArrayList<String>()
+            if (!TextUtils.isEmpty(topOrg)) {
+                topList.add(topOrg!!)
+            }
+            val bundle = ContactPickerActivity.startPickerBundle(
+                    arrayListOf("personPicker"),
+                    topUnitList =  topList,
+                    multiple = true
+            )
+            (activity as MainActivity).contactPicker(bundle) { result ->
+                if (result != null) {
+                    val users = result.users
+                    if (users.isNotEmpty()) {
+                        createGroupChat(users)
+                    }
+                }
+            }
+        } catch (e: Exception) {
+        }
+    }
+
     override fun onDestroy() {
         EventBus.getDefault().unregister(this)
         activity?.unregisterReceiver(mReceiver)
@@ -519,4 +565,85 @@ class NewsFragment : BaseMVPViewPagerFragment<NewsContract.View, NewsContract.Pr
             }
         }
     }
+
+    private fun createSingleChat(chooseUserList: List<O2PersonPickerResultItem>) {
+        val lastPersonIdList = chooseUserList.filter { it.id != JMessageClient.getMyInfo().userName }
+        if (lastPersonIdList.isEmpty()) {
+            XToast.toastShort(activity, "没有选择用户!")
+            return
+        }else {
+            if (O2App.instance._JMIsLogin()) {
+                val targetId = lastPersonIdList[0].id
+                val targetName = lastPersonIdList[0].name
+                var conv: Conversation? = JMessageClient.getSingleConversation(targetId)
+                //如果会话为空,使用EventBus通知会话列表添加新会话
+                if (conv == null) {
+                    conv = Conversation.createSingleConversation(targetId)
+                    EventBus.getDefault().post(jiguang.chat.entity.Event.Builder()
+                            .setType(jiguang.chat.entity.EventType.createConversation)
+                            .setConversation(conv)
+                            .build())
+                }
+                val intent = Intent(activity, ChatActivity::class.java)
+                //设置跳转标志
+                intent.putExtra(JGApplication.CONV_TITLE, conv!!.title)
+                intent.putExtra(JIMConstant.CONV_TITLE, targetName)
+                intent.putExtra(JIMConstant.TARGET_ID, targetId)
+                intent.putExtra(JIMConstant.TARGET_APP_KEY, O2App.instance.JM_IM_APP_KEY)
+                startActivity(intent)
+            }else {
+                XToast.toastShort(activity, "无法聊天,没有连接到IM服务器!!")
+            }
+        }
+    }
+
+    //创建群聊 服务端
+    private fun createGroupChat(chooseUserList: List<O2PersonPickerResultItem>) {
+        val lastPersonIdList = chooseUserList.filter { it.id != JMessageClient.getMyInfo().userName }.map { it.id }
+        if (lastPersonIdList.size < 2) {
+            XToast.toastShort(activity, "创建群里需要3位及以上成员!")
+            return
+        }else {
+            JMessageClient.createGroup(null, null, object : CreateGroupCallback() {
+                override fun gotResult(resCode: Int, resMessage: String?, groupId: Long) {
+                    if (resCode == 0) {
+                        JMessageClient.addGroupMembers(groupId, lastPersonIdList, object : BasicCallback() {
+                            override fun gotResult(code: Int, message: String?) {
+                                if (code == 0) {
+                                    //如果创建群组时添加了人,那么就在size基础上加上自己
+                                    createGroup(groupId, lastPersonIdList.size+1)
+                                } else {
+                                    XToast.toastShort(activity, "添加群聊失败,添加的成员中有从未登录过我们O2应用的用户!")
+                                }
+                            }
+                        })
+                    } else {
+                        XLog.error("code:$resCode, message:$resMessage")
+                        XToast.toastShort(activity, "创建群聊失败,IM服务器返回错误!")
+                    }
+                }
+            })
+        }
+    }
+
+
+    //创建群聊 本地
+    private fun createGroup(groupId: Long, size: Int) {
+        var groupConversation: Conversation? = JMessageClient.getGroupConversation(groupId)
+        if (groupConversation == null) {
+            groupConversation = Conversation.createGroupConversation(groupId)
+            EventBus.getDefault().post(jiguang.chat.entity.Event.Builder()
+                    .setType(jiguang.chat.entity.EventType.createConversation)
+                    .setConversation(groupConversation)
+                    .build())
+        }
+        val intent = Intent(activity, ChatActivity::class.java)
+        //设置跳转标志
+        intent.putExtra("fromGroup", true)
+        intent.putExtra(JGApplication.CONV_TITLE, groupConversation!!.title)
+        intent.putExtra(JGApplication.MEMBERS_COUNT, size)
+        intent.putExtra(JGApplication.GROUP_ID, groupId)
+        startActivity(intent)
+    }
+
 }

+ 2 - 1
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/person/PersonActivity.kt

@@ -24,6 +24,7 @@ import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.XLog
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.XToast
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.ZoneUtil
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.gone
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.makeCallDial
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.visible
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.imageloader.O2ImageLoaderManager
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.imageloader.O2ImageLoaderOptions
@@ -159,7 +160,7 @@ class PersonActivity : BaseMVPActivity<PersonContract.View, PersonContract.Prese
         mobileClickMenu.onMenuItemClickListener = object : CommonMenuPopupWindow.OnMenuItemClickListener {
             override fun itemClick(position: Int) {
                 when (position) {
-                    0 -> makeCall(phone)
+                    0 -> makeCallDial(phone)
                     1 -> sendSMS(phone)
                     2 -> {
                         AndroidUtils.copyTextToClipboard(phone, this@PersonActivity)

+ 39 - 15
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/security/AccountSecurityActivity.kt

@@ -59,6 +59,26 @@ class AccountSecurityActivity : BaseMVPActivity<AccountSecurityContract.View, Ac
     private val bioManager: BiometryManager by lazy { BiometryManager(this) }
     private fun initBiometryAuthView() {
 
+        tv_account_security_biometry_name.text = "指纹识别登录"
+        val bioAuthUser = O2SDKManager.instance().prefs().getString(BioConstants.O2_bio_auth_user_id_prefs_key, "") ?: ""
+        var isAuthed = false
+        //判断是否当前绑定的服务器的
+        if (bioAuthUser.isNotBlank()) {
+            val array = bioAuthUser.split("^^")
+            if (array.isNotEmpty() && array.size == 2) {
+                val unitId = O2SDKManager.instance().prefs().getString(O2.PRE_BIND_UNIT_ID_KEY, "") ?: ""
+                if (array[0] == unitId) {
+                    isAuthed = true
+                }
+            }
+        }
+
+        if (isAuthed) {
+            image_btn_account_security_biometry_enable.setImageResource(R.mipmap.icon_toggle_on_29dp)
+        }else {
+            image_btn_account_security_biometry_enable.setImageResource(R.mipmap.icon_toggle_off_29dp)
+        }
+
         if (bioManager.isBiometricPromptEnable()) {
             image_btn_account_security_biometry_enable.setOnClickListener {
                 bioManager.authenticate(object : OnBiometryAuthCallback{
@@ -68,13 +88,8 @@ class AccountSecurityActivity : BaseMVPActivity<AccountSecurityContract.View, Ac
 
                     override fun onSucceeded() {
                         XLog.debug("指纹识别验证成功")
-                        val userId = O2SDKManager.instance().prefs().getString(BioConstants.O2_bio_auth_user_id_prefs_key, "") ?: ""
                         XToast.toastShort(this@AccountSecurityActivity, "验证成功")
-                        if (userId.isNotEmpty()) {
-                            setBioAuthResult("")
-                        }else {
-                            setBioAuthResult(O2SDKManager.instance().cId)
-                        }
+                        setBioAuthResult()
                     }
 
                     override fun onFailed() {
@@ -93,13 +108,7 @@ class AccountSecurityActivity : BaseMVPActivity<AccountSecurityContract.View, Ac
 
                 })
             }
-            tv_account_security_biometry_name.text = "指纹识别登录"
-            val userId = O2SDKManager.instance().prefs().getString(BioConstants.O2_bio_auth_user_id_prefs_key, "") ?: ""
-            if (userId.isNotEmpty()) {
-                image_btn_account_security_biometry_enable.setImageResource(R.mipmap.icon_toggle_on_29dp)
-            }else {
-                image_btn_account_security_biometry_enable.setImageResource(R.mipmap.icon_toggle_off_29dp)
-            }
+
         }else {
             tv_account_security_biometry_name.text = "指纹识别登录不可用"
             image_btn_account_security_biometry_enable.setImageResource(R.mipmap.icon_toggle_off_29dp)
@@ -109,11 +118,26 @@ class AccountSecurityActivity : BaseMVPActivity<AccountSecurityContract.View, Ac
         }
     }
 
-    private fun setBioAuthResult(userId: String) {
+    //如果识别成功 设置结果
+    private fun setBioAuthResult() {
+        val bioAuthUser = O2SDKManager.instance().prefs().getString(BioConstants.O2_bio_auth_user_id_prefs_key, "") ?: ""
+        var isAuthed = false
+        val unitId = O2SDKManager.instance().prefs().getString(O2.PRE_BIND_UNIT_ID_KEY, "") ?: ""
+        //判断是否当前绑定的服务器的
+        if (bioAuthUser.isNotBlank()) {
+            val array = bioAuthUser.split("^^")
+            if (array.isNotEmpty() && array.size == 2) {
+                if (array[0] == unitId) {
+                    isAuthed = true
+                }
+            }
+        }
+        val userId = if(isAuthed)  "" else unitId+"^^"+O2SDKManager.instance().cId
+
         O2SDKManager.instance().prefs().edit{
             putString(BioConstants.O2_bio_auth_user_id_prefs_key, userId)
         }
-        if (userId.isNotEmpty()) {
+        if (isAuthed) {
             image_btn_account_security_biometry_enable.setImageResource(R.mipmap.icon_toggle_on_29dp)
         }else {
             image_btn_account_security_biometry_enable.setImageResource(R.mipmap.icon_toggle_off_29dp)

+ 3 - 2
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/im/ConversationListAdapter.java

@@ -358,7 +358,8 @@ public class ConversationListAdapter extends BaseAdapter {
                                         !lastMsg.getContentType().equals(ContentType.prompt) &&
                                         //排除自己给自己发送消息
                                         !((UserInfo) lastMsg.getTargetInfo()).getUserName().equals(JMessageClient.getMyInfo().getUserName())) {
-                                    content.setText("[已读]" + contentStr);
+                                    content.setText(contentStr);
+//                                    content.setText("[已读]" + contentStr);
                                 } else {
                                     content.setText(contentStr);
                                 }
@@ -367,7 +368,7 @@ public class ConversationListAdapter extends BaseAdapter {
                                         lastMsg.getDirect().equals(MessageDirect.send) &&
                                         !lastMsg.getContentType().equals(ContentType.prompt) &&
                                         !((UserInfo) lastMsg.getTargetInfo()).getUserName().equals(JMessageClient.getMyInfo().getUserName())) {
-                                    contentStr = "[未读]" + contentStr;
+//                                    contentStr = "[未读]" + contentStr;
                                     SpannableStringBuilder builder = new SpannableStringBuilder(contentStr);
                                     builder.setSpan(new ForegroundColorSpan(mContext.getResources().getColor(R.color.line_normal)),
                                             0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

+ 16 - 0
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/utils/extension/ViewEx.kt

@@ -5,7 +5,9 @@ import android.content.Context
 import android.content.Intent
 import android.graphics.Bitmap
 import android.graphics.BitmapFactory
+import android.net.Uri
 import android.os.Bundle
+import android.support.v4.app.Fragment
 import android.text.TextUtils
 import android.view.View
 import android.view.inputmethod.InputMethodManager
@@ -13,6 +15,7 @@ import android.widget.ImageView
 import android.widget.TextView
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.Base64ImageUtil
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.XLog
+import org.jetbrains.anko.ctx
 import rx.Observable
 import rx.android.schedulers.AndroidSchedulers
 import rx.schedulers.Schedulers
@@ -20,6 +23,19 @@ import rx.schedulers.Schedulers
 /**
  * Created by fancy on 2017/4/10.
  */
+inline fun Activity.makeCallDial(number: String): Boolean = ctx.makeCallDial(number)
+inline fun Fragment.makeCallDial(number: String): Boolean = activity.makeCallDial(number)
+
+fun Context.makeCallDial(number: String): Boolean {
+    return try {
+        val intent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:$number"))
+        startActivity(intent)
+        true
+    } catch (e: Exception) {
+        e.printStackTrace()
+        false
+    }
+}
 
 inline fun <reified T : Activity> Activity.go(bundle: Bundle? = null) {
     val intent = Intent(this, T::class.java)

+ 1 - 1
o2android/app/src/main/res/layout/activity_login.xml

@@ -188,7 +188,7 @@
                             android:id="@+id/tv_bioauth_btn"
                             android:layout_width="wrap_content"
                             android:layout_height="wrap_content"
-                            android:text="@string/activity_login_fingerprint"
+                            android:text="@string/activity_login_other"
                             android:textColor="@color/z_color_text_hint"
                             android:textSize="13sp"
                             android:layout_alignParentStart="true"

+ 0 - 1
o2android/app/src/main/res/layout/activity_person_info.xml

@@ -4,7 +4,6 @@
     android:id="@+id/main_content"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@color/z_color_primary"
     tools:context=".app.o2.person.PersonActivity">
 
 

+ 3 - 1
o2android/app/src/main/res/menu/menu_news_tribe_create.xml

@@ -3,8 +3,10 @@
     xmlns:tools="http://schemas.android.com/tools"
     tools:context=".app.o2.main.MainActivity">
 
+    <item android:id="@+id/menu_single_create"
+        android:orderInCategory="90"
+        android:title="@string/menu_single_create"/>
     <item android:id="@+id/menu_tribe_create"
-        app:showAsAction="always"
         android:orderInCategory="90"
         android:title="@string/menu_tribe_create"/>
 

+ 2 - 1
o2android/app/src/main/res/values/strings.xml

@@ -114,7 +114,7 @@
     <string name="login_code">验证码</string>
     <string name="activity_login_password">密码</string>
     <string name="activity_login_submit">登    录</string>
-    <string name="activity_login_fingerprint">指纹识别登录</string>
+    <string name="activity_login_other">其他登录方式</string>
     <string name="activity_login_fingerprint_click">点击开始认证</string>
     <string name="activity_login_face">人脸识别</string>
     <string name="activity_logout">退出登录</string>
@@ -191,6 +191,7 @@
     <string name="title_activity_chat">实时消息</string>
     <string name="activity_chat_send_btn_label">发送</string>
     <string name="chat_please_enter">请输入...</string>
+    <string name="menu_single_create">发起单聊</string>
     <string name="menu_tribe_create">发起群聊</string>
     <string name="activity_im_person_config_label">聊天设置</string>
     <string name="activity_im_tribe_create_label">创建群聊</string>

+ 2 - 2
o2android/gradle.properties

@@ -20,8 +20,8 @@ org.gradle.parallel=true
 
 
 # o2
-o2.versionName=4.9.5
-o2.versionCode=95
+o2.versionName=5.0.2
+o2.versionCode=102
 
 
 # sjgj