diff --git a/app/build.gradle b/app/build.gradle index 34de05d..309806c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,8 +12,18 @@ android { testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { + debug{ + //是否启动zipAlign + zipAlignEnabled true + //是否移除无用的resource文件 + shrinkResources false + } release { minifyEnabled false + //是否启动zipAlign + zipAlignEnabled true + //是否移除无用的resource文件 + shrinkResources false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } @@ -27,4 +37,6 @@ dependencies { compile 'com.android.support:appcompat-v7:26.0.0-alpha1' testCompile 'junit:junit:4.12' compile project(':easeui') +// compile 'com.github.isqing:HxTest:1.0' + compile 'pub.devrel:easypermissions:0.4.2' } diff --git a/build.gradle b/build.gradle index 6fa1f26..3f05071 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ buildscript { allprojects { repositories { jcenter() - + maven { url 'https://jitpack.io' } } } diff --git a/easeui/build.gradle b/easeui/build.gradle index c45d185..5fa3e7f 100644 --- a/easeui/build.gradle +++ b/easeui/build.gradle @@ -14,6 +14,10 @@ android { buildTypes { release { minifyEnabled false + //是否启动zipAlign + zipAlignEnabled true + //是否移除无用的resource文件 + shrinkResources false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } @@ -41,4 +45,5 @@ dependencies { testCompile 'junit:junit:4.12' compile 'com.android.support:support-core-utils:24.2.1' + compile 'pub.devrel:easypermissions:0.4.2' } diff --git a/easeui/proguard-rules.pro b/easeui/proguard-rules.pro index fc949db..ea470b0 100644 --- a/easeui/proguard-rules.pro +++ b/easeui/proguard-rules.pro @@ -15,3 +15,86 @@ #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} + + +-keepattributes Signature +# Retain declared checked exceptions for use by a Proxy instance. +-keepattributes Exceptions +#保留support库 +-keep class android.support.** { + *; +} + +##2D地图 +#-keep class com.amap.api.maps2d.*{*;} +#-keep class com.amap.api.mapcore2d.*{*;} +#-keep class com.amap.api.interfaces.*{*;} +#-keep class com.autonavi.amap.mapcore2d.*{*;} +# +# +##定位 +#-keep class com.amap.api.location.*{*;} +#-keep class com.amap.api.fence.*{*;} +#-keep class com.autonavi.aps.amapapi.model.*{*;} +#-keep class com.loc.*{*;} + + + #定位 + -keep class com.amap.api.location.**{*;} + -keep class com.amap.api.fence.**{*;} + -keep class com.autonavi.aps.amapapi.model.**{*;} + #2D地图 + -keep class com.amap.api.maps2d.**{*;} + -keep class com.amap.api.mapcore2d.**{*;} + + # 搜索 + -keep class com.amap.api.services.**{*;} + -dontwarn com.amap.** + -dontwarn com.amap.api.** +# -dontwarn com.github.lzyzsd.jsbridge.**{*;} +# -dontwarn comg.amap.api.mapcore2d.MapMessage +# -keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +# } +# -keep class com.hyphenate.** {*;} +# -dontwarn com.hyphenate.** +# -keep class com.hyphenate.easeui.utils.EaseSmileUtils {*;} + +# -dontwarn com.squareup.okhttp3.** +# -keep class com.squareup.okhttp3.** { *;} +# -dontwarn okio.** +# +-dontwarn com.parse.** +-keep class com.parse.** { *; } + +#环信部分混淆规则代码 +-dontwarn com.easemob.** +-keep class com.easemob.** {*;} +-keep class org.xmlpull.** {*;} +-keep class com.squareup.picasso.* {*;} +-keep class com.hyphenate.* {*;} +-keep class com.hyphenate.chat.** {*;} +-keep class org.jivesoftware.** {*;} +-keep class org.apache.** {*;} +#如果使用easeui库,需要这么写 +-keep class com.hyphenate.easeui.utils.EaseSmileUtils {*;} +#2.0.9后加入语音通话功能,如需使用此功能的api,加入以下keep +-dontwarn ch.imvs.** +-dontwarn org.slf4j.** +-keep class org.ice4j.** {*;} +-keep class net.java.sip.** {*;} +-keep class org.webrtc.voiceengine.** {*;} +-keep class org.bitlet.** {*;} +-keep class org.slf4j.** {*;} +-keep class ch.imvs.** {*;} +-keep class com.easemob.** {*;} +#环信3.0 +-keep class com.hyphenate.** {*;} +-dontwarn com.hyphenate.** +-keep class com.superrtc.** {*;} + +-dontwarn android.webkit.WebView** +-keep public class android.webkit** { *; } + +-dontwarn org.apache.http.conn.ssl.SSLSocketFactory** +-keep public class org.apache.http.conn.ssl** { *; } \ No newline at end of file diff --git a/easeui/src/main/java/com/hyphenate/easeui/ui/EaseChatFragment.java b/easeui/src/main/java/com/hyphenate/easeui/ui/EaseChatFragment.java index 286aa35..a857a09 100644 --- a/easeui/src/main/java/com/hyphenate/easeui/ui/EaseChatFragment.java +++ b/easeui/src/main/java/com/hyphenate/easeui/ui/EaseChatFragment.java @@ -1,5 +1,6 @@ package com.hyphenate.easeui.ui; +import android.Manifest; import android.app.Activity; import android.app.ProgressDialog; import android.content.ClipboardManager; @@ -11,8 +12,10 @@ import android.os.Bundle; import android.os.Handler; import android.provider.MediaStore; +import android.support.annotation.NonNull; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener; +import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -41,6 +44,7 @@ import com.hyphenate.easeui.domain.EaseEmojicon; import com.hyphenate.easeui.domain.EaseUser; import com.hyphenate.easeui.model.EaseAtMessageHelper; +import com.hyphenate.easeui.ui.hx.hxui.ImageGridActivity; import com.hyphenate.easeui.utils.EaseCommonUtils; import com.hyphenate.easeui.utils.EaseUserUtils; import com.hyphenate.easeui.widget.EaseAlertDialog; @@ -61,6 +65,10 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import pub.devrel.easypermissions.AfterPermissionGranted; +import pub.devrel.easypermissions.AppSettingsDialog; +import pub.devrel.easypermissions.EasyPermissions; + /** * you can new an EaseChatFragment to use or you can inherit it to expand. * You need call setArguments to pass chatType and userId @@ -69,7 +77,7 @@ * you can see ChatActivity in demo for your reference * */ -public class EaseChatFragment extends EaseBaseFragment implements EMMessageListener { +public class EaseChatFragment extends EaseBaseFragment implements EMMessageListener,EasyPermissions.PermissionCallbacks { protected static final String TAG = "EaseChatFragment"; protected static final int REQUEST_CODE_MAP = 1; protected static final int REQUEST_CODE_CAMERA = 2; @@ -114,7 +122,13 @@ public class EaseChatFragment extends EaseBaseFragment implements EMMessageListe protected MyItemClickListener extendMenuItemClickListener; protected boolean isRoaming = false; private ExecutorService fetchQueue; - + private static final int RC_LOCATION_PERM = 0x222; + public static final int RC_CAMERA_PERM = 0x224;//相机 + public static final int RC_ALBUM_PERM = 0x225;//相册 + public static final int RC_VOCIE_PERM = 0x226;//语音 + boolean pressToSpeak=false; + View speakView; + MotionEvent motionEvent; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.ease_fragment_chat, container, false); @@ -140,6 +154,7 @@ public void onActivityCreated(Bundle savedInstanceState) { /** * init view */ + @Override protected void initView() { // hold to record voice //noinspection ConstantConditions @@ -147,8 +162,9 @@ protected void initView() { // message list layout messageList = (EaseChatMessageList) getView().findViewById(R.id.message_list); - if(chatType != EaseConstant.CHATTYPE_SINGLE) + if(chatType != EaseConstant.CHATTYPE_SINGLE) { messageList.setShowUserNick(true); + } // messageList.setAvatarShape(1); listView = messageList.getListView(); @@ -166,13 +182,12 @@ public void onSendMessage(String content) { @Override public boolean onPressToSpeakBtnTouch(View v, MotionEvent event) { - return voiceRecorderView.onPressToSpeakBtnTouch(v, event, new EaseVoiceRecorderCallback() { - - @Override - public void onVoiceRecordComplete(String voiceFilePath, int voiceTimeLength) { - sendVoiceMessage(voiceFilePath, voiceTimeLength); - } - }); + Log.i("dd","dddddddddddd"); + speakView=v; + motionEvent=event; + voiceTask(); + + return pressToSpeak; } @Override @@ -193,7 +208,7 @@ public void onBigExpressionClicked(EaseEmojicon emojicon) { fetchQueue = Executors.newSingleThreadExecutor(); } } - + @Override protected void setUpView() { titleBar.setTitle(toChatUsername); if (chatType == EaseConstant.CHATTYPE_SINGLE) { @@ -210,8 +225,9 @@ protected void setUpView() { if (chatType == EaseConstant.CHATTYPE_GROUP) { //group chat EMGroup group = EMClient.getInstance().groupManager().getGroup(toChatUsername); - if (group != null) + if (group != null) { titleBar.setTitle(group.getGroupName()); + } // listen the event that user moved out group or group is dismissed groupListener = new GroupListener(); EMClient.getInstance().groupManager().addGroupChangeListener(groupListener); @@ -459,8 +475,9 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK) { if (requestCode == REQUEST_CODE_CAMERA) { // capture new image - if (cameraFile != null && cameraFile.exists()) + if (cameraFile != null && cameraFile.exists()) { sendImageMessage(cameraFile.getAbsolutePath()); + } } else if (requestCode == REQUEST_CODE_LOCAL) { // send local image if (data != null) { Uri selectedImage = data.getData(); @@ -486,8 +503,9 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { @Override public void onResume() { super.onResume(); - if(isMessageListInited) + if(isMessageListInited){ messageList.refresh(); + } EaseUI.getInstance().pushActivity(getActivity()); // register the event listener when enter the foreground EMClient.getInstance().chatManager().addMessageListener(this); @@ -547,8 +565,9 @@ public void onSuccess(final EMChatRoom value) { getActivity().runOnUiThread(new Runnable() { @Override public void run() { - if(getActivity().isFinishing() || !toChatUsername.equals(value.getId())) + if(getActivity().isFinishing() || !toChatUsername.equals(value.getId())) { return; + } pd.dismiss(); EMChatRoom room = EMClient.getInstance().chatroomManager().getChatRoom(toChatUsername); if (room != null) { @@ -658,13 +677,16 @@ public void onClick(int itemId, View view) { } switch (itemId) { case ITEM_TAKE_PICTURE: - selectPicFromCamera(); +// selectPicFromCamera(); + cameraTask(); break; case ITEM_PICTURE: - selectPicFromLocal(); +// selectPicFromLocal(); + picFromLocalTask(); break; case ITEM_LOCATION: - startActivityForResult(new Intent(getActivity(), EaseAmapActivity.class), REQUEST_CODE_MAP); + location(); +// startActivityForResult(new Intent(getActivity(), EaseAmapActivity.class), REQUEST_CODE_MAP); break; default: @@ -673,7 +695,133 @@ public void onClick(int itemId, View view) { } } - + @AfterPermissionGranted(RC_VOCIE_PERM) + public void voiceTask( ) { + if (Build.VERSION.SDK_INT >= 23) { + String[] perms = { Manifest.permission.RECORD_AUDIO,Manifest.permission.WRITE_EXTERNAL_STORAGE}; + if (EasyPermissions.hasPermissions(EaseUI.getInstance().getContext(), perms)) { + // Have permissions, do the thing! + pressToSpeak=voiceRecorderView.onPressToSpeakBtnTouch(speakView, motionEvent, new EaseVoiceRecorderCallback() { + + @Override + public void onVoiceRecordComplete(String voiceFilePath, int voiceTimeLength) { +// voicPath=voiceFilePath; +// voiceLength=voiceTimeLength; + Log.i("vocie","语音"); + sendVoiceMessage(voiceFilePath, voiceTimeLength); + } + }); + } else { + // Ask for both permissions + EasyPermissions.requestPermissions(this, "需要语音读取内存权限", + RC_VOCIE_PERM, perms); + } + }else { + pressToSpeak=voiceRecorderView.onPressToSpeakBtnTouch(speakView, motionEvent, new EaseVoiceRecorderCallback() { + + @Override + public void onVoiceRecordComplete(String voiceFilePath, int voiceTimeLength) { +// voicPath=voiceFilePath; +// voiceLength=voiceTimeLength; + Log.i("vocie","语音"); + sendVoiceMessage(voiceFilePath, voiceTimeLength); + } + }); + } + } + @AfterPermissionGranted(RC_CAMERA_PERM) + public void cameraTask() { + if (Build.VERSION.SDK_INT >= 23) { + String[] perms = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}; + if (EasyPermissions.hasPermissions(EaseUI.getInstance().getContext(), perms)) { + // Have permissions, do the thing! + selectPicFromCamera(); + } else { + // Ask for both permissions + EasyPermissions.requestPermissions(this, "需要打开摄像头权限和读取内存权限", + RC_CAMERA_PERM, perms); + } + }else { + selectPicFromCamera(); + } + + } + + @AfterPermissionGranted(RC_ALBUM_PERM) + public void picFromLocalTask() { + if (Build.VERSION.SDK_INT >= 23) { + String[] perms = { Manifest.permission.WRITE_EXTERNAL_STORAGE}; + if (EasyPermissions.hasPermissions(EaseUI.getInstance().getContext(), perms)) { + // Have permissions, do the thing! + selectPicFromLocal(); + } else { + // Ask for both permissions + EasyPermissions.requestPermissions(this, "需要读取内存权限", + RC_ALBUM_PERM, perms); + } + }else { + selectPicFromLocal(); + } + } + @AfterPermissionGranted(RC_LOCATION_PERM) + public void location() { + if (Build.VERSION.SDK_INT >= 23) { + String[] perms = {Manifest.permission.ACCESS_FINE_LOCATION}; + if (EasyPermissions.hasPermissions(EaseUI.getInstance().getContext(),perms)) { + // Have permissions, do the thing! + startActivityForResult(new Intent(getActivity(), EaseAmapActivity.class), REQUEST_CODE_MAP); + } else { + // Ask for both permissions + EasyPermissions.requestPermissions(this, "需要打开定位权限", + RC_LOCATION_PERM, perms); + } + }else { + startActivityForResult(new Intent(getActivity(), EaseAmapActivity.class), REQUEST_CODE_MAP); + } + } + @Override + public void onPermissionsGranted(int requestCode, List perms) { + Log.d(TAG, "onPermissionsGranted:" + requestCode + ":" + perms.size()); + switch (requestCode) { + case RC_LOCATION_PERM: + startActivityForResult(new Intent(getActivity(), EaseAmapActivity.class), REQUEST_CODE_MAP); + break; + case RC_CAMERA_PERM : {//调用系统相机申请拍照权限回调 + selectPicFromCamera(); + break; + } + case RC_VOCIE_PERM: + pressToSpeak=voiceRecorderView.onPressToSpeakBtnTouch(speakView, motionEvent, new EaseVoiceRecorderCallback() { + + @Override + public void onVoiceRecordComplete(String voiceFilePath, int voiceTimeLength) { +// voicPath=voiceFilePath; +// voiceLength=voiceTimeLength; + Log.i("vocie","语音"); + sendVoiceMessage(voiceFilePath, voiceTimeLength); + } + }); + break; + + } + } + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + // EasyPermissions handles the request result. + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + @Override + public void onPermissionsDenied(int requestCode, List perms) { + Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size()); + + // (Optional) Check whether the user denied any permissions and checked "NEVER ASK AGAIN." + // This will display a dialog directing them to enable the permission in app settings. + if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { + new AppSettingsDialog.Builder(this).build().show(); + } + } /** * input @ * @param username @@ -688,10 +836,12 @@ protected void inputAtUsername(String username, boolean autoAddAtSymbol){ if (user != null){ username = user.getNick(); } - if(autoAddAtSymbol) + if(autoAddAtSymbol) { inputMenu.insertText("@" + username + " "); - else + } + else { inputMenu.insertText(username + " "); + } } @@ -954,9 +1104,10 @@ protected void toGroupDetails() { */ protected void hideKeyboard() { if (getActivity().getWindow().getAttributes().softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) { - if (getActivity().getCurrentFocus() != null) + if (getActivity().getCurrentFocus() != null) { inputManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); + } } } @@ -1009,7 +1160,7 @@ class GroupListener extends EaseGroupListener { @Override public void onUserRemoved(final String groupId, String groupName) { getActivity().runOnUiThread(new Runnable() { - + @Override public void run() { if (toChatUsername.equals(groupId)) { Toast.makeText(getActivity(), R.string.you_are_group, Toast.LENGTH_LONG).show(); @@ -1026,6 +1177,7 @@ public void run() { public void onGroupDestroyed(final String groupId, String groupName) { // prompt group is dismissed and finish this activity getActivity().runOnUiThread(new Runnable() { + @Override public void run() { if (toChatUsername.equals(groupId)) { Toast.makeText(getActivity(), R.string.the_current_group_destroyed, Toast.LENGTH_LONG).show(); @@ -1047,6 +1199,7 @@ class ChatRoomListener extends EaseChatRoomListener { @Override public void onChatRoomDestroyed(final String roomId, final String roomName) { getActivity().runOnUiThread(new Runnable() { + @Override public void run() { if (roomId.equals(toChatUsername)) { Toast.makeText(getActivity(), R.string.the_current_chat_room_destroyed, Toast.LENGTH_LONG).show(); @@ -1062,6 +1215,7 @@ public void run() { @Override public void onRemovedFromChatRoom(final String roomId, final String roomName, final String participant) { getActivity().runOnUiThread(new Runnable() { + @Override public void run() { if (roomId.equals(toChatUsername)) { Toast.makeText(getActivity(), R.string.quiting_the_chat_room, Toast.LENGTH_LONG).show(); @@ -1080,6 +1234,7 @@ public void run() { public void onMemberJoined(final String roomId, final String participant) { if (roomId.equals(toChatUsername)) { getActivity().runOnUiThread(new Runnable() { + @Override public void run() { Toast.makeText(getActivity(), "member join:" + participant, Toast.LENGTH_LONG).show(); } @@ -1091,6 +1246,7 @@ public void run() { public void onMemberExited(final String roomId, final String roomName, final String participant) { if (roomId.equals(toChatUsername)) { getActivity().runOnUiThread(new Runnable() { + @Override public void run() { Toast.makeText(getActivity(), "member exit:" + participant, Toast.LENGTH_LONG).show(); } diff --git a/easeui/src/main/java/com/hyphenate/easeui/ui/hx/hxui/ChatFragment.java b/easeui/src/main/java/com/hyphenate/easeui/ui/hx/hxui/ChatFragment.java index de39863..98b6374 100644 --- a/easeui/src/main/java/com/hyphenate/easeui/ui/hx/hxui/ChatFragment.java +++ b/easeui/src/main/java/com/hyphenate/easeui/ui/hx/hxui/ChatFragment.java @@ -1,5 +1,6 @@ package com.hyphenate.easeui.ui.hx.hxui; +import android.Manifest; import android.app.Activity; import android.content.ClipData; import android.content.Intent; @@ -11,6 +12,7 @@ import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -23,6 +25,7 @@ import com.hyphenate.chat.EMMessage; import com.hyphenate.chat.EMTextMessageBody; import com.hyphenate.easeui.EaseConstant; +import com.hyphenate.easeui.EaseUI; import com.hyphenate.easeui.R; import com.hyphenate.easeui.ui.EaseChatFragment; import com.hyphenate.easeui.ui.EaseChatFragment.EaseChatFragmentHelper; @@ -38,6 +41,9 @@ import java.io.FileOutputStream; import java.util.List; +import pub.devrel.easypermissions.AfterPermissionGranted; +import pub.devrel.easypermissions.EasyPermissions; + public class ChatFragment extends EaseChatFragment implements EaseChatFragmentHelper { // constant start from 11 to avoid conflict with constant in base class @@ -317,6 +323,7 @@ public void onMessageBubbleLongClick(EMMessage message) { public boolean onExtendMenuItemClick(int itemId, View view) { switch (itemId) { case ITEM_VIDEO: + Log.i("voice","ITEM_VIDEO"); Intent intent = new Intent(getActivity(), ImageGridActivity.class); startActivityForResult(intent, REQUEST_CODE_SELECT_VIDEO); break; @@ -359,7 +366,10 @@ public boolean onExtendMenuItemClick(int itemId, View view) { //keep exist extend menu return false; } - + + + + /** * select file */