Android ios V3.2.1 SDK 已发布,发起电话支持自定义内容
Android V3.2.1 2016-11-12
新功能/优化:
- 聊天室列表支持分页获取
- 发起电话的接口增加ext参数,方便用户自定义内容
- EMOption中增加setUseHttps()的接口
- 优化会话加载的速度
- 修复使用视音频后可能导致手机外放没有声音的bug
- 修复发送消息后马上删除附件可能导致手机crash的bug
- 修复音视频呼叫在某些魅蓝手机上会卡死的bug
- 修复demo中呼叫时没有铃声的bug
- 修复了视频通话时使用后置摄像头时图像显示不正确的bug
- 聊天室列表支持分页获取
- 发起电话的接口增加ext参数,方便用户自定义内容
- EMOption中usingHttps默认为YES
- 修复Lite版本SDK编译warning的问题
版本历史:Android SDK更新日志 ios SDK更新日志
下载地址:SDK下载 收起阅读 »
环信CEO刘俊彦:SaaS领域一定能诞生千亿市值的科技巨头
提到客服这个词,人们第一印象可能是雪白衬衣、黑亮西服,甜美声线,端庄大方的业务员耐心接听电话的情景。没错,这是典型的人工客服场景,但随着信息技术不断发展,客服内涵更加丰富,文字、语音、视频以及人工智能开始结合,客服已经成为一项重要的企业服务内容,催生出新的产业市场。
环信就是客服产业中的一份子,从2013年成立到去年拿到1250万美元融资,随着市场潜力不断被释放,环信业绩也大幅增长,根据易观智库的数据显示去年环信已占据国内SaaS移动端客服市场77.4%的份额,在市场竞争中取得了不俗表现,但在新技术不断转化落地,竞争日益激烈的大环境下,如何让企业跑得更快,怎样更好地理解市场,行业天花板在哪里,作为客服领域参与者和受益者,环信CEO刘俊彦给出了他的理解。
亿欧:企业级服务赛道很多,为什么选择客服这个领域呢?
刘俊彦:企业服务可以分为5个核心赛道, 协同办公、CRM、客服、人力资源和财务 ,选择从客服切入首先是因为我们对这个行业了解,有过多年相关产品的开发经验,其次从市场角度来看,无论是北美市场还是目前的国内市场,客服的市场规模最大,仅国内在线服务和电话服务两个细分市场就已达到300亿元规模,像京东、阿里、苹果都在客服项目投入了巨大资源,从人员培训到系统的购买等,所以这是一项成本中心,是企业与客户沟通的第一窗口。
从其他赛道来看,协同办公是基础性战略服务,是腾讯、阿里这样巨头的必争领域,这个领域竞争很激烈;客服是CRM中占比最大的服务内容,综合性CRM企业有纷享销客、销售易和红圈营销等;人力资源领域有北森,也是一块大市场;财务方向主要是传统IT企业例如金蝶、用友等公司。环信选择在客服深耕是从主观和客观两个维度来判断,我看好这个赛道。
亿欧:很多客服公司都希望做中国的Zendesk,而您希望企业能有更大格局,能成为salesforce、微软和甲骨文这一类综合性公司,关于行业天花板您怎么看?
刘俊彦:与美国相比,中国企业面临着难得机遇,眼光应该看得更远,只要把握机会,成为一家百亿美元市值的综合性软件巨头是很有希望的。
中美两国市场环境是不同的,Zendesk在美国还不是最大客服企业,占据第一阶梯的仍然是巨头,去年salesforce的客服云收入大概是19.6亿美元,而Zendesk是2亿美元左右,双方差距近10倍,所以巨头在各个行业保持强势地位,让新型企业难以立足。其他巨头例如微软、甲骨文也有自己的客服云系统,主要服务面向客单价在几十万到几百万的大型企业,所以整体来看美国客服市场是巨头的竞技场,小型服务商机会渺茫。
而在国内由于云服务落地受到限制,国外巨头不得不和中国企业合作共建数据中心,造成了市场空白,这给本土企业 休养生息并不断发展壮大自己赢得了时间。另一方面国内中小型企业发展迅速,付费意识和能力逐渐增强,进一步扩大了市场空间,延长了赛道深度。更重要的因素是国内在各个赛道都没有形成像美国一样强大的巨无霸企业,竞争状态相对平行,群雄逐鹿的程中,第一阶梯的企业都有机会成为巨头。
亿欧:您说过环信有两场仗要打,一是客服赛道另一个是综合性软件,您认为打赢这两场仗的核心是什么,环信所处的阶段又是怎样的呢?
刘俊彦:因为有大机遇所以有更强的愿景,站在行业发展方向来看,企业成长路径从确定方向再到逐步成长为该领域的小巨头,最后跨赛道边界,跻身综合性企业行列,这个过程就是环信将要面对的,目前我们处在第二阶段,这也是时间上最漫长,洗牌压力最大的阶段,走好就能化蛹成蝶,走不好就只能被淘汰。
如果想在局部赛道和整个航道上打胜仗, 最关键就是产品和销售。
销售要做好服务,让客户实现价值;产品是核心竞争力,是服务基础,在两者之上是资金投入,在资本推动下能实现快速成长,以往的软件公司靠自我造血进行研发,但在SaaS领域初期投入非常巨大,资金不足、产品化速度太慢,很难把握市场机遇,所以做好产品和销售再加上资本催化,SaaS企业就能突破局部赛道藩篱实现大航道方向地起飞。
亿欧:环信在产品体系上有什么亮点吗?
刘俊彦: 第一个亮点是客服移动化。 移动互联网时代,单靠PC端并不能满足客户需求,客户更多会从手机端访问页面,这是共性趋势,但环信更强调移动端客户体验,保证产品舒适性。
第二个亮点是全媒体客服。社交渠道多元化和应用软件功能的丰富让全媒体客服成为客户新需求,微信公众号、微博、网页、电话等渠道的用户访问都能提供客服支持,同时数据可以统一记录并管理,以便更好服务用户。
第三个亮点是客服智能化。对于企业来讲客服既是成本中心也是获客窗口,如何压缩成本,扩大获客能力,是人工智能的重要应用方向。一般客服场景中很多对话具有重复性、结构化特点,通过人工智能方式能够代替前端基础信息的交互,能节省大量人力成本,同时赋能客服人员以更大专业性,进而提升服务水平。对于有多轮会话需求的企业,我们也会提供定制化服务,以满足不同层次业务需求,但目前多轮会话受会话场景影响,比如噪音问题等,在技术上还有待突破。
第四个亮点是客服营销化。通过客服这个窗口进行用户画像的描绘、有针对性采取互动营销手段,构筑完整闭环,打通服务链条,多维度布局产品,提供“从进到出”的全周期服务体验。
亿欧:续约率是SaaS企业的盈利命门,环信在这方面有什么措施?
刘俊彦:续约率高低体现了销售服务的好坏,我们在售出一套产品后并不是甩手不管而是有专业团队来帮助客户用好产品,根据反馈和意见来提升客户手中的产品价值。为了帮助客户在实践中提升产品使用效能,环信成立了客户成功与交付部,将服务从交付延伸到下次续约,实现全周期跟踪服务,从而保证续约率。 收起阅读 »
先定一个小目标,比如写一个QQ
本项目是即时通讯的示例项目,使用了MVP模式,集成了环信SDK和Bmob后端云,展示了即时通讯基本功能的实现,包括注册登录,退出登录,联系人列表,添加好友,删除好友,收发消息,消息提醒等功能。
使用的开源项目
学习目标
- 环信SDK的集成与使用
- MVP模式的运用
- ORM数据库的集成与使用
- 模块化思想的运用
允许两人或多人使用网络即时的传递文字讯息、档案、语音与视频交流。相关产品
- 鼻祖 ICQ
- 国内主流 QQ 微信 陌陌 YY等
- 国外主流 Facebook Messenger WhatsApp Skype Instagram Line
环信集成[list=1]
android { sourceSets { main { jniLibs.srcDirs = ['libs'] } } }
注意事项运行出错:Didn't find class "com.hyphenate.chat.adapter.EMACallSession",原因是hyphenatechat_3.2.0.jar包内没有该类。解决办法:导入Demo源码中EaseUI库里面的hyphenatechat_3.2.0.jar替换。软件架构MVCMVC应用于Ruby on Rails, Spring Framework, iOS开发和 ASP.NET等。- Model: 获取数据的业务逻辑,网络操作,数据库操作
- View: UI
- Controller: 操作Model层获取数据传递给UI
服务器端的MVC
Android中MVCAndroid中并没有清晰的MVC框架,如果把Activity当做Controller,根据我们实际开发经验,里面会有大量的UI操作,所以V和C就傻傻分不清了。
- Model:Java Bean, NetworkManager, DataBaseHelper
- View: xml res
- Controller: Activity Fragment
- ArrayList-ListView-Adapter(MVC)
- Model: 获取数据的业务逻辑,网络操作,数据库操作
- View: UI
- Presenter: 操作Model层获取数据传递给UI
MVVMMVVM主要应用于WPF, Silverlight, Caliburn, nRoute等。[list=1]
Android中MVVM 软件架构的核心思想
分层分模块
参考
- MVC,MVP和MVVM模式如何选择
- 教你认清MVC,MVP和MVVM
- android architectureUnderstanding MVC, MVP and MVVM Design Patterns
- Android Data Binding
- Clean Architecture
- adapter 存放适配器
- app 存放常量类,Application类以及一些app层级的全局类
- database 数据库相关类
- event EventBus使用的事件类
- factory 工厂类
- model 数据模型
- presenter MVP模型中的Presenter类
- ui 存放activity和fragment
- utils 工具类
- view MVP模型中的View类
- widget 自定义控件
- BaseActivity
- BaseFragment
- SplashView
- SplashPresenter
@Overridepublic void checkLoginStatus() { if (EMClient.getInstance().isLoggedInBefore() && EMClient.getInstance().isConnected()) { mSplashView.onLoggedIn(); } else { mSplashView.onNotLogin(); }}登录界面功能需求[list=1]
- LoginView
- LoginPresenter
android:imeOptions="actionNext"//下一个android:imeOptions="actionGo"//启动android:imeOptions="actionDone"//完成android:imeOptions="actionPrevious"//上一个android:imeOptions="actionSearch"//搜索android:imeOptions="actionSend"//发送监听软键盘Action事件,发起登录
private TextView.OnEditorActionListener mOnEditorActionListener = new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_GO) { startLogin(); return true; } return false; }};EMCallBack的适配器 EMCallBack是环信的一个请求回调接口,包括请求成功的回调onSuccess,请求失败的回调onError和请求进度回调onProgress,但在实际使用过程中,通常只使用到请求成功和失败的回调,请求进度回调通常留在那里成了一个空方法,对于一个有代码洁癖的搬砖师来说,这是很难受的。所以我们可以创建一个适配器类实现这个接口,使用时用适配器类来替换EMCallBack接口,这样只需要覆写我们想覆写的方法就可以了。
//EMCallBack接口的适配器public class EMCallBackAdapter implements EMCallBack{ @Override public void onSuccess() { } @Override public void onError(int i, String s) { } @Override public void onProgress(int i, String s) { }}//EMCallBack适配器的使用private EMCallBackAdapter mEMCallBack = new EMCallBackAdapter() { @Override public void onSuccess() { ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mLoginView.onLoginSuccess(); } }); } @Override public void onError(int i, String s) { ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mLoginView.onLoginFailed(); } }); }};Android6.0动态权限管理
Andrioid6.0对权限进行了分组,涉及到用户敏感信息的权限只能动态的去获取。当应用的targetSdkVersion小于23时,会默认采用以前的权限管理机制,当targetSdkVersion大于等于23时并且运行在Andorid6.0系统上,它才会采用这套新的权限管理机制。参考 动态获取写磁盘权限环信SDK内部维护了一个数据库来存储聊天记录等数据,需要读写磁盘的权限,所以我们在用户登录之前要申请该权限。类似的,很多同学在集成百度地图或者高德地图时常常不能正常定位,往往是忽略了在Android6.0上需要获取位置的权限。
/** * 是否有写磁盘权限 */private boolean hasWriteExternalStoragePermission() { int result = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); return result == PermissionChecker.PERMISSION_GRANTED;}/** * 申请权限 */private void applyPermission() { String permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE}; ActivityCompat.requestPermissions(this, permissions, REQUEST_WRITE_EXTERNAL_STORAGE);}/** * 申请权限回调 */@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) { switch (requestCode) { case REQUEST_WRITE_EXTERNAL_STORAGE: if (grantResults[0] == PermissionChecker.PERMISSION_GRANTED) { login(); } else { toast(getString(R.string.not_get_permission)); } break; }}
注册界面功能需求[list=1]
- RegisterView
- RegisterPresenter
private static final String USER_NAME_REGEX = "^[a-zA-Z]\\w{2,19}$";//用户名的正则表达式private static final String PASSWORD_REGEX = "^[0-9]{3,20}$";//密码的正则表达式
- ^ 匹配输入字符串的开始位置
- [a-zA-Z] 字符范围。匹配指定范围内的任意字符。
- \w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
- $ 匹配输入字符串的结束位置
云数据库 Bmob集成Bmob开发文档
- 注册创建应用
- 下载SDK
- 导入SDK
- 初始化SDk
protected void hideSoftKeyboard() { if (mInputMethodManager == null) { mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); } mInputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);}注册用户到BmobBmob用户管理
private void registerBmob(final String userName, final String pwd) { User user = new User(userName, pwd); user.signUp(new SaveListener注册到环信() { @Override public void done(User user, BmobException e) { if (e == null) { registerEaseMob(userName, pwd); } else { notifyRegisterFailed(e); } } });}
private void registerEaseMob(final String userName, final String pwd) { ThreadUtils.runOnBackgroundThread(new Runnable() { @Override public void run() { try { EMClient.getInstance().createAccount(userName, pwd); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mRegisterView.onRegisterSuccess(); } }); } catch (HyphenateException e) { e.printStackTrace(); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mRegisterView.onRegisterError(); } }); } } });}用户名已注册的处理当我们注册一个用户名到Bmob云数据库后,使用相同的用户名再次注册,Bmob会返回错误码202,信息为username '%s' already taken。所以我们应该处理该错误,通知用户换一个用户名注册。Bmob错误码
private void notifyRegisterFailed(BmobException e) { if (e.getErrorCode() == Constant.ErrorCode.USER_ALREADY_EXIST) { mRegisterView.onResisterUserExist(); } else { mRegisterView.onRegisterError(); }}主界面
底部导航条 主界面底部是一个Tab导航条,实现的方法可以有很多种,我们可以使用RadioGroup或者FragmentTabHost, 或者我们可以自定义一个控件,为了不重复造轮子,本Demo使用了第三方导航条BottomBar。BottomBar的使用请参考其Github地址。第三方导航条Fragment的切换
private OnTabSelectListener mOnTabSelectListener = new OnTabSelectListener() { @Override public void onTabSelected(@IdRes int tabId) { FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.fragment_container, FragmentFactory.getInstance().getFragment(tabId)).commit(); }};动态界面
MVP实现
- DynamicView
- DynamicPresenter
@Overridepublic void logout() { mDynamicView.onStartLogout(); EMClient.getInstance().logout(true, mEMCallBackAdapter);}联系人界面
MVP实现
- ContactView
- ContactPresenter
- LinearLayoutManager 线性布局管理器 (类似ListView效果)
- GridLayoutManager 网格布局管理器 (类似GridView效果)
- StaggeredGridLayoutManager 分散网格布局管理器(瀑布流效果)
private void initRecyclerView() { mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));//设置布局管理器 mRecyclerView.setHasFixedSize(true);//设置true如果列表内容不会影响RecyclerView的大小 mContactListAdapter = new ContactListAdapter(getContext(), mContactPresenter.getContactList()); mContactListAdapter.setOnItemClickListener(mOnItemClickListener); mRecyclerView.setAdapter(mContactListAdapter);}ContactListAdapter的实现 ContactListItemView
运用模块化的思想,将联系人的列表项抽取成一个独立的自定义组合式控件ContactListItemView。ContactListItemView只需传入一个与之对应的数据模型ContactListItem即可完成渲染。联系人是否在同一个组
当多个联系人的首字符相同时,只有第一个ContactListItemView显示首字符,后续首字符相同的ContactListItemView均不显示首字符。在ContactListItem中声明一个布尔型变量showFirstLetter来标记是否显示首字符。该变量在创建ContactListItem时赋值。
/** * 获取联系人列表数据 * @throws HyphenateException */private void startGetContactList() throws HyphenateException { ListCardView的使用contacts = EMClient.getInstance().contactManager().getAllContactsFromServer(); DatabaseManager.getInstance().deleteAllContacts(); if (!contacts.isEmpty()) { for (int i = 0; i < contacts.size(); i++) { ContactListItem item = new ContactListItem(); item.userName = contacts.get(i); if (itemInSameGroup(i, item)) { item.showFirstLetter = false; } mContactListItems.add(item); saveContactToDatabase(item.userName); } }}/** * 当前联系人跟上个联系人比较,如果首字符相同则返回true * @param i 当前联系人下标 * @param item 当前联系人数据模型 * @return true 表示当前联系人和上一联系人在同一组 */private boolean itemInSameGroup(int i, ContactListItem item) { return i > 0 && (item.getFirstLetter() == mContactListItems.get(i - 1).getFirstLetter());}
CardView继承自FrameLayout, 是Material Design里面的卡片设计,带有圆角和阴影效果。CardView效果非常好看,但也不能滥用,比如:
更多的使用规范,请参考Material Design的设计规范Material Design Cards。这里我们给ContactListItemView的布局里面包了一层CardView,实际上是不可取的做法,这里只是为了展示CardView的使用姿势,实际项目中请大家遵循Material Design的设计规范。参考SwipeRefreshLayout的使用
//设置SwipeRefreshLayout的颜色mSwipeRefreshLayout.setColorSchemeResources(R.color.qq_blue, R.color.qq_red);//设置SwipeRefreshLayout的监听器mSwipeRefreshLayout.setOnRefreshListener(mOnRefreshListener);自定义控件SlideBar分类字符数组
rivate static final String SECTIONS = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L" , "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};绘制居中文本FontMetrics
@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) { mTextSize = h * 1.0f / SECTIONS.length;//计算分配给字符的高度 Paint.FontMetrics fontMetrics = mPaint.getFontMetrics(); float mTextHeight = fontMetrics.descent - fontMetrics.ascent;//获取绘制字符的实际高度 mTextBaseline = mTextSize / 2 + mTextHeight/2 - fontMetrics.descent;//计算字符居中时的baseline}@Overrideprotected void onDraw(Canvas canvas) { float x = getWidth() * 1.0f / 2; float baseline = mTextBaseline; for(int i = 0; i < SECTIONS.length; i++) { canvas.drawText(SECTIONS[i], x, baseline, mPaint); baseline += mTextSize; }}[/i]在ContactFragment里面监听SlideBar的事件 当用户在SlideBar上ACTION_DOWN和ACTION_MOVE时,如果用户触摸到的首字符发生变化,则会回调监听器onSectionChange,当ACTION_UP时回调onSlidingFinish()。
private SlideBar.OnSlideBarChangeListener mOnSlideBarChangeListener = new SlideBar.OnSlideBarChangeListener() { @Override public void onSectionChange(int index, String section) { mSection.setVisibility(View.VISIBLE);//显示中间绿色背景的首字符 mSection.setText(section); scrollToSection(section);//滚动RecyclerView到用户滑到的首字符 } @Override public void onSlidingFinish() { mSection.setVisibility(View.GONE);//隐藏中间绿色背景的首字符 }};联系人点击事件当单击联系人时跳转到聊天界面,当长按联系人时弹出Dialog询问用户是否删除好友。
private ContactListAdapter.OnItemClickListener mOnItemClickListener = new ContactListAdapter.OnItemClickListener() { /** * 单击跳转到聊天界面 * @param name 点击item的联系人名字 */ @Override public void onItemClick(String name) { startActivity(ChatActivity.class, Constant.Extra.USER_NAME, name); } /** * 长按删除好友 * @param name 点击item的联系人名字 */ @Override public void onItemLongClick(final String name) { showDeleteFriendDialog(name); }};添加好友界面
MVP实现
- AddFriendView
- AddFriendPresenter
@Overridepublic void searchFriend(final String keyword) { mAddFriendView.onStartSearch(); //注:模糊查询只对付费用户开放,付费后可直接使用。 BmobQuerygreenDAOgreenDAO是Android SQLite数据库ORM框架的一种。ORM即对象关系映射, object/relational mapping, 将Java对象映射成数据库的表。我们需要存储联系人数据到数据库,在添加好友界面,需要判断搜索出来的用户是否已经是联系人,如果已经是好友,则应显示“已添加”。其他ORM框架 参考 创建实体类query = new BmobQuery (); query.addWhereContains("username", keyword).addWhereNotEqualTo("username", EMClient.getInstance().getCurrentUser()); query.findObjects(new FindListener () { @Override public void done(List list, BmobException e) { processResult(list, e); } });}
@Entitypublic class Contact { @Id public Long id; public String userName;}初始化
public void init(Context context) { DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(context, Constant.Database.DATABASE_NAME, null); SQLiteDatabase writableDatabase = devOpenHelper.getWritableDatabase(); DaoMaster daoMaster = new DaoMaster(writableDatabase); mDaoSession = daoMaster.newSession();}保存联系人
public void saveContact(String userName) { Contact contact = new Contact(); contact.setUsername(userName); mDaoSession.getContactDao().save(contact);}查询联系人
public List删除所有联系人queryAllContacts() { List list = mDaoSession.getContactDao().queryBuilder().list(); ArrayList contacts = new ArrayList (); for (int i = 0; i < list.size(); i++) { String contact = list.get(i).getUsername(); contacts.add(contact); } return contacts;}
public void deleteAllContacts() { ContactDao contactDao = mDaoSession.getContactDao(); contactDao.deleteAll();}发送好友请求 AddFriendItemView里面处理添加好友的点击事件
@OnClick(R.id.add)public void onClick() { String friendName = mUserName.getText().toString().trim(); String addFriendReason = getContext().getString(R.string.add_friend_reason); AddFriendEvent event = new AddFriendEvent(friendName, addFriendReason);//通过EventBus发布添加好友事件 EventBus.getDefault().post(event);}AddFriendPresenterImpl实现发送好友请求
@Subscribe(threadMode = ThreadMode.BACKGROUND)public void addFriend(AddFriendEvent event) { try { EMClient.getInstance().contactManager().addContact(event.getFriendName(), event.getReason()); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mAddFriendView.onAddFriendSuccess(); } }); } catch (HyphenateException e) { e.printStackTrace(); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mAddFriendView.onAddFriendFailed(); } }); }在联系人列表中监听联系人变化当新增好友或者被好友删除时刷新联系人列表。
private EMContactListenerAdapter mEMContactListener = new EMContactListenerAdapter() { @Override public void onContactAdded(String s) { mContactPresenter.refreshContactList(); } @Override public void onContactDeleted(String s) { mContactPresenter.refreshContactList(); }};聊天界面
MVP实现
- ChatView
- ChatPresenter
mEdit.addTextChangedListener(mTextWatcher);private TextWatcherAdapter mTextWatcher = new TextWatcherAdapter() { @Override public void afterTextChanged(Editable s) { mSend.setEnabled(s.length() != 0); }};动画文件
- anim文件夹:存放补间动画
- animator文件夹:存放属性动画
- drawable文件夹:存放帧动画
- animator文件夹:存放属性动画
9文件制作官方说明
发送一条消息 返回消息的类型 根据是发送的消息还是接受的消息,来创建不同的item。
@Overridepublic int getItemViewType(int position) { EMMessage message = mMessages.get(position); return message.direct() == EMMessage.Direct.SEND ? ITEM_TYPE_SEND_MESSAGE : ITEM_TYPE_RECEIVE_MESSAGE;}是否显示时间戳的判断
/** * 如果两个消息之间的时间太近,就不显示时间戳 */private boolean shouldShowTimeStamp(int position) { long currentItemTimestamp = mMessages.get(position).getMsgTime(); long preItemTimestamp = mMessages.get(position - 1).getMsgTime(); boolean closeEnough = DateUtils.isCloseEnough(currentItemTimestamp, preItemTimestamp); return !closeEnough;}更新消息的状态处理三种消息状态,正在发送中INPROGRESS,发送成功SUCCESS,发送失败FAIL。
private void updateSendingStatus(EMMessage emMessage) { switch (emMessage.status()) { case INPROGRESS: mSendMessageProgress.setVisibility(VISIBLE); mSendMessageProgress.setImageResource(R.drawable.send_message_progress); AnimationDrawable drawable = (AnimationDrawable) mSendMessageProgress.getDrawable(); drawable.start(); break; case SUCCESS: mSendMessageProgress.setVisibility(GONE); break; case FAIL: mSendMessageProgress.setImageResource(R.mipmap.msg_error); break; }}接收一条消息 监听消息的接收,当收到一条消息后,通知MessageListAdapter进行刷新,并且滚动RecyclerView到底部。
private EMMessageListenerAdapter mEMMessageListener = new EMMessageListenerAdapter() { @Override public void onMessageReceived(final List初始化聊天记录list) { ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { final EMMessage emMessage = list.get(0); mChatPresenter.makeMessageRead(mUserName); mMessageListAdapter.addNewMessage(emMessage); smoothScrollToBottom(); } }); }};
@Overridepublic void loadMessages(final String userName) { ThreadUtils.runOnBackgroundThread(new Runnable() { @Override public void run() { EMConversation conversation = EMClient.getInstance().chatManager().getConversation(userName); if (conversation != null) { //获取此会话的所有消息 List加载更多聊天记录messages = conversation.getAllMessages(); mEMMessageList.addAll(messages); //指定会话消息未读数清零 conversation.markAllMessagesAsRead(); } ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mChatView.onMessagesLoaded(); } }); } });}
@Overridepublic void loadMoreMessages(final String userName) { if (hasMoreData) { ThreadUtils.runOnBackgroundThread(new Runnable() { @Override public void run() { EMConversation conversation = EMClient.getInstance().chatManager().getConversation(userName); EMMessage firstMessage = mEMMessageList.get(0); //SDK初始化加载的聊天记录为20条,到顶时需要去DB里获取更多 //获取startMsgId之前的pagesize条消息,此方法获取的messages SDK会自动存入到此会话中,APP中无需再次把获取到的messages添加到会话中 final List会话界面messages = conversation.loadMoreMsgFromDB(firstMessage.getMsgId(), DEFAULT_PAGE_SIZE); hasMoreData = (messages.size() == DEFAULT_PAGE_SIZE); mEMMessageList.addAll(0, messages); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mChatView.onMoreMessagesLoaded(messages.size()); } }); } }); } else { mChatView.onNoMoreData(); }}
MVP实现
- ConversationView
- ConversationPresenter
加载所有会话
@Override
public void loadAllConversations() {
ThreadUtils.runOnBackgroundThread(new Runnable() {
@Override
public void run() {
Mapconversations = EMClient.getInstance().chatManager().getAllConversations();
mEMConversations.addAll(conversations.values());
//根据最后一条消息的时间进行排序
Collections.sort(mEMConversations, new Comparator() {
@Override
public int compare(EMConversation o1, EMConversation o2) {
return (int) (o2.getLastMessage().getMsgTime() - o1.getLastMessage().getMsgTime());
}
});
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
mConversationView.onAllConversationsLoaded();
}
});
}
});
}
未读消息计数更新
环信官方文档
会话列表中未读消息的更新
private EMMessageListenerAdapter mEMMessageListenerAdapter = new EMMessageListenerAdapter() {
@Override
public void onMessageReceived(Listlist) {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
toast(getString(R.string.receive_new_message));
//当收到一个新消息时,重新加载会话列表。
mConversationPresenter.loadAllConversations();
}
});
}
};
BottomBar badge的更新
private EMMessageListenerAdapter mEMMessageListenerAdapter = new EMMessageListenerAdapter() {
//该回调在子线程中调用
@Override
public void onMessageReceived(Listlist) {
updateUnreadCount();
}
};
private void updateUnreadCount() {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
BottomBarTab bottomBar = mBottomBar.getTabWithId(R.id.conversations);
int count = EMClient.getInstance().chatManager().getUnreadMsgsCount();
bottomBar.setBadgeCount(count);
}
});
}
标记消息已读
加载聊天数据时标记已读
//指定会话消息未读数清零
conversation.markAllMessagesAsRead();
在聊天界面收到新消息时将消息标记已读
private EMMessageListenerAdapter mEMMessageListener = new EMMessageListenerAdapter() {聊天界面返回时更新未读badge
@Override
public void onMessageReceived(final Listlist) {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
final EMMessage emMessage = list.get(0);
if (emMessage.getUserName().equals(mUserName)) {
//标记消息已读
mChatPresenter.makeMessageRead(mUserName);
mMessageListAdapter.addNewMessage(emMessage);
smoothScrollToBottom();
}
}
});
}
};
@Override
protected void onResume() {
super.onResume();
updateUnreadCount();
}
消息通知
通知
判断app是否在前台
public boolean isForeground() {
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
ListrunningAppProcesses = am.getRunningAppProcesses();
if (runningAppProcesses == null) {
return false;
}
for (ActivityManager.RunningAppProcessInfo info :runningAppProcesses) {
if (info.processName.equals(getPackageName()) && info.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return true;
}
}
return false;
}
如果app在后台则弹出Notification
private void showNotification(EMMessage emMessage) {声音
String contentText = "";
if (emMessage.getBody() instanceof EMTextMessageBody) {
contentText = ((EMTextMessageBody) emMessage.getBody()).getMessage();
}
Intent chat = new Intent(this, ChatActivity.class);
chat.putExtra(Constant.Extra.USER_NAME, emMessage.getUserName());
PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, chat, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new Notification.Builder(this)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.avatar1))
.setSmallIcon(R.mipmap.ic_contact_selected_2)
.setContentTitle(getString(R.string.receive_new_message))
.setContentText(contentText)
.setPriority(Notification.PRIORITY_MAX)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();
notificationManager.notify(1, notification);
}
初始化SoundPool
private void initSoundPool() {
mSoundPool = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);
mDuanSound = mSoundPool.load(this, R.raw.duan, 1);
mYuluSound = mSoundPool.load(this, R.raw.yulu, 1);
}
播放音效
private EMMessageListenerAdapter mEMMessageListenerAdapter = new EMMessageListenerAdapter() {多设备登录
@Override
public void onMessageReceived(Listlist) {
if (isForeground()) {
mSoundPool.play(mDuanSound, 1, 1, 0, 0, 1);
} else {
mSoundPool.play(mYuluSound, 1, 1, 0, 0, 1);
showNotification(list.get(0));
}
}
};
环信官方文档
private EMConnectionListener mEMConnectionListener = new EMConnectionListener() {
@Override
public void onConnected() {
}
@Override
public void onDisconnected(int i) {
if (i == EMError.USER_LOGIN_ANOTHER_DEVICE) {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
startActivity(LoginActivity.class);
toast(getString(R.string.user_login_another_device));
}
});
}
}
};
github地址:https://github.com/uncleleonfan/QQDemo 收起阅读 »
直聘学院| 独角兽产品养成记【深度对话摩拜单车/喜马拉雅FM等产品总监】
产品工作如何让你们的市场、运营、技术同事为你欢呼尖叫?
怎么样的产品策略能不靠投资后来居上逆袭行业排名第一?
2016年11月20日
让那些独角兽产品的创造者们和我们一起聊聊:
独角兽产品养成记!
活动嘉宾介绍:
活动流程
13:30-14:00丨现场签到 & 交流
14:00-15:00丨摩拜单车Stella主题分享《线上线下结合的产品实践》
15:00-16:00丨涂图石强主题分享《如何用产品思维驱动业务实践》
16:00-17:00丨Neta干田主题分享《运营背后的坑是这么填的》
17:00 —— 丨全场合影
关于直聘学院
对话产品总监是BOSS直聘 「 直聘学院 」 旗下系列活动之一。联合明星公司&合作伙伴共同发起,为互联网领域的产品经理从业者举办的专场沙龙,旨在通过纯业内的干货分享,推动互联网行业从业者职业路上进步。
特别鸣谢
抢票链接:http://gz.huodongxing.com/event/5358825198900
收起阅读 »
减少APK的大小,Android官方这样说
减小APK的大小。到处搜索一下各路大神的方法。还是觉得无论从原理上还是具体做法上都是官方的比较全面。所以就翻译了一下,分享出来。主要是用Google Translate,然后自己稍微按照中文逻辑修了一下。如有不妥的地方,请多提意见。(PS:另外还碰到了传奇的65535方法数这个大坑,后面再写这个。文中有些超链接可能需要梯子)
Android官网链接:Reduce APK Size
用户经常会避免下载看起来过大的应用程序,特别是在新兴市场,设备连接到常见的2G和3G网络或者使用按字节付费的网络。本文介绍如何减少应用程序的APK大小,让更多使用者下载你的应用程序。
一、了解APK结构
在讨论如何缩小应用程序的大小之前,先了解应用程序APK的结构,是有帮助的。APK文件包含ZIP文件,其中包含构成应用程序的所有文件。这些文件包括Java类文件,资源文件和已编译资源的文件。
APK包含以下目录:
- META-INF/:包含CERT.SF和CERT.RSA签名文件,以及MANIFEST.MF清单文件。
- assets/:包含应用程序的资源,应用程序可以使用AssetManager对象检索该资源。
- res/: 包含未编译到resources.arsc中的资源。
- lib/:包含特定处理器的软件层的编译代码。此目录包含每个平台类型的子目录,如armeabi,armeabi-v7a,arm64-v8a,x86,x86_64和mips。
- resources.arsc:包含已编译的资源。此文件包含来自res / values /文件夹的所有配置的XML内容。包装工具提取此XML内容,将其编译为二进制形式,并归档内容。此内容包括语言字符串和样式,以及未直接包含在resources.arsc文件中的内容路径,例如布局文件和图像。
- classes.dex:包含以Dalvik / ART虚拟机理解的DEX文件格式而编译的类。
- AndroidManifest.xml:包含核心Android清单文件。此文件列出应用程序的名称,版本,访问权限和引用的库文件。该文件使用Android的二进制XML格式。
res/layout/preferences.xml: Warning: The resource R.layout.preferences appears to be unused [UnusedResources]
注意:lint工具不扫描assets/文件夹,它是通过反射来发现引用的资源或已链接到你的应用程序的库文件。此外,它不会删除资源;它只会提醒你们他们的存在。 你添加到代码的库可能包含未使用的资源。如果在应用程序的build.gradle文件中启用shrinkResources,Gradle可以自动删除资源。android { // Other settings buildTypes { release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }}要使用shrinkResources,必须启用代码缩减。在构建过程中,首先要用ProGuard删除未使用的代码,但留下未使用的资源。然后Gradle删除未使用的资源。有关ProGuard和Android Studio帮助你减少APK大小的其他方法的详细信息,请参阅Shrink Your Code and Resources。在Android Gradle Plugin 0.7及更高版本中,你可以声明你的应用程序支持的配置。 Gradle使用resConfig 、resConfigs flavor和defaultConfig选项并将此信息传递给构建系统。然后,构建系统会阻止来自其他不受支持的配置的资源出现在APK中,从而减少APK的大小。有关此功能的详细信息,请参阅 Remove unused alternative resources最小化库中的资源使用开发Android应用程序时,通常使用外部库来提高应用程序的可用性和多功能性。例如,你可以引用Android Support Library 以改善旧设备上的用户体验,或者你可以使用 Google Play Services 检索应用内文字的自动翻译。如果库是为服务器或桌面设计的,它可能包括你的应用程序不需要的许多对象和方法。要仅包含应用程序需要的库的部分,你可以编辑库的文件(如果许可证允许你修改库)。你也可以使用其他适合移动设备的库给你的应用添加特定功能。
注意: ProGuard可以清理引用库导入的一些不必要的代码,但它不能删除库的大型内部依赖项 。仅支持特定密度Android支持非常大的设备集,包括各种屏幕密度。在Android 4.4(API级别19)及更高版本中,框架支持各种密度: ldpi,mdpi,tvdpi,hdpi,xhdpi,xxhdpi和xxxhdpi。虽然Android支持所有这些密度,但你不需要细化资源到适合每个密度。如果你知道只有一小部分用户使用具有特定密度的设备,请考虑是否需要将这些密度捆绑到应用中。如果你不包括特定屏幕密度的资源,Android会自动缩放最初为其他屏幕密度设计的现有资源。如果你的应用只需要缩放的图片,你可以通过在drawable-nodpi /中使用图片的单个变体来节省更多空间。我们建议每个应用程序至少包含一个xxhdpi图片版本。有关屏幕密度的详细信息,请参阅 Screen Sizes and Densities。减少动画帧逐帧动画会大幅增加APK的大小。图1显示了在目录中分成多个PNG文件的逐帧动画的示例。每个图像是动画中的一帧。对于添加到动画中的每个帧,都需要增加APK中存储的图片数量。在图1中,图像在应用程序中以30 FPS动画。如果图像仅以15FPS动画化,则动画将仅需要所需帧的数目的一半。
使用Drawable对象一些图像不需要静态图像资源; framework可以在运行时动态地绘制图像。 Drawable(XML中的<shape>)可能会占用你APK中的少量空间。此外,XML Drawable对象还能产生符合Material Design准则的单色图像。重用资源你可以为图像的变体使用单一的资源,例如同一图像的有色,阴影或旋转版本。但是,我们建议你重复使用相同的资源集,在运行时根据需要进行自定义。Android提供了几个实用程序来更改资产的颜色,使用Android 5.0(API级别21)或更高版本上的android:tint和tintMode属性。对于较低版本的平台,请使用 ColorFilter类。你还可以省略只是等效于另一个资源的资源。以下代码段提供了一个例子,通过简单地将原始图像旋转180度,将“展开”箭头转换为“折叠”箭头图标:
<?xml version="1.0" encoding="utf-8"?><rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_arrow_expand" android:fromDegrees="180" android:pivotX="50%" android:pivotY="50%" android:toDegrees="180" />从代码中呈现你还可以通过程序性渲染图片来减少APK大小。这个过程也释放了空间,因为你不再在APK中存储图像文件。压缩PNG文件aapt工具可以在构建过程期间优化放置在res / drawable /中的图像资源,以及无损压缩。例如, aapt工具可以将不需要多于256种颜色的真彩色PNG转换为带有调色板的8位PNG。这样做会产生质量相同但占用内存较小的映像。请记住,aapt有以下限制:
- aapt工具不会压缩资源/文件夹中包含的PNG文件
- 图像文件需要使用256个或更少的颜色的aapt工具来优化它们。
- aapt工具可能会使已压缩的PNG文件膨胀。为了防止这种情况,你可以在Gradle中使用cruncherEnabled标志为PNG文件禁用此过程:
aaptOptions { cruncherEnabled = false}压缩PNG和JPEG文件你可以使用像 pngcrush,pngquant,或 zopflipng等工具来减少PNG文件大小,而不会丢失图像质量。所有这些工具都可以减少PNG文件大小,同时保持图像质量。pngcrush工具特别有效:此工具在PNG过滤器和zlib(Deflate)参数上迭代,使用过滤器和参数的每个组合来压缩图像。然后选择产生最小压缩输出的配置。对于JPEG文件,你可以使用 packJPG 等工具将JPEG文件压缩为更紧凑的形式。使用WebP文件格式除了使用PNG或JPEG文件,你还可以为你的图像使用WebP 文件格式。 WebP格式提供有损压缩(如JPEG)和透明度(如PNG),还可以提供比JPEG或PNG更好的压缩效果。但是,使用WebP文件格式有一些显着的缺点。 首先,在低于Android 3.2(API级别13)的平台的版本中不支持WebP。 第二,系统解码WebP比PNG文件需要更长的时间。
注意:只有当所包含的图标使用PNG格式时,Google Play才接受APK。如果你打算通过Google Play发布应用,则无法对应用图标使用其他文件格式(如JPEG或WebP)。使用矢量图形你可以使用矢量图形创建独立于分辨率的图标和其他可伸缩图片。 使用这些图形可以大大减少APK的大小。 矢量图形在Android中表示为 VectorDrawable对象。 使用 VectorDrawable对象,100字节的文件可以生成屏幕大小的清晰图像。 然而,系统渲染每个 VectorDrawable对象需要大量的时间,较大的图像需要更长的时间才能出现在屏幕上。 因此,只有在显示小图像时才考虑使用这些矢量图形。有关使用 VectorDrawable更多信息,请参阅 Working with Drawables。三、减少原生和Java代码有几种方法可以用来减少应用程序中Java和原生代码库的大小。删除不必要的生成的代码确保了解自动生成的任何代码的足迹。例如,许多协议缓冲工具生成过多的方法和类,可以使应用程序的大小增加一倍或三倍。删除枚举单个枚举可以使应用程序的classes.dex文件添加大约1.0到1.4 KB的大小。 这些添加可以快速积累为复杂的系统或共享库。 如果可能,请考虑使用@IntDef注释和 ProGuard 来除去枚举并将它们转换为整数。 此类型转换保留枚举的所有类型的安全性好处。减少本地二进制文件的大小如果你的应用使用原生代码和Android NDK,你还可以通过优化代码来减小应用的大小。两个有用的技术是删除调试符号和提取原生库。
- 删除调试符号
- 避免提取原生库
将.so文件存储在APK中未压缩的文件,并在应用清单的<application> 元素中将android:extractNativeLibs标记设置为false。 这将防止 PackageManager在安装过程中将.so文件从APK复制到文件系统,并且将具有使你的应用程序的delta更新更小的额外好处。
四、维护多个精益版APK
你的APK可以包含用户下载但从不使用的内容,例如区域或语言信息。 要为用户创建最低限度的下载,你可以将应用细分为多个APK,并根据屏幕尺寸或GPU纹理支持等因素进行区分。
当用户下载你的应用时,其设备会根据设备的功能和设置接收正确的APK。这样,设备不会接收设备没有的功能的资源。例如,如果用户具有hdpi设备,则他们可能不需要你为具有更高密度显示的设备添加的xxxhdpi资源。
更多信息,请参阅 Configure APK Splits 和 Maintaining Multiple APKs。
本文作者:Android 工程师Kevin_Han 收起阅读 »
2016程序员技术交流年会
即将于2016年12月10日在北京东城区百富怡大酒店举办
大会介绍
大会坚持公益性质且技术干货为主,与数百位最具影响力的行业领袖和技术领军人物共同学习、了解最新互联网技术趋势,分享和讨论互联网最新研究成果和前沿技术,探讨互联网技术如何定义未来,致力于以多种形式灵活整合、分享软件和互联网技术最新动态,评估最新行业趋势;为技术研发人员开拓思路,找寻有效的研究方向。
届时将会有知名媒体到现场报道,国内著名门户网站、社交网站、O2O、移动互联网等各个领域产品和设计专家参与,无论您处于互联网行业的哪个领域,2016程序员技术交流年会将成为引领互联网技术的风向标,汇聚领域的顶尖专家,打造一场技术领域极具价值的技术盛会。
大会亮点
跨行业,跨技术领域,跨国度,年度盛会
与真正的程序员开发贡献者和参与者,直接互动
大数据,云计算,操作系统,全球领先的AI,VR技术,精彩纷呈
我们是谁
浪曦网是由中国支持软件程序员的企业、社区以及个人所组织的一个开发者联盟企业,一直以来致力于在中国软件开发推广,推动中国软件社区成为全球软件和硬件的积极贡献者。并携手国内社区,高校,企业,政府,共创健康可持续发展的生态体系。
我们打算办一个怎样的大会
通过这次大会,我们希望能够实现:
软件开发行业、企业的高手齐聚一堂、激荡火花
跨行业、跨技术领域、跨国度的年度盛会
与真正的软件开发贡献者、参与者,直接互动
最终达成我们“天下程序员是一家、浪曦携手迸火花”的理想!
会议形式
为了实现上述目标,我们策划了丰富的会议形式:
主题演讲:浪曦大牛为您带来精彩的软件开发模式相关的深度内容
高峰对话:行业领军人物,共同探讨程序员未来的发展
分论坛:包括操作系统、云计算、大数据、前沿技术、等诸多领域,精彩纷呈,一定会有你感兴趣的话题。
圆桌高峰会:邀请企业、社区、协会及专家代表,畅谈分享企业软件开发治理的心得,流程,实践与各种酸甜苦辣。
浪曦之夜:欢聚一堂、敞开心扉、畅所欲言的社区见面会。(仅限受邀嘉宾,讲师,赞助伙伴,及大会工作人员,恕不对外开放)
创新互动
和一般的大会不一样,我们知道草根程序员社区听众,期盼听到纯干货,更希望与讲师能有更多互动,因此我们安排了:讲师打赏(提供讲师更高的动力分享干货) 、现场在线抽奖
大会规模
500人,大部分来自浪曦网达到一定层次的高级会员
大会主办方
大会合作方
合作媒体
嘉宾名单
胡辛征 中国电子工业出版社社长
吴召学 滴滴运营总监CTO
黄维维 云和恩墨运营总监
郑文平 世界瑜伽大会组委会副主席
罗 皆 大数据实战项目专家
方 沛 阿里巴巴前端总指挥
更多嘉宾名单介绍,请关注浪曦官网 www.langsin.com
参加对象
企业创始人、CEO,合伙人、董事长、CTO 、VP 、总工程师 、总经理、总架构师 ,高级架构师 、资深架构师、高级经理、技术主管、技术负责人、高级工程师 、资深工程师、开发开程师 、运维工程师、研究员等 软件行业新上岗一线技术工程师、拟提拔一线经理、二线经理、项目经理。
注册费
赞助企业与浪曦网高级会员免注册费及餐费(如您是浪曦会员填表时请附上您的浪曦网会员用户名)
无赞助企业与非会员注册费:1000元/人,含餐。
从五千元到二十万元不等的多种赞助推广方案。
我要报名:http://www.bagevent.com/event/264024
大会招商部
联系人:刘先生
手机:18210801352
Q Q:1598234192
邮箱:lhs_852@163.com 收起阅读 »
从中国女排里约夺冠看企业培训管理
中国人对于排球运动的热情始于20世纪80年代,中国女排曾获得过“五连冠”的辉煌,郎平的“铁榔头”称号在当时成为了中国女排的代名词。当时的中国刚刚开始改革开放,中国女排在1981年的世界杯中战胜日本队为中国人创造了一个英雄形象。
在本届里约奥运会的女排赛场上,中国女排一路披荆斩棘,先是以2胜3负的小组成绩进入八强,然后接着在1/4决赛中力压上届卫冕冠军东道主巴西队,接着在半决赛中击败了小组赛中曾获胜的荷兰队,最后在决赛中以3:1战胜了塞尔维亚夺得了冠军!有人说中国女排这次在里约奥运会是爆发了“洪荒之力”,让中国在12年之后重返世界女排巅峰的地位,让我们再次领略了什么叫“女排精神”,让中国人重振民族自豪感!那么,中国女排的里约夺冠对于我们的企业培训管理工作,又有什么启发呢?
NO.1 一支队伍
随着2004年奥运会“黄金一代”的逐渐淡出,郎平教练在采访中是这样说的:“虽然今年最主要任务是奥运会,但是训练不能只考虑奥运会,还要考虑明年、后年,不能说完成奥运会的比赛任务,下个奥运周期的事儿就不管了。国家队人才的培养需要长期的规划,有新人我们是一定要培养的。”在郎平执教时代,一个又一个新人被挖掘出来,国家队不但实现了技术的上年年进步,球员也呈现越来越年轻化的趋势。郎平在执教上,擅长整合管理。利用有限的资源,将本土化与国际化相结合,打造一支高效的、年轻化的复合型团队。复合型团队,即由主教练、助理教练、陪打教练、医生、康复师、体能师、营养师、科研、信息研究、数据统计等专业人才组成。
培训是企业培养人才的重要手段。企业的每个发展阶段都有企业最需要的人才和相应的岗位,企业只有通过持续不断地培训,员工的工作技能和个人综合素质才会得到显著提升,为企业高速发展做出他们应有的贡献。对于企业管理者来说,员工培养是一个长期的、持续的过程。不管是发掘潜力股还是发现培养新人对于打造优秀企业团队都是同等重要的。
强化自主培训功能,加强对员工特别是一线员工的教育和培训,除了聘请外部师资和教育资源,企业内部的重要手段就是发展一支自己的企业内训师队伍。企业内训师队伍建设,需从企业、行业、专业三方面进行考虑。
(1)“企业人”。要求候选对象在本企业工作有一定时间,一般大概在2年以上,这样才能保证他们对企业足够了解,保证其能够准确传递企业文化和业务知识。当候选对象对企业充满感情,才能在内训活动中充满激情,为公司人才培养事业尽自己全力去发光发热。
(2)“行业人”。要求候选对象具备深厚理论基础或者专业的技术水平。他们既可以是管理人才,也可以是业务骨干。由于他们受到广大员工的普遍认可,避免了员工对内训师可能会产生的抵触情绪。候选对象对企业有深入了解,能够给企业留下宝贵的知识积累和经验,可以通过培训让更多的人学习到知识,从而提高企业员工的整体素质。
(3)“专业人”。作为一名内训师,其核心职能就是通过培训活动的开展传达知识、培养人才,这要求内训师候选对象需要具备一定的岗位专业能力,同时要具备强烈的个人动机、一定的文化程度、潜在的培训师特质、主动的服务意识等。
NO.2 一个体系
自从郎平接队之后,构建了“大国家队”的概念。“大国家队”理念,顾名思义就是增加国家队球员人数,集训的国家队大名单扩大到30多人,每次参加国家队集训的也有20至30多人,老中青结合,每个位置保持三到四个人在竞争。
这一小小管理范围的转变,改善的不仅仅是运动成绩,更是充满希望的年轻一代。郎平的大国家队理念目的是广纳贤才,为国家队建立各个梯度的预备人才。这种不拘一格发现人才、使用人才的训练管理理念及人才培养体系,对于企业管理者来说也有一定的启示意义。
在人力资源管理工作中,持续不断地培训不仅让员工得到了个人知识和能力的提高,同时也使员工会发自内心的感激企业促使自我成长,提供自我价值实现的机会。我们不妨搭建一个“2+2”的人才培养体系为企业人才发展铺路。
1、两项制度
建立企业自身的培训体系首先需要明确企业内部的内训师管理、培训项目管理的制度。
(1)内训师管理制度:
从培训的实用性、适应性、持续性和经济性方面考虑,发展内部培训将逐渐成为企业未来培训的主流。完善内训师管理制度,首先从日常管理工作出发。根据内训师级别、授课满意度、授课时长、培训人数等方面,周期性进行星级考核评定。其次,给予一定的物质激励,同时将非货币激励如内训师等级纳入员工职位晋升考评与年度绩效考评,作为主管、经理选拔重要参考因素等,促使并保持内训师在企业中的活跃性,形成完整的内训师闭环管理。
(2)培训项目管理制度:
培训是企业知识传播、积累、创新的重要途径。从企业日常生产运营角度出发,规范培训项目生成的实施流程,实现“常态性”、“临时性”培训项目的分类管理,打通培训项目生成渠道,形成“需求”与“供给”的“市场”机制,提高内部培训质量水平。下面以内部常态化的课程开发培训项目管理为例,介绍一下培训项目管理在实践中的具体操作(图1:课程开发及评估流程项目):
2、两种模式
(1)新员工培养模式:
从企业需求出发,针对新入职员工开展入职培训,通过结业考试、导师制、定期沟通会等一系列基础工作,将企业文化和理念、岗位职责与意识渗透到员工日常工作中。同时也可适当融入一些性格测试等心理学方面的管理方法,如Tree-House-Person房树人测验、FPA性格色彩测试等。
(2)转岗人员培养模式:
在企业内部因市场转型、结构调整、岗位变化等外在原因,时常会有人员转岗、重新学习技能的情况,为了规范转岗人员培养流程,使转岗人员快速融入企业内部新的工作团队、适应企业文化、行为规范、岗位技能与知识对其的要求,帮助转岗人员短时间成长为公司所需要的优秀人才,促进员工与组织共同发展。可结合岗位胜任力模型开展转岗人员培养,进行学习清单制培养,分线条、分技能的清单学习,最后再进行评估与验收。
NO.3 一套方法
说起“女排精神”,郎平说过“单靠精神不能赢球!对于中国女排来说,夺冠的主要还是靠战术、队员素质和临场指挥,建立规范的、科学的培训制度!”在采访中郎平还说,“平时训练不好我们都要加班。这不是讲点故事和心灵鸡汤就够了,技术上我们也做了很多计划,就是要突破自己!”有人说“三从一大”的训练模式是中国女排夺得世界冠军的法宝,“三从一大”就是指训练过程中从难、从严、从实战出发,坚持大运动量训练。
道理相同,没有专业的企业培训方法,就没有高素质的员工队伍。每个行业都有结合自身实际情况的科学培训训练方法。下面,我们分三个步骤来演示一下如何训练和提升客服代表的沟通能力:
第一步:沟通训练情景化
客服人员在为客户服务的过程中应该怎样与客户沟通呢?通过情景对话引出每一环节可能用到的沟通技巧,模拟客户服务工作中可能出现的场景,从客户心理、服务态度、沟通礼仪、倾听、提问、处理抱怨、解决投诉和解答问题等角度,通过多个场景去全面、生动地展示各个环节中客服人员与客户电话去沟通的方法,训练过程中将客服人员代入到沟通情景中,增强学习画面感。
首先,在沟通中客服人员把握客户心理需求的能力非常重要。因为客服工作的目标是让客户满意,而只有满足了客户的心理需求,排除了客户的负面情绪,让客户在享受服务的同时获得一份愉悦的心情,才能给客户留下良好的印象。沟通的能力与客户的需求分不开,首先需要从如何寻找客户的需求开始,有效的开场白、通过询问探询顾客的需求、通过有效聆听了解客户的需求。
其次,就是倾听和询问。有人说沟通是倾听的艺术,这句话充分体现了倾听在沟通中的重要作用。倾听可以获取信息、发现问题,客服人员只有认真倾听,知道客户需要什么样的帮助和服务,客户的不满和抱怨在什么地方,才能对症下药,解决客户的问题。另外,认真倾听还是对客户尊重的一种表现,有利于营造良好的沟通氛围。因此,一名优秀的客服人员必须掌握良好的倾听技巧。
最后,处理客户抱怨。客服人员在工作中经常会听到客户的抱怨,只要客户所得到的产品或服务和他们的期望值之间存在距离,就会产生抱怨。客户投诉处理不当,会影响客户关系和客户感知,甚至还会影响到公司的社会形象,造成恶劣的影响,掌握处理客户抱怨的技巧对于每一位客服人员来说都非常有必要。
第二步:沟通训练套路化
针对客户服务工作中可能出现的沟通问题、客服异议等,通过情景对话将这些技巧套路化,使员工从中学到沟通的技能,掌握解决问题的方法。在客户服务和营销沟通中,常用的套路化技巧有:SPIN销售法、FABE话术、影响力话术、3F法则、三句半等。
第三步:沟通训练模板化
通过上面的技巧套路总结出“万能话术模板”,便于学员在实际工作情景中灵活套用。 下面举两个模板化的例子,图1为当客户抛出问题后客服人员如何接招并处理的技巧套路;图2为当客户提出异议或是投诉抱怨时,客服人员如何处理的技巧套路。掌握了简单的套路后可以将其运用在相同场景的不同问题的处理中,当客服人员遇到类似问题时就能够很顺畅的处理完成客户问题。
中国女排里约夺冠不仅是中国人的一份荣誉,当然中国女排带给我们的启发也不仅仅只有一支队伍、一个体系、一套方法那么简单!对于各行各业来说,女排成功的背后其中所蕴含的理念、方法和精神是一门值得我们好好学习和深入研究的课程。
本文刊载于《客户世界》2016年10月刊文章;原文作者周四维,本文作者作者单位为中移在线服务有限公司重庆分公司. 收起阅读 »
【开源项目】家聊 -- 一款基于环信开发专为老人打造的轻量级IM开源项目
写在前面的话:
简单来说,这是一款做来给家里老人用的APP,核心组件就是采用的环信sdk,感谢环信做的这么棒的sdk!!!感兴趣或者看过项目的人希望给出宝贵意见与我探讨,文章末尾有作者联系方式(放后面是确定你在联系我之前知道了家聊)
初衷:
很久之前想就教家里老人学习使用智能机,让他们能用App和家人交流沟通,但是发现市面上流行的社交软件对于他们来说学习成本太高。
这个项目属于轻量级的IM项目,聊天形式只有文字、语音、图片、短视频、实时音视频。这个软件的定位和市面上大多数社交软件不一样,我希望去掉那些复杂的社交元素,专门做一款能适合老人快速上手智能机的软件。
所以类似群聊、朋友圈那样的社交模块都没有做,力争每个功能的入口简单清晰,老人一眼就能看懂,所以产品逻辑不会特别复杂,想了解的同学可以clone下来运行看看(有时间我会打包个测试apk出来)。
项目特点:
项目里的业务架构类似MVP,在环信官方的基础上加了一些自己的实现,代码阅读更加顺畅。无论是做开源项目还是工作上的项目,我个人更倾向于能用原生实现就用原生实现,类似现在流行的RX系列、注解框架等我都没有采用(这里不是说不要去学,新技术当然值得去学,但是至于要不要在项目中采用需要自己或团队考量)
当然这么多做的前提是有把握做好,不要随随便便就崩溃,目的其实就是为了降低别人阅读或者接管代码时的学习成本,所以大家在看代码的时候应该不会有特别难理解的地方
主要功能:
- 聊天模块,包含文字聊天、语音聊天、发送图片、短视频、实时音频通话、实时视频通话。
- 通讯录:可获取系统通讯录,和环信好友关系整合。
- 拨号器:自定义的简单拨号盘,方便老人直接拨打电话
项目运行效果图:
联系作者:
如果发现项目bug或者对项目有好的建议,欢迎提交issue,或者通过下面的联系方式联系我.
*QQ:505515031 746604151
*邮箱:505515031@qq.com
*微信:Vanish520136
github地址:https://github.com/Vanish136/FamilyChat
oschina地址:http://git.oschina.net/vanish136/FamilyChat 收起阅读 »
草草们的忧伤:环信IM昵称和头像
在环信草草群(群号:340452063)中,无论是安卓还是IOS或者WebIM,每天遇到最多的问题就是“如何显示昵称和头像”,鉴于大家的墙裂需求,所以我最近花了点时间研究了相关解决方案,希望能跟大家一起探索。
运行效果
目标
集成环信IM的SDK后,能以最快方式,最少代码管理用户的昵称和头像。
解决方案
使用本地缓存(sqlite)和后端云实现头像和昵称的二级缓存
【参考】 http://docs.easemob.com/im/490integrationcases/10nickname#昵称和头像的显示与更新
计划
先在IOS上验证该方案的优缺点,待方案完善后,再将此模式复制到Android和WebIM上
项目快速集成
1. 按照简版Demo的方式在项目中快速集成环信IM功能
IOS快速集成环信IM - 基于官方的Demo优化,5分钟集成环信IM功能http://www.imgeek.org/article/825307886
2. 注册第三方后端云账号,使用数据存储服务
(1). 在第三方后端注册用户,进入控制台,创建应用(例如名称为【环信简版Demo】),点击【存储】按钮进入数据存储管理页面:
(2). 创建数据表UserWebInfo,并且按照新增三个字段(字段名开头必须小写):
openId String 环信ID
nickName String 用户昵称
avatarUrl String 用户头像(绝对路径)
其中,avatarUrl是app端上传头像到【_File】数据表后获取到的绝对路径:
(3). 在【设置】-> 【应用Key】页面中
复制AppID和AppKey替换AppDelagate里didFinishLaunchingWithOptions的key:
// 初始化web缓存配置参考: 简版demo中的AppDelegate+EaseMob.m第56行
[UserWebManager config:launchOptions
appId:@"utUG5ot9Y64dqJIFG9Ir2rqu-gzGzoHsz"
appKey:@"IbHhNkPo4gfrFFc3epCw3eG2"];
3. 上传用户头像和昵称到第三方后端云服务器
用户在app中调用开发者服务器API接口登录成功后,一般都会返回用户的属性信息(昵称和头像等),我们可以在这里上传用户信息到云服务器:
// 登录成功后,如果后端云没有缓存用户信息,则新增一个用户参考:简版demo中LoginViewController.m的第156行代码
[UserWebManager createUser:username nickName:nickName avatarUrl:avatarUrl];
4.显示用户昵称和头像
在需要显示用户昵称和头像的地方,调用UserCacheManager里的方法即可,具体调用地方,请在xcode里搜索简版Demo代码“[UserCacheManager ”,如图所示,在这里就不累赘了:
5.修改用户昵称和头像
(1). 更改头像
// 上传头像到后端云参考简版Demo中UserProfileEditViewController.m第181行代码
[UserWebManager updateCurrAvatar:orgImage completed:^(UIImage *imageData) {
[weakSelf hideHud];
if(!imageData){
[self showHint:@"更新头像失败~"];
return;
}
[weakSelf.headImageView imageWithUsername:kCurrEaseUserId placeholderImage:imageData];
[self showHint:@"更新头像成功~"];
}];
(2). 更新昵称
[UserWebManager updateCurrNick:@"小草" completed:^(BOOL isSucc) {参考简版Demo中UserProfileEditViewController.m第152行代码
if (weakSelf) {
UserProfileEditViewController *strongSelf = weakSelf;
[strongSelf hideHud];
if (isSucc) {
[strongSelf.tableView reloadData];
[strongSelf showHint:@"修改成功~"];
} else {
[strongSelf showHint:@"修改失败~" yOffset:0];
}
}
}];
6.二级缓存处理流程图
由于能力有限,此方案难免有不妥之处,欢迎大家拍砖。
环信互帮互助-非官方 340452063
Q&A
问:如何安装第三方后端云存储服务 SDK?
答:安装还是比较简单的,可以参考第三方的文档,有不明白的可以看下教程
问:使用第三方云存储服务是否稳定、安全,比如不久他关闭了app会不会受影响?
答:云服务厂商一般不会关闭,退一万步来说,即使第三方后端云停止服务了也会提前通知,我们也可以将接口换成我们开发者自己服务器的api。类似的第三方云存储服务还有MaxLeap、bmob。
收起阅读 »
初步引入easeui遇到的问题
- duplicate 项目中重复依赖了包
- .so文件报错找不到
- Dex问题
- Error:Configuration with name 'default' not found
这个问题应该是gradle版本问题,进工作目录修改app的gradle信息 收起阅读 »
环信移动客服v5.5更新:机器人支持物流场景智能应答,微博渠道支持自定义菜单。
环信移动客服v5.5已经正式发布,包括机器人支持物流场景智能应答以及微博渠道支持自定义菜单等新特性。环信智能机器人已经能够智能识别访客的物流相关的咨询,现在您可以为特定的物流意图(物流差错、物流咨询、物流查询、物流催促)设置相应的回复。其中,“物流查询”这一意图支持多轮问答,机器人能够自动为访客查询物流状态,并直接将查询结果回复给访客。在环信移动客服系统绑定微博认证账号后,可以设置微博账号私信页面的菜单,并且设置粉丝首次关注自动回复。
环信移动客服v5.5产品更新说明:
- 客服模式
“留言”页面支持播放语音留言
当收到APP访客端发送的语音留言时,可以直接在移动客服系统的留言页面进行播放。
“访客中心”支持连续查看历史会话记录
当访客与当前客服有多条历史会话记录时,客服可以在访客中心页面连续查看这些历史会话的消息。
在客服模式下,选择“访客中心”,点击某位访客,在详情页点击“互动记录”,点击任意历史会话,可查看该历史会话的消息。消息界面提示会话开始、会话结束时间,点击“更多历史消息”、“查看下一条历史会话”可分别查看之前、之后的历史会话。
访客轨迹分析(增值服务)
访客轨迹分析功能收集访客在网站浏览的轨迹。对来自Web渠道的访客,客服接起会话后,可以直接在聊天窗口了解到该访客在发起会话前的浏览轨迹,从而判断客户的兴趣范围和偏好。
“访客轨迹分析”与“全站访客统计”为增值服务,只需先开通“全站访客统计”功能,并且在您的网站上安装一个数据统计SDK,即可使用“访客轨迹分析”。如需开通这两个功能,请联系环信商务经理。
关于SDK安装流程引导,请参考文档:全站访客统计。
探索移动客服
新增“探索移动客服”页面,新版本上线的功能将在此页面进行展示,登录后即可查看,不错过移动客服的任何更新。
管理员模式
机器人支持物流场景智能应答
环信智能机器人已经能够智能识别访客的物流相关的咨询,现在您可以为特定的物流意图(物流差错、物流咨询、物流查询、物流催促)设置相应的回复。其中,“物流查询”这一意图支持多轮问答,机器人能够自动为访客查询物流状态,并直接将查询结果回复给访客。
在管理员模式,选择“智能机器人 > 机器人设置”,点击“场景智能应答”Tab页,将您需要机器人回答的物流意图全部勾选开通。未勾选时,表示不需要针对该物流意图进行相应的回复。
如果您对意图定义有疑问,不妨将鼠标放在问号上,了解它的详细定义哟。
以下为开启物流差错、物流咨询、物流查询、物流催促这些物流意图,并设置“物流查询”意图的问答方式为多轮问答后,访客端咨询示例:
“留言”页面支持播放语音留言
当收到APP访客端发送的语音留言时,可以直接在移动客服系统的留言页面进行播放。
注意:APP端发送语音留言的功能需要调用环信的留言API自行集成。
“当前会话”支持分配、关闭会话
管理员在当前会话页面监控客服与访客的聊天过程时,可以将会话分配给其他客服,也可以根据实际情况关闭会话。
“访客中心”支持连续查看历史会话记录
当访客与客服有多条历史会话记录时,管理员可以在访客中心页面连续查看这些历史会话的消息。
在管理员模式下,选择“访客中心”,点击某位访客,在详情页点击“互动记录”,点击任意历史会话,可查看该历史会话的消息。消息界面提示会话开始、会话结束时间,点击“更多历史消息”、“查看下一条历史会话”可分别查看之前、之后的历史会话。
微博渠道支持自定义菜单和首次关注自动回复
在移动客服系统绑定微博认证账号后,可以设置微博账号私信页面的菜单,并且设置粉丝首次关注自动回复。
在管理员模式下,选择“渠道管理 > 微博”,点击“自定义菜单”Tab页,可以对菜单进行设置。最多可以创建3个一级菜单,每个一级菜单均可以跳转至网页或创建最多5个二级菜单。当设置一级菜单跳转至网页时,不可以再在该一级菜单下创建二级菜单。
在管理员模式下,选择“渠道管理 > 微博”,点击“粉丝首次关注自动回复”Tab页,设置自动回复消息。目前仅可以选择文字方式回复。
探索移动客服
新增“探索移动客服”页面,新版本上线的功能将在此页面进行展示,登录后即可查看,不错过移动客服的任何更新。
作为管理员,您还可以通过此页面快速定位到系统的其他位置,例如:快速设置接入渠道、快速定位到收发消息相关的设置页面、一键查看历史会话或统计报表等。
多租户管理后台
多租户管理后台为增值服务,如需开通,请联系环信商务经理。
支持查看租户的历史会话
多租户管理后台增加“历史会话”功能,支持管理员查看各个租户下所有客服的历史会话。
登录多租户管理后台(kefuorg.easemob.com),进入“租户管理”页面,选择任意租户,点击“历史会话”,可以查看该租户的所有历史会话。点击任意一条会话,可以查看该会话的全部消息。
Android客服工作台
Android客服工作台V2.3版本已发布!可前往环信官网下载。
支持显示微信、微博表情
Android客服工作台支持显示微信、微博默认表情。
支持发送语音消息
使用Android客服工作台时,可以对APP渠道的会话直接回复语音消息,沟通更高效。
注意:网页、微信、微博渠道的访客无法收到语音消息。
移动客服Android SDK
移动客服Android SDK 1.0.1 发布了!该Android SDK基于IM SDK 3.x,登录、发消息速度更快。提供内置会话相关UI,集成后可立即给移动客服发送文本、语音、图片、文件消息。
支持双通道:已集成双通道功能,确保不丢消息;
极简集成:集成移动客服通用功能,只需5分钟。
集成指南:集成指南
环信移动客服更新日志http://docs.easemob.com/cs/releasenote/5.5
环信移动客服登陆地址http://kefu.easemob.com/ 收起阅读 »
谈谈iOS使用环信的几个问题
1. 不过,需要注意的是环信的文档上是这样说的
pod "Hyphenate_CN" 是导入不了的, 因为找不到这个库。当然很多人都会先pod search "Hyphenate" 再选择需要导入的版本。
2.昵称、头像的设置
关于怎样设置昵称头像 环信官方也给出了解决方案http://docs.easemob.com/im/490integrationcases/10nickname
关于方法二 我还是遇到了一些问题:
手机先后登入两个帐号 (帐号A 、帐号B),那么帐号B的会话列表中就会出现帐号A的会话 ,如果帐号A发起了和帐号B的会话,甚至还会出现帐号B自己和自己的会话(这个很不明白)。
NSArray *conversations = [[EMClient sharedClient].chatManager getAllConversations];
既然这个是获取当前登入帐号的所有会话,那么为什么会出现这种状况? 我想是不是环信服务器里并没有保存我们的会话,仅仅是保存在当前设备上了?
收起阅读 »
猿生态十城巡回沙龙丨大连
无猿不生态
猿生态十城巡回沙龙丨大连
2016.11.12 13:30-17:00
高新园区数码广场1号软件园8号楼coco space
感受DevOps全新开发运维模式
畅聊云计算常用框架和虚拟化技术
体验PHP全新的语言和Slim框架
更有特邀嘉宾带你一探Ruby不为人知的技术特性和编程哲学
活动议程:
13: 00 – 13: 30
活动签到
13: 30 – 16: 30
技术分享 + 实战演示
16: 30 – 17: 00
抽奖 + 自由交流
讲师介绍:
✦自带电脑:在实战演示环节,讲师们将带领大家现场写代码、做demo,建议带上电脑。
✦AA餐会:活动结束后,与讲师和现场小伙伴们共进晚餐,交流、交友~~活动现场报名喔;-)
✦✦✦✦✦✦✦✦
更多精彩即将上线
报名链接:
http://devhub.cc/api/h5/activity/d1641f6021837c6dd700d1a9a6e69dfa
收起阅读 »
环信大客户部总经理陈磊--下一代客户服务软件的三大核心驱动力
陈磊:非常高兴有这么一个机会在这里跟大家分享环信过去几年所做的事情。我本身是贵州人,地地道道的遵义人,二十多年前求学离开遵义,之后就很少回来。如果我们环信所做的事情能够为家乡做点贡献,我将感到非常的自豪。今天现场各位如需要环信能够与您合作共同拓展业务,我们将非常的高兴为您提供服务。
今天我演进的题目是“下一代客户服务软件的核心驱动力”。
在讲这个内容之前,我们回顾一下客户中心发展的历程。最早客户中心都是语音的,大家都是电话进行客服咨询。在2000年左右,随着互联网的发展,有了网页客服的新方式与客户进行沟通。随着移动互联网的发展以社交媒体如微信的的客服沟通方式逐步流行起来,同时移动端客服也正被大家所广泛采纳和接受,这些客服类型发展到现在,对所有的客户中心面临的挑战即是需要一个将呼叫中心、网页、微信、移动端多渠道全面集成的多渠道客服系统。客服行业发展中遇到的5个痛点,1.我们需要一个统一的平台,解决客服人员不用在不同的客服渠道系统间进行不停的切换;2.随着多渠道的客服的使用以后,有更多的客户跟客服人员之间进行了更为密集的接触,造成我们客服服务成本逐渐的上升;3.再一个传统的语音呼叫中心都是打电话的方式与客户沟通,通过电话的方式进行沟通时间是完全独占的模式,效率很低;4.在移动网络环境很差的情况下,如何保证客户通过移动端客服和客服人员之间进行不中断的交流,技术上有很大的挑战。5.我们传统的客服都是用语音的方式,但如很多家政业务的投诉时仅用语音是描述不清楚问题的,这个时候需就要富媒体的方式来解决体验差的问题。
刚才给大家回顾了一下呼叫中心发展的情况和面临的痛点,现在怎么解决这些问题?环信在过去三年多做了很多有益的探索,环信通过机器人技术、通过大数据和移动互联网技术来推动呼叫中心行业的整个转型发展。现在我着重的讲一下推动呼叫中心向下一代发展的三大核心驱动力。
(图)大家很熟悉,有这么多渠道,有传统的语音,有网页、APP、网络、微信、微博的接入,但大多都是来自移动端。未来我们最主要的趋势,客户最主要的访问渠道将都是来自于移动端。每年双11绝大部分的定单都是来自移动端,这个趋势势不可当。
1、呼叫中心技术成熟没有门槛。
2、网页客服也没有门槛。
3、微信的接入依赖于微信的接口,也没有门槛。
真正的难点是在移动端APP的客户,国内能做好这个移动端APP的客服仅有1、2家,现在的客户都在通过移动端来跟客服人员进行交流。在座的客服总监是不是做好这样的准备,在建立好移动端客服为客户提供服务。
我们环信在移动端APP客服通过这几年的实践我们已经发现,IM即时通讯是移动端客服的最佳体现。1,支持富媒体消息,表现能力强。2,IM沟通是典型的异步沟通方式。3,使用IM客服,消息必达。我们的环信内部一个客服人员可以同时服务20个人,相比传统是1比20的效率提高。环信通过它自己在移动互联网IM独特的技术,能够有效的解决客户在移动端与客服的交流。
(图)IM这种服务模式已被实践证明是所有的客户最为接受的模式。国美在线APP通过环信提供的APP内置客服很好的服务了上亿用户。
今天我们大家经常说的事情就是全媒体客服,但是大家在谈的实际上是多渠道接入其仅是全媒体客服的冰山一角。真正的全媒体客服的关注的是客户通过跨渠道进来以后真正的体验和旅程是什么样的?这里想让大家先了解一下客户声音这款产品,这是基于自然语言分析、人工智能技术透析客户行为,然后去提升改善客户旅程的这么一款产品。目前客户中心更为关注的即是客户的体验如何?
核心驱动力二,客户声音。我们把所有多渠道的数据进行分析,然后会牵扯很多企业的部门的合作,为所有的部门来提供服务。我们可以看到,对于客服部门实际上通过他的情感分析,会看出来客户的满意度有多少?客户提出的问题是什么?对与销售部门来说,可以知道产品销售的热点是在那里?对于市场部门是通过主题热点会提取发现下一个热点是什么,会帮助我们更好做市场活动。客户声音这个产品,环信通过这几年摸索,实际上在三个方面的客户实践体验做得比较好。
一、可以通过分析今天所有的对话当中去提取前二十个关注热点最多的主题,去分析热点的问题。
二、可以把所有的热点问题拿出来,他的情绪是什么样的?如果有负面情绪提出来,然后分析这些问题。
三、更重要的是把发现这些问题的对话找出来,找到客户再去跟客户沟通。通过客户声音产品将对于发现问题、分析问题和解决问题整个事件处理的闭环完全打通,这样可以更好的提高客户满意度。
通过上面的介绍,大家都已经看到越来越多的客户跟客服人员通过这么多的渠道进行了密集的接触,对于客服中心来说成本在不断的提升,就必须要有一有效的方式来解决人力成本的不断提升。智能机器人技术将会是改变这种情况所产生的颠覆性创新的技术。核心驱动力三:智能客服机器人,17年客服机器人就会成为客服服务中一个非常重要的环节。
对于不需要做人工标记和人工维护的机器人单轮对话,很多企业都没有很好利用:很多企业的机器人的知识库维护工作量巨大。比如通常的一个问题,有几十种问法,但答案都是一个,但机器人没有自学习能力,这样就要员工在每天工作结束后去逐条整理知识库。我们环信的机器人技术是具有自学习能力的人工智能技术,比如几种对话问的都是同样的问题,环信智能机器人能够自动识别回答,并自学习添加到知识库,无需人工逐条编辑词条整理知识库,有效的推动了智能机器人在客服中心的初步落地。但具备多轮对话功能的机器人其实才能再客服领域发挥更大价值,也是鉴定客服机器人是否成熟的重要标准,比如面临退货的问题,不知道订单号,机器人可能会通过手机号码来识别,只有机器人能够满足多轮对话,机器人的技术才能够真正的进入到实际的应用当中。
目前的智能机器人,从实际上技术水平上看,还不能达到完全替代人工,所以现阶段最具有效率的智能客服一定是人机混合模式,在关键时刻还需要人工进行实时的参与。
简单的介绍一下环信,环信公司成立3年多时间,是一家年轻的企业级服务软件提供商,并于2016年荣膺“Gartner 2016 Cool Vendor”。产品包括国内上线最早规模最大的即时通讯云平台——环信即时通讯云,以及移动端最佳实践的全媒体智能云客服平台——环信移动客服。截至2016年上半年,环信即时通讯云共服务了82149家App客户,SDK覆盖手机终端5.64亿,平台日发送消息5.57亿条。 环信移动客服共服务了29437家企业用户,现已覆盖包括电商、O2O、互联网金融、在线教育、在线旅游、移动医疗、智能硬件、游戏等领域的Top10客户,典型用户包括国美在线、58到家、楚楚街、海尔、神州专车、新东方、链家自如客、泰康在线、号码百事通等众多标杆企业。
全球最具权威的的IT研究咨询机构Gartner的行业发展报告应该是这个行业中各企业都遵从的一个标准。其在中国境内选择环信做为2016年SAAS服务领域的唯一的cool vendor厂家,这个荣誉是对我们环信最大的认可。
(图)环信联合Gartner共同推出了客服行业研究的白皮书:下一代客户服务软件趋势。白皮中的内容参考了环信近3万家客服用户的最佳实践及Gartner在这个领域的研究成果。如果大家需要的话可以到展台进行登记,英文版的会先出来,中文版的相应随后出来,我们邮寄给大家。
《全媒体客户中心管理》,是环信与蜜芽VP张艳老师一起所做的国内第一本关于全媒体客户服务的著作,书中内容也是参考了环信过去在客服领域的实践以及张艳老师多么行业积累的心得,如果大家需要也可以到我们的展台上领取。
今天我的演讲就这么多,非常感谢大家!
收起阅读 »
为什么有些APP自带廉价感
▍何为廉价
一辆4万元的车,我们可以说是便宜的车,但是鲜有人说是廉价的车。我们会说廉价的爱情,但是不会说便宜的爱情。
对于“廉价感”一词来说,与通常我们所说的“粗糙”、“便宜”等形容词不同,它是一个难以量化的心智形容词,而且几乎没有统一的判别标准可言。 而对于APP来说,怎样才能叫廉价呢?要解决这个问题,从反面说明简单不少:名贵的东西,从设计开始,就是为了“打败时间”的。为了更长时间保住用户,其任何一个细节都在向用户传递一件事:我能让你一直用下去。那么对于廉价来说,笔者认为,其产生于“仅活于短时间”,即这种产品让用户感觉:这玩意儿随便用用,很快就可以抛弃的。廉价的东西外壳一般都是迎合时下流行的,其余细节大多粗糙,易快速死亡。
▍为什么有些APP会自带廉价感
☛疲劳感
我们都会对身边每日接触到的事物产生各方面的疲劳感,这样的疲劳感虽然不会直接的带来“廉价”这个感觉。但是一旦出现了一个基本功能属性与之完全一致的产品时(抄袭、模仿、换皮的圈钱产品目前是最为常见的),我们会因为对旧事物的疲劳感,而产生“廉价”的感觉。
☛定位
多在于产品的生产者与开发者对于产品本身定位以及基本属性认识的不透彻。也就是过分的商业化(过分的商业化在于过于看重销售方面,而忽略对于产品本身的思考)。例如一款社交类APP最关键的是让用户体验到产品的易于结交性与便利交流性,那么无论是UI还是功能,我们首要着重是在好友交互上,而不是其他自认为牛逼的无用功能上,你在用户希望拥有良好体验的功能上做low了,APP的廉价感自然而生。
☛细节
“细节决定成败”,这句话放在APP上仍为真理。很多开发者通常都过于小看了用户,对于APP的细节末枝,很多用户其实都能敏感,而往往这些细节,就能决定你这款产品的命运:有不少APP在第一次使用时都会自动进入教程页面,但很多APP却没有跳过这样的选项或者根本不明显,让我们无法取消导致被迫浏览/进行完引导,而对于这种情况来说,有不少朋友是抱以厌烦态度的,我相信有不少的朋友遇到这种情况会弃坑,毕竟仍有大量同类产品在后方等待着。
☛质量
廉价未必是低劣,但低劣一定会让人感到廉价,质量差体验注定好不到哪里去。秒杀团购整点哄抢的时候,遇见闪退;传送\下载重要文件时出现程序异常,又要重来….很多时候,一个APP总是在关键的时候出现质量问题,这让人抓狂又无奈,这样的情况发生频率稍高,大部分用户一定会有“这东西很渣”心声,淘汰也是必然选择。
▍总结
对于竞争激烈的移动应用市场来说,同类产品太多,相应来说对比就更加明显。而其实廉价感的根本便产于比较,开发团队以怎样的态度来制作一款APP,最终是能够通过我们使用而体现出来的。用匠人的精神去打造一款产品,敲细节重质量,尽力严格的APP测试,这才能从根本消除一款APP可能带有的廉价感。
用没用料,决定了是否便宜;
用没用心,决定了是否廉价!
TestBird - 手游和App自动化测试平台 收起阅读 »
短信团购,低价高质:短信验证码进入3分时代!
稳定高效的验证码是注册转化的基础,鉴于环信的用户们短信验证码业务需求强烈,环信经过严格的短信服务商筛选,为环信的用户团购了低价高质的短信验证码服务,需要的小伙伴们请填写详细信息,我们将在12小时内安排技术支持专员为您服务。
短信验证码团购地址http://www.easemob.com/sms 收起阅读 »
iOS 环信3.2集成单聊教程
前言
1、本教程对应环信即时聊天 iOS SDK V3.2.0 (2016-10-15)
2、请自行注册好环信APP_ID和APP_KEY
3、请自行下载好环信即时聊天SDK对应的版本(iOS SDK V3.2.0)
一、集成环信SDK
1、导入SDK
下载SDK到本地,进行解压,包含以下几个文件。
如果你的项目中需要用到语音电话和语音视频请把HyphenateFullSDK拖入你的工程;
如果你的项目中只不需要语音电话和语音视频请把HyphenateSDK拖入你的工程;
这个两个只需要拖入一个,区别就是一个包含语音电话、视频,一个不不含,其他的都是一样的。
2、添加对应的依赖库
(1) 在 Build Phases -> Link Binary With Libraries 添加以下依赖库:
CoreMedia.framework
AudioToolbox.framework
AVFoundation.framework
MobileCoreServices.framework
ImageIO.framework
libc++.tbd
libz.tbd
libstdc++.6.0.9.tbd
libsqlite3.tbd
libiconv.tbd
如果你选择的是不包含语音电话、视频的SDK,最后一个依赖库(libiconv.tbd)不需添加。
(2) SDK 不支持 bitcode,向 Build Settings → Linking → Enable Bitcode 中设置 NO。
3、登录环信
在AppDelegate.m 中添加欢喜初始化和登录的代码,如果编译成功,则说明你导入SDK成功了。
#define EaseMob_Appkey @"1101#testnickname" //环信AppKey提醒:记得在plist文件中设置https请求喔
#import "AppDelegate.h"
#import "EMSDK.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//AppKey:注册的AppKey,详细见下面注释。
//apnsCertName:推送证书名(不需要加后缀),详细见下面注释。
EMOptions *options = [EMOptions optionsWithAppkey:EaseMob_Appkey];
options.apnsCertName = @"";
[[EMClient sharedClient] initializeSDKWithOptions:options];
EMError *error = [[EMClient sharedClient] loginWithUsername:@"yuancan001" password:@"123456"];
if (!error) {
NSLog(@"登录成功");
}
return YES;
}
4、添加EaseUI文件 要想实现环信的及时聊天,只加入SDK是不够的,还需要添加其他的一些相关的文件。回到我们之前下载环信SDK的文件中,有一个EaseUI的文件,把这个文件加入你的工程中。
这个文件夹中包含了一些与聊天相关的类,比如说聊天的界面、聊天的键盘等,总之是为了帮助开发者快速实现聊天功能。 编译一下,结果编译失败,因为还需要做一步操作,添加pch文件的路径。
EaseUI目录下有一个pch文件,你把它的路径添加到Prefix Header中。怎么添加呢?最简单的办法,就是先选择EaseUI-Prefix.pch文件,然后按住它,把它拖过去。不过这个要看人品,人品好一次就可以拖成功,如果没有拖成功,就多试几次。要是人品太差,就只能手动添加了
$(SRCROOT)/EaseMob3.2/EaseMob/EaseUI/EaseUI-Prefix.pch再编译一下,就可以成功了。
$(SRCROOT):这是一个宏,代表你这个项目文件的相对路径;
EaseMob3.2:这个是我的工程名,需要替换成你自己的工程名;
EaseMob/EaseUI/EaseUI-Prefix.pch:这个是pch文件在工程中的相对路径,需要替换成你自己对应的.
二、实现单聊
集成环信SDK,我们已经完成了第一步工作,接着我们来实现一下聊天的功能。
1、添加与聊天相关的文件
环信官方提供的Demo中集成了所有的功能,对于开发者来说既是一件好事也是一件坏事。之所以说是好事是因为所有功能都有,之所以说坏事是因为功能太多,都杂糅在一起,对于新手来说却是感觉无从下手。下面,就随我一起慢慢来深入了解环信。
实现单聊还需要添加一些文件,这些文件我们可以从官方的Demo中拷贝过来。我们需要添加的文件叫做 Chat,Chat目录下包含两个文件夹。ChatList里面的东西是与回话列表相关的,ChatView里面的东西是与聊天界面相关的 , 把Chat整个文件夹都拖入工程中。编译之后,你会发现会出现很多报错的,不要怀疑你自己,这是正常的。因为这些文件是从环信官方Demo中拷贝过来,里面用了很多其他的文件,但是我们不需要那些文件,没有添加到我们的工程中,所以会报错。其实,这几个步骤很关键,但是官方文档却没有说明,估计把新手坑死了,幸亏有小编来拯救你们,哈哈。这里好心的小编提供一个已经处理好的下载Chat文件,下载可以直接使用。不然,你就需要自己手动去注释一些报错的地方,知道编译成功。
2、修改pch文件
在我们之前用的那个EaseUI-Prefix.pch中添加一些头文件:
#ifdef __OBJC__3、测试单聊
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
//#import "ChatDemoUIDefine.h"
//#import "EMAlertView.h"
//#import "TTGlobalUICommon.h"
#import "EMSDKFull.h"
#import "EaseUI.h"
#endif
(1) 在AppDelegate.m 中创建一个UINavigationController :
#define EaseMob_Appkey @"1101#testnickname" //环信AppKey
#import "AppDelegate.h"
#import "EMSDK.h"
#import "ViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//AppKey:注册的AppKey,详细见下面注释。
//apnsCertName:推送证书名(不需要加后缀),详细见下面注释。
EMOptions *options = [EMOptions optionsWithAppkey:EaseMob_Appkey];
options.apnsCertName = @"";
[[EMClient sharedClient] initializeSDKWithOptions:options];
EMError *error = [[EMClient sharedClient] loginWithUsername:@"yuancan001" password:@"123456"];
if (!error) {
NSLog(@"登录成功");
}
ViewController *vc = [[ViewController alloc] init];
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = navigation;
self.window.backgroundColor = [UIColor whiteColor];
return YES;
}
OK,完了,到点了吃中饭去了。
欢迎关注我的博客,原文地址
收起阅读 »
【产品快递】Web IM V1.1.3发布,支持自动重连
- 功能改进:
SDK支持 Windows SDK。http://www.easemob.com/download/im 新增黑名单功能。获取聊天室列表: 支持分页、下拉刷新,新增以下2个参数:pagenum 和 pagesize。调试更方便,webpack 支持开发和生产模式。`npm run dev`:开发模式,支持热加载,启动一个供调试的webserve http://localhost:3000。 `npm run prod`:生产模式,编译速度更快。群组增加以下功能:创建群组、修改群组名称、修改群组简介、群组成员管理、加入公开群。strophe 从 v1.2.2 升级到 v1.2.8,在生产模式使用 strophe-1.2.8.min.js, 在开发模式使用 strophe.js。
支持自动重连: 在 webim.config.js 文件中新增相关参数 `autoReconnectNumMax` 和`autoReconnectInterval`。
- Bug fixes:
DEMO
增加 `babel-core/browser-polyfill.js`文件,修复了 IE 不支持 HTML5 elements 的 bug。
修复了有未读消息时点击联系人不生效的bug。
修复了strophe.js v1.2.8在IE9中使用BOSH会报错的bug。
https://github.com/strophe/strophejs/issues/213
SDK
修复了存在大量离线消息时收发消息延迟的bug。客户端将发送ack应答消息的速度限制在5个/秒,不影响其他正常消息。
将心跳消息从空body的 json message 切换为 ping/pong iq。前者会作为离线消息被XMPP Server缓存。
webim体验:http://webim.easemob.com/
版本历史:更新日志
SDK下载:点击下载 收起阅读 »
环信连续三届荣膺“易观之星”大奖,人工智能大数据优势凸显
环信荣膺2016“易观之星”大奖
从“互联网化”到“互联网+”,从“拟人智能”到“数据是新能源”,易观的每一个理念都对产业带来重大改变。作为即时通讯云领域和SaaS客服领域的先行者,环信用即时通讯云场景化社交,连接人与人。用全媒体智能客服重构现代商业,连接人与企业。环信和易观一样在不断践行创新,每次突破都给行业带来了翻天覆地的变化。
环信移动客服首推的客户声音产品运用自然语言解析,人工神经网络深度学习等人工智能技术,对来自多种渠道的非结构化数据源进行客服业务的特征提取,主题聚类解析,情感分析建模。从而帮助企业挖掘和分析客户服务中的热点话题,发现服务运营问题,寻找畅销或问题产品,洞察销售机会。比如,在环信客户声音系统中,主题关键词热度越高,说明用户关注度就越高。关键词对应的情感越负面,说明用户的体验感就越差。企业可以优先解决用户最关心,体验感最差的产品和服务问题。环信客户声音系统可以帮助企业识别和改善客户旅程的各个阶段。
基于自然语言处理和机器学习技术的环信智能客服机器人,能够辅助或代替人工客服精准回答超过80%的常见问题,极大降低企业客服人力成本。环信智能机器人使用海量数据对模型进行训练,并借助客服系统中访客和客服的实时反馈来增强学习,精准识别用户意图,帮助人工客服回答各种问题无需人工标记和人工维护的机器人单轮会话,极大降低客服机器人的维护成本。同时,环信智能机器人支持上下文语义和多轮会话,并预装多行业的领域知识,如电商行业的物流状态查询模型,产品保修会话模型等。这种基于行业领域和业务模型的多轮会话能力,相比单轮会话,进一步扩展了客服机器人对复杂客服业务场景的自动支撑能力。
截止2016年上半年,环信已经服务了八万多家客户,现已覆盖包括电商、O2O、互联网金融、在线教育、在线旅游、移动医疗、智能硬件、游戏等领域的Top10客户,在客服领域的典型用户包括国美在线、58到家、楚楚街、海尔、神州专车、新东方、链家自如客、泰康在线等众多标杆企业。积累了大量人工智能和大数据在即时通讯云和客户服务行业落地的最佳实践。
随着“互联网+”国家战略的不断深化,人工智能的崛起以及大数据分析思想将助力企业拥抱更广阔的互联网+未来。近期,李克强总理在出席会议时表示:“以大数据为代表的创新意识和传统产业长期孕育的工匠精神相结合,使新旧动能融合发展,并带动改造和提升传统产业,有力推动虚拟世界和现实世界融合发展。”未来在技术和服务的双动力驱动下,大数据和人工智能产业的发展将更加迅速,更加产业化、垂直化和精准化。同时,企业级服务的大数据和人工智能时代也即将全面开启。
关于“易观之星”
被誉为大数据行业的“奥斯卡”,易观A10峰会传承至今已有8年历史。易观之星颁奖典礼作为A10峰会上最为瞩目的板块充分利用大数据进行行业洞察,基于易观千帆、易观方舟等易观大数据产品,以用户规模、企业增速等标准进行多重考评,用以表彰和鼓励创新有潜力的企业和应用。本届评选历时两个多月,历经资格征集、资格复核、终审评奖三轮审核,环信凭借其在即时通讯云领域的绝对优势以及SaaS客服领域的厚积薄发连续第三年荣膺“易观之星”大奖。 收起阅读 »
关于会话列表的置顶聊天
其实刚刚开始 ,我自己在想,我是不是要去做出类似于QQ那种的滑动,然后显示置顶和删除。
我就开始写,写完了之后然后去置顶,取消置顶,其实是有用的,但是为什么我到最后还是没有选择这个效果呢?
因为这个最后是要到Adapter里面去设置这两个按钮,我本人并不喜欢这东西放到Adapter里面,接下来强迫症来了,直接把代码全部删除,换一种思路..........我想到了微信,点击弹出一个菜单,和dialog很很像的一个功能。
好,来跟着我一起走一下思路。
首先是,要实现置顶聊天,那么我们就要有两个List集合,一个是置顶的,一个是不是置顶的,然后置顶的是需要一个小小的数据库去保存置顶的对话人的UserName;这里,环信给出了EMConversation的一个方法,带大家看看技术文档。
这里框出来的就是我们要用的至关重要的方法,特别重要,
看下这个文档里面说的非常清楚,也就是扩展字段,设置一个扩展字段我们才知道这条Conversation的特别之处,然后去判断这个会话有没有设置扩展消息,有的话,那就排到置顶的那个集合里面去。
接下来我们要准备的是数据库
也就是这两个东西,准备就绪,蓝后 ..... 要开始大动,也就是把关于会话列表里面的东西全部放到项目里面来。
所要动的就是这3个类,全部移动到项目中,因为数据库要在Adapter和ListView里面操作,这一步很简单,动动手就行。
那么这些全部做完之后,我们开始写代码了,仿照通讯录的数据库来
这里就是getset,然后在DemoHelper里面
蓝后,再Application里面去给它暴露出两个方法。
好了,数据库的东西是配置完成了,那么,问题就来了,怎么去启动数据库?
这样就添加了数据库,注意,这里添加了数据库之后,然后再去真正的写置顶的代码了。。。。
首先我们先看看会话列表界面
在setupView方法中,别忘了获取数据库里面的置顶会话。
这里直接贴出来了ConversationListFragment,这里就是把EaseUI里面的EaseConversationlistFragment里面的内容,然后BaseFragment也就是EaseBaseFragment里面的内容了。
主要加载会话的方法就是这个方法,主要代码就是synchronized里面的内容,这里很容易就能够理解For循环里面的内容,然后我们要在这里面判断,有没有会话是包含扩展字段的,有的话就将包含扩展字段的会话放入top_list这个集合里面;蓝后你们可以看到topList,这个List就是图10里面的topList,topMap也是图10里面的。蓝后,我们可以看到排序方法,也就是会话列表的排序方法(sortConversationByLastChatTime),这里我自己写了一个排序方法,并没有用到Pair。
其实这两个方法是一样的,一样的效果。
那么接下来,就是看看ConversationList
最主要的就是这个init方法,也没什么说的。。那么接下来就到ConversationAdapter
这里就和EaseUI里面的那个EaseConversationAdapter有点不一样了,EaseConversationAdapter里面是继承ArrayAdapter的,这里是继承BaseAdapter,在这里使用BaseAdapter为了方便大家能够理解。
我们只需要在getItem和getCount里面做点手脚就可以了
好了,到这里就完成了整个置顶会话的显示,那么接下来,我们就要写一下置顶功能了,这里很有必要说明下,个人意见,在写会话列表的时候,推荐使用一个Fragment去继承EaseConversationListFragment。继承之后我们就可以重写setUpView方法,在这方法里面我们进行一系列的操作。
这里就是用到的长按事件,然后显示一个Dialog,在Dialog里面去实现置顶功能的操作。这里由于代码过长,所以截两张图。。。。
图18主要就是Dialog的显示
在这里就是删除会话等这个按钮的点击事件。
在里就是置顶的点击事件了。。
好了 到这里已经完成了置顶的全部代码展示了。个人感觉还是很详细的,如果还是不懂,那就环信互帮互助-非官方 340452063来这,给你解答你的问题 收起阅读 »
聊天工具的架构分析
随着统一通信的发展,聊天工具有了更好的发展,其中要算手机和网上的即时聊天工具的发展了。手机主要是3G的开发,有了统一通信技术的支持,我们才可以实现第三代的通信,但是这里要说的另一个方面,关于聊天工具的。
下面就聊天工具开发聊聊现有聊天工具的架构,需要先说明的是TCP和UDP这两个协议,因为只有先确定了这两个最重要的协议,才可以确定一个即时聊天软件的架构。首先举两个例子,即时聊天软件MSN使用的就是TCP,然而QQ使用的是UDP协议。其实这两者的最大区别就是TCP的可靠保证,是它的三次握手机制,这一机制保证校验了数据,保证了他的可靠性。而UDP就没有了,所以不可靠。比如说,在MSN上,要传输文件,首先是发送文件,对方确定接受,然后再发送,这样,三次握手。但是UDP不同,它是直接发送,不管对方是否同意,还是会发送,所以很不安全,但是这是由于这样,也保证了传输的速度,不会受到安全性的限制。而TCP一般会保证发送和收到,更适合一些对安全性质需要较高的工具软件。但是为什么同样是即时聊天性质的软件,MSN使用的是TCP,而QQ的则是UDP呢?通过思考,我认为,国外的网络环境相对国内的好很多,安全性也有保证,而国内的网络环境不如国外,还有很多代理服务器,再加上网通和电信,造成了很多不便,如果使用的是TCP的话,那么我们很多用户将无法使用这个软件,或者是在传输文件和数据的时候将会遇到很多的困难,甚至无法传送文件,所以QQ使用了UDP。其实呢,大多聊天软件例如QQ,不光是使用了UDP,在某些方面也用到了TCP,就像QQ的文字聊天协议。
统一通信中即时聊天软件的架构,由三部分组成,DispatchServer(DS) Notification Server (NS)和Switchboard Server (SB)。
DS采用的负载均衡方式应该比较简单,通过DNS解析来做负载均衡。并且由于在DS上的连接都是短连接,保持时间非常短,所以应该DS服务器的数量应该不会很多。由于DS必须要返回一个可用的NS IP,那么内部应该还有其他种类的服务器来保存当前所有可用的NS服务器,以及这些NS服务器上的负载。通过DS这一层来为接下来的NS做负载均衡。NS连接均为长连接,所以在这一层上的负载由DS来调节。如果NS负载太大,新客户连接上DS时会返回其他相对空闲的NS服务器。当然NS服务器之间也有相互通讯的机制也是少不了的,比如上下线通知、对话发起等等。SB连接的时间介于NS和DS之间,其负载由NS来作控制。对话完成后和SB之间的连接就关闭了。不过由于所有的对话都在SB上进行,MS的服务器资源再强也会吃紧,所以现在新版的MSN Messenger都加入了P2P Message类型,在发起对话的时候会判断如果双方都支持sustain ,则会直接点对点连接连接,绕过SB这一层。
在及时软件的交互过程中,首先客户端向服务器发送一个请求登录令牌的数据包,服务器返回登录令牌。这个令牌是在服务器端生成的,和客户端的IP地址,版本信息等数据相关。在客户端得到登录令牌后,就会向服务器发送一个包含登录信息的登录请求,服务器首先会查看客户端的号码、IP地址和版本是否可以在本服务器上进行登录,如果可以就验证客户端的登录信息是否与服务器上保存的登录信息一致,如果一致就向客户端返回一个连接成功的数据包,不匹配则返回登录失败。这就是整个的登录的实现过程。
收起阅读 »
移动OA后台最方便的流程图js组件
谈到OA,我就要提一下其中最重要的一个部分“工作流引擎”。
js工作流组件很多,但是要找一款适合自己的却有点难,所以,咬咬牙,决定自己做一款。
本着“不重复造轮子”的原则,我打算还是基于gojs封装流程图组件比较现实一点。
基于GOJS封装的流程图设计(展示)工具类,主要分为两个工具类:
工具库依赖于go.js、jquery以及layer.js
http://gojs.net/
http://jquery.com/
http://layer.layui.com/
希望支持FlowDiagram的童鞋能够到Github给我们一个star_^
https://github.com/mengmakies/FlowDiagram
在线demo http://www.c3dn.net/gojs/samples/demo.html
流程设计器操作指南:
在任意位置双击设计器空白处:新建步骤;
选中步骤,单击右键:弹出右键菜单;
鼠标滑过步骤,显示连接点,拖动连接点即可创建新的连接线;
鼠标滑过步骤:显示tooltip。
流程图数据:
{ "class": "go.GraphLinksModel",
"modelData": {"position":"-5 -5"},
"nodeDataArray": [
{"key":"1", "text":"开始", "figure":"Circle", "fill":"#4fba4f", "stepType":1, "loc":"90 110"},
{"key":"2", "text":"结束", "figure":"Circle", "fill":"#CE0620", "stepType":4, "loc":"770 110"},
{"key":"3", "text":"填写请假信息 ", "loc":"210 110", "remark":""},
{"key":"4", "text":"部门经理审核 ", "loc":"370 110", "remark":""},
{"key":"5", "text":"人事审核 ", "loc":"640 110", "remark":""},
{"key":"6", "text":"副总经理审核 ", "loc":"510 40", "remark":""},
{"key":"7", "text":"总经理审核 ", "loc":"500 180", "remark":""}
],
"linkDataArray": [
{"from":"1", "to":"3"},
{"from":"3", "to":"4"},
{"from":"4", "to":"5"},
{"from":"5", "to":"2"},
{"from":"4", "to":"6", "key":"1001", "text":"小于5天 ", "remark":"", "condition":"Days<5"},
{"from":"6", "to":"5"},
{"from":"4", "to":"7", "key":"1002", "text":"大于5天 ", "remark":"", "condition":"Days>5"},
{"from":"7", "to":"5"}
]}
1.流程图设计 flow-desinger.js
var areaFlow = document.getElementById('mySavedModel');
var myDesigner= new FlowDesigner('myFlowDesignerDiv');// 流程图设计器
myDesigner.initToolbar('myPaletteDiv');// 初始化控件面板
myDesigner.displayFlow(areaFlow.value);// 在设计面板中显示流程图
2.流程图展示 flow-display.js
var areaFlow = document.getElementById('mySavedModel');详细代码请参考目录下的html文件:/gojs1.6.10/site/samples/_demo.html
var myDisplay = new FlowDisplay('myDisplayDiv');// 流程图显示器
var flowPath = '3,4,6,5';// 3,4,6,5是步骤的id,最后一个步骤为"待处理"或"已完成"的步骤
var isCompleted = false;// "待处理"或"已结束"
myDisplay.loadFlow(areaFlow.value);// 显示流程图
myDisplay.animateFlowPath(flowPath, isCompleted);// 动画显示流程路径
http://git.oschina.net/markies/FlowDiagram/raw/master/gojs1.6.10/site/samples/_demo.html
收起阅读 »
猿生态十城巡回沙龙丨天津
开发环境、测试环境、生产环境存在着怎样的鸿沟?如何通过DevOps既保持服务的稳定运行,又为开发者提供便利?在轻松跨越C10K需求的今天,怎样快速基于Wordpress打造全平台软件?如何基于OpenResty快速实现高性能Web服务器?...... 无猿不生态猿生态十城巡回沙龙
精彩继续 10月29日 天津市南开区白堤路42号百豪视听广场3楼草帽众创空间
活动报名:点击报名
活动议程
13: 00 – 13: 30 活动签到
13: 30 – 16: 30 技术分享+实战演示
16: 30 – 17: 00 抽奖+自由交流讲师介绍
Tips
✦自带电脑:在实战演示环节,讲师们将带领大家现场写代码、做demo,建议带上电脑。
✦AA餐会:活动结束后,与讲师和现场小伙伴们共进晚餐,交流、交友~~活动现场报名喔;-)
本场活动将通过云犀直播,在斗鱼、战旗、爱奇艺、熊猫TV等多个平台全程同步直播,扫描下方二维码即可收看
收起阅读 »
厉害了Word哥,环信连续两年荣膺“金耳唛杯”年度中国最佳客户中心技术产品奖
2016年10月18日,国内客户中心行业历史最久、水准最高、规模最大的年度性行业会议——2016客户世界年度大会在京圆满落幕。环信移动客服作为国内全媒体智能云客服领域的开拓者和践行者继2015年摘得桂冠,本次大会经过评委会的一致通过再次荣膺“金耳唛杯”2016年度中国最佳客户中心技术产品奖。再次获得客户世界、中国呼叫中心与电子商务发展研究院以及CC-CMM国际标准组织的一致认可,这和环信始终践行以客户成功为己任,始终保持对产品和服务的敬畏密不可分。
环信移动客服荣获“金耳唛杯”2016年度中国最佳客户中心技术产品奖
同时,环信CEO刘俊彦作为国内SaaS客服行业的意见领袖受邀发表主题演讲《下一代客户服务软件的核心驱动力》,分享了环信联合Gartner在SaaS客服领域的一些前沿探索和实践,给行业描绘了一副未来SaaS客服技术变迁和最佳实践的新蓝图。
环信CEO刘俊彦做主题演讲
环信CEO刘俊彦认为:“未来以移动端为核心的全媒体接入,跨媒体、跨渠道、跨部门的客户服务体验,以及智能客服机器人将成为下一代客服软件的三大核心驱动力。”客户中心经过多年的发展,从单一的语音服务渠道进化成为多介质的全媒体服务渠道,并最终将发展成整合传播服务、营销、销售和产品用户体验为一体的互动中心。未来客户中心将以“体验”为核心视角,描绘一副全媒体接入、人工智能驱动、大数据升华,参与企业全要素、全流程运作的服务蓝图。
近年来,伴随着客户互动方式的改变,呼叫中心作为基本的客户交互平台也正经历着深刻的变革。运营日益精益化、多媒体化、智能化和网络化。已经从早期单纯的语音服务通道发展成为集语音和非语音客户互动渠道为一体的整合化客户中心。相关行业在中国的发展路径也正在遵循着呼叫、接触、互动 (call center -> contact center -> interaction center)这样一个过程发生深刻的演化。呼叫中心行业正在从单一的语音服务渠道进化成为多介质的复合服务渠道体(接触中心),并最终发展为整合服务、营销、销售为一体的互动中心的机制架构。作为企业电子商务中信息流的接入平台和整合载体,客户中心(Customer Engagement Center)已经成为传统呼叫中心的升级版,并正在快速、大规模地在国内得到新的应用和发展。
“金耳唛杯”中国最佳客户中心评选活动的前身是由客户世界机构联合CNCCA创办于2005年的“中国最佳呼叫中心”年度评选活动。自创立之日起即以其学术性和实践精神,逐步发展成为中国客户中心行业发展的风向标。评选活动的目的是在全社会各行业普及和推广客户服务管理的理念,提升客户中心运营管理水平,建立国际化的客户中心标准及交流体系,推动客户中心相关产业在中国的发展。通过此前十多年的发展,评审工作取得了非常良好的行业推动成果。评选由权威的第三方行业研究和发展平台–客户世界机构主办,中国呼叫中心与电子商务发展研究院以及中国呼叫中心产业能力建设管理规范工作组提供官方指导。评选依据CC-CMM国际标准的评价体系并采用CustomerServiceAudit公司Snapshotz服务标杆测评工具进行指标分析。
历年的活动得到全球呼叫中心产业联盟ContactCenterWorld、亚太客户中心协会联盟APCCAL以及欧洲客户中心联盟ECCCO及其所属各国客户(呼叫)中心成员协会共同支持;评选接轨亚太及全球客户中心多项评选活动;是一个全球化的产业交流机制。“金耳唛杯”年度中国最佳客户中心评选活动通过企业报名、专家推荐、电话暗访、数据采集、标杆测评、入户评审、集中评议、票选结果等程序进行;提前设置评奖类别并严格控制每类别获奖单位数量。评选程序科学公正,所得荣誉有极高的含金量。
环信移动客服——全媒体智能云客服倡领者,于2016年荣膺“Gartner 2016 Cool Vendor”。环信支持全媒体接入,包括网页在线客服、社交媒体客服(微博、微信)、APP内置客服和呼叫中心等多种渠道均可一键接入。基于环信业界领先的IM长连接技术保证消息必达,并通过智能客服机器人技术降低人工客服工作量。同时,基于人工智能和大数据挖掘的客户旅程透析产品"环信客户声音"能够帮助企业优化运营,提高跨渠道客服体验。收起阅读 »
截至2016年上半年,环信移动客服共服务了29437家企业用户,现已覆盖包括电商、O2O、互联网金融、在线教育、在线旅游、移动医疗、智能硬件、游戏等领域的Top10客户,典型用户包括国美在线、58到家、楚楚街、海尔、神州专车、新东方、链家、泰康在线、号码百事通等众多标杆企业。根据易观发布的《中国SaaS客服市场专题研究报告》显示,环信移动客服在SaaS移动端客服用户覆盖占比高达77.4%,稳居行业第一。
1024程序员节,那些年我们错过的30个段子,向改变世界的程序员致敬!
1024程序员节,是全世界程序员的共同节日。在1842年,人称“数字女王”的阿达·洛芙莱斯(Ada Lovelace)编写了历史上首款电脑程序。在1834年,阿达的朋友——英国数学家、发明家兼机械工程师查尔斯·巴贝其(Charles Babbage)——发明了一台分析机;阿达则致力于为该分析机编写算法,并于1843 年公布了世界上第一套算法。巴贝其分析机后来被认为是最早期的计算机雏形,而阿达的算法则被认为是最早的计算机程序和软件。
从2014年起,每年10月24日定义为程序员节。以一个节日的形式,向通过coding改变世界,也以实际行动在浮躁的世界里,固执地坚持自己对于知识、技术和创新追求的程序员们表示致敬。
正值1024程序员节日来临之际,你有哪些关于程序猿的套路和段子?欢迎跟帖回复。
1.整数
A:“借我1000块 ”B:“拿去 1024块 我给你凑了个整儿 ”
2.客户端
某程序猿在用膳问老板,你们饭店需要客户端吗?老板:不忙的时候都是服务员端,只有忙的时候才需要客户端...
3.PHP
女神:你能让这个论坛的人都吵起来,我今晚就跟你走。
程序猿:PHP语言是最好的语言!
论坛炸锅了,各种吵架。
女神:服了你了,我们走吧,你想干啥都行。
程序猿:今天不行,我一定要说服他们,PHP语言是最好的语言。
4.睡觉
我是一个苦b的程序员,今晚加班到快通宵了,困得快睁不开眼了,女上司很关心,问我要不要吃宵夜。
我没好气地说,宵夜就算了,能让我睡一觉就行了。
女上司红着脸说了句讨厌啊,然后坐在我身边不动,好像距离我很近,搞得我很紧张,难道她发现我的程序出了bug?
5.包子
老婆给当程序员的老公打电话:“下班顺路买一斤包子带回来,如果看到卖西瓜的,就买一个。”
当晚,程序员老公手捧一个包子进了家门……
老婆怒道:“你怎么就买了一个包子?!”
老公答曰:“因为看到了卖西瓜的。”
6.下班
某人发帖子:“各位JR,我想做一个程序猿,请问有什么要注意的……”
某猿:“等我下班跟你细说……”
然后……就没有然后了
7.10种人
世界上只有10种人,一种是懂二进制的,一种是不懂的二进制的.
8.书法
某程序员退休后决定练习书法,于是重金购买文房四宝。一日,饭后突生雅兴,一番研墨拟纸,并点上上好檀香。定神片刻,泼墨挥毫,郑重地写下一行字:hello world!
9.说话
一女同学在食堂吃饭时,一程序猿凑到旁边,“同学,我能和你说话不,我已经一个月没和女生说话了。
10、数数
宝宝数学很好,2 岁就可以从 1 数到 10 了。后来,我告诉他 0 比 1 还小。
今天吃饺子,我说:“宝宝,你数数你想吃几个饺子?”
“0,1,2,3。”一边说着一边拿起一个饺子,“这是第 0 个。”
老婆怒吼:“下一代还是做程序员的命!”
11.借钱
程序员甲:哎,借我点钱呗?
程序员乙:借多少?
程序员甲:1000。
程序员乙:行。哎,要不要多借你 24,好凑个整?
程序员甲:也好。
12.还是借钱
程序员A:哥们儿,有钱吗?
程序员B:有
程序员A:借我点呗?
程序员B:啊?你说什么?
程序员A:借我点呗?
程序员B:不是,上一句?
程序员A:有钱吗?
程序员B:没有。
程序员A:晕,程序重新请求一下,结果还不一样了!
13.夜路
昨天晚上下班回家,一民警迎面巡逻而来。突然对我大喊:站住!
民警:int 类型占几个字节?
我:4 个。
民警:你可以走了。
我感到很诧异。
我:为什么问这样的问题?
民警:深夜还在街上走,寒酸苦逼的样子,不是小偷就是程序员。
14.烦恼
程序猿最烦两件事,第一件事是别人要他给自己的代码写文档,第二件呢?是别人的程序没有留下文档。
15.和谐
随机函数可以帮你实现家庭和谐: Talk(){:top word(1)="恩!"; word(2)="好的!";word(3)="然后呢?";word(4)="有道理";i=random(4); say word(i) goto top;}
16.车
Delphi象吉普车,什么路上都能开,却在啥路上也开不好;PB就象卡丁车,只能在固定线路上开,到室外就有些不稳;VC象跑车,你开得起却买 不 起,而且一旦发生故障,想修都找不到毛病在哪;Java象敞棚车,不管刮风下雨还是艳阳高照,都能照开不误;VB就是摩托车,骑的时间越长,你越痛 恨 它!
17.修车
据说有一位软件工程师,一位硬件工程师和一位项目经理同坐车参加研讨会。不幸在从盘山公路下山时坏在半路上了。于是两位工程师和一位经理就如何修车的问题 展开了讨论。
硬件工程师说:“我可以用随身携带的瑞士军刀把车坏的部分拆下来,找出原因,排除故障。”
项目经理说:“根据经营管理学,应该召开会议,根据问题现状写出需求报告,制订计划,编写日程安排,逐步逼近,alpha测试,beta1测试和 beta2测试解决问题。”
软件工程说:“咱们还是应该把车推回山顶再开下来,看看问题是否重复发生。”
18.效率
当世界末日还有5分钟就要到来的时候。
程序员: 让我们在这最后的时刻作些什么吧!
女友: 那好,让我们在做最后一次吧!
程序员: 那剩下的4分50秒做什么啊?
19.挣钱
一程序员家的水管坏了,他打电话叫来一个水管工修理。 水管工鼓捣了一个小时,终于把管子修好了,他递给程序员一张600元的帐单。
“600元!”程序员愤怒地说:“我当程序员一天都赚不了这么多钱!”
“是啊。”水管工平静地说,“我当程序员的时候也是。”
20.代码
文艺程序员写代码追求让别人看懂,普通程序员追求让自己看懂,2B程序员则追求让编译器能看懂;半年后看自己当初写的代码,文艺程序员不知道是自 己 写的但很容易看懂,普通程序员知道是自己写的但是不太容易看懂,2B程序员埋头看了半天后拍着桌子吼到:“这是哪个SB写的程序!”
21.经验
一程序员去面试,面试官问:“你毕业才两年,这三年工作经验是怎么来的?!”
程序员答:“加班。”
22.醒来
程xx遭遇车祸成植物人,医生说她活下来的希望只有万分之一,唤醒更为渺茫。
他的同事和亲人没放弃,并根据程xx对testing痴迷的作风,每天都在她身边念:“你测的模块上线后回滚了。”
奇迹发生了,程xx醒来第一句话:确认那模块是我测的?
23.烂代码
程序员最憋屈的事情就是:你辛辛苦苦熬夜写了一个风格优雅的源文件,被一个代码风格极差的同事改了且没署名,以至于别人都以为你是写的。
24.应聘
程序员应聘必备词汇:了解=听过名字;熟悉=知道是啥;熟练=用过;精通=做过东西。
25.讨厌
程序员最讨厌的四件事:写注释、写文档、别人不写注释、别人不写文档……
26.钓鱼
有两个程序员钓鱼,其中一个钓到一条美人鱼,这个美人鱼上半身是美女,下半身是鱼,于是这个程序员就把她放了,另一个问他:Why,他回答说:没有API。
27.谁?
“咚咚咚”“谁?”过了很久……“Java”
28.//
A:嘿 //是什么意思啊?
B:嘿.
A:呃 我问你//是什么意思?
B:问吧.
A:我刚才不是问了么?
B:啊?
A:你再看看记录...
B:看完了.
A:......所以//是啥?
B:所以什么?
A:你存心耍我呢吧?
B:没有啊 你想问什么?
……
不断循环之后,A一气之下和B绝交,自己苦学程序。
N年之后,A终于修成正果,回想起B,又把聊天记录翻出来看,这时,他突然发现B没有耍他……
而他自己也不知道当年他问B的究竟是什么问题……
29.笑话
我想听一个 TCP 的笑话。
你好,你想听 TCP 的笑话么?
嗯,我想听一个 TCP 的笑话。
好的,我会给你讲一个TCP 的笑话。
好的,我会听一个TCP 的笑话。
你准备好听一个TCP 的笑话么?
嗯,我准备好听一个TCP 的笑话
Ok,那我要发 TCP 笑话了。大概有 10 秒,20 个字。
嗯,我准备收你那个 10 秒时长,20 个字的笑话了。
抱歉,你的连接超时了。你好,你想听 TCP 的笑话么 。
30.问题
从前有个程序员遇到了一个问题。他想,没事,我懂,用线程就好了。现他有两个问题了。
收起阅读 »
环信移动客服v5.4发布:第二消息通道保证不丢消息+客户之声优化+机器人支持识别物流意图
查看历史版本请点击版本历史
环信移动客服v5.4_产品更新说明
- 客服模式
3.微信渠道超过48小时后禁止发消息或回呼 对于来自微信网友的进行中会话,如果访客超过48小时未回复消息,禁止客服再次向其发送消息。对于微信渠道的历史会话,会话结束48小时后,不允许对访客进行回呼。4.第二消息通道功能为了更好地保证系统稳定性并确保不丢消息,移动客服系统与访客端之间支持环信即时通讯云和REST API两条通道进行消息收发。即时通讯云消息通道为第一通道,REST API消息通道为第二通道,当IM服务器暂时不可用时,消息自动切换到第二通道。切换后,访客和客服之间依然可以发送和接收文本消息。网页访客端默认支持第二消息通道;APP访客端需要单独集成,请参考集成访客端双通道功能(暂时仅Android版APP支持)。
- 管理员模式
选择“管理员模式 > 渠道管理 > 手机APP”,进入“手机APP”页面,点击“添加APP关联”按钮,创建APP关联。支持两种方式:快速创建、关联IM账号。
- 快速创建:如果您还没有环信即时通讯云的账号,可以直接点击“快速创建”,系统会为您自动创建一个APP关联;
- 关联IM账号:如果您已有环信即时通讯云的账号,并创建了应用,可以点击“去关联IM账号”,填写关联名称、AppKey、ClientId、ClientSecret、IM服务号、IM Password,手动将您的APP绑定到环信移动客服。
创建APP关联后,可以查看关联的APP信息,包括关联名称、AppKey、ClientId、ClientSecret等。对于快速创建的关联,您还可以点击“直接登录IM关联后台”,查看更多相关信息。
- 关联名称:该关联在移动客服系统中的名称,可修改。
- AppKey:应用的唯一标识,与“IM服务号”共同构成手机APP与移动客服之间的消息通道,不可修改。
- ClientId和ClientSecret:自动生成,用于获取管理员token,不可修改。其中,管理员token用于使用REST API进行服务端集成。
- IM服务号:该应用下,IM用户的用户名,与“AppKey”共同构成手机APP与移动客服之间的消息通道,可以修改为其他IM用户的用户名(及对应的密码)。
3.不活跃会话超时自动结束 新增不活跃会话超时自动结束开关。当开关打开时,如果访客和客服在设定时间内均未回复消息,系统将自动发送提示语给访客,并结束会话。选择“管理员模式 > 设置 > 系统开关”,进入“系统开关”页面,打开“不活跃会话超时自动结束”开关。注意:如果同时打开了“访客超时未回复自动结束会话”开关,当满足任意开关的超时条件时,会话将会被自动结束。
- 客户之声功能优化
2.关键词详情优化 关键词详情页改为弹屏显示,包括该关键词的频度趋势、情感指数趋势、消息列表。并且可以快速添加该关键词至停用词列表。在“客户之声”页面,点击任意关键词,可以查看该关键词的详情。如果不需要关注该关键词的频度与情感指数等,可将其停用,只需点击“添加停用词”按钮即可。
- 访客端
- 物流咨询(到北京一般几天到,下单后一般几天发货,快递费用多少等)
- 查物流(询问物流单号,物流状态等信息)
- 物流催促(催促发快递,催促快递加快速度)
- 物流差错(由于物流送错,或者疑似送错,质疑或者投诉物流,快递费收错,过错方可能在商家)
- 物流信息修改(由于用户信息输入错误,需要修改,信息填错,取消订单,退换货,过错方在用户)
机器人支持多轮会话
支持多轮对话,比如查物流状态的场景下,机器人会根据具体情况收集客户多个信息(快递单号及快递公司名称),再去执行快递状态查询任务。
2.网页访客端优化
网页访客端优化功能对应网页插件版本43.9,定制开发版需要更新插件。
显示客服状态
网页端访客与客服会话过程中,访客可以在客服头像位置看到客服的状态,包括在线、繁忙、离开、隐身,帮助会话
双方更好的交流。
前提条件:选择“管理员模式 > 设置 > 系统开关”,进入“系统开关”页面,打开“访客端显示客服昵称”开关。
收到满意度邀请直接弹窗
网页端访客与客服会话过程中,收到客服发起的满意度评价邀请时,可以直接在弹窗中给出评价。
显示会话创建、接起、转接、结束等提示
网页端访客与客服会话过程中,可以看到会话创建、接起、转接、结束等提示,直观地了解会话状态。
收起阅读 »
Android ios V3.2.0 SDK 已发布,全新实时音视频,让你聊得更痛快
十一长假归来,环信发布了Android ios V3.2.0 SDK,适配了ios10 ,增加红包转账等功能;值得一提的是本次V3.2.0对实时音视频做了大量升级改造,包括之前大家期待的横竖屏切换、高清视频模式等几项新功能上线!环信实时音视频,更懂移动端APP 的实时音视频,让小伙伴们玩得更爽!赶紧下载体验吧!
Android V3.2.0 2016-10-15
音视频包含大量升级改进,细节请参考集成文档
- 增强的自适应视频质量算法,根据网络环境动态调整清晰度;
- 优化了语音算法,通话更清晰;
- 支持高清视频,画质更细腻;
- 支持客户端视频和语音数据回调,;
- 支持横屏和竖屏自由转换;
- 支持画面fit和fill模式;
- 增加个人间转账功能
- 增加拆红包音效
- cmd消息增加“em_” 和 “easemob::” 开头的action为内部保留字段;
- Fix 个别情况下会话未读消息数显示不准确的bug;
- Fix 个别情况下获取联系人不正确的bug;
- Fix 登录户马上加入聊天室某些情况下会失败的bug;
- 发送语音或者视频时,如果文件内容过小会给出提示;
- 优化读取数据库的性能;
- 增强的自适应视频质量算法,根据网络环境动态调整清晰度;
- 优化了语音算法,通话更清晰;
- 支持高清视频,画质更细腻;
- 支持客户端视频和语音数据回调,;
- 支持横屏和竖屏自由转换;
- 支持画面fit和fill模式;
- 增加个人间转账功能
- 增加拆红包音效
- iOS10进行适配
- cmd消息增加“em_” 和 “easemob::” 开头的action为内部保留字段;
- Fix 个别情况下会话未读消息数显示不准确的bug;
- Fix 个别情况下获取联系人不正确的bug;
- Fix 登录户马上加入聊天室某些情况下会失败的bug;
- 发送语音或者视频时,如果文件内容过小会给出提示;
- 优化读取数据库的性能;
版本历史:Android sdk更新日志 ios sdk更新日志
下载地址:sdk下载 收起阅读 »
下一代客户服务软件的三大核心驱动力
经过十余年的发展,国内客户服务中心发展经历了语音呼叫中心、网页端客服、社交媒体客服、移动端客服,并最终发展成为了全媒体客服的复合形态。
中国客户服务中心发展历程
随着客服形态的不断演进,也面临了越来越多的挑战。包括:1,渠道杂。2,成本高。3,效率低。4,弱网络。5,体验差。
客服行业面临的五大挑战
客户服务软件将如何解决这些痛点?未来将如何发展?哪些技术将重塑行业?环信联合Gartner在SaaS客服行业的一些前沿探索已经给出了答案。
环信联合Gartner即将发布《Trends of Next-Generation Customer Service Software》敬请期待!
1.基于移动端的客户服务。(全媒体客服核心在于移动端接入,移动端客服最佳体验是基于IM。)
移动互联时代,客户正转移至移动端,服务需要紧跟客户步伐。Gartner预测,到2017年35%的客户将通过移动设备发起服务请求,这个数据是2014年的3倍。因为技术门槛高目前仅有部分大型企业能够在移动APP上提供端到端的、完整的客户服务支持能力,但是中小型企业的部署热情高涨。同时,在社交媒体上(如Facebook、微博、微信等)入驻的企业都已经开始在平台上提供客户服务能力,相比传统的网页客服和呼叫中心,社交媒体客服更是得到年轻用户的青睐。包括移动APP内置客服、社交媒体客服、网页客服/HTML5客服、传统呼叫中心等接入的全媒体客服已是大势所趋,而全媒体接入的核心在于移动端接入。
移动APP内置客服的最佳体验是基于IM(即时通讯)。随着IM(即时通讯)类APP如Whatsapp, 微信等在手机上的流行,IM已经被证明是在移动终端上最适合连接人与人的沟通方式。在客服领域,以环信为代表的一批移动APP内置客服技术提供商的成功,也证明了IM同样是移动终端上最适合连接人与服务的沟通方式。将IM方式用于消费者与客服人员沟通有几大优势:
1,支持富媒体消息,表现能力强。比如消费者可以发送位置,图片,订单消息等类型消息。这种类型的富媒体消息,往往很难通过电话描述。
2,IM沟通是典型的异步沟通方式。对客服坐席来说,使用IM,可以和最多几十个消费者同时沟通,相比电话这种传统的一对一同步沟通方式,效率有极大的提高。与此同时,对于消费者来说,使用IM沟通,更符合手机碎片化使用的特点。
3,使用IM客服,消息必达。只要用户不卸载APP,即使用户离开APP,甚至杀死APP,客服也随时可以将消息以推送方式通知到手机。用户绝不会错过任何有价值的消息。
最佳实践示例:国美在线APP通过环信提供的APP内置客服很好的服务了上亿用户。
2.参与企业全流程运作,帮助企业优化运营,提高跨渠道客服体验的客户体验透析产品"客户声音"。(跨媒体、跨渠道、跨部门的客户服务体验是客服行业面对全媒体客服新趋势的主要挑战。)
全媒体客服的最佳体验不仅只是多渠道的接入和各个接入渠道之间的数据打通,更重要的是用户跨媒体、跨渠道、跨部门的体验和跟踪,在海量的数据中发现问题。而要做到这一点,企业首先需要理解客户到底体验到了什么。今天,全球来看,越来越多的企业正在通过构建一个有效的客户声音系统,来透析客户对企业产品和服务的准确体验,帮助企业识别和改善客户旅程的各个阶段。对企业而言,倾听客户声音的能力决定了他们在客户体验这个领域上的竞争力。Gartner的预测报告指出:“未来五年之内,客户声音系统是全球企业最重要的战略投资之一”。
“客户声音”将帮助企业解决四大挑战
环信客户声音是一款基于人工智能和大数据挖掘的客户体验透析产品。通过对来自多个渠道的非结构化客服数据进行自然语言解析,主题聚类,情感度建模等技术分析手段来挖掘和分析热点话题,发现服务运营问题,寻找畅销或问题产品,洞察销售机会。环信客户声音通过透析客户对企业产品和服务的准确体验,帮助企业识别和改善客户旅程的各个阶段。
1,整合多渠道数据源,透析客户对企业产品和服务的准确体验。(包括网页在线客服数据、微博微信客服数据、移动APP内置客服数据、百度贴吧、博客论坛以及其他互联网社交网站数据等。)
2,基于人工智能技术,帮助企业识别和改善客户旅程的各个阶段。(在客户声音系统中,主题关键词热度越高,说明用户关注度就越高。关键词对应的情感越负面,说明用户的体验感就越差。)
示例:上图显示了某电商主题关键词热度分布。四种颜色代表四个主题。主题和关键词百分比代表了该主题或关键词的用户讨论热度。
示例:上图是讨论热度最高的主题“注册登录”下头15个关键词的情感估值对比图,绿柱表示用户满意度高。如果用户对某关键词对应的业务充满负面情绪,系统用红柱突出表示出来。黄色表示中性。
示例:某电商按关键词或情感度追踪并解决物流快递问题。
3.极大解放生产力的智能客服机器人。
随着全媒体客服的普及和广泛应用导致企业和消费者多点接触,同时用户体验得到了企业的重视,导致客服咨询量暴增,企业有限的客服人力资源与日益增加的客服请求之间的矛盾日益尖锐,如何用有限的客服资源服务不断增长的海量客服请求需要一个颠覆型的技术来解决。相比人工客服,智能客服机器人将提供极大的效率优势。Gartner报告指出智能客服机器人(VCA-virtual customer assistance)技术将在2017年成为客户服务行业的核心驱动力。
环信作为智能客服企业的先行者,基于自然语言处理和机器学习技术推出了环信智能客服机器人,辅助或代替人工客服精准回答常见或高频问题,降低企业客服人力成本。目前,环信在客服领域已经服务了29000多家标杆客户,积累了人工智能在客户服务行业落地的大量最佳实践。
1、 无需人工标记和人工维护的机器人单轮会话,极大降低机器人维护成本。
最佳实践示例:环信机器人无需人工维护相似问法,就可以在会话过程中识别同一问题的多种不同问法。
2、 机器人多轮会话,支持更多复杂业务,进一步拓展机器人使用场景。
最佳实践示例:环信机器人通过多轮会话支持查询物流状态,并和企业业务系统做集成,真正意义上节省人工。
3、 无缝人机协作体验,复杂场景下最佳用户体验的客服模式。
在一些比较复杂和特殊的服务场景,比如高客单价的金融行业售前咨询,机器人客服不能完全理解客户的个性化咨询要求的时候,我们可以无缝进入人机混合模式。在人机混合模式下,环信智能客服机器人向人工客服推荐备选答案,人工客服起到了保证答案质量充当专家客服的角色,这样既保证了客服的响应速度又提高了问题的回答准确性,同时降低了人工客服的工作量。
4、 智能质检,准确率达到替代人工质检水平。
环信机器人还提供自动智能质检功能,可以对全部客服会话进行实时或离线质检。 智能质检是基于环信在线客服各个领域的海量用户对话,提取出数百个客服对话特征,并用这些特征训练得到的一个通用质检模型。智能质检的准确率达到替代人工质检水平。 收起阅读 »
让客服中心提供更出色服务的十大法宝
因此,每天接听电话的客服代表,便是您最具价值的员工。他们必须具备影响客户认知品牌的技能和能力,来与客户直接沟通。
缤特力将探讨一些方法,让客服中心可以做出一些循序渐进的改变来满足并超越客户的期望。以下是提升客服中心客户体验的10大方法:
1、停止测量平均处理时长
在如今的通话变得比以往更复杂。 您的客户期待获得最佳服务,这并不意味着快速结束通话就能提供最佳服务。关键在于问题的解决,而不在于所花时间的长短。
2、每位员工配备两块显示屏
有些呼叫中心的员工每天使用多达 15 种的不同软件工具。 但是在单块屏幕上打开和关闭所有软件窗口是一件繁琐的事。双屏幕可让他们在查找信息解决手头问题的同时,仍可以查看客户信息。
3、改善您的音频质量
这看起来也许是小事一桩,但是通过一款专业的耳机,可以大大改善您的通话质量。
4、尝试在家办公
朝九晚五的工作方式不再适合现代人的生活,人们想要实现工作与生活的平衡。因此,在家办公的方式必定能将员工满意度提升到一个全新水平。它能建立信任度,降低员工流失率并提升员工“工作时”的效率。
5、测量您的噪音
五分之四的员工认为办公室的背景噪音会分散注意力。 而且它会破坏客户信息的保密性尤其是在医疗保健和金融服务方面。您可以采取声景技术 (SoundScaping) 等措施监控噪音热点的位置
6、定期更新耳垫
无论您的员工使用自己的耳机还是共用耳机,定期更换耳垫都是很重要的。 通过平时注意卫生,团队重要成员不会因为忙碌的呼叫中心工作而引起耳部痛苦,进而影响工作。
7、随时移动
接听电话时,客户服务代表不可能每次都能解决客户问题。 因此您的员工需要在不切断通话的情况下自由走动。通过这种方式他们可以在进行客户对话的同时找内部专家讨论,或查找正确的信息。一款专业的无线耳机,能帮助团队成员之间以及后台专家进行联系,同时能与客户保持直接沟通。
8、针对不同的活动使用工作区
有时您需要其他人围坐在您身旁才能更好地工作。 而在其他时候 , 你需要思考或交谈的私密空间。通过针对不同的活动使用不同的工作区,您可以在需要时帮助您的同事专注、思考、交流或协作。
9、简化您的软件
有多少个不同的软件工具是您的员工真正需要的? 在数字时代,人们很容易想要利用一切可以利用的资源,但这只会削弱“对话”传播。因此,请仔细思考哪些软件是必要的,然后削减其余的软件。
10、更改职位名称
众所周知,当员工感到自己的价值被认可时,会更加努力地工作。 职位名称在激励员工以及增进其工作的自豪感方面发挥着重大作用。有时所需要做的仅仅是将职位名称从“接线员”、“话务员”、“座席”等更改为“客服代表”、“客户官员”、“营养顾问”、“理财顾问”、“客户管理专员”、“技术支持工程师”、“订单处理专员”等。
相信以上10种方法会对您的客户服务中心的管理有所裨益。将这些方法结合起来,让客户服务代表与您客户之间的互动体验更加出色。 收起阅读 »
环信Window版SDK发布,通讯大有可为
- 关于Windows SDK
- 集成准备
|include|-bin|-lib|-docrelease 目录中包含SDK的头文件、lib文件和dll文件,其中easemob_d.lib和easemob_d.dll是Debug版,doc 目录包含对 sdk 的详细说明。
- 集成示例
CString strAppDir = GetAppDataPath();//获取当前用户APPDATA路径CefString sAppDir(strAppDir);easemob::EMChatConfigsPtr configs(new easemob::EMChatConfigs(sAppDir, sAppDir, "easemob-demo#chatdemoui"));//最后一个参数是开发者从环信官方申请的AppKeyconfigs->setOs(EMChatConfigs::OS_MSWIN);configs->setEnableConsoleLog(false);configs->setClientResource("windows");EMClient *client = EMClient::create(configs);g_client = client;
- 注册、登录及登出
登录的示例 :easemob::EMErrorPtr result = chatClient->createAccount("zhangsan", "passw0rd");if(result->mErrorCode == EMError::NO_ERROR) { //注册成功} else { //注册失败提示错误描述 cout << result->mDescription << endl;}
登出的示例 :easemob::EMErrorPtr result = chatClient->login("zhangsan", "passw0rd");if(result->mErrorCode == EMError::NO_ERROR) { //登录成功} else { //登录失败提示错误描述 cout << result->mDescription << endl;}
注意:createAccount(), login() 是需要与后台服务器通讯的操作,可能需要一定时间,如果程序想同时显示 UI 的话,需要放在单独线程中处理。chatClient->logout();
- 注册连接状态监听
class ConnectionListener : public EMConnectionListener {
public:
ConnectionListener()
{
}
virtual void onDisconnect(EMErrorPtr error);
virtual void onConnect();
};
...
...
mConnectionListener = new ConnectionListener();
g_client->addConnectionListener(mConnectionListener);
Window Demo和SDK下载:点击下载
Windows SDK 集成文档:集成指南 收起阅读 »
全面质量管理下的动态二级预警机制
近年来,呼叫中心正在从传统的电话运营方式向多媒体、智能化迅猛发展,全媒体/全渠道客户互动平台、AI人工智能客户机器人在呼叫行业的技术实现指日可待。随着硬件、软件环境的不断完善,呼叫中心与客户的沟通渠道变得越来越多样化,原本占有主导地位的人工客服数量不断缩减,但同时对其沟通能力、业务水平的要求却越来越高,这将是一支高素质、高能效、高水平的精益化客服队伍,同时,人力资源管理水平也将始终是呼叫中心运营的核心主线之一。
随着市场竞争不断加剧,企业对服务质量的要求也不断提高,在质量管理中,预警机制可以有效发现问题、控制问题,进而妥善处理问题。本文对呼叫中心日常质检差错动态二级预警机制进行了一系列探索和实践,在质检差错闭环管理中取得了较好成效,达到了分层级、持续提升的管理效果。
一些传统的差错预警机制如“偏差底线三级预警机制”的判断标准为累计出现n次定义为一级预警;累计出现n+2次定义为二级预警;累计出现n+4次定义为三级预警。举例说明,若用月度一般差错(非致命差错)数/率作为衡量客服代表的阶段质检水平的标准之一,平均每位客服代表的月质检录音数量约为25通,一级预警阈值设定为6通;二级预警阈值设定为8通;三级预警阈值设定为10通。此时若某客服代表在月度第一周就出现5条一般差错,在此预警机制中就将被忽略,而事实上此客服代表应是被预警的重点人员。
此类预警机制有两大弊端,一是预警周期较长,通常以月、季度为累计周期,预警阈值单一,常常达不到预期的预警效果,若将累计周期缩短又会失去评判的合理性;二是预警层级较多,在警告力度与绩效考核不能提供相应配合的情况下,被预警人员积极性不断削减,预警效果适得其反。
不同于传统的质检差错预警,动态二级预警机制预警阈值通过对当前质检差错数学建模后以周为周期设定动态阈、,以月为差错累计周期制定考核标准,在深度透视质检结果的同时实现短期、实时的预警效果,充分配合质检标准校准频繁、质检水平变化迅速、要求差错快速整改的质量管理现状。
由于质检数据每日更新、质检内容纷繁复杂、数据透视工作量较大、预警阈值动态变化等客观因素,为了减轻人工工作量、提高数据统计准确性,我们建立了质检评分明细数据库,通过文字匹配对每日日常质检一般差错、严重差错进行数据透视,为质检差错分析提供数据支持。另外通过对部门、班组、个人的质检差错数量统计,用软件设计实现动态二级预警机制,最终建立日常质检动态二级预警平台。
二、动态二级预警机制阈值设定
日常质检差错预警采取“红、橙”二级预警制度,每周统计截至当日月度质检差错累计值,根据每周动态阈值进行预警,以月为差错累计周期制定考核标准,具体统计周期、预警阈值见下表:
1、质检评判:质检工作遵照质检检测/评判标准,常态开展质检工作。内部质检对日常质检突出问题进行专项质检。
2、预警发布:建立日常质检差错预警周发布机制,定期编制“预警通知单”并按时按需发布预警。
3、预控执行:各班组接受“预警通知单”,及时组织制定、落实预控措施,并于2个工作日内反馈措施落实情况及业务支撑与培训需求。
4、监督与考核:由值班经理进行差错整改的闭环检查,持续跟踪重点人员与频发差错,同时提供整改措施,督促班长进行QC提升活动。对月末仍为红色预警的重点人员,在月度绩效中进行考核。
三、软件设计
日常质检数据明细为每日导入,软件主要实现部门、班组、个人三个层级对本月截止当日差错累计数量进行统计,并通过文字匹配对一般差错、严重差错根据存在问题一栏差错分类子项进行数据透视,由界面友好的预警平台输出预警人员名单与部门、班组、个人的差错突出问题,为质检差错分析提供数据支持。
建立质检评分明细数据库,其中一般差错透视项分为两大类:工单质量和录音质量。工单质量分为工单填写、工单分级,工单填写又细分为受理内容记录不完整准确(含错别字、不通顺)、客户信息记录不完整准确(含联系人姓名、地址、联系电话等)等九个小项。工单分类差错不设下级透视子项。录音质量分为业务能力、服务规范、服务态度、沟通能力及下属多个子项。
四、全面质量管理下的动态二级预警机制
服务质量的提升是整个团队管理与执行的合力,而非单单依靠质检团队,这就是全面质量管理的概念。全面质量管理要求全面质量、全部过程、全员参与,而对于呼叫中心则是要求质量管理全业务、全流程、全人员覆盖,强调各层级人员、各运营关键点与质检之间的配合。ISO 9000强调“全员参与、过程方法”的质量管理理念,动态二级预警机制正是实现全面质量管理的有力工具。
动态二级预警机制平台的受众是部门所有的客服代表、班组长、主管、值班经理等各层级人员,可以通过查看个人、班组的质检成绩与数据透视结果以及全体接听人员的质检差错预警情况来达到全人员参与、全人员监督的效果。
对于平台导出的人员差错预警与日常质检透视分析成果,由客服专员自行整改、班组长一对一辅导、主管对红色预警人员进行谈话、内部培训对共性问题进行集中培训、值班经理闭环检查等实现全流程管控及闭环分层级管理。
本文刊载于《客户世界》2016年8月刊文章;原文作者汪东邻 ,本文作者为单位为国家电网公司客服中心南方分中心。 收起阅读 »
Android-按二次返回键退出
在onBackPressed 方法中做下时间判断
/**第二种在onKeyDown 方法中做下判断
* 最后按下的时间
*/
private long lastTime ;
/**
* 按二次返回键退出应用
*/
@Override
public void onBackPressed() {
long currentTime = System.currentTimeMillis();
if(currentTime-lastTime<2*1000){
super.onBackPressed();
}else {
Toast.makeText(this, "再按一次退出应用", Toast.LENGTH_SHORT).show();
lastTime=currentTime;
}
}
@Overrideexit方法就是第一种的写法
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_BACK){
//禁用返回键
exit();
return false;
}
return super.onKeyDown(keyCode, event);
}
有些页面不让用返回键可以禁用
@Override收起阅读 »
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_BACK){
//禁用返回键
return false;
}
return super.onKeyDown(keyCode, event);
}
环信助力2016中国开源年会(COSCon'16)
由开源社主办的中国开源年会2016 (COSCon'16 - China Open Source Conference 2016) 即将于今年10月15日-16日在北京举办。
这是一场--跨社区,跨技术领域,跨国度的年度盛会!
您可以与真正的开源贡献者和参与者,直接互动!
大数据,云计算,操作系统,开源治理,精彩纷呈,绝对让您不虚此行!
区别于一般的大会,我们知道草根开源社区听众,期盼听到纯干货,更希望与讲师能有更多互动,因此我们安排了:
讲师打赏(提供讲师更高的动力分享干货)
现场在线抽奖(直接回馈热情投入的听众,特等奖为Endless赞助的Endless mini电脑两台)
视频直播/弹幕/评论(全国范围远程参与互动反馈)
越来越多的讲师课题涌入,愈加提升了大会的质感,相信大会的丰满程度将超乎您想象!
- 时间地点
- 大会亮点
- 在线直播
- 我们是谁
- 我们打算办一个怎样的大会
- 会议形式
- 创新互动
- 大会议程
第一天(上午)
08:00 注册报到
09:00 致欢迎辞 – 吕卫锋,北京航空航天大学计算机学院院长/教授
09:05 开场致辞 - 廖湘科,中国工程院院士
09:10 主题演讲 - 变革:企业的开源之旅;申元庆,微软亚太研发集团首席运营官、微软中国云计算与企业事业部总经理
09:50 主题演讲 - 中国云计算开源产业发展机遇;何宝宏,中国信息通信研究院标准所副所长,云计算开源产业联盟常务副理事长
10:30 主题演讲 - Elephant in the Room; Niclas Hedhman,Apache 软件基金会副总裁
11:10 高峰对话 - 廖湘科,中国工程院院士;梁莉,FreeBSD基金会执行总监;栗蔚,云计算开
源产业联盟秘书长;庄表伟,开源l社理事会代表;
第一天(下午 - 操作系统分会场)
13:30 Linux性能剖析工具的现状以及我们的优化 - 宋宝华, Linux资深工程师
14:10 ZRAM那点事--ZRAM/ZSMALLOC简介以及3个问题修正和1个提高 - 朱辉, 小米电视工程师
15:00 FreeBSD,the Unknown Giant in Internet Industry - Dr. Hiroki Sato, Director, FreeBSD Foundation
15:40 Ubuntu Core 和SNAP 开发技术介绍 – 刘晓国Canonical, 高级软件工程师
16:20 Linux启动管理器对比及启动性能优化方法 – 刘易,优麒麟社区,优麒麟核心开发者
第一天(下午 - 云计算分会场 - OSCAR)
13:30 OpenStack分布式 SDN: Dragonflow 简介 - 肖宏辉, 华为, 高级软件工程师
14:10 Kubernetes on Mesos: 现在与未来 - 马达, IBM, 软件架构师
15:00 容器对 OpenStack 基础架构的影响 - 陈沙克, 九州云信息科技, 技术副总裁
15:40 开源云计算成为中国企业的IT发动机 - 何军辉, Easystack, 大企业部资深架构师
16:20 从DevOps到自动化运维实战分享 -季文轩, 云途腾系统架构师,Magicstack全线产品经理
17:00 OSCAR在开源上的思考 - 陈屹力, 中国信息通信研究院工程师
第一天(下午 - 开源治理分会场)
13:30 Commercialization around Apache Licensed Software - NiclasHedhman, VP, Apache Zest
14:10 如何持续地开发一款开源软件 - 王春生,青岛易软天创网络科技,创始人
15:00 Seafile四年开源路 - 潘凌涛, Seafile CEO
15:40 Inner Source-如何在企业内部采用开源软件模式 - 李建盛,开放云精选,创始人
16:20 结合GitHub的开源审批和部署流程 - 宋青见, 微软, 首席产品经理
17:00 闪电演讲:我的开源经历,开源心得, 开源社区运营经验及展望 - 杜金房, 北京信悦通和烟台小樱桃创始人,FreeSWITCH-CN中文社区创始人
17:20 闪电演讲:开源硬件的社区治理 - 梁尧, BOE知识产权和技术管理中心中级研究员、专利工程师,中国知识产权研究会会员研究员
第二天(上午 - 大数据分会场)
09:00 Building a Reliable Large-Scale Distributed Database: Principles and Practice - 申砾, PingCAP, Engineering VP
09:40 Apache HAWQ: 替代传统数据仓库的SQL-on-Hadoop引擎 - 常雷, Apache HAWQ创始人
10:20 开源指南针 - 王启泰,指南针开发团队项目管理
11:00 从 PostgreSQL到云端大数据处理 - 马涛,北京酷克数据科技,联合创始人
11:40 三个五分钟,构建流式,批处理,交互式应用 - 祝威廉,乐视云, 资深数据工程师
第二天(上午 - 云计算分会场 - OSCAR)
09:00 Docker开源社区初探 - 魏世江, 云栈科技 (希云cSphere) CTO, Docker社区代码贡献者
09:40 基于DC/OS的现代应用落地实践 - 陈冉, DCOS中国社区创始人
10:20 我的2016感悟—云技术社区运营及云计算给运维职业选择带来的变化 - 肖力, KVM云技术社区发起人
11:00 重新打造一个开源容器管理面板 - 肖德时, 北京数人科技有限公司, CTO
11:40 OpenStack Zaqar项目简介 - 王昊,烽火通信科技股份有限公司,架构师
第二天(下午 - 前沿(新)技术分会场)
13:30 Hyper:基于硬件隔离的容器技术 -王旭, Hyper, 联合创始人, CTO
14:10 开源代码项目的质量/安全缺陷检测与法律版权管控技术 - 韩葆, Synopsys
15:00 物联网技术发展研究 - 李永华, 北京邮电大学北京邮电大学教授
15:40 开源软件在华为容器项目测试中的应用 - 孙远 ,华为资深工程师
16:20 When the going gets tough, Get TUF going! - 胡科平, 华为,高级系统工程师
17:00 闪电演讲:《更了不起的Node.js》或《从零开始构建一个Node.js Web框架(基于Koa 2.x)》 - 桑世龙, 空弦科技, CTO
17:20 闪电演讲:Firefox 的 Servo 引擎 - 赵博通, 谋智火狐(火狐社区)
第二天(下午 - 云计算分会场 - OSCAR)
13:30 基于OpenStack技术的云计算开源产业发展介绍 - 陈文弢, 中国信息通信研究院, 工程师
14:10 开源容器云 OpenShiftOrigin: 基于Docker与Kubernetes的容器云 - 陈耿,Redhat,高级技术顾问
15:00 开源如何解决 DevOps的问题: Cloud Foundry and more - 况宁, 微软,高级项目经理
15:40 DaoliNet:一种高可用高带宽虚拟化网络技术 - 中国通信学会云计算与大数据专家委员会委员, 道里云公司 CEO 毛文波
16:20 Docker image on PaaS:如何在PaaS平台上持续集成 - 轻元科技 PaaS组工程师 唐飞雄
17:00 闪电演讲:大数据paas平台运维体系构建分享 - 王福旺 亚信高级运维研发工程师
17:20 闪电演讲:《将openstack-infra引入企业级软件开发》 - 赵祯龙 浪潮信息
开源高峰圆桌会第二天全天
主题:如何畅饮一杯滚烫的开源
一、讨论范围:仅限受邀企业、社区、协会及专家代表(具体名单待定,不会超过12人)
二、主要议题:从公司政策、文化、流程、工具等层面,讨论企业与开源相关的各种话题:
企业如何用好开源?
企业项目如何对外开源?
企业内部研发如何互联互通?
企业与开源社区,如何互利互惠?
企业自建开源社区,开放平台,开发者社区,有何区别?如何运作?
国际经验与中国实际;
政府定位与可选策略;
微软工作坊 第二天全天
09:00 实验室活动#1:Azure 入门和 Docker 搭建动手实践.(欢迎自带电脑,提前或现场申请1元账号,获得1500元额度);现场会手把手从 Azure 门户、Powershell/CL等用户接口,创建虚机开始。通过Dockers1.12的Swarm集群(若干虚机)的动手实践进入高潮.
10:20 区块链技术介绍及其开源项目- Ethereum(以太坊)演示 -闫莺 微软亚洲研究院 主管研究员
11:00 MySQL及LAMP快速建站演示
11:40 答疑和抽奖环节
13:30 实验室活动#2: .Net Xamarin + Typescrip + Node.JS(移动+Web+Azure) 一体化开发动手实践,继续上午的Azure后端开发的热身之后,从Node.js开发演练开始,过渡到前端应用开发的实践,开源的Xmarin跨iOS和Android开发的神器,以及让Javascript升级为严谨大项目开发的利器Typescript
15:00 VS Code 插件开发演练 - 张晨 MVP 白鹭引擎
15:40 拥抱开源的大数据平台 - 姜英,微软大数据平台首席产品经理
16:20 一小时玩转Azure镜像市场的开源镜像 - 刘明,微软 高级产品经理
17:00 答疑和抽奖环节
收起阅读 »
告别客服时代,进入互动服务时代!
然而,这种定位已经与现实社会越来越无法适应。每次我听到坐席员在解答消费者问题后都生硬地问那句标准结束语:“我的服务有让您非常满意吗?”在电话另一头的客户往往拒绝回应而挂掉了电话。按照流程设计者的本意,消费者在这种人力管理模式中也竟然成了一个特定角色,他们也被裹挟到了这种程序中,企业并不向他们支付任何回报,也没有顾及他们真实感受,这些都仅仅是为了做一份美丽的客户调查反馈报表而设计的。显然,我们从这种程序中不但看到那些可怜巴巴的坐席员在刻意讨好甚至感情贿赂那些消费者,以此提高业绩,而消费者不但没有从中获取好的体验感受,反而加重了心理负担。如果我们稍稍回味一下,就会发现客服流程作为产品流程延续是多么荒谬,你明明就是要告诉那些消费者不要退货,不要索赔,不要找麻烦,却说是为他们服务的,甚至是为他们提供了产品之外的使用价值。
对于这种与现实的脱节我们宁可选择视而不见,因为它确让我们这些依靠KPI管理体系讨生活的人们深感恐惧。这种恐惧来自于遇到了一个无比强大的对手,我们所面临的竞争者是一个强大无比的人工智能系统,它可以在国际象棋和围棋上战胜最强的人类棋手,当然处理我们这些简单枯燥的工作应答程序不在话下。面对这种高级科学产物,我们现有的科学化管理显得非常低端,而且它并不符合自然法则,把人类鲜活的智慧变成了机械性工具,把生动灵活的交流变成了具有敌意的竞争对话。现实中我们看到的是这种非理性思维被不断强化,随之而来的是各类时间管理软件和录音系统把坐席人员的一举一动按照时间和内容进行标准化,简直就如让一个戴着枷锁的犯人去自我惩罚。我曾经看到一个中国呼叫企业使用有七十多条质检标准的业绩表格,让每个坐席都每半个月承受这种惩罚性“与领导沟通”。当然,最惨的就是那位质检领导,他不得不天天面对坐席员做这件同样的事情,深怕自己成为一个思想虐待狂。
显然这套KPI管理体系预设了一种错误的逻辑前提;它假设人类是根据行为数据标准进行工作的,而心理学告诉我们人类是根据工作目标工作的,可惜我们直到电话诈骗蔓延全国才意识到这点:“为何这些诈骗团伙用如此简陋的设备就能做的比我们高效的多?”。正因为骗子们没有KPI的约束才能进行如此灵活生动的对话表演,而我们在KPI枷锁之中依然是工业产品的一种部件而已。然而呼叫中心行业对于KPI管理体系的迷信是何等深入骨髓,它形成了一系列的评估标准,并配以奖罚制度,并以此为标准开发出越来越精美的机器系统,从二十年前十多个KPI指标到如今的上百个指标,企业为此花费了更多的金钱,人员流失却越来越加剧,客服满意度却没有实质性提升。
在美国当年那些电信巨头都曾有过世界上最强悍的KPI客服管理体系,也正是这种极端化技术管理向社会暴露了它们的低效和粗纰。微软开启了人工智能时代,却是乔布斯奉献给这个世界最可贵的礼物----智能手机,才彻底颠覆了工业时代那种企业和消费者关系,让消费者真正成为了市场运营的主动一方。苹果手机的名言就是“你是掌握方向盘的主人”,作为手机主人没有其他人能够迫使你做不愿意做的事情,包括手机后续服务麻烦处理。美国电信(AT&T)如今已经沦落成纯粹的信号管道提供商,而苹果手机却成了消费者的生活体验核心平台,盈利与社会生活发展同步共赢。
中国中产阶级在全球到处走的人越来越多,他们根本对现有的客户呼叫服务不屑一顾,因为他们只选择那些无需后续客服的产品和服务,这类产品和服务直接把后台客服需求集中起来交给软件打包处理,以免造成不良反馈和体验。就如现代智能手机里的那些APP一样,你只需按一下指令就可以确信获得所需服务,这就是所谓的“主体服务”----消费者作为主体为自己服务。如果今天你说需要一个数百人的呼叫中心用于客服,我会反问你的产品市场定位是否要彻底反思检讨。人类的确已经到了“非客服时代”,把客服变成了“主体服务”模式,消费者不再是被踢来踢去的客体(皮球),反而成了掌握客服平台方向盘的主体,客服人员成了他们的助手。
如今客服体验模式是个备受关注的问题,显然已经无法用过去那种简单的产品使用感受充当内容主干。随着时代发展,消费者所处的文化氛围不断改变,网络生活促使个性化需求迅猛发展,同时也能够更有效地满足这些需求,随之而起的是小众化市场如同雨后春笋到处出现,社交网络成为了这种市场的集散与服务平台,形成了众多的分享经济模式的同时,也为今后客户业界发展提供了前瞻性预测。在这个时代里,消费者不再是一个被动的产品使用者,而是一群提供消费能量作用的“消费商人”。(选自《客服革命时代》,作者:邹达辉)
本文为转发仅代表作者观点。 收起阅读 »
猿生态十城巡回沙龙丨西安站
微软的小冰机器人为什么会得到奶茶妹妹的青睐并命名
Cortana语音助手为什么会后来居上,超越苹果的Siri
如何将软件测试做到极致
微信小程序来了,你的js知识储备好了吗
哪里才是全世界学习web开发最好的地方
......
无猿不生态
猿生态十城巡回沙龙
精彩继续
10月15日 陕西省科技资源统筹中心
A区一楼众创空间
活动议程
13: 00 – 13: 30
活动签到
13: 30 – 16: 30
技术分享 + 实战演示
16: 30 – 17: 00
抽奖 + 自由交流
讲师介绍
Tips
✦自带电脑:在实战演示环节,讲师们将带领大家现场写代码、做demo,建议带上电脑。
✦ AA餐会:活动结束后,与讲师和现场小伙伴们共进晚餐,交流、交友~~活动现场报名喔;-)
本场活动将通过云犀直播,在斗鱼、战旗、爱奇艺、熊猫TV等多个平台全程同步直播,扫描下方二维码即可收看
✦ ✦ ✦ ✦ ✦ ✦ ✦ ✦
更多精彩即将上线
阅读原文报名链接:阅读原文 收起阅读 »
探究全媒体客户中心的员工胜任力管理
一、 传统的胜任力解读
随着“互联网+”概念的普及以及网络信息技术的进一步发展与应用,客户服务正向着“交互体验,个性定制”的方向转变, 而打造一支稳定高效、富于战斗力的客户服务团队是大部分客 户中心管理者面临的重要课题,新形势对客户中心员工胜任力 提出了新的要求。 传统胜任力模型主要涵盖职业、行为和战略综合三个维度。 就呼叫中心行业而言,因需要直接与客户接触并解答客户问题, 因此熟练的业务知识和良好的沟通能力显得尤为重要。基于这 个考虑,呼叫中心传统培训主要以业务知识为主,通过强化记 忆和考试练习等方式不断加强人员的业务熟悉程度,务求人员 能够快速准确地解决客户问题。
二、全媒体时代客户中心员工胜任力的新挑战
1、渠道信息多元化
从传统的单一电话沟通发展到现在的在线、电话、机器 人沟通,出现了“淘宝小二”、“京东JIMI”等智能机器人客服, 意味着客服行业全面进入智能化阶段。
2、客户需求个性化全媒体时代随着客户购物渠道的增加和客户群体的壮大
客户购买产品除了满足其基本的使用需求外还追求心理层面的 附加价值及人本价值,因此客户服务也要从一通电话简单地解 决客户问题扩展到满足客户的所有需求,包括预约回电、语言选择、回复时间以及其他诸多个性化需求。
3、客户服务人文化
客户中心人员要能够对客户行为作出准确判断并增加人文关怀, 在沟通中增加信任感和真实感,做有温度的服务。
三、全媒体下客户中心员工胜任力思考 笔者结合对客户需求的调研和分析,对员工胜任力新增需求思 考如下:
1、信息整合和应用能力
全媒体环境中人员与客户交互方式的多元化使得能够对大量无 序信息进行精心筛选、整理并发掘出有价值、可利用的信息,经过 分析、综合、加工而转换成新的信息成为一项不可或缺的重要能力。
2、EQ能力
全媒体环境下客户个性化需求的增加导致工作压力变大,要求 客户中心员工能够在把控自己情绪的同时安抚好客户的情绪,更好 地解决客户问题。
3、行为分析能力
全媒体环境下客户的行为及表达方式呈现多样化,客户中心人 员需要全面分析用户的行为动机,对客户需求做出精准判断,及时 有效解决客户问题。 由此可见,现有客户中心的员工胜任力管理需要转型以适应全 媒体时代带来的新挑战。
本文刊载于《客户世界》2016年7月刊观点文章;原文作者姜迪,本文作者为百合网股份有限公司客服总监。 收起阅读 »
全媒体客户中心的管理体系变革
随着人工智能的推动,简单重复的劳动逐步被自助服务取代,这为服务升级提供了快速发展和快速迭代的土壤。企业间服务体验、服务效率、服务成本的竞争更加激烈,这既影响着客户的活跃度也影响着企业的运营成本。
客户中心作为业务处理中心、信息集散中心,每天经历着大量的案例,每个案例都交集着各个运营环节的问题。如果不能将问题看清、摸透,让日常的问题通过流程、制度以及系统来解决,就无法推动人工智能的建设。如果客户中心仍借助人的力量进行判断,突发事件众多、个案协调众多,因无制度可循,流程也不顺畅,更谈不上轻平台的建设。那么,如何搭建完善的服务管理体系从而推动服务体验提升、自助服务能力提升与服务成本的下降呢?笔者认为需要通过以下几个方面来进行 “华丽”转身。
一、思维方式转变
在当前人工智能发展的大趋势下,客服中心要实现“华丽转身”最重要的是进行思维方式的转变。
1、由“运动员”角色转向“裁判员”角色。
以往的客服人员,尤其是客诉处理人员,往往认为投诉的完成意味着客户接受解释或处理方案,投诉处理完成也即工作完成。实际上这只是完成了投诉的一半,即相当于客服人员扮演“运动员”的角色完成了案件的执行部分;而另一半投诉的深度分析、责任判定、推动改进、改善方案等“裁判员”负责的工作并没有真正开展,由此带来了投诉问题的重复发生。因此,这个转变应该自上而下,由管理人员意识的转变带动工作机制和能力培养方向的转变,最终使得每一位接触投诉、舆情、负面评价的一线人员具备“裁判员”的能力。
2、由处理问题向根除问题转变。
从单点的处理问题转向举一反三梳理同类问题,从判断问题以及问题的判责进化到从源头上根除问题。这需要管理者在充分了解问题的情况下,梳理上下游业务流程及规则的执行,才能够追本溯源,推进问题改进。要实现这一转变,需从以下两个方向入手:
由平台的使用者向平台的建设者转变。
服务的自助化,要求平台的迭代速度更快,更加贴近需求。而推动技术平台不断迭代的一定是业务需求和业务问题。因此,管理者必须摆脱等、靠、要的心态,从业务场景出发来改变技术的功能。而系统的功能要从支持常规业务向支持多场景业务的方向转变。
由用人解决问题向通过流程与系统解决问题转变。
在业务波峰阶段或在销售大促集中期,传统的客服中心往往从人力测算到人员储备的思路来进行服务应对的准备,而全媒体客户中心应从自动化推动的角度提升自助化服务能力,并做以下的转变。
从预知到预防:无论是单点的促销还是常规的业务,要从预测预知服务场景、问题场景、需求场景,到预防方案的设计。
从预防到预设:预防方案的设计推动系统在各个业务场景的功能设计。系统的自助服务程度取决于预设场景的覆盖程度,当各类突发事件全部在预设的常规服务机制当中时,服务的自动化能力才能够得以体现。
前置服务场景测试:传统客服中心大量的工作是在问题发生后,而全媒体客户中心大量的工作是在前置服务时,包括服务场景的设计、系统测试、知识库应答测试等等。
正所谓:“思维转变天地变,思想不变原地转”,只有自上而下思维方式的转变,才能够推动客服中心不断的创新、提升与改变。
二、管理机制与流程的转变
1、问题改善流程与问题预防机制并重。
在过去的服务管理中,对于售后服务类的客服中心在流程的管理与执行上有三个阶段的演变(如图1):
第一阶段:作为流程的一个环节,处理好当前业务环节。处于这一阶段的作业流程较为被动,易导致管理者局限于眼前的工作内容缺乏全局观。
第二阶段:作为问题处理的一个环节,通过问题反馈倒逼前端事前预防与事中的规范执行。从客户问题的反馈到内部问题的反馈,起到了反馈和推动的作用,是后知后觉的管理。
第三阶段:通过大量的案例积累与专业服务的沉淀,建立预知和预防风险机制,做到先知先觉的管理,引领
服务提升。
2、强化场景细分:
在多媒体运营环境下,需要做好从主业务流程的梳理到场景流程的细化的转变,通过场景细化细分业务单元推动人工智能的完善。
三、日常分析思路的转变
1、运营分析与案例分析并重。
传统客服中心的分析以业务量、咨询量、处理效率以及各项运营指标为主,但要实现服务管理推动服务提升,需要侧重于案例的深度分析与持续跟踪。
对于案例的分析必须深入分析每一个环节并进行各个时间节点和业务节点的细节分析。包括:投诉处理状态、案例类名称、留存图片、投诉日期、工单号、投诉渠道、客户地址、责任部门、订单类型、投诉人、备注、客户投诉内容详细记录、投诉受理人、投诉事件调查情况分析、调查人、协商后解决方案及结果、回复人、目前存在的问题、分析人、回访客户情况记录、回访人、投诉后购物行为、客户贡献值。
2、结果分析结合归因分析。
无论不满意度的服务评价或是网站各类差评以及日常的投诉工单,都需要进行原因分析,并结合问题、责任归属追踪投诉率、处理速度等(如图2)。这需要几个前提条件:
- 多渠道接入的工单系统:即评价、舆情、升级投诉、客户发起投诉等生成工单并进行统一路由分配。
- 投诉分级处理、投诉判责功能支持。
- 设立内部投诉工单路由规则及超时提醒等流转流程。
- 通过判责、追踪、目标分解等方式降低人为失误带来的投诉风险。
四、外部服务政策制定
统一的对外服务政策是客户服务体验的基础保障。客户中心作为各类业务和投诉的授理中心,应结合行业政策、业务场景、客户诉求制定统一的对外服务政策并推动政策在全公司内执行,对内达成共识,对外形成服务保障。比如电商企业必须要规定的的政策包含:
1、政策及鉴定标准:要结合商品品类确定退换货周期及可退换的范围、界定标准。尽可能细化、量化。只有被细化、量化的标准才能够实现系统功能开发及客户的自检自助服务流程。早期的电商企业由人来判断退换货,服务人员起到的是讨价还价的作用,这不仅是一种低效能的处理方式,更成为损伤客户并导致客户流失的要因。
2、消费者服务保障体系:例如,平台类电商消费者服务保障体系即是对商家的服务约束也是对顾客的服务保障。该体系一般包含服务处理效率的保障及超时的服务赔付;产品质量方面的保障以及由于假货、劣质商品或过期商品等问题对商家的处罚及对消费者的补偿政策等。对于商家违规的服务或产品,消费者可直接与平台监管举报并由平台客服进行处理及跟进(如图3)。
3、投诉理赔政策:对于投诉的处理时效、不同情节的投诉按场景细分制定理赔标准及赔付流程,对外的承诺即是内部的标准。标准范围内流程化处理,标准范围外除了一单一议的处理机制以外,要有形成标准和改善的循环。
服务体系的搭建除了明确、细化的服务政策以外,还要强化场景化、客户化的知识转化。
五、内部管理机制制定
1、 投诉内部管理和处罚:投诉必须进行认责、追责和分析。服务质量是在每个环节百分之百执行的前提下才能够得以保证。因此人为投诉必须有认责和处罚的机制。投诉的内部管理制度,包括客户投诉回复及解决的时效、问题纠正及持续改善的时效、追责涉及到的处罚、降职等方面的落地实施等。
2、 平台质量监控:通常电商包括商户和自营两种模式。对于商户提供客服及物流服务的,在服务时效、政策、规范方面应按统一的管理规范进行执行,并形成考核制度。基础通过培训认证的方式颁发上岗和提供服务的资质,后续进行统一服务监控。
3、 风险预防与应急处理:涉及支付风险、个人信息风险、流程风险、运营风险等应有现场突发事件的预防与应急处理方案。
4、 内部分析与沟通机制:作为推动各环节进步的服务管理部门,必须建立起投诉分享及改进方案推进进展的分享或讨论。
5、 商品上架下架原则:商品上架必须在商家服务保障达标、商品质量及证照相关材料审核通过的前提下方可上架销售,对于同类商品周期性出现一定比率的质量投诉情况必须有紧急的下架检核机制,检核通过方可恢复上架。一方面通过标准规避风险,另一方面通过制定防范风险再发。
全媒体客户中心作为企业面向客户互动的最重要的互动界面,既是企业发展的驱动引擎和探测器,又是核心竞争力的缔造者;管理者既要结合企业发展的方向及时调整思路、节奏、步伐,又要深度挖掘客户的反馈和各环节潜在的机会与风险。新型的客户互动中心不再是被动接受的服务者,而是参与企业决策的“一员”,是经营客户和产品的主体。
定位决定思路,思路决胜未来!
本文刊载于《客户世界》2016年7月刊文章;原文作者张艳,本文作者为《全媒体客户中心管理》作者,现任蜜芽服务副总裁。 收起阅读 »
【环信集成笔记】进阶篇-android环信昵称头像解决方法
那么接下来,我来告诉大家,怎么解决昵称头像的问题,
首先,这篇文章是接在我大表哥江南孤鹜在im社区写的一篇文章之后写的,上个链接地址 Android获取昵称头像接下来,我对此文章做些补充:
我看到有些人在问,这个方法放在哪里?
好吧,大表哥没说出来,这个放在UserApiModel里面
那么接下来,大表哥写的是这样的,利用扩展消息去获取头像昵称,在这里我提醒下大家,要判断这个头像是自己的还是好友的
怎么判断呢,作为新手的我们,我推荐使用shareprefences在登陆的时候保存下自己的头像昵称,然后再这里获取,并且设置给扩展
在demohelper里面有个getuserinfo方法
这里就是把获取到的头像昵称设置给环信,然后显示出来,这里最重要,切记不要写错。
那么,到此为止,其实都说完了,可是,毕竟是一个延伸,怎么可能就此结束,接下来给大家看下,请求数据,然后设置给数据库
请求的过程我就不写了,这个大家都会,获取到username,id,logo,之后先要把头像,昵称存到userdao里面,如果userdao是环信的一个数据库,这个大家自己看看demo的代码就知道了,设置到这里,是为了在联系人列表里面显示,UserInfoCacheSvc.createOrUpdate(id,username,logo_img);这句就是把头像昵称放到大表哥写的数据库里面
最后,补充一下,忘记说了,导入框架
好了,这样就结束了,如果有什么还不明白,就加入大表哥粉丝群(环信IM互帮互助群 340452063),我会帮你解答一切问题 收起阅读 »
环信刘俊彦演讲预告:《下一代客户服务软件的三大核心驱动力》
刘俊彦毕业于英国伦敦国王学院。17年研发经验;先后任职IONA,RedHat; 重度开源软件参与者。JBOSS ESB, SOA-P、Apache CXF、JBOSS Drools、jBPM 等开源项目committer;专注于高并发消息中间件,实时消息系统,异构分布式企业系统集成,应用服务器。
环信移动客服——全媒体智能云客服倡领者,于2016年荣膺“Gartner 2016 Cool Vendor”。环信支持全媒体接入,包括网页在线客服、社交媒体客服(微博、微信)、APP内置客服和呼叫中心等多种渠道均可一键接入。基于环信业界领先的IM长连接技术保证消息必达,并通过智能客服机器人技术降低人工客服工作量。同时,基于人工智能和大数据挖掘的客户旅程透析产品"环信客户声音"能够帮助企业优化运营,提高跨渠道客服体验。截至2016年上半年,环信移动客服共服务了29437家企业用户,根据易观发布的《中国SaaS客服市场专题研究报告》显示,环信移动客服在SaaS移动端客服用户覆盖占比高达77.4%。
收起阅读 »
使用AndroidStudio开发测试Java程序实现直接运行main方法
自动Google发布了AndroidStudio1.5之后,现在经常使用AndroidStudio开发程序了,在习惯了他的强大之后已经深深的把Eclipse给抛弃了,现在就算有Eclipse的项目也直接导入到AndroidStudio里去查看;不过在有时候发现Eclipse比AndroidStudio还是有一点儿有时的,就是在有时候突然有个小想法,或者想测试小段计算的代码,这个时候也还必须连上手机去运行程序才行,这让我一直很苦恼;
不过后来发现,原来可以通过另外一种方式实现运行java类的main方法,不过在刚开始的测试过程中一直有问题,最近更新了下SDK突然想起来试下,发现成功了,这里记录下,给大家一个参考;
开始
首先如果想实现在AndroidStudio上运行java类,必须有个正常的项目,他是不能直接使用的,有了正常的AndroidStudio项目之后我们就可以在项目上新建一个Module;
步骤:
右击项目->New->Module
然后在弹出界面选择Java Library
然后填写Libarary的信息就行了
开始编写Java代码
基础我们都已经做好了,下边就可以开始进行编码测试了,这个编码都要在刚才创建的Library下进行,这样就可以像在Eclipse里进行一样了
创建完成之后就是下边这样,我们的java代码都是在这个library下编写测试;
首先我们要写一个main方法,并在里边输出一句话
/**然后我们可以直接右击当前类,点击Run'MLMain.main()'
* 我们java library 的额第一个类
*/
public class MLMain {
/**
* java类的 main方法,可以直接 run
* @param args
*/
public static void main(String[] args) {
System.out.print("hello java library!");
}
}
可以看到控制台输出了我们打印的那句话
结束语
OK了,以后我们就可以愉快的在AndroidStudio中测试java代码了!O(∩_∩)O~
希望这篇文章能对大家有所帮助!
作者:lzan13 收起阅读 »
【环信集成笔记】进阶篇-EaseUI集成以及会话列表开发
1.全有iOS端和环信交互。2.让服务器替我们保存环信密码。
先不说方式,先教大家如何集成。环信里有一个自带已经弄好的EaseUI,如果你对页面的要求不是很大,那就用环信自带的EaseUI开发。我使用的就是环信的EaseUI。为了不影响项目,你先导入需要的系统框架。我使用的是即时通讯V2版本。
集成准备前请看他们的官网文档介绍。http://docs.easemob.com/start/300iosclientintegration/20iossdkimport
是即时通讯V3,请按照他去添加对应的库!没有安全感的可以全部添加!只要你不限工程大,麻烦就可以。
添加完成以后。下载他的SDK,有几种文件需要你拖进来。
1.EaseUIResource.bundle如果还是少了什么东西不知道怎么加,请加我QQ:1119718338,我给你发送所有需要的文件,前提请注意加好友时候留言清楚。
2.gifimage(包含文件:EMGifImage.h以及.m)
3.EaseMobSDK
4.EaseUI(包括子目录:include,lib,resources*请注意里面不是图片是库,XMPP框架。 )
5.Resource(环信的图片文件夹)
6.ChatViewController(你可以用他们示范demo里拖,这个类就是对话类)
7.CystomizableCell
8.PrefixHeader.pch
9.Localizable.strings
如果你前面有一个会话列表页面,例如下图:
如果你也有一个消息页面的话,如果没有什么太多内容,我建议放弃你自己自定义的TableViewCell,因为EaseUI 里有已经写好的消息页面:EaseConversationListViewController
这个页面不用改动太多。如果你发现这个页面为什么不用登录环信账号,环信是这样的:你在AppDelegate登录。
登录的demo为:
[[EaseMob sharedInstance].chatManager asyncLoginWithUsername:@“用户的环信账号” password:@“用户的环信密码” completion:^(NSDictionary *loginInfo, EMError *error) {
NSLog(@"error====%@",error);
if (!error)
{
NSLog(@"登录成功");
NSLog(@"===%@",loginInfo);
//获取数据库中数据
[[EaseMob sharedInstance].chatManager loadDataFromDatabase];
}
} onQueue:nil];
当然有登录就有注册
[[EaseMob sharedInstance].chatManager asyncRegisterNewAccount:phone.text password:password2.text withCompletion:^(NSString *username, NSString *password, EMError *error) {
NSLog(@"error====%@",error);
if (!error)
{
NSLog(@"注册成功");
NSLog(@"===%@",loginInfo);
}
} onQueue:nil];
1.只用iOS和环信交互:在你app注册会员的时候,注册成功获得返回值,正确的返回值内去注册环信账号,而环信账号就是用户注册你app的账号,密码需要写死,例如:123456,那么无论谁注册,传给环信的密码都是123456。这样方便登录。如果环信返回给你是注册成功,那么你需要在成功里创建NSUserDeafults存储你的环信账号,密码就不用存了。并且调用环信登录方法。如果不在AppDelegate里写登录,你的APP如果退出了,下次打开就没用了,所以必须时时刻刻登录。所以你需要在AppDelegate登录,账号就是你本地存储的账号。密码还是死的。如果正常流程来说就是:
1.注册自己APP账号-成功-注册环信账号,密码为死的-成功-登录环信账号。
2.登录自己APP账号-成功-登录环信
3.AppDelegate存储账号。
2.让iOS,服务器,环信交互:通过上面的那种方式,跟服务器唯一交互的就是密码,你需要在用户注册你自己产品的时候,密码也注册环信。注册成功,将密码post给服务器,登录的时候成功,服务器不光返回error,msg,还要加一个环信的password,这样你拿到password 可以再进行登录。当然注册的时候Phone和Password需都需要存储,方便在AppDelegate入口类登录。
1.注册自己APP账号-成功-注册环信账号,密码为注册APP的密码-成功-Post密码给服务器-成功-登录环信账号。
2.登录自己APP账号-成功-拿到服务器返回的Password,登录环信账号-成功。
3.AppDelegate存储账号和密码
除了上面两种方式,还有一种就是环信有一个会记录的方法,除了注销会一直存在。怎么简单怎么来。
OK,注册成功,我们继续讨论:EaseConversationListViewController
如果你的页面换成了EaseConversationListViewController,那么你不需要做任何操作都可以获取到最新数据,但是你需要点击进入会话页面。
ChatViewController 就是你的会话列表页,关于ChatViewController * chatVc = [[ChatViewController alloc]initWithConversationChatter:model.title conversationType:eConversationTypeChat];
1.model.title 这个会话列表的用户名,你也可以写死。
2.eConversationTypeChat,枚举,这是单人会话,还有群聊等等。
有了这个就可以传到会话列表页了。
会话列表就不多说了,没有这个文件我直接发给你好了。
对了有人会出现这种情况,如下图:
是否发现重复消息。[self tableViewDidTriggerHeaderRefresh]; 检查一下这个方法是不是在chatViewController 和EaseMessageViewCOntroller 的ViewDidLoad 里面都调用了,看如果都有,随便删除一个这个方法。就ok了!
关于头像昵称如何能做成活的,思路是:环信有一个方法,可以获取消息列表的信息。
这个方法就在你的根视图里拿出来。能获取到所有消息的环信的账号,如果你们注册的环信账号是手机号的。第一次发请求的话给服务器依次发送这个手机号,获取他的昵称和头像,然后存到本地。下次再次发请求的时候之前获取一下这个信息,有的话直接拿,没有的话就发送请求。
现在我在研究如何改变会话列表的名字和头像,因为有些产品的需要,不能展示账号或者手机号,所以如果你还有不懂得地方你加我好友QQ:1119718338,欢迎一起交流。当然如果您觉得对您有帮助,请点赞或打赏!谢谢!
收起阅读 »
架构师的技术领导力之路:看环信一乐聊些什么
全球技术领导力峰会(GTLC)30日【Tim会客厅】环节,迎来了EGO北京分会第2小组的3名成员——环信首席架构师梁宇鹏、爱因互动联合创始人兼CTO洪强宁、当当架构部总监史海峰,一起聊聊他们的技术领导力之路。
主持人(左一):杨卫华(Tim Yang),新浪微博研发副总经理
从技术人到领导者
Tim:大家先做一个简单的自我介绍吧!
梁宇鹏:在技术圈大家都叫我一乐,我来自环信,这是一家做即时通讯云服务和全媒体智能客服的公司,我是环信的首席架构师,同时也兼任IM事业部技术总监,负责即时通讯云服务产品线。
史海峰:我现在在当当负责架构部,之前在神州数码和亚信做电信业务系统集成,做过七年北京移动的项目,来到当当四年多,如果大家是北京移动的号码或者在当当买过书的话,都是我的衣食父母。
洪强宁:我之前在豆瓣网做首席架构师,2014年到了宜信做首席架构师,现在创业,和豆瓣首席科学家王守崑一起创办了爱因互动。
Tim:各位从刚毕业到目前的位置,其中有哪些难忘的事情或者关键的事情?怎么能够成为像你们这样的“老司机”?
梁宇鹏:我在微博工作了几年,Tim是我的老领导,在微博负责聊天、通讯系统,一开始我也是一心钻研技术,当时整个IM系统即将到达千万级的时候,大家都想做一个酷一点的中间件,这个方案当时出了好几版,一到这儿被枪毙了。当时Facebook做了一个通讯中间件,我当时很不理解,每天拉着Tim讨论,“这个东西业界肯定还缺,而且我们一定需要,就想做这个东西,为什么不能做?”讨论了半天,后来Tim问我一句话,“你觉得现在的系统能不能搞得定?”我说“能搞定”,他其实也将信将疑,说“你证明一下现在的系统搞得定”,我证明完之后,这个中间件没有下文了,觉得现在系统没有问题了,不需要做中间件。
后来想起来这是对我影响比较大的一点,从那之后,不再单纯地去追求做一个能写很酷的中间件的技术人员,会换个角度来思考我们团队需要什么样的东西,或者当前的团队能做到什么样的程度,如果能做到足够好,那么就去想这是不是你最需要做的。我觉得这个事情对我触动很大,当时整个观念都变化了,中间的沟通过程也是比较痛苦的,因为当时我每天都觉得我有一个理想,我要去实现,然而并没有得到支持。
现在在环信做的通讯协议、IM协议,这是原来我们也想做的。2012年移动互联网来了之后,都要做面向移动互联网的IM协议。除了中间件,还有很多可以做,比如现在做的跨全球远距离数据同步的后端系统等等。我不觉得我放弃了追求,而应该是自身的一次蜕变,因为我知道有很多技术可以做,而且也可以跟业务结合起来。
Tim:从我的角度补充一下,作为一个技术人,在大部分环境里面,你要做的事情很多时候确实是够用就行了,大家可能听说过很多反面的情况,一些技术负责人做了不恰当的决策,导致整个技术团队陷在泥潭里面,最终产品没出来,而且大家很累,也没有成就感。
梁宇鹏:我们做微博的时候,Twitter天天宕机,技术体系转来转去,折腾了好多轮。在技术人员心中,大家就觉得技术氛围很好,也很愿意折腾。我觉得我们微博这块虽然技术上走得慢一点或者走得很稳健,但是在服务质量上业界都看得见。我现在比较理解了,我会告诉大家什么先不要做,先把最主要的事情做完。
史海峰:我说一点,希望对在座的各位有一点借鉴意义。因为我之前是做电信软件的,现在在当当,从传统IT转到互联网这个过程还是挺痛苦,也挺刺激的。刚到互联网公司,对于常用技术、架构、场景,包括电商这一套业务都不是特别了解。而且大家都知道,互联网公司人员流动大,没有什么文档,很难快速切入。我凭着一些坚持,找各种机会去了解,有时候厚着脸皮跟人聊,哪怕他不愿意搭理你,最后发现自己应该是有一些钝感力,就这样坚持下来,让大家认可了我,在当当也待了下来,还算是转型成功。总结一下,就是坚持做一些别人做不了或者说不愿意做的事情。
洪强宁:坚持很重要。怎么成为“老司机”?我是足够老了,开始进入IT这个行业大概是上小学时,找了一本书开始自学,那时候就决定自己要做一个程序员。大学毕业后,终于找到了一个正式的程序员工作。最开始是做嵌入式系统,也是在那个时候接触到Python这个语言,也很喜欢,在Python社区也很活跃,2005年豆瓣的创始人给我发了封邮件,问我要不要一起干,我就过来了。随着豆瓣规模越来越大,我的重心慢慢转移到平台这个层面,在这个层面学到了很多东西,也得到了架构师的头衔。
另外一个转变,是我从豆瓣离职,到了宜信担任首席架构师,眼界得到了提高,看到了不一样的公司中不同的管理方法,从这个时候开始对管理产生了兴趣,也诞生了我要亲手创造一个伟大的公司的想法。今年6月份,终于开始创业,这对我来说是人生的一个大转变。但是不管怎样,最重要的是坚持。我一直觉得技术是能够改变世界的,我能够通过自己的手去让这个世界变得更美好一些,这是值得奋斗一生的事情。
Tim:从技术人到领导者,你们的心态发生了哪些变化?
梁宇鹏:原来觉得自己加一加班或者自己熬一下夜,这个程序就做完了,现在要调整自己,如果他们觉得做不完,你要不要接受这个状态,能不能补救,而不是推着他们一定要这样做。总之就是,知道什么不要做,知道什么你做不到。
史海峰:我来总结的话,就是“以德服人”。一乐说得特别好,以前面对的更多是机器,都是标准化的,现在面对的是一个团队,每个人都不一样,领导一个团队的话,不要求在每个技术领域都比团队成员强,最重要的是在最基本的素质和为人上超过他们,对自己的要求要比对他们的要求更高,要学会控制自己。
领导者有时候的一些方式方法,大家未必会接受的,这样实施起来会有一些抵触情绪,需要领导者更好地琢磨怎么去调整,最好的办法就是以身作则。
洪强宁:我给所有的技术人的建议是保持不断学习,但是如果是技术管理者这个群体,我的建议可能更加务实一点,就是做好授权这一件事情,不要把所有事情都把握在自己手上,把权力下放到团队去,给他们更多的自由度,创业公司效率为什么比大公司高很多,很重要的原因是创业公司几个人一碰头就可以把这个事情决定了,大公司要层层上报,最后可能就不了了之了。把权力下放,找到合适的人让他放手去做,团队成长得会更快,你也可以拥有一些得力的助手。
- 首席架构师之路
Tim:在座的几位都是非常优秀的架构师,你们典型的一天是怎么度过的?都做了哪些事情?
梁宇鹏:我一天最重要的两件事情,一是跟大家梳理架构,康威定律指出,公司的组织架构能够反映出公司产品的技术架构,如果我们的架构比较落后,那么瓶颈在我身上,因为只有我一个人能够把这个事情搞清楚,其他人都不明白,那么工作就没办法进行。所以我想的最多的事情就是组织尽量多的人,大家一起来讨论这个架构,最终大家就都了解这个架构,了解每个组件以及服务的权衡点在哪,就可以自己来设计这个服务。有很多创业公司的增长是非常快速的,如果没有一个很好的基础,那么流量来了的时候,大家压力就很大。架构能否撑得住,这个对我来说是最焦虑的。
Tim:作为首席架构师,跟其他架构师怎么分工呢?
梁宇鹏:为什么叫首席呢?因为每个人都有架构的思路和想法,我们团队至少一半以上可以做架构的,我来做的话,可能只是把大家的想法汇总起来,把大家不一致的观点组合起来找到一个一致的想法。
大家一定要达成一致,达不成一致这个架构其实没有任何价值,我觉得重要的是我让大家在有争执的时候,我们选择一个大家都能同意的点来开始做,这是我做的事情,还算比较重要的一部分。
史海峰:声明一下,当当还没有首席架构师,我主要的工作还是参与一些项目的架构设计,也会评审一些设计方案。我比较关注的问题是,如果在会议或者邮件中遇到一些不是特别了解的情况时,尽可能跟当事人当面沟通;技术债我都会记下来,很多东西都是我们来不及做或者说只是知道了然而怎么解决我们也不清楚,这种情况下,我就记下来,自己回头有时间再看一看。将来再遇到其他项目的时候,可能顺手能把这个事情解决了,这样能达到一石二鸟的效果,这是我比较关注的事情。
洪强宁:在豆瓣期间,刷豆瓣是我工作的一部分,因为豆瓣所有工程师,页面右上角会出现渲染时间,而且会有颜色标注。我每天关注的点就是一些关键的指标,我在豆瓣负责平台部门,我会关注性能指标、可用性指标,从中发现是不是存在问题。同时作为首席架构师,业务部门对于平台所有的需求,最后汇集到我这儿来,我会判断是否需要对架构做调整,更好地支持业务。在这个基础上,我会设计下一步的架构发展。我的原则是,作为架构师,可以超前设计一点,但是不要超前太多,有一定的冗余量,等到流量突然增加的时候,可以应付得了。
Tim:洪教授曾经是豆瓣的首席架构师,能不能介绍一个由你作为首席架构师发挥重要作用的产品或者技术?
洪强宁:我在豆瓣主持的其中一个比较大的项目是豆瓣的服务化,豆瓣最早期的时候是一套代码,一个代码仓库,所有的产品都是应用这一套代码。随着业务的发展,这个代码量越来越大,峰值的时候50万行,会出现各种各样的问题,当时判断这种方式是不能持久的。我主持做了服务化的拆分,也设计了一些服务化的框架、辅助的工具,这差不多是我在豆瓣做的工作中,对于整个豆瓣的发展影响最大的事情。
技术与管理的平衡
Tim:对于技术领导者这样的角色,你们认为最重要的素质或者能力是什么?
梁宇鹏:对我来讲,心态特别重要,之前无论是做技术、做架构、还是写技术组件的代码,面对的都是机器,如果要做一个技术领导者,需要面对的是人,你就要调整自己好自己的状态,你面对的这帮兄弟们,他们的状态不像机器一样恒定,有些时候他的状态可能随着他的心情或者生活状态发生变化。
我经常用跑步来举例子,我跟团队很多兄弟一起跑,跑步这件事情,你会对自己能跑多远有一个期望,假设现在能跑10公里,那么跑马拉松就会有非常大的压力,对于技术人也一样,如果他自己觉得只能跑10公里,那么把他推到马拉松的级别,他可能会直接跟你决裂。所以最重要的是随时观察团队成员的状态,他们现在能到什么级别,你再去往前推动,而不是像机器一样,让他们发挥出100%的性能。
Tim:如何从一个写代码的角色转变到一个技术领导者的角色?怎么把握这两者之间的平衡?
梁宇鹏:我只能试着去平衡,因为我觉得写代码的时候应该是大多数技术人员心情最平静的时候,或者说最高兴的时候。真正去管人的时候,你会发现有太多的不确定性,可能相当于遇到了一段读不懂,但是永远有bug的代码,没办法,只能试着适应他,把他当成一个库来调用,我没有太好的经验。但是对我个人来讲,如果遇到问题,我会通过跑步去换一个环境,可能只是半个小时、1个小时,但回来之后能够静下心来。
史海峰:首先,一部分的同学是被动地被提到了一个管理岗位,很可能你的领导离职了或者去了更高的职位,由你来带团队。基本上最简单的是模仿,毕竟当过下属,你知道你的上级是怎么安排任务,怎么去跟踪,需要关注哪些点,这是最初的。
第二点,后来慢慢关注了一些方式方法,成熟的管理理论或者解决问题的方法论,你会发现很多东西有人已经琢磨得非常明白,只是自己之前没关注不了解。
第三点,做技术的人离开安全区的时候,都会有一个想法——我以后不能全天写代码了,我的竞争力在哪里。这要靠时间,靠团队协作,靠实践,慢慢去调整你的认识,你会发现团队能做更大事情的,你在其中做一个核心角色,这样才会更有价值。
洪强宁:我最开始的时候就是一个非常标准的程序员,什么事情都自己做,很快发现最后所有的事情都堆在你手上,忙得要死,你的团队其实工作并不饱和,这时你会逼迫自己去改变这个问题,我找到了方法,就是把自己的重心从实现变成设计,并且进行分解,分解出来的任务并行开发。从这个阶段开始,我的工作职责慢慢从实践者变成了管理者。
这个过程需要特别注意的是,要克制自己,比如你看到一个技术难题,特别想自己解决,结果陷入问题当中导致项目延期。另一方面,即使成为一个管理者,也不应该放弃技术,架构师还是要写代码的,因为这样才能知道你设计的东西是不是真正适合开发。随着管理的工作越来越多,真正写代码的时候,你给自己安排的代码任务不能成为别人的阻碍,像我现在写的代码更多的是一些偏研究性的代码,偏提升效率的工具,还有一些打杂性的工作,没人做的事情我来做,这样既可以不阻碍团队的开发效率,也不至于丧失对代码的理解。
本文由EGO原创首发,请获取授权后转载,完整演讲PPT下载请戳“阅读原文”
关于全球技术领导力峰会(GTLC)
由极客邦旗下高端技术人社交网络EGO举办,旨在聚集国内一线技术领导者,共同分享、探讨技术管理、技术领导过程中的最佳实践,为参会者打造一个高质量的交流、学习平台。本次大会由超高性价比CDN又拍云独家冠名赞助。
阅读原文 收起阅读 »
Android混淆那些事,看这篇就够了
作为Android开发者,如果你不想开源你的应用,那么在应用发布前,就需要对代码进行混淆处理,从而让我们代码即使被反编译,也难以阅读。混淆概念虽然容易,但很多初学者也只是网上搜一些成型的混淆规则粘贴进自己项目,并没有对混淆有个深入的理解。本篇文章的目的就是让一个初学者在看完后,能在不进行任何帮助的情况下,独立写出适合自己代码的混淆规则。
说在前面
这里我们直接用Android Studio来说明如何进行混淆,Android Studio自身集成Java语言的ProGuard作为压缩,优化和混淆工具,配合Gradle构建工具使用很简单,只需要在工程应用目录的gradle文件中设置minifyEnabled为true即可。然后我们就可以到proguard-rules.pro文件中加入我们的混淆规则了。
android {以上示例代码表示对release版本就行混淆处理。下面我们先来简介下ProGuard的三大作用,并简要说明下它们常用的命令。
...
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
ProGuard作用
压缩(Shrinking):默认开启,用以减小应用体积,移除未被使用的类和成员,并且会在优化动作执行之后再次执行(因为优化后可能会再次暴露一些未被使用的类和成员)。
-dontshrink 关闭压缩优化(Optimization):默认开启,在字节码级别执行优化,让应用运行的更快。
-dontoptimize 关闭优化混淆(Obfuscation):默认开启,增大反编译难度,类和类成员会被随机命名,除非用keep保护。
-optimizationpasses n 表示proguard对代码进行迭代优化的次数,Android一般为5
-dontobfuscate 关闭混淆混淆后默认会在工程目录app/build/outputs/mapping/release下生成一个mapping.txt文件,这就是混淆规则,我们可以根据这个文件把混淆后的代码反推回源本的代码,所以这个文件很重要,注意保护好。原则上,代码混淆后越乱越无规律越好,但有些地方我们是要避免混淆的,否则程序运行就会出错,所以就有了下面我们要教大家的,如何让自己的部分代码避免混淆从而防止出错。
基本规则
先看如下两个比较常用的命令,很多童鞋可能会比较迷惑以下两者的区别。
-keep class cn.hadcn.test.**一颗星表示只是保持该包下的类名,而子包下的类名还是会被混淆;两颗星表示把本包和所含子包下的类名都保持;用以上方法保持类后,你会发现类名虽然未混淆,但里面的具体方法和变量命名还是变了,这时如果既想保持类名,又想保持里面的内容不被混淆,我们就需要以下方法了
-keep class cn.hadcn.test.*
-keep class cn.hadcn.test.* {*;}
在此基础上,我们也可以使用Java的基本规则来保护特定类不被混淆,比如我们可以用extend,implement等这些Java规则。如下例子就避免所有继承Activity的类被混淆
-keep public class * extends android.app.Activity
如果我们要保留一个类中的内部类不被混淆则需要用$符号,如下例子表示保持ScriptFragment内部类JavaScriptInterface中的所有public内容不被混淆。
-keepclassmembers class cc.ninty.chat.ui.fragment.ScriptFragment$JavaScriptInterface {再者,如果一个类中你不希望保持全部内容不被混淆,而只是希望保护类下的特定内容,就可以使用
public *;
}
<init>; //匹配所有构造器你还可以在<fields>或<methods>前面加上private 、public、native等来进一步指定不被混淆的内容,如
<fields>; //匹配所有域
<methods>; //匹配所有方法方法
-keep class cn.hadcn.test.One {表示One类下的所有public方法都不会被混淆,当然你还可以加入参数,比如以下表示用JSONObject作为入参的构造函数不会被混淆
public <methods>;
}
-keep class cn.hadcn.test.One {有时候你是不是还想着,我不需要保持类名,我只需要把该类下的特定方法保持不被混淆就好,那你就不能用keep方法了,keep方法会保持类名,而需要用keepclassmembers ,如此类名就不会被保持,为了便于对这些规则进行理解,官网给出了以下表格
public <init>(org.json.JSONObject);
}
保留 防止被移除或者被重命名 防止被重命名
类和类成员 -keep -keepnames
仅类成员 -keepclassmembers -keepclassmembernames
如果拥有某成员,保留类和类成员 -keepclasseswithmembers -keepclasseswithmembername移除是指在压缩(Shrinking)时是否会被删除。以上内容时混淆规则中需要重点掌握的,了解后,基本所有的混淆规则文件你应该都能看懂了。再配合以下几点注意事项,
注意事项
1,jni方法不可混淆,因为这个方法需要和native方法保持一致;
-keepclasseswithmembernames class * { # 保持native方法不被混淆2,反射用到的类不混淆(否则反射可能出现问题);
native <methods>;
}
3,AndroidMainfest中的类不混淆,所以四大组件和Application的子类和Framework层下所有的类默认不会进行混淆。自定义的View默认也不会被混淆;所以像网上贴的很多排除自定义View,或四大组件被混淆的规则在Android Studio中是无需加入的;
4,与服务端交互时,使用GSON、fastjson等框架解析服务端数据时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象;
5,使用第三方开源库或者引用其他第三方的SDK包时,如果有特别要求,也需要在混淆文件中加入对应的混淆规则;
6,有用到WebView的JS调用也需要保证写的接口方法不混淆,原因和第一条一样;
7,Parcelable的子类和Creator静态成员变量不混淆,否则会产生Android.os.BadParcelableException异常;
-keep class * implements Android.os.Parcelable { # 保持Parcelable不被混淆8,使用enum类型时需要注意避免以下两个方法混淆,因为enum类的特殊性,以下两个方法会被反射调用,见第二条规则。
public static final Android.os.Parcelable$Creator *;
}
-keepclassmembers enum * {写在最后
public static ** values();
public static ** valueOf(java.lang.String);
}
发布一款应用除了设minifyEnabled为ture,你也应该设置zipAlignEnabled为true,像Google Play强制要求开发者上传的应用必须是经过zipAlign的,zipAlign可以让安装包中的资源按4字节对齐,这样可以减少应用在运行时的内存消耗。
作者简介
彭涛(@彭涛me) 致力于让技术变得易懂且有趣
GitHub地址:https://github.com/CPPAlien 收起阅读 »
《全媒体客户中心管理》读书沙龙,南京-杭州-合肥三站齐发
9月27日-29日,《全媒体客户中心管理》读书沙龙,南京-杭州-合肥三站齐发,小伙伴还在等什么!
《全媒体客户中心管理》读书沙龙——南京站
- 2016-09-27 14:00
- 南京市秦淮区莫愁路329号117号楼101市室
- 2016-09-28 14:00
- 合肥市蜀山电子商务产业园3期2号楼3楼党政服务中心
- 2016-09-29 14:00
- 杭州市江干区钱潮路369智谷人才广场7楼
活动介绍:
8月3日,国内第一本“全媒体”客服学术著作《全媒体客户中心管理》读书沙龙将在包括北上广深等全国十大城市陆续举办。环信作为国内全媒体智能SaaS客服的倡领者一直致力于推动整个中国SaaS客服行业的发展,给企业提供最具效率和最佳用户体验的客服产品及服务。此次和客服行业权威媒体《客户世界》以及行业专家一起联合推出《全媒体客户中心管理》一书,环信提供了在全媒体客服领域包括产品技术和客户运营方面大量的最佳实践及成功案例。同时,环信参与了从前期图书主题的设定、相关最佳实践和成功案例的准备、中期文档图表的梳理、后期出版环节的编审和呈现,一直到各地读书沙龙的组织工作,目的也是推动整个SaaS客服行业和企业用户少走弯路,加速企业用户的信息化和用户体验进程,让呼叫中心(客户中心)提速迈向智能化和数据化时代。
部分演讲主题展示:
全媒体客户中心的规划、建设、运营与管理
演讲嘉宾:张艳
蜜芽服务副总裁 近20年客服中心管理经验,专注于企业自建呼叫中心运营管理、服务管理、会员精准营销。为多家企业搭建、重建呼叫中心,并成功推动呼叫中心从分布到集中、从服务到营销、从单渠道到全媒体转型。先后就职于携程旅行网、中青旅、中移动12580、红孩子、苏宁云商等企业, 现任蜜芽服务副总裁。 从呼叫中心基础管理工作开始,多年来在电子商务类企业组织实战。张老师将她多年来的理论总结和实战经验加以提炼和归纳,汇集成为新书《全媒体客户中心管理》,期待对国内本行业管理者们的运营工作提供积极的帮助。从呼叫中心基础管理工作开始,多年来在电子商务类企业组织实战。张老师将她多年来的理论总结和实战经验加以提炼和归纳,汇集成为新书《全媒体客户中心管理》,期待对国内本行业管理者们的运营工作提供积极的帮助。
收起阅读 »