Commit b979c75194cd950ba968a5eedea12f21c5f7f61e
1 parent
0c0bc784
demo修改为支持3.0版本功能
Showing
62 changed files
with
1820 additions
and
411 deletions
.idea/misc.xml
| 1 | 1 | <?xml version="1.0" encoding="UTF-8"?> |
| 2 | 2 | <project version="4"> |
| 3 | - <component name="EntryPointsManager"> | |
| 4 | - <entry_points version="2.0" /> | |
| 5 | - </component> | |
| 6 | 3 | <component name="NullableNotNullManager"> |
| 7 | 4 | <option name="myDefaultNullable" value="android.support.annotation.Nullable" /> |
| 8 | 5 | <option name="myDefaultNotNull" value="android.support.annotation.NonNull" /> |
| ... | ... | @@ -27,17 +24,7 @@ |
| 27 | 24 | </value> |
| 28 | 25 | </option> |
| 29 | 26 | </component> |
| 30 | - <component name="ProjectLevelVcsManager" settingsEditedManually="false"> | |
| 31 | - <OptionsSetting value="true" id="Add" /> | |
| 32 | - <OptionsSetting value="true" id="Remove" /> | |
| 33 | - <OptionsSetting value="true" id="Checkout" /> | |
| 34 | - <OptionsSetting value="true" id="Update" /> | |
| 35 | - <OptionsSetting value="true" id="Status" /> | |
| 36 | - <OptionsSetting value="true" id="Edit" /> | |
| 37 | - <ConfirmationsSetting value="0" id="Add" /> | |
| 38 | - <ConfirmationsSetting value="0" id="Remove" /> | |
| 39 | - </component> | |
| 40 | - <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK"> | |
| 27 | + <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK"> | |
| 41 | 28 | <output url="file://$PROJECT_DIR$/build/classes" /> |
| 42 | 29 | </component> |
| 43 | 30 | <component name="ProjectType"> | ... | ... |
.idea/modules.xml
| ... | ... | @@ -2,12 +2,10 @@ |
| 2 | 2 | <project version="4"> |
| 3 | 3 | <component name="ProjectModuleManager"> |
| 4 | 4 | <modules> |
| 5 | - <module fileurl="file://$PROJECT_DIR$/CNChatNDemo.iml" filepath="$PROJECT_DIR$/CNChatNDemo.iml" /> | |
| 5 | + <module fileurl="file://D:\gitlab\CNIMDemo\CNChatNDemo.iml" filepath="D:\gitlab\CNIMDemo\CNChatNDemo.iml" /> | |
| 6 | 6 | <module fileurl="file://$PROJECT_DIR$/CNIMDemo.iml" filepath="$PROJECT_DIR$/CNIMDemo.iml" /> |
| 7 | - <module fileurl="file://$PROJECT_DIR$/CNIMDemo.iml" filepath="$PROJECT_DIR$/CNIMDemo.iml" /> | |
| 8 | - <module fileurl="file://$PROJECT_DIR$/CNIMDemo23.iml" filepath="$PROJECT_DIR$/CNIMDemo23.iml" /> | |
| 9 | - <module fileurl="file://$PROJECT_DIR$/CNIMDemo5.iml" filepath="$PROJECT_DIR$/CNIMDemo5.iml" /> | |
| 10 | - <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" /> | |
| 7 | + <module fileurl="file://D:\gitlab\CNIMDemo\CNIMDemo23.iml" filepath="D:\gitlab\CNIMDemo\CNIMDemo23.iml" /> | |
| 8 | + <module fileurl="file://D:\gitlab\CNIMDemo\CNIMDemo5.iml" filepath="D:\gitlab\CNIMDemo\CNIMDemo5.iml" /> | |
| 11 | 9 | <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" /> |
| 12 | 10 | </modules> |
| 13 | 11 | </component> | ... | ... |
app/build.gradle
| ... | ... | @@ -27,11 +27,17 @@ android { |
| 27 | 27 | minifyEnabled true |
| 28 | 28 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' |
| 29 | 29 | signingConfig signingConfigs.myConfig |
| 30 | + ndk { | |
| 31 | + abiFilters "armeabi-v7a", "arm64-v8a" | |
| 32 | + } | |
| 30 | 33 | } |
| 31 | 34 | debug { |
| 32 | 35 | minifyEnabled false |
| 33 | 36 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' |
| 34 | 37 | debuggable true |
| 38 | + ndk { | |
| 39 | + abiFilters "armeabi-v7a", "arm64-v8a" | |
| 40 | + } | |
| 35 | 41 | } |
| 36 | 42 | } |
| 37 | 43 | } |
| ... | ... | @@ -46,5 +52,5 @@ dependencies { |
| 46 | 52 | compile 'com.android.support:recyclerview-v7:23.4.0' |
| 47 | 53 | compile 'com.github.bumptech.glide:glide:3.7.0' |
| 48 | 54 | |
| 49 | - compile 'com.cnlive:lib_cnutil:2.0.1' | |
| 55 | +// compile 'com.cnlive:lib_cnutil:2.0.1' | |
| 50 | 56 | } | ... | ... |
app/src/main/AndroidManifest.xml
| ... | ... | @@ -2,18 +2,20 @@ |
| 2 | 2 | <manifest xmlns:android="http://schemas.android.com/apk/res/android" |
| 3 | 3 | package="com.cnlive.im"> |
| 4 | 4 | |
| 5 | - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | |
| 6 | - <uses-permission android:name="android.permission.INTERNET" /> | |
| 7 | 5 | <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> |
| 8 | 6 | <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> |
| 9 | - <uses-permission android:name="android.permission.READ_PHONE_STATE" /> | |
| 10 | - <uses-permission android:name="android.permission.RECORD_AUDIO" /> | |
| 7 | + <uses-permission android:name="android.permission.CAMERA" /> | |
| 8 | + <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> | |
| 11 | 9 | <uses-permission android:name="android.permission.GET_TASKS" /> |
| 12 | - <uses-permission android:name="android.permission.WAKE_LOCK" /> | |
| 10 | + <uses-permission android:name="android.permission.INTERNET" /> | |
| 13 | 11 | <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> |
| 14 | - <uses-permission android:name="android.permission.VIBRATE" /> | |
| 15 | - <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> | |
| 12 | + <uses-permission android:name="android.permission.READ_LOGS" /> | |
| 13 | + <uses-permission android:name="android.permission.READ_PHONE_STATE" /> | |
| 16 | 14 | <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> |
| 15 | + <uses-permission android:name="android.permission.RECORD_AUDIO" /> | |
| 16 | + <uses-permission android:name="android.permission.VIBRATE" /> | |
| 17 | + <uses-permission android:name="android.permission.WAKE_LOCK" /> | |
| 18 | + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | |
| 17 | 19 | |
| 18 | 20 | <application |
| 19 | 21 | android:name=".CNLiveApplication" |
| ... | ... | @@ -21,7 +23,7 @@ |
| 21 | 23 | android:icon="@mipmap/ic_launcher" |
| 22 | 24 | android:label="@string/app_name" |
| 23 | 25 | android:supportsRtl="true" |
| 24 | - android:theme="@style/AppTheme"> | |
| 26 | + android:theme="@style/AppTheme.NoActionBar"> | |
| 25 | 27 | <activity android:name=".ui.MainActivity"> |
| 26 | 28 | <intent-filter> |
| 27 | 29 | <action android:name="android.intent.action.MAIN" /> |
| ... | ... | @@ -46,20 +48,54 @@ |
| 46 | 48 | <activity android:name=".ui.PrivateActivity" |
| 47 | 49 | android:screenOrientation="portrait"/> |
| 48 | 50 | |
| 51 | + <activity android:name=".ui.VideoActivity" | |
| 52 | + android:screenOrientation="portrait" | |
| 53 | + android:launchMode="singleTop"/> | |
| 54 | + | |
| 55 | + <activity android:name=".ui.ImageViewActivity" | |
| 56 | + android:screenOrientation="portrait" | |
| 57 | + android:launchMode="singleTop"/> | |
| 58 | + | |
| 59 | + <!-- 【必须】消息收发service --> | |
| 49 | 60 | <service |
| 50 | - android:name="io.rong.imlib.ipc.RongService" | |
| 61 | + android:name="com.tencent.qalsdk.service.QalService" | |
| 51 | 62 | android:exported="true" |
| 52 | - android:process=":ipc" /> | |
| 63 | + android:process=":QALSERVICE" > | |
| 64 | + </service> | |
| 53 | 65 | <service |
| 54 | - android:name="io.rong.imlib.ReConnectService" | |
| 55 | - android:exported="true" /> | |
| 66 | + android:name="com.tencent.qalsdk.service.QalAssistService" | |
| 67 | + android:exported="false" | |
| 68 | + android:process=":QALSERVICE" > | |
| 69 | + </service> | |
| 56 | 70 | |
| 71 | + <!-- 【必须】 离线消息广播接收器 --> | |
| 57 | 72 | <receiver |
| 58 | - android:name="io.rong.imlib.ConnectChangeReceiver" | |
| 59 | - android:exported="true" /> | |
| 73 | + android:name="com.tencent.qalsdk.QALBroadcastReceiver" | |
| 74 | + android:exported="false"> | |
| 75 | + <intent-filter> | |
| 76 | + <action android:name="com.tencent.qalsdk.broadcast.qal" /> | |
| 77 | + </intent-filter> | |
| 78 | + </receiver> | |
| 60 | 79 | <receiver |
| 61 | - android:name="io.rong.imlib.HeartbeatReceiver" | |
| 62 | - android:process=":ipc" /> | |
| 80 | + android:name="com.tencent.qalsdk.core.NetConnInfoCenter" android:process=":QALSERVICE"> | |
| 81 | + <intent-filter> | |
| 82 | + <action android:name="android.intent.action.BOOT_COMPLETED" /> | |
| 83 | + </intent-filter> | |
| 84 | + <intent-filter> | |
| 85 | + <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> | |
| 86 | + </intent-filter> | |
| 87 | + <intent-filter> | |
| 88 | + <action android:name="android.intent.action.TIME_SET" /> | |
| 89 | + </intent-filter> | |
| 90 | + <intent-filter> | |
| 91 | + <action android:name="android.intent.action.TIMEZONE_CHANGED" /> | |
| 92 | + </intent-filter> | |
| 93 | + | |
| 94 | + <!-- ImSDK 3.0.2 后添加 --> | |
| 95 | + <intent-filter> | |
| 96 | + <action android:name="com.tencent.qalsdk.service.TASK_REMOVED" /> | |
| 97 | + </intent-filter> | |
| 98 | + </receiver> | |
| 63 | 99 | |
| 64 | 100 | </application> |
| 65 | 101 | ... | ... |
app/src/main/java/com/cnlive/im/CNLiveApplication.java
| 1 | 1 | package com.cnlive.im; |
| 2 | 2 | |
| 3 | 3 | import android.app.Application; |
| 4 | +import android.content.Context; | |
| 4 | 5 | |
| 5 | 6 | import com.cnlive.libs.util.Config; |
| 6 | 7 | |
| ... | ... | @@ -11,10 +12,17 @@ import com.cnlive.libs.util.Config; |
| 11 | 12 | * @desc ${TODD} |
| 12 | 13 | */ |
| 13 | 14 | public class CNLiveApplication extends Application { |
| 15 | + private static Context context; | |
| 16 | + | |
| 14 | 17 | @Override |
| 15 | 18 | public void onCreate() { |
| 16 | 19 | super.onCreate(); |
| 17 | - Config.init(this, "60_j07o9s9b65", "dc1e76f87c7c2d83dcedb8a1204ec22fca3e156b21eb0d",true); | |
| 20 | + context = getApplicationContext(); | |
| 21 | + Config.init(this, "60_j07o9s9b65", "dc1e76f87c7c2d83dcedb8a1204ec22fca3e156b21eb0d"); | |
| 22 | + } | |
| 23 | + | |
| 24 | + public static Context getContext(){ | |
| 25 | + return context; | |
| 18 | 26 | } |
| 19 | 27 | } |
| 20 | 28 | ... | ... |
app/src/main/java/com/cnlive/im/adapter/ChatRoomAdpter.java
| 1 | 1 | package com.cnlive.im.adapter; |
| 2 | 2 | |
| 3 | 3 | import android.content.Context; |
| 4 | -import android.database.Cursor; | |
| 5 | 4 | import android.graphics.Color; |
| 6 | -import android.net.Uri; | |
| 7 | -import android.provider.ContactsContract; | |
| 8 | -import android.provider.MediaStore; | |
| 5 | +import android.graphics.drawable.AnimationDrawable; | |
| 9 | 6 | import android.support.v7.widget.RecyclerView; |
| 10 | -import android.util.Log; | |
| 11 | 7 | import android.view.LayoutInflater; |
| 12 | 8 | import android.view.View; |
| 13 | 9 | import android.view.ViewGroup; |
| 14 | -import android.view.WindowManager; | |
| 15 | 10 | import android.widget.ImageView; |
| 16 | -import android.widget.LinearLayout; | |
| 17 | 11 | import android.widget.TextView; |
| 18 | 12 | |
| 19 | 13 | import com.bumptech.glide.Glide; |
| 20 | 14 | import com.cnlive.im.R; |
| 21 | 15 | import com.cnlive.im.adapter.base.BaseRecyclerAdapter; |
| 22 | -import com.cnlive.im.adapter.base.VoiceItemClickListener; | |
| 16 | +import com.cnlive.im.adapter.base.ItemClickListener; | |
| 23 | 17 | import com.cnlive.im.mode.ImagMessage; |
| 24 | 18 | import com.cnlive.im.mode.StringMessage; |
| 19 | +import com.cnlive.im.mode.VideoMessage; | |
| 25 | 20 | import com.cnlive.im.mode.VoiceMessage; |
| 21 | +import com.cnlive.im.util.FileUtil; | |
| 22 | +import com.cnlive.libs.util.chat.base.IChat; | |
| 26 | 23 | |
| 27 | 24 | import org.json.JSONException; |
| 28 | 25 | import org.json.JSONObject; |
| 29 | 26 | |
| 30 | -import java.text.SimpleDateFormat; | |
| 31 | -import java.util.Calendar; | |
| 32 | -import java.util.Date; | |
| 33 | -import java.util.HashMap; | |
| 34 | -import java.util.Locale; | |
| 35 | - | |
| 36 | 27 | /** |
| 37 | 28 | * @author 陈硕 |
| 38 | 29 | * @time 2017/7/14 14:35 |
| ... | ... | @@ -46,8 +37,10 @@ public class ChatRoomAdpter extends BaseRecyclerAdapter { |
| 46 | 37 | private int imaOppsite = 4; |
| 47 | 38 | private int voiceUser = 5; |
| 48 | 39 | private int voiceOppsite = 6; |
| 40 | + private int videoUser = 7; | |
| 41 | + private int videoOppsite = 8; | |
| 49 | 42 | private Context mContext; |
| 50 | - private VoiceItemClickListener mVoiceItemClickListener; | |
| 43 | + private ItemClickListener mItemClickListener; | |
| 51 | 44 | |
| 52 | 45 | private boolean isPrivate; |
| 53 | 46 | |
| ... | ... | @@ -58,8 +51,8 @@ public class ChatRoomAdpter extends BaseRecyclerAdapter { |
| 58 | 51 | } |
| 59 | 52 | |
| 60 | 53 | |
| 61 | - public void setonVoiceItemClickListener(VoiceItemClickListener voiveItemClickListener) { | |
| 62 | - this.mVoiceItemClickListener = voiveItemClickListener; | |
| 54 | + public void setonVoiceItemClickListener(ItemClickListener itemClickListener) { | |
| 55 | + this.mItemClickListener = itemClickListener; | |
| 63 | 56 | } |
| 64 | 57 | |
| 65 | 58 | @Override |
| ... | ... | @@ -80,6 +73,12 @@ public class ChatRoomAdpter extends BaseRecyclerAdapter { |
| 80 | 73 | return voiceUser; |
| 81 | 74 | else return voiceOppsite; |
| 82 | 75 | |
| 76 | + } else if (o instanceof VideoMessage) { | |
| 77 | + VideoMessage o1 = (VideoMessage) o; | |
| 78 | + if (o1.isUserSend()) | |
| 79 | + return videoUser; | |
| 80 | + else return videoOppsite; | |
| 81 | + | |
| 83 | 82 | } |
| 84 | 83 | return 0; |
| 85 | 84 | } |
| ... | ... | @@ -98,6 +97,10 @@ public class ChatRoomAdpter extends BaseRecyclerAdapter { |
| 98 | 97 | return new VoiceMessageHolder(LayoutInflater.from(mContext).inflate(R.layout.voice_layout_item_user, null)); |
| 99 | 98 | } else if (viewType == voiceOppsite) { |
| 100 | 99 | return new VoiceMessageHolder(LayoutInflater.from(mContext).inflate(R.layout.voice_layout_item_oppsite, null)); |
| 100 | + } else if (viewType == videoUser) { | |
| 101 | + return new VideoMessageHolder(LayoutInflater.from(mContext).inflate(R.layout.video_layout_item_user, null)); | |
| 102 | + } else if (viewType == videoOppsite) { | |
| 103 | + return new VideoMessageHolder(LayoutInflater.from(mContext).inflate(R.layout.video_layout_item_oppsite, null)); | |
| 101 | 104 | } |
| 102 | 105 | return null; |
| 103 | 106 | } |
| ... | ... | @@ -108,42 +111,22 @@ public class ChatRoomAdpter extends BaseRecyclerAdapter { |
| 108 | 111 | StringMessageHolder holder1 = (StringMessageHolder) holder; |
| 109 | 112 | Object o = mItems.get(position); |
| 110 | 113 | StringMessage o1 = (StringMessage) o; |
| 111 | - if (isPrivate) { | |
| 112 | - try { | |
| 113 | - holder1.msg_text.setText((String) (new JSONObject(o1.getCnMessage().getContent()).get("message"))); | |
| 114 | - } catch (JSONException e) { | |
| 115 | - e.printStackTrace(); | |
| 116 | - } | |
| 117 | - } else { | |
| 118 | - holder1.msg_text.setText(o1.getCnMessage().getContent()); | |
| 119 | - } | |
| 120 | - holder1.user_name.setText(o1.getCnMessage().getUserInfo().getUserName()); | |
| 121 | - holder1.user_name.setTextColor(Color.parseColor("#d61d0c")); | |
| 122 | - holder1.msg_text.setTextColor(Color.BLACK); | |
| 114 | + holder1.showMessage(o1); | |
| 123 | 115 | } else if (holder instanceof ImaMessageHolder) { |
| 124 | 116 | ImaMessageHolder holder1 = (ImaMessageHolder) holder; |
| 125 | 117 | Object o = mItems.get(position); |
| 126 | 118 | ImagMessage o1 = (ImagMessage) o; |
| 127 | - holder1.ima_user_name.setTextColor(Color.parseColor("#d61d0c")); | |
| 128 | - holder1.img_content.getLayoutParams().height = 200; | |
| 129 | - holder1.img_content.getLayoutParams().width = 200; | |
| 130 | - holder1.img_content.setLayoutParams(holder1.img_content.getLayoutParams()); | |
| 131 | - Glide.with(mContext).load(o1.getCnImgMessage().getRemoteUri()).into(holder1.img_content); | |
| 132 | - holder1.ima_user_name.setText(o1.getCnImgMessage().getUserInfo().getUserName()); | |
| 119 | + holder1.showMessage(o1); | |
| 133 | 120 | } else if (holder instanceof VoiceMessageHolder) { |
| 134 | - VoiceMessageHolder holder1 = (VoiceMessageHolder) holder; | |
| 135 | - Object o = mItems.get(position); | |
| 136 | - VoiceMessage o1 = (VoiceMessage) o; | |
| 137 | - holder1.voice_user_name.setText(o1.getCnVoiceMessage().getUserInfo().getUserName()); | |
| 138 | - final Uri voiceUri = o1.getCnVoiceMessage().getVoiceUri(); | |
| 139 | - int duration = o1.getCnVoiceMessage().getVoiceTime(); | |
| 140 | - holder1.voice_duration.setText(String.valueOf(duration).concat("\"")); | |
| 141 | - holder1.itemView.setOnClickListener(new View.OnClickListener() { | |
| 142 | - @Override | |
| 143 | - public void onClick(View v) { | |
| 144 | - mVoiceItemClickListener.onItemClick(voiceUri); | |
| 145 | - } | |
| 146 | - }); | |
| 121 | + final VoiceMessageHolder holder1 = (VoiceMessageHolder) holder; | |
| 122 | + final Object o = mItems.get(position); | |
| 123 | + final VoiceMessage o1 = (VoiceMessage) o; | |
| 124 | + holder1.showMessage(o1); | |
| 125 | + } else if (holder instanceof VideoMessageHolder) { | |
| 126 | + final VideoMessageHolder holder1 = (VideoMessageHolder) holder; | |
| 127 | + final Object o = mItems.get(position); | |
| 128 | + final VideoMessage o1 = (VideoMessage) o; | |
| 129 | + holder1.showMessage(o1); | |
| 147 | 130 | } |
| 148 | 131 | |
| 149 | 132 | } |
| ... | ... | @@ -151,12 +134,48 @@ public class ChatRoomAdpter extends BaseRecyclerAdapter { |
| 151 | 134 | public class StringMessageHolder extends RecyclerView.ViewHolder { |
| 152 | 135 | private TextView user_name; |
| 153 | 136 | private TextView msg_text; |
| 137 | + private TextView status; | |
| 154 | 138 | |
| 155 | 139 | public StringMessageHolder(View itemView) { |
| 156 | 140 | super(itemView); |
| 157 | 141 | user_name = (TextView) itemView.findViewById(R.id.user_name); |
| 158 | 142 | msg_text = (TextView) itemView.findViewById(R.id.msg_text); |
| 143 | + status = (TextView) itemView.findViewById(R.id.status); | |
| 144 | + } | |
| 145 | + | |
| 146 | + public void showMessage(StringMessage item) { | |
| 147 | + user_name.setText(item.getCnMessage().getUserInfo().getUserName()); | |
| 159 | 148 | |
| 149 | + switch (item.getCnMessage().getStatus()) { | |
| 150 | + case IChat.CN_MSG_STATUS_SENDING: | |
| 151 | + if (status != null) | |
| 152 | + status.setText("发送中"); | |
| 153 | + sendMsg(item); | |
| 154 | + break; | |
| 155 | + case IChat.CN_MSG_STATUS_SEND_FAIL: | |
| 156 | + if (status != null) | |
| 157 | + status.setText("发送失败"); | |
| 158 | + sendMsg(item); | |
| 159 | + break; | |
| 160 | + case IChat.CN_MSG_STATUS_SEND_SUCCESS: | |
| 161 | + if (status != null) | |
| 162 | + status.setText("发送成功"); | |
| 163 | + sendMsg(item); | |
| 164 | + break; | |
| 165 | + } | |
| 166 | + } | |
| 167 | + | |
| 168 | + private void sendMsg(StringMessage item) { | |
| 169 | + if (isPrivate) { | |
| 170 | + try { | |
| 171 | + msg_text.setText((String) (new JSONObject(item.getCnMessage().getContent()).get("message"))); | |
| 172 | + } catch (JSONException e) { | |
| 173 | + e.printStackTrace(); | |
| 174 | + } | |
| 175 | + } else { | |
| 176 | + msg_text.setText(item.getCnMessage().getContent()); | |
| 177 | + } | |
| 178 | + msg_text.setTextColor(Color.BLACK); | |
| 160 | 179 | } |
| 161 | 180 | } |
| 162 | 181 | |
| ... | ... | @@ -164,11 +183,74 @@ public class ChatRoomAdpter extends BaseRecyclerAdapter { |
| 164 | 183 | |
| 165 | 184 | private TextView ima_user_name; |
| 166 | 185 | private ImageView img_content; |
| 186 | + private TextView status; | |
| 167 | 187 | |
| 168 | 188 | public ImaMessageHolder(View itemView) { |
| 169 | 189 | super(itemView); |
| 170 | 190 | ima_user_name = (TextView) itemView.findViewById(R.id.img_user_name); |
| 171 | 191 | img_content = (ImageView) itemView.findViewById(R.id.img_content); |
| 192 | + status = (TextView) itemView.findViewById(R.id.status); | |
| 193 | + } | |
| 194 | + | |
| 195 | + public void showMessage(final ImagMessage imagMessage) { | |
| 196 | + ima_user_name.setText(imagMessage.getCnImgMessage().getUserInfo().getUserName()); | |
| 197 | + img_content.getLayoutParams().height = 200; | |
| 198 | + img_content.getLayoutParams().width = 200; | |
| 199 | + img_content.setLayoutParams(img_content.getLayoutParams()); | |
| 200 | + switch (imagMessage.getCnImgMessage().getStatus()) { | |
| 201 | + case IChat.CN_MSG_STATUS_SENDING: | |
| 202 | + if (status != null) | |
| 203 | + status.setText("发送中"); | |
| 204 | + Glide.with(mContext).load(imagMessage.getCnImgMessage().getImagePath()).into(img_content); | |
| 205 | + break; | |
| 206 | + case IChat.CN_MSG_STATUS_SEND_FAIL: | |
| 207 | + if (status != null) | |
| 208 | + status.setText("发送失败"); | |
| 209 | + Glide.with(mContext).load(imagMessage.getCnImgMessage().getImagePath()).into(img_content); | |
| 210 | + break; | |
| 211 | + case IChat.CN_MSG_STATUS_SEND_SUCCESS: | |
| 212 | + if (status != null) | |
| 213 | + status.setText("发送成功"); | |
| 214 | + sendSuccess(imagMessage); | |
| 215 | + break; | |
| 216 | + } | |
| 217 | + } | |
| 218 | + | |
| 219 | + private void sendSuccess(final ImagMessage imagMessage) { | |
| 220 | + if (imagMessage.getCnImgMessage().isSelf()) { | |
| 221 | + Glide.with(mContext).load(imagMessage.getCnImgMessage().getImagePath()).into(img_content); | |
| 222 | + } else { | |
| 223 | + String thumbUuid = imagMessage.getCnImgMessage().getThumbUuid(); | |
| 224 | + final String imagePath = FileUtil.getCacheFilePath(thumbUuid); | |
| 225 | + if (FileUtil.isCacheFileExist(thumbUuid)) { | |
| 226 | + if (img_content != null && mContext != null) | |
| 227 | + Glide.with(mContext).load(imagePath).into(img_content); | |
| 228 | + } else { | |
| 229 | + if (!imagMessage.isDownloading()) { | |
| 230 | + imagMessage.setDownloading(true); | |
| 231 | + imagMessage.getCnImgMessage().getThumbImage(imagePath, new IChat.OnDownloadListener() { | |
| 232 | + @Override | |
| 233 | + public void onSuccess() { | |
| 234 | + imagMessage.setDownloading(false); | |
| 235 | + if (img_content != null && mContext != null) | |
| 236 | + Glide.with(mContext).load(imagePath).into(img_content); | |
| 237 | + } | |
| 238 | + | |
| 239 | + @Override | |
| 240 | + public void onError(int i, String s) { | |
| 241 | + imagMessage.setDownloading(false); | |
| 242 | + } | |
| 243 | + }); | |
| 244 | + } | |
| 245 | + } | |
| 246 | + } | |
| 247 | + img_content.setOnClickListener(new View.OnClickListener() { | |
| 248 | + @Override | |
| 249 | + public void onClick(View v) { | |
| 250 | + if (mItemClickListener != null) | |
| 251 | + mItemClickListener.onImageClick(imagMessage); | |
| 252 | + } | |
| 253 | + }); | |
| 172 | 254 | } |
| 173 | 255 | } |
| 174 | 256 | |
| ... | ... | @@ -176,14 +258,127 @@ public class ChatRoomAdpter extends BaseRecyclerAdapter { |
| 176 | 258 | |
| 177 | 259 | |
| 178 | 260 | private TextView voice_user_name; |
| 179 | - private TextView voice_content; | |
| 261 | + private ImageView voiceAnim; | |
| 180 | 262 | private TextView voice_duration; |
| 263 | + private View voice_none_read; | |
| 264 | + private TextView status; | |
| 181 | 265 | |
| 182 | 266 | public VoiceMessageHolder(View itemView) { |
| 183 | 267 | super(itemView); |
| 184 | 268 | voice_user_name = (TextView) itemView.findViewById(R.id.voice_user_name); |
| 185 | - voice_content = (TextView) itemView.findViewById(R.id.voice_content); | |
| 269 | + voiceAnim = (ImageView) itemView.findViewById(R.id.voiceAnim); | |
| 186 | 270 | voice_duration = (TextView) itemView.findViewById(R.id.voice_duration); |
| 271 | + voice_none_read = itemView.findViewById(R.id.noneRead); | |
| 272 | + status = (TextView) itemView.findViewById(R.id.status); | |
| 273 | + } | |
| 274 | + | |
| 275 | + public void showMessage(final VoiceMessage voiceMessage) { | |
| 276 | + voice_user_name.setText(voiceMessage.getCnVoiceMessage().getUserInfo().getUserName()); | |
| 277 | + int duration = voiceMessage.getCnVoiceMessage().getVoiceTime(); | |
| 278 | + voice_duration.setText(String.valueOf(duration).concat("\"")); | |
| 279 | + switch (voiceMessage.getCnVoiceMessage().getStatus()) { | |
| 280 | + case IChat.CN_MSG_STATUS_SENDING: | |
| 281 | + if (status != null) | |
| 282 | + status.setText("发送中"); | |
| 283 | + break; | |
| 284 | + case IChat.CN_MSG_STATUS_SEND_FAIL: | |
| 285 | + if (status != null) | |
| 286 | + status.setText("发送失败"); | |
| 287 | + break; | |
| 288 | + case IChat.CN_MSG_STATUS_SEND_SUCCESS: | |
| 289 | + if (status != null) | |
| 290 | + status.setText("发送成功"); | |
| 291 | + sendSuccess(voiceMessage); | |
| 292 | + break; | |
| 293 | + } | |
| 294 | + } | |
| 295 | + | |
| 296 | + private void sendSuccess(final VoiceMessage voiceMessage) { | |
| 297 | + if (voice_none_read != null) | |
| 298 | + voice_none_read.setVisibility(voiceMessage.getCnVoiceMessage().isRead() ? View.GONE : View.VISIBLE); | |
| 299 | + itemView.setOnClickListener(new View.OnClickListener() { | |
| 300 | + @Override | |
| 301 | + public void onClick(View v) { | |
| 302 | + if (mItemClickListener != null) | |
| 303 | + mItemClickListener.onItemClick(voiceMessage, (AnimationDrawable) voiceAnim.getBackground()); | |
| 304 | + if (voice_none_read != null) | |
| 305 | + voice_none_read.setVisibility(View.GONE); | |
| 306 | + } | |
| 307 | + }); | |
| 308 | + } | |
| 309 | + } | |
| 310 | + | |
| 311 | + public class VideoMessageHolder extends RecyclerView.ViewHolder { | |
| 312 | + | |
| 313 | + private TextView video_user_name; | |
| 314 | + private ImageView video_snapshot; | |
| 315 | + private View videoLayout; | |
| 316 | + private TextView status; | |
| 317 | + | |
| 318 | + public VideoMessageHolder(View itemView) { | |
| 319 | + super(itemView); | |
| 320 | + video_user_name = (TextView) itemView.findViewById(R.id.user_name); | |
| 321 | + video_snapshot = (ImageView) itemView.findViewById(R.id.img_content); | |
| 322 | + videoLayout = itemView.findViewById(R.id.videoLayout); | |
| 323 | + status = (TextView) itemView.findViewById(R.id.status); | |
| 324 | + } | |
| 325 | + | |
| 326 | + public void showMessage(final VideoMessage videoMessage) { | |
| 327 | + video_user_name.setText(videoMessage.getCnVideoMessage().getUserInfo().getUserName()); | |
| 328 | + switch (videoMessage.getCnVideoMessage().getStatus()) { | |
| 329 | + case IChat.CN_MSG_STATUS_SENDING: | |
| 330 | + if (status != null) | |
| 331 | + status.setText("发送中"); | |
| 332 | + Glide.with(mContext).load(videoMessage.getCnVideoMessage().getSnapshotPath()).into(video_snapshot); | |
| 333 | + break; | |
| 334 | + case IChat.CN_MSG_STATUS_SEND_FAIL: | |
| 335 | + if (status != null) | |
| 336 | + status.setText("发送失败"); | |
| 337 | + Glide.with(mContext).load(videoMessage.getCnVideoMessage().getSnapshotPath()).into(video_snapshot); | |
| 338 | + break; | |
| 339 | + case IChat.CN_MSG_STATUS_SEND_SUCCESS: | |
| 340 | + if (status != null) | |
| 341 | + status.setText("发送成功"); | |
| 342 | + sendSuccess(videoMessage); | |
| 343 | + break; | |
| 344 | + } | |
| 345 | + } | |
| 346 | + | |
| 347 | + private void sendSuccess(final VideoMessage videoMessage) { | |
| 348 | + videoLayout.setOnClickListener(new View.OnClickListener() { | |
| 349 | + @Override | |
| 350 | + public void onClick(View v) { | |
| 351 | + if (mItemClickListener != null) | |
| 352 | + mItemClickListener.onVideoClick(videoMessage); | |
| 353 | + } | |
| 354 | + }); | |
| 355 | + if (videoMessage.getCnVideoMessage().isSelf()) { | |
| 356 | + Glide.with(mContext).load(videoMessage.getCnVideoMessage().getSnapshotPath()).into(video_snapshot); | |
| 357 | + } else { | |
| 358 | + String snapshotUuid = videoMessage.getCnVideoMessage().getSnapshot().getUuid(); | |
| 359 | + final String imagePath = FileUtil.getCacheFilePath(snapshotUuid); | |
| 360 | + if (FileUtil.isCacheFileExist(snapshotUuid)) { | |
| 361 | + if (video_snapshot != null && mContext != null) | |
| 362 | + Glide.with(mContext).load(imagePath).into(video_snapshot); | |
| 363 | + } else { | |
| 364 | + if (!videoMessage.isDownloading()) { | |
| 365 | + videoMessage.setDownloading(true); | |
| 366 | + videoMessage.getCnVideoMessage().getSnapshot().getImage(imagePath, new IChat.OnDownloadListener() { | |
| 367 | + @Override | |
| 368 | + public void onSuccess() { | |
| 369 | + videoMessage.setDownloading(false); | |
| 370 | + if (video_snapshot != null && mContext != null) | |
| 371 | + Glide.with(mContext).load(imagePath).into(video_snapshot); | |
| 372 | + } | |
| 373 | + | |
| 374 | + @Override | |
| 375 | + public void onError(int i, String s) { | |
| 376 | + videoMessage.setDownloading(false); | |
| 377 | + } | |
| 378 | + }); | |
| 379 | + } | |
| 380 | + } | |
| 381 | + } | |
| 187 | 382 | } |
| 188 | 383 | } |
| 189 | 384 | ... | ... |
app/src/main/java/com/cnlive/im/adapter/CommentAdapter.java
| ... | ... | @@ -10,7 +10,7 @@ import android.widget.TextView; |
| 10 | 10 | |
| 11 | 11 | import com.bumptech.glide.Glide; |
| 12 | 12 | import com.cnlive.im.R; |
| 13 | -import com.cnlive.libs.util.model.CommentItem; | |
| 13 | +import com.cnlive.libs.util.comment.model.CommentItem; | |
| 14 | 14 | |
| 15 | 15 | import java.util.ArrayList; |
| 16 | 16 | import java.util.List; | ... | ... |
app/src/main/java/com/cnlive/im/adapter/base/VoiceItemClickListener.java renamed to app/src/main/java/com/cnlive/im/adapter/base/ItemClickListener.java
| 1 | 1 | package com.cnlive.im.adapter.base; |
| 2 | 2 | |
| 3 | -import android.net.Uri; | |
| 3 | +import android.graphics.drawable.AnimationDrawable; | |
| 4 | + | |
| 5 | +import com.cnlive.im.mode.ImagMessage; | |
| 6 | +import com.cnlive.im.mode.VideoMessage; | |
| 7 | +import com.cnlive.im.mode.VoiceMessage; | |
| 4 | 8 | |
| 5 | 9 | /** |
| 6 | 10 | * @author 陈硕 |
| 7 | 11 | * @time 2017/7/14 17:50 |
| 8 | 12 | * @desc ${TODD} |
| 9 | 13 | */ |
| 10 | -public interface VoiceItemClickListener { | |
| 11 | - void onItemClick(Uri uri); | |
| 14 | +public interface ItemClickListener { | |
| 15 | + void onItemClick(VoiceMessage voiceMessage, AnimationDrawable animationDrawable); | |
| 16 | + | |
| 17 | + void onVideoClick(VideoMessage videoMessage); | |
| 18 | + | |
| 19 | + void onImageClick(ImagMessage imagMessage); | |
| 12 | 20 | } | ... | ... |
app/src/main/java/com/cnlive/im/mode/ImagMessage.java
| ... | ... | @@ -12,6 +12,8 @@ public class ImagMessage { |
| 12 | 12 | private CNImgMessage cnImgMessage; |
| 13 | 13 | boolean isUserSend; |
| 14 | 14 | |
| 15 | + private boolean isDownloading = false; | |
| 16 | + | |
| 15 | 17 | |
| 16 | 18 | public String getType() { |
| 17 | 19 | return type; |
| ... | ... | @@ -37,7 +39,15 @@ public class ImagMessage { |
| 37 | 39 | isUserSend = userSend; |
| 38 | 40 | } |
| 39 | 41 | |
| 40 | - public ImagMessage( String type,CNImgMessage cnImgMessage, boolean isUserSend) { | |
| 42 | + public boolean isDownloading() { | |
| 43 | + return isDownloading; | |
| 44 | + } | |
| 45 | + | |
| 46 | + public void setDownloading(boolean downloading) { | |
| 47 | + isDownloading = downloading; | |
| 48 | + } | |
| 49 | + | |
| 50 | + public ImagMessage(String type, CNImgMessage cnImgMessage, boolean isUserSend) { | |
| 41 | 51 | this.type = type; |
| 42 | 52 | this.cnImgMessage = cnImgMessage; |
| 43 | 53 | this.isUserSend = isUserSend; | ... | ... |
app/src/main/java/com/cnlive/im/mode/UgcVideoMessage.java
0 → 100644
| 1 | +package com.cnlive.im.mode; | |
| 2 | + | |
| 3 | +import com.cnlive.libs.util.chat.model.CNUgcMessage; | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * Created by gujun on 2017/12/19. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +public class UgcVideoMessage { | |
| 10 | + private String type; | |
| 11 | + private CNUgcMessage cnUgcMessage; | |
| 12 | + boolean isUserSend; | |
| 13 | + | |
| 14 | + private boolean isDownloading = false; | |
| 15 | + | |
| 16 | + public UgcVideoMessage(String type, CNUgcMessage cnUgcMessage, boolean isUserSend) { | |
| 17 | + this.type = type; | |
| 18 | + this.cnUgcMessage = cnUgcMessage; | |
| 19 | + this.isUserSend = isUserSend; | |
| 20 | + } | |
| 21 | + | |
| 22 | + public String getType() { | |
| 23 | + return type; | |
| 24 | + } | |
| 25 | + | |
| 26 | + public void setType(String type) { | |
| 27 | + this.type = type; | |
| 28 | + } | |
| 29 | + | |
| 30 | + public CNUgcMessage getCnUgcMessage() { | |
| 31 | + return cnUgcMessage; | |
| 32 | + } | |
| 33 | + | |
| 34 | + public void setCnUgcMessage(CNUgcMessage cnUgcMessage) { | |
| 35 | + this.cnUgcMessage = cnUgcMessage; | |
| 36 | + } | |
| 37 | + | |
| 38 | + public boolean isUserSend() { | |
| 39 | + return isUserSend; | |
| 40 | + } | |
| 41 | + | |
| 42 | + public void setUserSend(boolean userSend) { | |
| 43 | + isUserSend = userSend; | |
| 44 | + } | |
| 45 | + | |
| 46 | + public boolean isDownloading() { | |
| 47 | + return isDownloading; | |
| 48 | + } | |
| 49 | + | |
| 50 | + public void setDownloading(boolean downloading) { | |
| 51 | + isDownloading = downloading; | |
| 52 | + } | |
| 53 | +} | |
| 54 | + | ... | ... |
app/src/main/java/com/cnlive/im/mode/VideoMessage.java
0 → 100644
| 1 | +package com.cnlive.im.mode; | |
| 2 | + | |
| 3 | +import com.cnlive.libs.util.chat.model.CNVideoMessage; | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * @author 陈硕 | |
| 7 | + * @time 2017/7/14 16:51 | |
| 8 | + * @desc ${TODD} | |
| 9 | + */ | |
| 10 | +public class VideoMessage { | |
| 11 | + private String type; | |
| 12 | + private CNVideoMessage cnVideoMessage; | |
| 13 | + boolean isUserSend; | |
| 14 | + | |
| 15 | + private boolean isDownloading = false; | |
| 16 | + | |
| 17 | + public VideoMessage(String type, CNVideoMessage cnVideoMessage, boolean isUserSend) { | |
| 18 | + this.type = type; | |
| 19 | + this.cnVideoMessage = cnVideoMessage; | |
| 20 | + this.isUserSend = isUserSend; | |
| 21 | + } | |
| 22 | + | |
| 23 | + public String getType() { | |
| 24 | + return type; | |
| 25 | + } | |
| 26 | + | |
| 27 | + public void setType(String type) { | |
| 28 | + this.type = type; | |
| 29 | + } | |
| 30 | + | |
| 31 | + public CNVideoMessage getCnVideoMessage() { | |
| 32 | + return cnVideoMessage; | |
| 33 | + } | |
| 34 | + | |
| 35 | + public void setCnVideoMessage(CNVideoMessage cnVideoMessage) { | |
| 36 | + this.cnVideoMessage = cnVideoMessage; | |
| 37 | + } | |
| 38 | + | |
| 39 | + public boolean isUserSend() { | |
| 40 | + return isUserSend; | |
| 41 | + } | |
| 42 | + | |
| 43 | + public void setUserSend(boolean userSend) { | |
| 44 | + isUserSend = userSend; | |
| 45 | + } | |
| 46 | + | |
| 47 | + public boolean isDownloading() { | |
| 48 | + return isDownloading; | |
| 49 | + } | |
| 50 | + | |
| 51 | + public void setDownloading(boolean downloading) { | |
| 52 | + isDownloading = downloading; | |
| 53 | + } | |
| 54 | +} | ... | ... |
app/src/main/java/com/cnlive/im/receiver/CNPushMessageReceiver.java
| 1 | -package com.cnlive.im.receiver; | |
| 2 | - | |
| 3 | -import android.content.Context; | |
| 4 | - | |
| 5 | -import com.cnlive.libs.util.chat.model.CNNotificationMessage; | |
| 6 | -import com.cnlive.libs.util.chat.receiver.SealNotificationReceiver; | |
| 7 | - | |
| 8 | - | |
| 9 | -/** | |
| 10 | - * Created by Lynn on 2/17/2017. | |
| 11 | - */ | |
| 12 | - | |
| 13 | -public class CNPushMessageReceiver extends SealNotificationReceiver { | |
| 14 | - | |
| 15 | - @Override | |
| 16 | - public boolean onNotificationMessageArrived(Context var1, CNNotificationMessage var2) { | |
| 17 | - //返回false,会弹出SDK默认的通知;返回true,SDK不会弹出通知,通知需要您自定义 | |
| 18 | - return false; | |
| 19 | - } | |
| 20 | - | |
| 21 | - @Override | |
| 22 | - public boolean onNotificationMessageClicked(Context var1, CNNotificationMessage var2) { | |
| 23 | - //返回false,会走SDK默认的处理逻辑,即点击该通知则会打开会话列表或会话界面;返回true,则由您自定义处理逻辑 | |
| 24 | - return false; | |
| 25 | - } | |
| 26 | -} | |
| 1 | +//package com.cnlive.im.receiver; | |
| 2 | +// | |
| 3 | +//import android.content.Context; | |
| 4 | +// | |
| 5 | +//import com.cnlive.libs.util.chat.model.CNNotificationMessage; | |
| 6 | +//import com.cnlive.libs.util.chat.receiver.SealNotificationReceiver; | |
| 7 | +// | |
| 8 | +// | |
| 9 | +///** | |
| 10 | +// * Created by Lynn on 2/17/2017. | |
| 11 | +// */ | |
| 12 | +// | |
| 13 | +//public class CNPushMessageReceiver extends SealNotificationReceiver { | |
| 14 | +// | |
| 15 | +// @Override | |
| 16 | +// public boolean onNotificationMessageArrived(Context var1, CNNotificationMessage var2) { | |
| 17 | +// //返回false,会弹出SDK默认的通知;返回true,SDK不会弹出通知,通知需要您自定义 | |
| 18 | +// return false; | |
| 19 | +// } | |
| 20 | +// | |
| 21 | +// @Override | |
| 22 | +// public boolean onNotificationMessageClicked(Context var1, CNNotificationMessage var2) { | |
| 23 | +// //返回false,会走SDK默认的处理逻辑,即点击该通知则会打开会话列表或会话界面;返回true,则由您自定义处理逻辑 | |
| 24 | +// return false; | |
| 25 | +// } | |
| 26 | +//} | ... | ... |
app/src/main/java/com/cnlive/im/ui/ChatRoomActivity.java
| ... | ... | @@ -5,10 +5,14 @@ import android.app.Activity; |
| 5 | 5 | import android.content.Context; |
| 6 | 6 | import android.content.Intent; |
| 7 | 7 | import android.content.pm.PackageManager; |
| 8 | +import android.graphics.Bitmap; | |
| 9 | +import android.graphics.drawable.AnimationDrawable; | |
| 10 | +import android.media.ThumbnailUtils; | |
| 8 | 11 | import android.net.Uri; |
| 9 | 12 | import android.os.Build; |
| 10 | 13 | import android.os.Bundle; |
| 11 | 14 | import android.os.Handler; |
| 15 | +import android.provider.MediaStore; | |
| 12 | 16 | import android.support.annotation.NonNull; |
| 13 | 17 | import android.support.v4.app.ActivityCompat; |
| 14 | 18 | import android.support.v4.content.ContextCompat; |
| ... | ... | @@ -33,24 +37,28 @@ import android.widget.Toast; |
| 33 | 37 | |
| 34 | 38 | import com.cnlive.im.R; |
| 35 | 39 | import com.cnlive.im.adapter.ChatRoomAdpter; |
| 36 | -import com.cnlive.im.adapter.base.VoiceItemClickListener; | |
| 40 | +import com.cnlive.im.adapter.base.ItemClickListener; | |
| 37 | 41 | import com.cnlive.im.mode.ImagMessage; |
| 38 | 42 | import com.cnlive.im.mode.StringMessage; |
| 43 | +import com.cnlive.im.mode.VideoMessage; | |
| 39 | 44 | import com.cnlive.im.mode.VoiceMessage; |
| 40 | 45 | import com.cnlive.im.util.AudioRecordUtil; |
| 46 | +import com.cnlive.im.util.FileUtil; | |
| 47 | +import com.cnlive.im.util.MediaUtil; | |
| 41 | 48 | import com.cnlive.im.util.MessageType; |
| 42 | -import com.cnlive.im.util.PlayerUtil; | |
| 43 | 49 | import com.cnlive.im.util.TimeUtils; |
| 44 | 50 | import com.cnlive.im.util.UploadImageUtils; |
| 45 | 51 | import com.cnlive.libs.util.chat.ChatUtil; |
| 46 | 52 | import com.cnlive.libs.util.chat.base.IChat; |
| 53 | +import com.cnlive.libs.util.chat.model.CNBaseMessage; | |
| 47 | 54 | import com.cnlive.libs.util.chat.model.CNImgMessage; |
| 48 | 55 | import com.cnlive.libs.util.chat.model.CNMessage; |
| 49 | 56 | import com.cnlive.libs.util.chat.model.CNUserInfo; |
| 57 | +import com.cnlive.libs.util.chat.model.CNVideoMessage; | |
| 50 | 58 | import com.cnlive.libs.util.chat.model.CNVoiceMessage; |
| 51 | 59 | |
| 52 | -import org.json.JSONException; | |
| 53 | - | |
| 60 | +import java.io.File; | |
| 61 | +import java.io.FileInputStream; | |
| 54 | 62 | import java.util.ArrayList; |
| 55 | 63 | |
| 56 | 64 | |
| ... | ... | @@ -59,10 +67,13 @@ import java.util.ArrayList; |
| 59 | 67 | * @time 2017/3/7 14:36 |
| 60 | 68 | * @desc ${TODD} |
| 61 | 69 | */ |
| 62 | -public class ChatRoomActivity extends AppCompatActivity implements View.OnClickListener, VoiceItemClickListener { | |
| 70 | +public class ChatRoomActivity extends AppCompatActivity implements View.OnClickListener, ItemClickListener { | |
| 63 | 71 | private static final String TAG = "ChatRoomActivity"; |
| 64 | - private ArrayList<Object> groupChatOneListMy; | |
| 65 | - private String roomIdOne = "ChatRoom05"; | |
| 72 | + | |
| 73 | + private final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 0x2001; | |
| 74 | + | |
| 75 | + private ArrayList<String> groupChatOneListMy; | |
| 76 | + private String roomIdOne = "ChatRoom10"; | |
| 66 | 77 | private EditText editText; |
| 67 | 78 | private Button send_messageOneBtn; |
| 68 | 79 | private RecyclerView listViewOne; |
| ... | ... | @@ -70,7 +81,7 @@ public class ChatRoomActivity extends AppCompatActivity implements View.OnClickL |
| 70 | 81 | private Button foundChatBtn; |
| 71 | 82 | private Handler mHandler; |
| 72 | 83 | private RelativeLayout re_chat; |
| 73 | -// private LinearLayout lin_user; | |
| 84 | + // private LinearLayout lin_user; | |
| 74 | 85 | // private EditText user_id, user_name; |
| 75 | 86 | private Button exit_chat1; |
| 76 | 87 | public static String user_name_string; |
| ... | ... | @@ -100,8 +111,6 @@ public class ChatRoomActivity extends AppCompatActivity implements View.OnClickL |
| 100 | 111 | |
| 101 | 112 | private String mFilePath; |
| 102 | 113 | |
| 103 | - private PlayerUtil playerUtil; | |
| 104 | - | |
| 105 | 114 | // 所需的全部权限 |
| 106 | 115 | static final String[] PERMISSIONS = new String[]{ |
| 107 | 116 | Manifest.permission.RECORD_AUDIO, |
| ... | ... | @@ -130,7 +139,6 @@ public class ChatRoomActivity extends AppCompatActivity implements View.OnClickL |
| 130 | 139 | ChatUtil.login(new CNUserInfo(user_id_string, user_name_string, ""), connectListener); |
| 131 | 140 | else ChatUtil.logOut(connectListener); |
| 132 | 141 | requestPermission(); |
| 133 | - playerUtil = new PlayerUtil(this); | |
| 134 | 142 | |
| 135 | 143 | } |
| 136 | 144 | |
| ... | ... | @@ -169,6 +177,9 @@ public class ChatRoomActivity extends AppCompatActivity implements View.OnClickL |
| 169 | 177 | keybordBtn = (ImageView) findViewById(R.id.keybord); |
| 170 | 178 | keybordBtn.setOnClickListener(this); |
| 171 | 179 | |
| 180 | + findViewById(R.id.videoBtn).setOnClickListener(this); | |
| 181 | + findViewById(R.id.ugcVideoBtn).setOnClickListener(this); | |
| 182 | + | |
| 172 | 183 | |
| 173 | 184 | StartListener(); |
| 174 | 185 | |
| ... | ... | @@ -181,43 +192,21 @@ public class ChatRoomActivity extends AppCompatActivity implements View.OnClickL |
| 181 | 192 | */ |
| 182 | 193 | private IChat.OnSendMessageListener sendMessageListener = new IChat.OnSendMessageListener() { |
| 183 | 194 | @Override |
| 184 | - public void onAttached(Object o) { | |
| 185 | - | |
| 195 | + public void onAttached(CNBaseMessage o) { | |
| 196 | + showMessage(o); | |
| 186 | 197 | } |
| 187 | 198 | |
| 188 | 199 | @Override |
| 189 | - public void onSuccess(final Object o) throws JSONException { | |
| 190 | - mHandler.post(new Runnable() { | |
| 191 | - @Override | |
| 192 | - public void run() { | |
| 193 | - if (o instanceof CNMessage) { | |
| 194 | - CNMessage o1 = (CNMessage) o; | |
| 195 | - chatListAdapterOne.addItem(new StringMessage(MessageType.stringMessage, o1, true)); | |
| 196 | - } else if (o instanceof CNImgMessage) { | |
| 197 | - CNImgMessage o1 = (CNImgMessage) o; | |
| 198 | - chatListAdapterOne.addItem(new ImagMessage(MessageType.imaMessage, o1, true)); | |
| 199 | - } else if (o instanceof CNVoiceMessage) { | |
| 200 | - CNVoiceMessage o1 = (CNVoiceMessage) o; | |
| 201 | - VoiceMessage voiceMessage = new VoiceMessage(MessageType.voiceMessage, o1, true); | |
| 202 | - chatListAdapterOne.addItem(voiceMessage); | |
| 203 | - //发送成功后删除保存在本地的录制文件 | |
| 204 | - mAudioRecordUtil.deleteRecordFile(mFilePath); | |
| 205 | - | |
| 206 | - } | |
| 207 | - listViewOne.smoothScrollToPosition(chatListAdapterOne.getItemCount() - 1); | |
| 208 | - } | |
| 209 | - }); | |
| 200 | + public void onSuccess(final CNBaseMessage o) { | |
| 201 | + updateItem(o); | |
| 210 | 202 | } |
| 211 | 203 | |
| 212 | 204 | @Override |
| 213 | - public void onError(Object o, int i, String s) { | |
| 214 | - if (o instanceof CNImgMessage) { | |
| 215 | - | |
| 216 | - } | |
| 205 | + public void onError(CNBaseMessage o, int i, String s) { | |
| 206 | + updateItem(o); | |
| 217 | 207 | } |
| 218 | 208 | }; |
| 219 | 209 | |
| 220 | - | |
| 221 | 210 | //连接状态监听 |
| 222 | 211 | private IChat.OnConnectStatusListener connectStatusListener = new IChat.OnConnectStatusListener() { |
| 223 | 212 | @Override |
| ... | ... | @@ -229,28 +218,59 @@ public class ChatRoomActivity extends AppCompatActivity implements View.OnClickL |
| 229 | 218 | |
| 230 | 219 | private IChat.OnReceiveMessageListener receiveMessageListener = new IChat.OnReceiveMessageListener() { |
| 231 | 220 | @Override |
| 232 | - public void processMessage(final Object o) { | |
| 233 | - mHandler.post(new Runnable() { | |
| 234 | - @Override | |
| 235 | - public void run() { | |
| 236 | - if (o instanceof CNMessage) { | |
| 237 | - CNMessage o1 = (CNMessage) o; | |
| 238 | - chatListAdapterOne.addItem(new StringMessage(MessageType.stringMessage, o1, false)); | |
| 239 | - } else if (o instanceof CNImgMessage) { | |
| 240 | - CNImgMessage o1 = (CNImgMessage) o; | |
| 241 | - chatListAdapterOne.addItem(new ImagMessage(MessageType.imaMessage, o1, false)); | |
| 242 | - } else if (o instanceof CNVoiceMessage) { | |
| 243 | - CNVoiceMessage o1 = (CNVoiceMessage) o; | |
| 244 | - VoiceMessage voiceMessage = new VoiceMessage(MessageType.voiceMessage, o1, false); | |
| 245 | - chatListAdapterOne.addItem(voiceMessage); | |
| 246 | - } | |
| 247 | - listViewOne.smoothScrollToPosition(chatListAdapterOne.getItemCount() - 1); | |
| 248 | - } | |
| 249 | - }); | |
| 250 | - | |
| 221 | + public void processMessage(final CNBaseMessage o) { | |
| 222 | + showMessage(o); | |
| 251 | 223 | } |
| 252 | 224 | }; |
| 253 | 225 | |
| 226 | + /** | |
| 227 | + * 更新消息 | |
| 228 | + */ | |
| 229 | + public void updateItem(CNBaseMessage o) { | |
| 230 | + int updateIndex = groupChatOneListMy.indexOf(o.getMessageId()); | |
| 231 | + if (updateIndex < 0 || chatListAdapterOne.getItemCount() <= 0) return; | |
| 232 | + if (o.getMsgType() == IChat.CN_MSG_TYPE_TEXT) { | |
| 233 | + CNMessage o1 = (CNMessage) o; | |
| 234 | + chatListAdapterOne.updateItem(new StringMessage(MessageType.stringMessage, o1, o1.isSelf()), updateIndex); | |
| 235 | + } else if (o.getMsgType() == IChat.CN_MSG_TYPE_IMAGE) { | |
| 236 | + CNImgMessage o1 = (CNImgMessage) o; | |
| 237 | + chatListAdapterOne.updateItem(new ImagMessage(MessageType.imaMessage, o1, o1.isSelf()), updateIndex); | |
| 238 | + } else if (o.getMsgType() == IChat.CN_MSG_TYPE_VOICE) { | |
| 239 | + CNVoiceMessage o1 = (CNVoiceMessage) o; | |
| 240 | + VoiceMessage voiceMessage = new VoiceMessage(MessageType.voiceMessage, o1, o1.isSelf()); | |
| 241 | + chatListAdapterOne.updateItem(voiceMessage, updateIndex); | |
| 242 | + } else if (o.getMsgType() == IChat.CN_MSG_TYPE_VIDEO) { | |
| 243 | + CNVideoMessage ol = (CNVideoMessage) o; | |
| 244 | + VideoMessage videoMessage = new VideoMessage(MessageType.videoMessage, ol, ol.isSelf()); | |
| 245 | + chatListAdapterOne.updateItem(videoMessage, updateIndex); | |
| 246 | + } | |
| 247 | + } | |
| 248 | + | |
| 249 | + /** | |
| 250 | + * 展示消息 | |
| 251 | + * | |
| 252 | + * @param o | |
| 253 | + */ | |
| 254 | + private void showMessage(CNBaseMessage o) { | |
| 255 | + groupChatOneListMy.add(o.getMessageId()); | |
| 256 | + if (o.getMsgType() == IChat.CN_MSG_TYPE_TEXT) { | |
| 257 | + CNMessage o1 = (CNMessage) o; | |
| 258 | + chatListAdapterOne.addItem(new StringMessage(MessageType.stringMessage, o1, o1.isSelf())); | |
| 259 | + } else if (o.getMsgType() == IChat.CN_MSG_TYPE_IMAGE) { | |
| 260 | + CNImgMessage o1 = (CNImgMessage) o; | |
| 261 | + chatListAdapterOne.addItem(new ImagMessage(MessageType.imaMessage, o1, o1.isSelf())); | |
| 262 | + } else if (o.getMsgType() == IChat.CN_MSG_TYPE_VOICE) { | |
| 263 | + CNVoiceMessage o1 = (CNVoiceMessage) o; | |
| 264 | + VoiceMessage voiceMessage = new VoiceMessage(MessageType.voiceMessage, o1, o1.isSelf()); | |
| 265 | + chatListAdapterOne.addItem(voiceMessage); | |
| 266 | + } else if (o.getMsgType() == IChat.CN_MSG_TYPE_VIDEO) { | |
| 267 | + CNVideoMessage ol = (CNVideoMessage) o; | |
| 268 | + VideoMessage videoMessage = new VideoMessage(MessageType.videoMessage, ol, ol.isSelf()); | |
| 269 | + chatListAdapterOne.addItem(videoMessage); | |
| 270 | + } | |
| 271 | + listViewOne.smoothScrollToPosition(chatListAdapterOne.getItemCount() - 1); | |
| 272 | + } | |
| 273 | + | |
| 254 | 274 | |
| 255 | 275 | //聊天室操作 |
| 256 | 276 | private IChat.OnChatRoomActionListener chatRoomActionListener = new IChat.OnChatRoomActionListener() { |
| ... | ... | @@ -333,7 +353,7 @@ public class ChatRoomActivity extends AppCompatActivity implements View.OnClickL |
| 333 | 353 | } |
| 334 | 354 | break; |
| 335 | 355 | case R.id.creatChat: |
| 336 | - ChatUtil.joinChatRoom(roomIdOne, 20, onOperationListener); | |
| 356 | + ChatUtil.joinChatRoom(roomIdOne, -1, onOperationListener); | |
| 337 | 357 | break; |
| 338 | 358 | case R.id.exit_chat1: |
| 339 | 359 | ChatUtil.quitChatRoom(roomIdOne, onOperationListener); |
| ... | ... | @@ -356,9 +376,30 @@ public class ChatRoomActivity extends AppCompatActivity implements View.OnClickL |
| 356 | 376 | isVoiceBtnVisible = false; |
| 357 | 377 | } |
| 358 | 378 | break; |
| 379 | + case R.id.videoBtn: | |
| 380 | + openSystemRecorder(); | |
| 381 | + break; | |
| 382 | + case R.id.ugcVideoBtn: | |
| 383 | + | |
| 384 | + break; | |
| 359 | 385 | } |
| 360 | 386 | } |
| 361 | 387 | |
| 388 | + private void openSystemRecorder() { | |
| 389 | + // 创建拍照Intent并将控制权返回给调用的程序 | |
| 390 | + Intent intent = new Intent(); | |
| 391 | + intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE); | |
| 392 | + intent.addCategory(Intent.CATEGORY_DEFAULT); | |
| 393 | + | |
| 394 | + // 保存录像到指定的路径 | |
| 395 | + File file = new File("/sdcard/video.mp4"); | |
| 396 | + Uri uri = Uri.fromFile(file); | |
| 397 | + intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); | |
| 398 | + | |
| 399 | + // 启动图像捕获Intent | |
| 400 | + startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE); | |
| 401 | + } | |
| 402 | + | |
| 362 | 403 | |
| 363 | 404 | public void fromPicture() { |
| 364 | 405 | if (Build.VERSION.SDK_INT >= 23) { |
| ... | ... | @@ -394,7 +435,12 @@ public class ChatRoomActivity extends AppCompatActivity implements View.OnClickL |
| 394 | 435 | Uri uri = Uri.parse("file://" + picturePath); |
| 395 | 436 | ChatUtil.sendImaMessage(IChat.CHATROOM, roomIdOne, uri, uri, sendMessageListener); |
| 396 | 437 | break; |
| 397 | - | |
| 438 | + case CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE: | |
| 439 | + String videoPath = data.getData().getPath(); | |
| 440 | + Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Images.Thumbnails.FULL_SCREEN_KIND); | |
| 441 | + String imgPath = FileUtil.createFile(bitmap, System.currentTimeMillis() + ""); | |
| 442 | + ChatUtil.sendVideoMessage(IChat.CHATROOM, roomIdOne, videoPath, imgPath, MediaUtil.getInstance().getDuration(videoPath), sendMessageListener); | |
| 443 | + break; | |
| 398 | 444 | default: |
| 399 | 445 | break; |
| 400 | 446 | } |
| ... | ... | @@ -425,11 +471,137 @@ public class ChatRoomActivity extends AppCompatActivity implements View.OnClickL |
| 425 | 471 | } |
| 426 | 472 | }; |
| 427 | 473 | |
| 474 | + /** | |
| 475 | + * 播放语音文件 | |
| 476 | + * | |
| 477 | + * @param voicePath | |
| 478 | + * @param animationDrawable | |
| 479 | + */ | |
| 480 | + private void startVoice(String voicePath, final AnimationDrawable animationDrawable) { | |
| 481 | + try { | |
| 482 | + FileInputStream fis = new FileInputStream(voicePath); | |
| 483 | + MediaUtil.getInstance().play(fis); | |
| 484 | + animationDrawable.start(); | |
| 485 | + MediaUtil.getInstance().setEventListener(new MediaUtil.EventListener() { | |
| 486 | + @Override | |
| 487 | + public void onStop() { | |
| 488 | + animationDrawable.stop(); | |
| 489 | + animationDrawable.selectDrawable(0); | |
| 490 | + } | |
| 491 | + }); | |
| 492 | + } catch (Exception e) { | |
| 493 | + } | |
| 494 | + } | |
| 428 | 495 | |
| 429 | 496 | @Override |
| 430 | - public void onItemClick(Uri uri) { | |
| 431 | - playerUtil.start(uri); | |
| 497 | + public void onItemClick(VoiceMessage voiceMessage, final AnimationDrawable animationDrawable) { | |
| 498 | + if (voiceMessage == null) { | |
| 499 | + Toast.makeText(this, "数据异常", Toast.LENGTH_LONG).show(); | |
| 500 | + return; | |
| 501 | + } | |
| 502 | + if (voiceMessage.getCnVoiceMessage().isSelf()) { | |
| 503 | + startVoice(voiceMessage.getCnVoiceMessage().getVoiceUri().getPath(), animationDrawable); | |
| 504 | + } else { | |
| 505 | + //设置本地已读 | |
| 506 | + voiceMessage.getCnVoiceMessage().setRead(true); | |
| 507 | + String voiceUuid = voiceMessage.getCnVoiceMessage().getUuid(); | |
| 508 | + final String voicePath = FileUtil.getCacheFilePath(voiceUuid); | |
| 509 | + if (FileUtil.isCacheFileExist(voiceUuid)) { | |
| 510 | + File file = new File(voicePath); | |
| 511 | + if (file.length() < voiceMessage.getCnVoiceMessage().getDataSize()) { | |
| 512 | + Toast.makeText(context, "请稍等,正在下载...", Toast.LENGTH_SHORT).show(); | |
| 513 | + return; | |
| 514 | + } | |
| 515 | + startVoice(voicePath, animationDrawable); | |
| 516 | + } else { | |
| 517 | + voiceMessage.getCnVoiceMessage().getVoice(voicePath, new IChat.OnDownloadListener() { | |
| 518 | + @Override | |
| 519 | + public void onSuccess() { | |
| 520 | + startVoice(voicePath, animationDrawable); | |
| 521 | + } | |
| 522 | + | |
| 523 | + @Override | |
| 524 | + public void onError(int i, String s) { | |
| 432 | 525 | |
| 526 | + } | |
| 527 | + }); | |
| 528 | + } | |
| 529 | + } | |
| 530 | + } | |
| 531 | + | |
| 532 | + @Override | |
| 533 | + public void onVideoClick(VideoMessage videoMessage) { | |
| 534 | + if (videoMessage.getCnVideoMessage().isSelf()) { | |
| 535 | + Intent intent = new Intent(ChatRoomActivity.this, VideoActivity.class); | |
| 536 | + intent.putExtra("videoPath", videoMessage.getCnVideoMessage().getVideoPath()); | |
| 537 | + startActivity(intent); | |
| 538 | + } else { | |
| 539 | + String videoUuid = videoMessage.getCnVideoMessage().getVideo().getUuid(); | |
| 540 | + final String videoPath = FileUtil.getCacheFilePath(videoUuid); | |
| 541 | + if (FileUtil.isCacheFileExist(videoUuid)) { | |
| 542 | + Intent intent = new Intent(ChatRoomActivity.this, VideoActivity.class); | |
| 543 | + intent.putExtra("videoPath", videoPath); | |
| 544 | + startActivity(intent); | |
| 545 | + } else { | |
| 546 | + videoMessage.getCnVideoMessage().getVideo().getVideo(videoPath, new IChat.OnDownloadListener() { | |
| 547 | + @Override | |
| 548 | + public void onSuccess() { | |
| 549 | + Intent intent = new Intent(ChatRoomActivity.this, VideoActivity.class); | |
| 550 | + intent.putExtra("videoPath", videoPath); | |
| 551 | + startActivity(intent); | |
| 552 | + } | |
| 553 | + | |
| 554 | + @Override | |
| 555 | + public void onError(int i, String s) { | |
| 556 | + | |
| 557 | + } | |
| 558 | + }); | |
| 559 | + } | |
| 560 | + } | |
| 561 | + | |
| 562 | + } | |
| 563 | + | |
| 564 | + @Override | |
| 565 | + public void onImageClick(final ImagMessage imagMessage) { | |
| 566 | + if (imagMessage.getCnImgMessage().isSelf()) { | |
| 567 | + Intent intent = new Intent(ChatRoomActivity.this, ImageViewActivity.class); | |
| 568 | + intent.putExtra("path", imagMessage.getCnImgMessage().getImagePath()); | |
| 569 | + startActivity(intent); | |
| 570 | + } else { | |
| 571 | + String remoteUuid = imagMessage.getCnImgMessage().getRemoteUuid(); | |
| 572 | + final String imagePath = FileUtil.getCacheFilePath(remoteUuid); | |
| 573 | + if (FileUtil.isCacheFileExist(remoteUuid)) { | |
| 574 | + File file = new File(imagePath); | |
| 575 | + if (file.length() < imagMessage.getCnImgMessage().getRemoteSize()) { | |
| 576 | + Toast.makeText(context, "请稍等,正在下载...", Toast.LENGTH_SHORT).show(); | |
| 577 | + return; | |
| 578 | + } | |
| 579 | + Intent intent = new Intent(ChatRoomActivity.this, ImageViewActivity.class); | |
| 580 | + intent.putExtra("path", imagePath); | |
| 581 | + startActivity(intent); | |
| 582 | + } else { | |
| 583 | + if (imagMessage.isDownloading()) { | |
| 584 | + Toast.makeText(context, "请稍等,正在下载...", Toast.LENGTH_SHORT).show(); | |
| 585 | + } else { | |
| 586 | + imagMessage.setDownloading(true); | |
| 587 | + imagMessage.getCnImgMessage().getRemoteImage(imagePath, new IChat.OnDownloadListener() { | |
| 588 | + @Override | |
| 589 | + public void onSuccess() { | |
| 590 | + imagMessage.setDownloading(false); | |
| 591 | + Intent intent = new Intent(ChatRoomActivity.this, ImageViewActivity.class); | |
| 592 | + intent.putExtra("path", imagePath); | |
| 593 | + startActivity(intent); | |
| 594 | + } | |
| 595 | + | |
| 596 | + @Override | |
| 597 | + public void onError(int i, String s) { | |
| 598 | + imagMessage.setDownloading(false); | |
| 599 | + Toast.makeText(context, "下载失败", Toast.LENGTH_SHORT).show(); | |
| 600 | + } | |
| 601 | + }); | |
| 602 | + } | |
| 603 | + } | |
| 604 | + } | |
| 433 | 605 | } |
| 434 | 606 | |
| 435 | 607 | |
| ... | ... | @@ -444,14 +616,15 @@ public class ChatRoomActivity extends AppCompatActivity implements View.OnClickL |
| 444 | 616 | Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) && |
| 445 | 617 | (ContextCompat.checkSelfPermission(context, |
| 446 | 618 | Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) |
| 447 | - ) { | |
| 619 | + && (ContextCompat.checkSelfPermission(context, | |
| 620 | + Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)) { | |
| 448 | 621 | StartListener(); |
| 449 | 622 | |
| 450 | 623 | //判断是否开启语音权限 |
| 451 | 624 | } else { |
| 452 | 625 | //请求获取摄像头权限 |
| 453 | 626 | ActivityCompat.requestPermissions((Activity) context, |
| 454 | - new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, VOICE_REQUEST_CODE); | |
| 627 | + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA}, VOICE_REQUEST_CODE); | |
| 455 | 628 | } |
| 456 | 629 | } |
| 457 | 630 | |
| ... | ... | @@ -592,4 +765,16 @@ public class ChatRoomActivity extends AppCompatActivity implements View.OnClickL |
| 592 | 765 | } |
| 593 | 766 | }; |
| 594 | 767 | |
| 768 | + @Override | |
| 769 | + protected void onPause() { | |
| 770 | + super.onPause(); | |
| 771 | + MediaUtil.getInstance().stop(); | |
| 772 | + } | |
| 773 | + | |
| 774 | + @Override | |
| 775 | + protected void onDestroy() { | |
| 776 | + super.onDestroy(); | |
| 777 | + ChatUtil.removeReceiveMessageListener(receiveMessageListener); | |
| 778 | + ChatUtil.removeConnectListener(connectListener); | |
| 779 | + } | |
| 595 | 780 | } | ... | ... |
app/src/main/java/com/cnlive/im/ui/CommentActivity.java
| ... | ... | @@ -13,14 +13,14 @@ import android.widget.Toast; |
| 13 | 13 | |
| 14 | 14 | import com.cnlive.im.R; |
| 15 | 15 | import com.cnlive.im.adapter.CommentAdapter; |
| 16 | -import com.cnlive.libs.util.chat.model.ErrorMessage; | |
| 17 | 16 | import com.cnlive.libs.util.comment.CommentUtil; |
| 18 | 17 | import com.cnlive.libs.util.comment.base.CommentCallback; |
| 19 | 18 | import com.cnlive.libs.util.comment.base.CommentListCallback; |
| 20 | 19 | import com.cnlive.libs.util.comment.base.CommentProgramCallback; |
| 21 | -import com.cnlive.libs.util.model.CommentItem; | |
| 22 | -import com.cnlive.libs.util.model.CommentPage; | |
| 23 | -import com.cnlive.libs.util.model.CommentProgram; | |
| 20 | +import com.cnlive.libs.util.comment.model.CommentItem; | |
| 21 | +import com.cnlive.libs.util.comment.model.CommentPage; | |
| 22 | +import com.cnlive.libs.util.comment.model.CommentProgram; | |
| 23 | +import com.cnlive.libs.util.comment.model.ErrorMessage; | |
| 24 | 24 | |
| 25 | 25 | import java.util.List; |
| 26 | 26 | ... | ... |
app/src/main/java/com/cnlive/im/ui/ImageViewActivity.java
0 → 100644
| 1 | +package com.cnlive.im.ui; | |
| 2 | + | |
| 3 | +import android.app.Activity; | |
| 4 | +import android.os.Bundle; | |
| 5 | +import android.support.annotation.Nullable; | |
| 6 | +import android.widget.ImageView; | |
| 7 | + | |
| 8 | +import com.bumptech.glide.Glide; | |
| 9 | +import com.cnlive.im.R; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * Created by gujun on 2017/12/18. | |
| 13 | + */ | |
| 14 | + | |
| 15 | +public class ImageViewActivity extends Activity { | |
| 16 | + | |
| 17 | + private ImageView imageView; | |
| 18 | + | |
| 19 | + private String imagePath; | |
| 20 | + | |
| 21 | + @Override | |
| 22 | + protected void onCreate(@Nullable Bundle savedInstanceState) { | |
| 23 | + super.onCreate(savedInstanceState); | |
| 24 | + setContentView(R.layout.activity_image_view); | |
| 25 | + imageView = (ImageView) findViewById(R.id.image); | |
| 26 | + imagePath = getIntent().getStringExtra("path"); | |
| 27 | + Glide.with(this).load(imagePath).into(imageView); | |
| 28 | + } | |
| 29 | +} | ... | ... |
app/src/main/java/com/cnlive/im/ui/PrivateActivity.java
| ... | ... | @@ -6,6 +6,9 @@ import android.content.Context; |
| 6 | 6 | import android.content.Intent; |
| 7 | 7 | import android.content.pm.PackageManager; |
| 8 | 8 | import android.database.Cursor; |
| 9 | +import android.graphics.Bitmap; | |
| 10 | +import android.graphics.drawable.AnimationDrawable; | |
| 11 | +import android.media.ThumbnailUtils; | |
| 9 | 12 | import android.net.Uri; |
| 10 | 13 | import android.os.Build; |
| 11 | 14 | import android.os.Bundle; |
| ... | ... | @@ -29,33 +32,38 @@ import android.widget.Button; |
| 29 | 32 | import android.widget.EditText; |
| 30 | 33 | import android.widget.ImageView; |
| 31 | 34 | import android.widget.LinearLayout; |
| 32 | -import android.widget.ListView; | |
| 33 | 35 | import android.widget.RelativeLayout; |
| 34 | 36 | import android.widget.TextView; |
| 35 | 37 | import android.widget.Toast; |
| 36 | 38 | |
| 37 | 39 | import com.cnlive.im.R; |
| 38 | 40 | import com.cnlive.im.adapter.ChatRoomAdpter; |
| 39 | -import com.cnlive.im.adapter.base.VoiceItemClickListener; | |
| 41 | +import com.cnlive.im.adapter.base.ItemClickListener; | |
| 40 | 42 | import com.cnlive.im.mode.CNMessageModole; |
| 41 | 43 | import com.cnlive.im.mode.ImagMessage; |
| 42 | 44 | import com.cnlive.im.mode.StringMessage; |
| 45 | +import com.cnlive.im.mode.VideoMessage; | |
| 43 | 46 | import com.cnlive.im.mode.VoiceMessage; |
| 44 | 47 | import com.cnlive.im.util.AudioRecordUtil; |
| 48 | +import com.cnlive.im.util.FileUtil; | |
| 49 | +import com.cnlive.im.util.MediaUtil; | |
| 45 | 50 | import com.cnlive.im.util.MessageType; |
| 46 | -import com.cnlive.im.util.PlayerUtil; | |
| 47 | 51 | import com.cnlive.im.util.TimeUtils; |
| 48 | 52 | import com.cnlive.im.util.ToStringUtils; |
| 49 | 53 | import com.cnlive.libs.util.chat.ChatUtil; |
| 50 | 54 | import com.cnlive.libs.util.chat.base.IChat; |
| 55 | +import com.cnlive.libs.util.chat.model.CNBaseMessage; | |
| 51 | 56 | import com.cnlive.libs.util.chat.model.CNImgMessage; |
| 52 | 57 | import com.cnlive.libs.util.chat.model.CNMessage; |
| 53 | 58 | import com.cnlive.libs.util.chat.model.CNUserInfo; |
| 59 | +import com.cnlive.libs.util.chat.model.CNVideoMessage; | |
| 54 | 60 | import com.cnlive.libs.util.chat.model.CNVoiceMessage; |
| 55 | 61 | |
| 56 | 62 | import org.json.JSONException; |
| 57 | 63 | import org.json.JSONObject; |
| 58 | 64 | |
| 65 | +import java.io.File; | |
| 66 | +import java.io.FileInputStream; | |
| 59 | 67 | import java.util.ArrayList; |
| 60 | 68 | |
| 61 | 69 | import static com.cnlive.im.R.id.opposite_id_edit; |
| ... | ... | @@ -64,10 +72,12 @@ import static com.cnlive.im.R.id.opposite_id_edit; |
| 64 | 72 | * Created by Lynn on 2017/7/24. |
| 65 | 73 | */ |
| 66 | 74 | |
| 67 | -public class PrivateActivity extends AppCompatActivity implements View.OnClickListener, VoiceItemClickListener { | |
| 75 | +public class PrivateActivity extends AppCompatActivity implements View.OnClickListener, ItemClickListener { | |
| 68 | 76 | |
| 69 | 77 | private static final String TAG = "PrivateChatActivity"; |
| 70 | 78 | |
| 79 | + private final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 0x2001; | |
| 80 | + | |
| 71 | 81 | // 所需的全部权限 |
| 72 | 82 | static final String[] PERMISSIONS = new String[]{ |
| 73 | 83 | Manifest.permission.RECORD_AUDIO, |
| ... | ... | @@ -87,7 +97,7 @@ public class PrivateActivity extends AppCompatActivity implements View.OnClickLi |
| 87 | 97 | private EditText messageContent; |
| 88 | 98 | private Button sendMessageBtn; |
| 89 | 99 | private ChatRoomAdpter chatListAdapter; |
| 90 | - private ArrayList<Object> messageList = new ArrayList<>(); | |
| 100 | + private ArrayList<String> messageList = new ArrayList<>(); | |
| 91 | 101 | // private CNMessage cnMessage; |
| 92 | 102 | private LinearLayout linearLayoutUseID; |
| 93 | 103 | private EditText user_id_edit; |
| ... | ... | @@ -108,7 +118,6 @@ public class PrivateActivity extends AppCompatActivity implements View.OnClickLi |
| 108 | 118 | private ImageView keybordBtn; |
| 109 | 119 | private Button sendVoice; |
| 110 | 120 | private AudioRecordUtil mAudioRecordUtil; |
| 111 | - private PlayerUtil playerUtil; | |
| 112 | 121 | private String mFilePath; |
| 113 | 122 | private PopupWindowFactory mPop; |
| 114 | 123 | private RelativeLayout privateLayout; |
| ... | ... | @@ -132,9 +141,8 @@ public class PrivateActivity extends AppCompatActivity implements View.OnClickLi |
| 132 | 141 | mAudioRecordUtil.setOnAudioStatusUpdateListener(onAudioStatusUpdateListener); |
| 133 | 142 | mHandler = new Handler(); |
| 134 | 143 | ChatUtil.setOnConnectStatusListener(connectStatusListener); |
| 135 | - ChatUtil.setOnReceiveMessageListener(receiveMessageListener); | |
| 144 | + ChatUtil.setOnReceivePrivateMessageListener(receiveMessageListener); | |
| 136 | 145 | requestPermission(); |
| 137 | - playerUtil = new PlayerUtil(this); | |
| 138 | 146 | } |
| 139 | 147 | |
| 140 | 148 | private void initView() { |
| ... | ... | @@ -184,6 +192,9 @@ public class PrivateActivity extends AppCompatActivity implements View.OnClickLi |
| 184 | 192 | chatListView.setLayoutManager(new LinearLayoutManager(PrivateActivity.this)); |
| 185 | 193 | chatListView.setAdapter(chatListAdapter); |
| 186 | 194 | |
| 195 | + findViewById(R.id.videoBtn).setOnClickListener(this); | |
| 196 | + findViewById(R.id.ugcVideoBtn).setOnClickListener(this); | |
| 197 | + | |
| 187 | 198 | StartListener(); |
| 188 | 199 | } |
| 189 | 200 | |
| ... | ... | @@ -251,9 +262,31 @@ public class PrivateActivity extends AppCompatActivity implements View.OnClickLi |
| 251 | 262 | case R.id.ima_send: |
| 252 | 263 | sendMessage(IMAGE_MESSAGE); |
| 253 | 264 | break; |
| 265 | + case R.id.videoBtn: | |
| 266 | + openSystemRecorder(); | |
| 267 | + break; | |
| 268 | + case R.id.ugcVideoBtn: | |
| 269 | + | |
| 270 | + break; | |
| 254 | 271 | } |
| 255 | 272 | } |
| 256 | 273 | |
| 274 | + private void openSystemRecorder() { | |
| 275 | + // 创建拍照Intent并将控制权返回给调用的程序 | |
| 276 | + Intent intent = new Intent(); | |
| 277 | + intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE); | |
| 278 | + intent.addCategory(Intent.CATEGORY_DEFAULT); | |
| 279 | + | |
| 280 | + // 保存录像到指定的路径 | |
| 281 | + File file = new File("/sdcard/video.mp4"); | |
| 282 | + Uri uri = Uri.fromFile(file); | |
| 283 | + intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); | |
| 284 | + | |
| 285 | + // 启动图像捕获Intent | |
| 286 | + startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE); | |
| 287 | + } | |
| 288 | + | |
| 289 | + | |
| 257 | 290 | private void sendMessage(String type) { |
| 258 | 291 | if (sendInfo == 2) { |
| 259 | 292 | Toast.makeText(this, "等待对方接受邀请", Toast.LENGTH_SHORT).show(); |
| ... | ... | @@ -329,6 +362,12 @@ public class PrivateActivity extends AppCompatActivity implements View.OnClickLi |
| 329 | 362 | Uri uri = Uri.parse("file://" + picturePath); |
| 330 | 363 | ChatUtil.sendImaMessage(IChat.PRIVATE, oppositeID, uri, uri, sendMessageListener); |
| 331 | 364 | break; |
| 365 | + case CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE: | |
| 366 | + String videoPath = data.getData().getPath(); | |
| 367 | + Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Images.Thumbnails.FULL_SCREEN_KIND); | |
| 368 | + String imgPath = FileUtil.createFile(bitmap, System.currentTimeMillis() + ""); | |
| 369 | + ChatUtil.sendVideoMessage(IChat.PRIVATE, oppositeID, videoPath, imgPath, MediaUtil.getInstance().getDuration(videoPath), sendMessageListener); | |
| 370 | + break; | |
| 332 | 371 | |
| 333 | 372 | default: |
| 334 | 373 | break; |
| ... | ... | @@ -365,120 +404,110 @@ public class PrivateActivity extends AppCompatActivity implements View.OnClickLi |
| 365 | 404 | /** |
| 366 | 405 | * 发送消息监听 |
| 367 | 406 | */ |
| 368 | - | |
| 369 | 407 | private IChat.OnSendMessageListener sendMessageListener = new IChat.OnSendMessageListener() { |
| 370 | 408 | @Override |
| 371 | - public void onAttached(Object o) { | |
| 409 | + public void onAttached(CNBaseMessage o) { | |
| 410 | + showMessage(o, false); | |
| 372 | 411 | } |
| 373 | 412 | |
| 374 | 413 | @Override |
| 375 | - public void onSuccess(final Object o) throws JSONException { | |
| 376 | - if (View.VISIBLE == vistor_btn.getVisibility()) { | |
| 377 | - vistor_btn.setVisibility(View.GONE); | |
| 378 | - } | |
| 379 | - | |
| 380 | - mHandler.post(new Runnable() { | |
| 381 | - @Override | |
| 382 | - public void run() { | |
| 383 | - if (o instanceof CNMessage) { | |
| 384 | - CNMessage o1 = (CNMessage) o; | |
| 385 | - JSONObject jsonObject = null; | |
| 386 | - try { | |
| 387 | - jsonObject = new JSONObject(o1.getContent().toString()); | |
| 388 | - String type = (String) jsonObject.get("type"); | |
| 389 | - String message = (String) jsonObject.get("message"); | |
| 390 | - Toast.makeText(PrivateActivity.this, "发送消息成功", Toast.LENGTH_SHORT).show(); | |
| 391 | - if ("3".equals(type) && message.equals("你好我们可以进行私聊吗")) { | |
| 392 | - sendInfo = 2; | |
| 393 | - Toast.makeText(PrivateActivity.this, "申请已发送等待对方验证", Toast.LENGTH_SHORT).show(); | |
| 394 | - } else if ("3".equals(type) && message.equals("拒绝")) { | |
| 395 | - sendInfo = 5; | |
| 396 | - } else if ("3".equals(type) && message.equals("同意")) { | |
| 397 | - sendInfo = 1; | |
| 398 | - } else if ("4".equals(type)) { | |
| 399 | - chatListAdapter.addItem(new StringMessage(MessageType.stringMessage, o1, true)); | |
| 400 | - chatListView.smoothScrollToPosition(chatListAdapter.getItemCount() - 1); | |
| 401 | - | |
| 402 | - } | |
| 403 | - } catch (JSONException e) { | |
| 404 | - | |
| 405 | - | |
| 406 | - } | |
| 407 | - } else if (o instanceof CNImgMessage) { | |
| 408 | - CNImgMessage o1 = (CNImgMessage) o; | |
| 409 | - chatListAdapter.addItem(new ImagMessage(MessageType.imaMessage, o1, true)); | |
| 410 | - chatListView.smoothScrollToPosition(chatListAdapter.getItemCount() - 1); | |
| 411 | - } else if (o instanceof CNVoiceMessage) { | |
| 412 | - CNVoiceMessage o1 = (CNVoiceMessage) o; | |
| 413 | - VoiceMessage voiceMessage = new VoiceMessage(MessageType.voiceMessage, o1, true); | |
| 414 | - chatListAdapter.addItem(voiceMessage); | |
| 415 | - //发送成功后删除保存在本地的录制文件 | |
| 416 | - mAudioRecordUtil.deleteRecordFile(mFilePath); | |
| 417 | - chatListView.smoothScrollToPosition(chatListAdapter.getItemCount() - 1); | |
| 418 | - } | |
| 419 | - } | |
| 420 | - }); | |
| 414 | + public void onSuccess(final CNBaseMessage o) { | |
| 415 | + updateItem(o); | |
| 421 | 416 | } |
| 422 | 417 | |
| 423 | 418 | @Override |
| 424 | - public void onError(Object o, int i, String s) { | |
| 419 | + public void onError(CNBaseMessage o, int i, String s) { | |
| 420 | + updateItem(o); | |
| 425 | 421 | } |
| 426 | 422 | }; |
| 427 | 423 | |
| 428 | - | |
| 429 | 424 | //连接状态监听 |
| 430 | 425 | private IChat.OnConnectStatusListener connectStatusListener = new IChat.OnConnectStatusListener() { |
| 431 | 426 | @Override |
| 432 | 427 | public void onConnectStatus(int i, String s) { |
| 433 | - Log.i(TAG, "私聊连接状态监听私聊" + i + " " + s); | |
| 434 | - | |
| 435 | - | |
| 428 | + Log.i(TAG, "连接状态监听" + i + " " + s); | |
| 436 | 429 | } |
| 437 | 430 | }; |
| 431 | + | |
| 432 | + | |
| 438 | 433 | //接收消息监听 |
| 439 | 434 | private IChat.OnReceiveMessageListener receiveMessageListener = new IChat.OnReceiveMessageListener() { |
| 440 | 435 | @Override |
| 441 | - public void processMessage(final Object o) { | |
| 442 | - mHandler.post(new Runnable() { | |
| 443 | - @Override | |
| 444 | - public void run() { | |
| 445 | - if (o instanceof CNMessage) { | |
| 446 | - CNMessage o1 = (CNMessage) o; | |
| 447 | - JSONObject jsonObject = null; | |
| 448 | - try { | |
| 449 | - jsonObject = new JSONObject(o1.getContent().toString()); | |
| 450 | - String type = (String) jsonObject.get("type"); | |
| 451 | - if ("3".equals(type) && "你好我们可以进行私聊吗".equals(jsonObject.get("message"))) { | |
| 452 | - vistor_btn.setVisibility(View.GONE); | |
| 453 | - agree_reject_lin.setVisibility(View.VISIBLE); | |
| 454 | - } else if ("3".equals(type) && "同意".equals(jsonObject.get("message"))) { | |
| 455 | - sendInfo = 1; | |
| 456 | - } else if ("3".equals(type) && "拒绝".equals(jsonObject.get("message"))) { | |
| 457 | - sendInfo = 4; | |
| 458 | - } else if ("4".equals(type)) { | |
| 459 | - Log.v(TAG, o1.getContent().toString()); | |
| 460 | - chatListAdapter.addItem(new StringMessage(MessageType.stringMessage, o1, false)); | |
| 461 | - chatListView.smoothScrollToPosition(chatListAdapter.getItemCount() - 1); | |
| 462 | - } | |
| 436 | + public void processMessage(final CNBaseMessage o) { | |
| 437 | + showMessage(o, true); | |
| 438 | + } | |
| 439 | + }; | |
| 463 | 440 | |
| 464 | - } catch (JSONException e) { | |
| 465 | - e.printStackTrace(); | |
| 466 | - } | |
| 467 | - } else if (o instanceof CNImgMessage) { | |
| 468 | - CNImgMessage o1 = (CNImgMessage) o; | |
| 469 | - chatListAdapter.addItem(new ImagMessage(MessageType.imaMessage, o1, false)); | |
| 470 | - chatListView.smoothScrollToPosition(chatListAdapter.getItemCount() - 1); | |
| 471 | - } else if (o instanceof CNVoiceMessage) { | |
| 472 | - CNVoiceMessage o1 = (CNVoiceMessage) o; | |
| 473 | - VoiceMessage voiceMessage = new VoiceMessage(MessageType.voiceMessage, o1, false); | |
| 474 | - chatListAdapter.addItem(voiceMessage); | |
| 441 | + /** | |
| 442 | + * 更新消息 | |
| 443 | + */ | |
| 444 | + public void updateItem(CNBaseMessage o) { | |
| 445 | + int updateIndex = messageList.indexOf(o.getMessageId()); | |
| 446 | + if (updateIndex < 0 || chatListAdapter.getItemCount() <= 0) return; | |
| 447 | + if (o.getMsgType() == IChat.CN_MSG_TYPE_TEXT) { | |
| 448 | + CNMessage o1 = (CNMessage) o; | |
| 449 | + chatListAdapter.updateItem(new StringMessage(MessageType.stringMessage, o1, o1.isSelf()), updateIndex); | |
| 450 | + } else if (o.getMsgType() == IChat.CN_MSG_TYPE_IMAGE) { | |
| 451 | + CNImgMessage o1 = (CNImgMessage) o; | |
| 452 | + chatListAdapter.updateItem(new ImagMessage(MessageType.imaMessage, o1, o1.isSelf()), updateIndex); | |
| 453 | + } else if (o.getMsgType() == IChat.CN_MSG_TYPE_VOICE) { | |
| 454 | + CNVoiceMessage o1 = (CNVoiceMessage) o; | |
| 455 | + VoiceMessage voiceMessage = new VoiceMessage(MessageType.voiceMessage, o1, o1.isSelf()); | |
| 456 | + chatListAdapter.updateItem(voiceMessage, updateIndex); | |
| 457 | + } else if (o.getMsgType() == IChat.CN_MSG_TYPE_VIDEO) { | |
| 458 | + CNVideoMessage ol = (CNVideoMessage) o; | |
| 459 | + VideoMessage videoMessage = new VideoMessage(MessageType.videoMessage, ol, ol.isSelf()); | |
| 460 | + chatListAdapter.updateItem(videoMessage, updateIndex); | |
| 461 | + } | |
| 462 | + } | |
| 463 | + | |
| 464 | + /** | |
| 465 | + * 展示消息 | |
| 466 | + * | |
| 467 | + * @param o | |
| 468 | + */ | |
| 469 | + private void showMessage(CNBaseMessage o, boolean isReceivedMsg) { | |
| 470 | + messageList.add(o.getMessageId()); | |
| 471 | + if (o.getMsgType() == IChat.CN_MSG_TYPE_TEXT) { | |
| 472 | + if (isReceivedMsg) { | |
| 473 | + CNMessage o1 = (CNMessage) o; | |
| 474 | + JSONObject jsonObject = null; | |
| 475 | + try { | |
| 476 | + jsonObject = new JSONObject(o1.getContent().toString()); | |
| 477 | + String type = (String) jsonObject.get("type"); | |
| 478 | + if ("3".equals(type) && "你好我们可以进行私聊吗".equals(jsonObject.get("message"))) { | |
| 479 | + vistor_btn.setVisibility(View.GONE); | |
| 480 | + agree_reject_lin.setVisibility(View.VISIBLE); | |
| 481 | + } else if ("3".equals(type) && "同意".equals(jsonObject.get("message"))) { | |
| 482 | + sendInfo = 1; | |
| 483 | + } else if ("3".equals(type) && "拒绝".equals(jsonObject.get("message"))) { | |
| 484 | + sendInfo = 4; | |
| 485 | + } else if ("4".equals(type)) { | |
| 486 | + Log.v(TAG, o1.getContent().toString()); | |
| 487 | + chatListAdapter.addItem(new StringMessage(MessageType.stringMessage, o1, false)); | |
| 475 | 488 | chatListView.smoothScrollToPosition(chatListAdapter.getItemCount() - 1); |
| 476 | 489 | } |
| 490 | + } catch (JSONException e) { | |
| 491 | + e.printStackTrace(); | |
| 477 | 492 | } |
| 478 | - }); | |
| 479 | - | |
| 493 | + } else { | |
| 494 | + CNMessage o1 = (CNMessage) o; | |
| 495 | + chatListAdapter.addItem(new StringMessage(MessageType.stringMessage, o1, o1.isSelf())); | |
| 496 | + } | |
| 497 | + } else if (o.getMsgType() == IChat.CN_MSG_TYPE_IMAGE) { | |
| 498 | + CNImgMessage o1 = (CNImgMessage) o; | |
| 499 | + chatListAdapter.addItem(new ImagMessage(MessageType.imaMessage, o1, o1.isSelf())); | |
| 500 | + } else if (o.getMsgType() == IChat.CN_MSG_TYPE_VOICE) { | |
| 501 | + CNVoiceMessage o1 = (CNVoiceMessage) o; | |
| 502 | + VoiceMessage voiceMessage = new VoiceMessage(MessageType.voiceMessage, o1, o1.isSelf()); | |
| 503 | + chatListAdapter.addItem(voiceMessage); | |
| 504 | + } else if (o.getMsgType() == IChat.CN_MSG_TYPE_VIDEO) { | |
| 505 | + CNVideoMessage ol = (CNVideoMessage) o; | |
| 506 | + VideoMessage videoMessage = new VideoMessage(MessageType.videoMessage, ol, ol.isSelf()); | |
| 507 | + chatListAdapter.addItem(videoMessage); | |
| 480 | 508 | } |
| 481 | - }; | |
| 509 | + chatListView.smoothScrollToPosition(chatListAdapter.getItemCount() - 1); | |
| 510 | + } | |
| 482 | 511 | |
| 483 | 512 | /** |
| 484 | 513 | * 开启扫描之前判断权限是否打开 |
| ... | ... | @@ -489,14 +518,15 @@ public class PrivateActivity extends AppCompatActivity implements View.OnClickLi |
| 489 | 518 | Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) && |
| 490 | 519 | (ContextCompat.checkSelfPermission(context, |
| 491 | 520 | Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) |
| 492 | - ) { | |
| 521 | + && (ContextCompat.checkSelfPermission(context, | |
| 522 | + Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)) { | |
| 493 | 523 | StartListener(); |
| 494 | 524 | |
| 495 | 525 | //判断是否开启语音权限 |
| 496 | 526 | } else { |
| 497 | 527 | //请求获取摄像头权限 |
| 498 | 528 | ActivityCompat.requestPermissions((Activity) context, |
| 499 | - new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, VOICE_REQUEST_CODE); | |
| 529 | + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA}, VOICE_REQUEST_CODE); | |
| 500 | 530 | } |
| 501 | 531 | } |
| 502 | 532 | |
| ... | ... | @@ -638,8 +668,149 @@ public class PrivateActivity extends AppCompatActivity implements View.OnClickLi |
| 638 | 668 | } |
| 639 | 669 | }; |
| 640 | 670 | |
| 671 | + /** | |
| 672 | + * 播放语音文件 | |
| 673 | + * | |
| 674 | + * @param voicePath | |
| 675 | + * @param animationDrawable | |
| 676 | + */ | |
| 677 | + private void startVoice(String voicePath, final AnimationDrawable animationDrawable) { | |
| 678 | + try { | |
| 679 | + FileInputStream fis = new FileInputStream(voicePath); | |
| 680 | + MediaUtil.getInstance().play(fis); | |
| 681 | + animationDrawable.start(); | |
| 682 | + MediaUtil.getInstance().setEventListener(new MediaUtil.EventListener() { | |
| 683 | + @Override | |
| 684 | + public void onStop() { | |
| 685 | + animationDrawable.stop(); | |
| 686 | + animationDrawable.selectDrawable(0); | |
| 687 | + } | |
| 688 | + }); | |
| 689 | + } catch (Exception e) { | |
| 690 | + } | |
| 691 | + } | |
| 692 | + | |
| 693 | + @Override | |
| 694 | + public void onItemClick(VoiceMessage voiceMessage, final AnimationDrawable animationDrawable) { | |
| 695 | + if (voiceMessage == null) { | |
| 696 | + Toast.makeText(this, "数据异常", Toast.LENGTH_LONG).show(); | |
| 697 | + return; | |
| 698 | + } | |
| 699 | + if (voiceMessage.getCnVoiceMessage().isSelf()) { | |
| 700 | + startVoice(voiceMessage.getCnVoiceMessage().getVoiceUri().getPath(), animationDrawable); | |
| 701 | + } else { | |
| 702 | + //设置本地已读 | |
| 703 | + voiceMessage.getCnVoiceMessage().setRead(true); | |
| 704 | + String voiceUuid = voiceMessage.getCnVoiceMessage().getUuid(); | |
| 705 | + final String voicePath = FileUtil.getCacheFilePath(voiceUuid); | |
| 706 | + if (FileUtil.isCacheFileExist(voiceUuid)) { | |
| 707 | + File file = new File(voicePath); | |
| 708 | + if (file.length() < voiceMessage.getCnVoiceMessage().getDataSize()) { | |
| 709 | + Toast.makeText(context, "请稍等,正在下载...", Toast.LENGTH_SHORT).show(); | |
| 710 | + return; | |
| 711 | + } | |
| 712 | + startVoice(voicePath, animationDrawable); | |
| 713 | + } else { | |
| 714 | + voiceMessage.getCnVoiceMessage().getVoice(voicePath, new IChat.OnDownloadListener() { | |
| 715 | + @Override | |
| 716 | + public void onSuccess() { | |
| 717 | + startVoice(voicePath, animationDrawable); | |
| 718 | + } | |
| 719 | + | |
| 720 | + @Override | |
| 721 | + public void onError(int i, String s) { | |
| 722 | + | |
| 723 | + } | |
| 724 | + }); | |
| 725 | + } | |
| 726 | + } | |
| 727 | + } | |
| 728 | + | |
| 729 | + @Override | |
| 730 | + public void onVideoClick(VideoMessage videoMessage) { | |
| 731 | + if (videoMessage.getCnVideoMessage().isSelf()) { | |
| 732 | + Intent intent = new Intent(PrivateActivity.this, VideoActivity.class); | |
| 733 | + intent.putExtra("videoPath", videoMessage.getCnVideoMessage().getVideoPath()); | |
| 734 | + startActivity(intent); | |
| 735 | + } else { | |
| 736 | + String videoUuid = videoMessage.getCnVideoMessage().getVideo().getUuid(); | |
| 737 | + final String videoPath = FileUtil.getCacheFilePath(videoUuid); | |
| 738 | + if (FileUtil.isCacheFileExist(videoUuid)) { | |
| 739 | + Intent intent = new Intent(PrivateActivity.this, VideoActivity.class); | |
| 740 | + intent.putExtra("videoPath", videoPath); | |
| 741 | + startActivity(intent); | |
| 742 | + } else { | |
| 743 | + videoMessage.getCnVideoMessage().getVideo().getVideo(videoPath, new IChat.OnDownloadListener() { | |
| 744 | + @Override | |
| 745 | + public void onSuccess() { | |
| 746 | + Intent intent = new Intent(PrivateActivity.this, VideoActivity.class); | |
| 747 | + intent.putExtra("videoPath", videoPath); | |
| 748 | + startActivity(intent); | |
| 749 | + } | |
| 750 | + | |
| 751 | + @Override | |
| 752 | + public void onError(int i, String s) { | |
| 753 | + | |
| 754 | + } | |
| 755 | + }); | |
| 756 | + } | |
| 757 | + } | |
| 758 | + | |
| 759 | + } | |
| 760 | + | |
| 761 | + @Override | |
| 762 | + public void onImageClick(final ImagMessage imagMessage) { | |
| 763 | + if (imagMessage.getCnImgMessage().isSelf()) { | |
| 764 | + Intent intent = new Intent(PrivateActivity.this, ImageViewActivity.class); | |
| 765 | + intent.putExtra("path", imagMessage.getCnImgMessage().getImagePath()); | |
| 766 | + startActivity(intent); | |
| 767 | + } else { | |
| 768 | + String remoteUuid = imagMessage.getCnImgMessage().getRemoteUuid(); | |
| 769 | + final String imagePath = FileUtil.getCacheFilePath(remoteUuid); | |
| 770 | + if (FileUtil.isCacheFileExist(remoteUuid)) { | |
| 771 | + File file = new File(imagePath); | |
| 772 | + if (file.length() < imagMessage.getCnImgMessage().getRemoteSize()) { | |
| 773 | + Toast.makeText(context, "请稍等,正在下载...", Toast.LENGTH_SHORT).show(); | |
| 774 | + return; | |
| 775 | + } | |
| 776 | + Intent intent = new Intent(PrivateActivity.this, ImageViewActivity.class); | |
| 777 | + intent.putExtra("path", imagePath); | |
| 778 | + startActivity(intent); | |
| 779 | + } else { | |
| 780 | + if (imagMessage.isDownloading()) { | |
| 781 | + Toast.makeText(context, "请稍等,正在下载...", Toast.LENGTH_SHORT).show(); | |
| 782 | + } else { | |
| 783 | + imagMessage.setDownloading(true); | |
| 784 | + imagMessage.getCnImgMessage().getRemoteImage(imagePath, new IChat.OnDownloadListener() { | |
| 785 | + @Override | |
| 786 | + public void onSuccess() { | |
| 787 | + imagMessage.setDownloading(false); | |
| 788 | + Intent intent = new Intent(PrivateActivity.this, ImageViewActivity.class); | |
| 789 | + intent.putExtra("path", imagePath); | |
| 790 | + startActivity(intent); | |
| 791 | + } | |
| 792 | + | |
| 793 | + @Override | |
| 794 | + public void onError(int i, String s) { | |
| 795 | + imagMessage.setDownloading(false); | |
| 796 | + Toast.makeText(context, "下载失败", Toast.LENGTH_SHORT).show(); | |
| 797 | + } | |
| 798 | + }); | |
| 799 | + } | |
| 800 | + } | |
| 801 | + } | |
| 802 | + } | |
| 803 | + | |
| 804 | + @Override | |
| 805 | + protected void onPause() { | |
| 806 | + super.onPause(); | |
| 807 | + MediaUtil.getInstance().stop(); | |
| 808 | + } | |
| 809 | + | |
| 641 | 810 | @Override |
| 642 | - public void onItemClick(Uri uri) { | |
| 643 | - playerUtil.start(uri); | |
| 811 | + protected void onDestroy() { | |
| 812 | + super.onDestroy(); | |
| 813 | + ChatUtil.removeReceiveMessageListener(receiveMessageListener); | |
| 814 | + ChatUtil.removeConnectListener(connectListener); | |
| 644 | 815 | } |
| 645 | 816 | } | ... | ... |
app/src/main/java/com/cnlive/im/ui/VideoActivity.java
0 → 100644
| 1 | +package com.cnlive.im.ui; | |
| 2 | + | |
| 3 | +import android.app.Activity; | |
| 4 | +import android.content.Intent; | |
| 5 | +import android.media.MediaPlayer; | |
| 6 | +import android.os.Bundle; | |
| 7 | +import android.support.annotation.Nullable; | |
| 8 | +import android.widget.VideoView; | |
| 9 | + | |
| 10 | +import com.cnlive.im.R; | |
| 11 | + | |
| 12 | +/** | |
| 13 | + * Created by gujun on 2017/12/12. | |
| 14 | + */ | |
| 15 | + | |
| 16 | +public class VideoActivity extends Activity { | |
| 17 | + private String videoPath; | |
| 18 | + private VideoView videoView; | |
| 19 | + private boolean isStart = false; | |
| 20 | + | |
| 21 | + @Override | |
| 22 | + protected void onCreate(@Nullable Bundle savedInstanceState) { | |
| 23 | + super.onCreate(savedInstanceState); | |
| 24 | + setContentView(R.layout.activity_play); | |
| 25 | + init(getIntent()); | |
| 26 | + } | |
| 27 | + | |
| 28 | + @Override | |
| 29 | + protected void onNewIntent(Intent intent) { | |
| 30 | + super.onNewIntent(intent); | |
| 31 | + init(intent); | |
| 32 | + } | |
| 33 | + | |
| 34 | + private void init(Intent intent) { | |
| 35 | + videoPath = intent.getStringExtra("videoPath"); | |
| 36 | + | |
| 37 | + videoView = (VideoView) findViewById(R.id.video); | |
| 38 | + videoView.setVideoPath(videoPath); | |
| 39 | + videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { | |
| 40 | + @Override | |
| 41 | + public void onPrepared(MediaPlayer mp) { | |
| 42 | + isStart = true; | |
| 43 | + videoView.start(); | |
| 44 | + } | |
| 45 | + }); | |
| 46 | + } | |
| 47 | + | |
| 48 | + @Override | |
| 49 | + protected void onResume() { | |
| 50 | + super.onResume(); | |
| 51 | + if (videoView != null && isStart) { | |
| 52 | + videoView.start(); | |
| 53 | + } | |
| 54 | + } | |
| 55 | + | |
| 56 | + @Override | |
| 57 | + protected void onPause() { | |
| 58 | + super.onPause(); | |
| 59 | + if (videoView != null && isStart) { | |
| 60 | + videoView.pause(); | |
| 61 | + } | |
| 62 | + } | |
| 63 | + | |
| 64 | + @Override | |
| 65 | + protected void onDestroy() { | |
| 66 | + super.onDestroy(); | |
| 67 | + if (videoView != null) { | |
| 68 | + videoView.stopPlayback(); | |
| 69 | + videoView = null; | |
| 70 | + } | |
| 71 | + } | |
| 72 | +} | ... | ... |
app/src/main/java/com/cnlive/im/util/FileUtil.java
0 → 100644
| 1 | +package com.cnlive.im.util; | |
| 2 | + | |
| 3 | +import android.app.Activity; | |
| 4 | +import android.content.ContentUris; | |
| 5 | +import android.content.Context; | |
| 6 | +import android.database.Cursor; | |
| 7 | +import android.graphics.Bitmap; | |
| 8 | +import android.net.Uri; | |
| 9 | +import android.os.Build; | |
| 10 | +import android.os.Environment; | |
| 11 | +import android.provider.DocumentsContract; | |
| 12 | +import android.provider.MediaStore; | |
| 13 | +import android.util.Log; | |
| 14 | + | |
| 15 | +import com.cnlive.im.CNLiveApplication; | |
| 16 | + | |
| 17 | +import java.io.ByteArrayOutputStream; | |
| 18 | +import java.io.File; | |
| 19 | +import java.io.FileOutputStream; | |
| 20 | +import java.io.IOException; | |
| 21 | + | |
| 22 | +/** | |
| 23 | + * 文件工具类 | |
| 24 | + */ | |
| 25 | +public class FileUtil { | |
| 26 | + | |
| 27 | + private static final String TAG = "FileUtil"; | |
| 28 | + private static String pathDiv = "/"; | |
| 29 | + private static File cacheDir = !isExternalStorageWritable() ? CNLiveApplication.getContext().getFilesDir() : CNLiveApplication.getContext().getExternalCacheDir(); | |
| 30 | + | |
| 31 | + private FileUtil() { | |
| 32 | + /* cannot be instantiated */ | |
| 33 | + throw new UnsupportedOperationException("cannot be instantiated"); | |
| 34 | + } | |
| 35 | + | |
| 36 | + | |
| 37 | + /** | |
| 38 | + * 创建临时文件 | |
| 39 | + * | |
| 40 | + * @param type 文件类型 | |
| 41 | + */ | |
| 42 | + public static File getTempFile(FileType type) { | |
| 43 | + try { | |
| 44 | + File file = File.createTempFile(type.toString(), null, cacheDir); | |
| 45 | + file.deleteOnExit(); | |
| 46 | + return file; | |
| 47 | + } catch (IOException e) { | |
| 48 | + return null; | |
| 49 | + } | |
| 50 | + } | |
| 51 | + | |
| 52 | + | |
| 53 | + /** | |
| 54 | + * 获取缓存文件地址 | |
| 55 | + */ | |
| 56 | + public static String getCacheFilePath(String fileName) { | |
| 57 | + return cacheDir.getAbsolutePath() + pathDiv + fileName; | |
| 58 | + } | |
| 59 | + | |
| 60 | + | |
| 61 | + /** | |
| 62 | + * 判断缓存文件是否存在 | |
| 63 | + */ | |
| 64 | + public static boolean isCacheFileExist(String fileName) { | |
| 65 | + File file = new File(getCacheFilePath(fileName)); | |
| 66 | + return file.exists(); | |
| 67 | + } | |
| 68 | + | |
| 69 | + | |
| 70 | + /** | |
| 71 | + * 将图片存储为文件 | |
| 72 | + * | |
| 73 | + * @param bitmap 图片 | |
| 74 | + */ | |
| 75 | + public static String createFile(Bitmap bitmap, String filename) { | |
| 76 | + File f = new File(cacheDir, filename); | |
| 77 | + try { | |
| 78 | + if (f.createNewFile()) { | |
| 79 | + ByteArrayOutputStream bos = new ByteArrayOutputStream(); | |
| 80 | + bitmap.compress(Bitmap.CompressFormat.PNG, 0, bos); | |
| 81 | + byte[] bitmapdata = bos.toByteArray(); | |
| 82 | + FileOutputStream fos = new FileOutputStream(f); | |
| 83 | + fos.write(bitmapdata); | |
| 84 | + fos.flush(); | |
| 85 | + fos.close(); | |
| 86 | + } | |
| 87 | + } catch (IOException e) { | |
| 88 | + Log.e(TAG, "create bitmap file error" + e); | |
| 89 | + } | |
| 90 | + if (f.exists()) { | |
| 91 | + return f.getAbsolutePath(); | |
| 92 | + } | |
| 93 | + return null; | |
| 94 | + } | |
| 95 | + | |
| 96 | + /** | |
| 97 | + * 将数据存储为文件 | |
| 98 | + * | |
| 99 | + * @param data 数据 | |
| 100 | + */ | |
| 101 | + public static void createFile(byte[] data, String filename) { | |
| 102 | + File f = new File(cacheDir, filename); | |
| 103 | + try { | |
| 104 | + if (f.createNewFile()) { | |
| 105 | + FileOutputStream fos = new FileOutputStream(f); | |
| 106 | + fos.write(data); | |
| 107 | + fos.flush(); | |
| 108 | + fos.close(); | |
| 109 | + } | |
| 110 | + } catch (IOException e) { | |
| 111 | + Log.e(TAG, "create file error" + e); | |
| 112 | + } | |
| 113 | + } | |
| 114 | + | |
| 115 | + | |
| 116 | + /** | |
| 117 | + * 判断缓存文件是否存在 | |
| 118 | + */ | |
| 119 | + public static boolean isFileExist(String fileName, String type) { | |
| 120 | + if (isExternalStorageWritable()) { | |
| 121 | + File dir = CNLiveApplication.getContext().getExternalFilesDir(type); | |
| 122 | + if (dir != null) { | |
| 123 | + File f = new File(dir, fileName); | |
| 124 | + return f.exists(); | |
| 125 | + } | |
| 126 | + } | |
| 127 | + return false; | |
| 128 | + } | |
| 129 | + | |
| 130 | + | |
| 131 | + /** | |
| 132 | + * 将数据存储为文件 | |
| 133 | + * | |
| 134 | + * @param data 数据 | |
| 135 | + * @param fileName 文件名 | |
| 136 | + * @param type 文件类型 | |
| 137 | + */ | |
| 138 | + public static File createFile(byte[] data, String fileName, String type) { | |
| 139 | + if (isExternalStorageWritable()) { | |
| 140 | + File dir = CNLiveApplication.getContext().getExternalFilesDir(type); | |
| 141 | + if (dir != null) { | |
| 142 | + File f = new File(dir, fileName); | |
| 143 | + try { | |
| 144 | + if (f.createNewFile()) { | |
| 145 | + FileOutputStream fos = new FileOutputStream(f); | |
| 146 | + fos.write(data); | |
| 147 | + fos.flush(); | |
| 148 | + fos.close(); | |
| 149 | + return f; | |
| 150 | + } | |
| 151 | + } catch (IOException e) { | |
| 152 | + Log.e(TAG, "create file error" + e); | |
| 153 | + return null; | |
| 154 | + } | |
| 155 | + } | |
| 156 | + } | |
| 157 | + return null; | |
| 158 | + } | |
| 159 | + | |
| 160 | + | |
| 161 | + /** | |
| 162 | + * 从URI获取图片文件地址 | |
| 163 | + * | |
| 164 | + * @param context 上下文 | |
| 165 | + * @param uri 文件uri | |
| 166 | + */ | |
| 167 | + public static String getImageFilePath(Context context, Uri uri) { | |
| 168 | + if (uri == null) { | |
| 169 | + return null; | |
| 170 | + } | |
| 171 | + String path = null; | |
| 172 | + final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; | |
| 173 | + if (isKitKat) { | |
| 174 | + if (!isMediaDocument(uri)) { | |
| 175 | + try { | |
| 176 | + final String docId = DocumentsContract.getDocumentId(uri); | |
| 177 | + final String[] split = docId.split(":"); | |
| 178 | + Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; | |
| 179 | + final String selection = "_id=?"; | |
| 180 | + final String[] selectionArgs = new String[]{ | |
| 181 | + split[1] | |
| 182 | + }; | |
| 183 | + path = getDataColumn(context, contentUri, selection, selectionArgs); | |
| 184 | + } catch (IllegalArgumentException e) { | |
| 185 | + path = null; | |
| 186 | + } | |
| 187 | + } | |
| 188 | + } | |
| 189 | + if (path == null) { | |
| 190 | + String[] projection = {MediaStore.Images.Media.DATA}; | |
| 191 | + Cursor cursor = ((Activity) context).managedQuery(uri, projection, null, null, null); | |
| 192 | + if (cursor != null) { | |
| 193 | + int column_index = cursor | |
| 194 | + .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); | |
| 195 | + cursor.moveToFirst(); | |
| 196 | + return cursor.getString(column_index); | |
| 197 | + } | |
| 198 | + | |
| 199 | + path = null; | |
| 200 | + } | |
| 201 | + return path; | |
| 202 | + } | |
| 203 | + | |
| 204 | + | |
| 205 | + /** | |
| 206 | + * 从URI获取文件地址 | |
| 207 | + * | |
| 208 | + * @param context 上下文 | |
| 209 | + * @param uri 文件uri | |
| 210 | + */ | |
| 211 | + public static String getFilePath(Context context, Uri uri) { | |
| 212 | + final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; | |
| 213 | + // DocumentProvider | |
| 214 | + if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { | |
| 215 | + // ExternalStorageProvider | |
| 216 | + if (isExternalStorageDocument(uri)) { | |
| 217 | + final String docId = DocumentsContract.getDocumentId(uri); | |
| 218 | + final String[] split = docId.split(":"); | |
| 219 | + final String type = split[0]; | |
| 220 | + | |
| 221 | + if ("primary".equalsIgnoreCase(type)) { | |
| 222 | + return Environment.getExternalStorageDirectory() + "/" + split[1]; | |
| 223 | + } | |
| 224 | + | |
| 225 | + // TODO handle non-primary volumes | |
| 226 | + } | |
| 227 | + // DownloadsProvider | |
| 228 | + else if (isDownloadsDocument(uri)) { | |
| 229 | + | |
| 230 | + final String id = DocumentsContract.getDocumentId(uri); | |
| 231 | + final Uri contentUri = ContentUris.withAppendedId( | |
| 232 | + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); | |
| 233 | + | |
| 234 | + return getDataColumn(context, contentUri, null, null); | |
| 235 | + } | |
| 236 | + // MediaProvider | |
| 237 | + else if (isMediaDocument(uri)) { | |
| 238 | + final String docId = DocumentsContract.getDocumentId(uri); | |
| 239 | + final String[] split = docId.split(":"); | |
| 240 | + final String type = split[0]; | |
| 241 | + | |
| 242 | + Uri contentUri = null; | |
| 243 | + if ("image".equals(type)) { | |
| 244 | + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; | |
| 245 | + } else if ("video".equals(type)) { | |
| 246 | + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; | |
| 247 | + } else if ("audio".equals(type)) { | |
| 248 | + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; | |
| 249 | + } | |
| 250 | + | |
| 251 | + final String selection = "_id=?"; | |
| 252 | + final String[] selectionArgs = new String[]{ | |
| 253 | + split[1] | |
| 254 | + }; | |
| 255 | + | |
| 256 | + return getDataColumn(context, contentUri, selection, selectionArgs); | |
| 257 | + } | |
| 258 | + } | |
| 259 | + // MediaStore (and general) | |
| 260 | + else if ("content".equalsIgnoreCase(uri.getScheme())) { | |
| 261 | + return getDataColumn(context, uri, null, null); | |
| 262 | + } | |
| 263 | + // File | |
| 264 | + else if ("file".equalsIgnoreCase(uri.getScheme())) { | |
| 265 | + return uri.getPath(); | |
| 266 | + } | |
| 267 | + | |
| 268 | + return null; | |
| 269 | + } | |
| 270 | + | |
| 271 | + | |
| 272 | + /** | |
| 273 | + * Get the value of the data column for this Uri. This is useful for | |
| 274 | + * MediaStore Uris, and other file-based ContentProviders. | |
| 275 | + * | |
| 276 | + * @param context The context. | |
| 277 | + * @param uri The Uri to query. | |
| 278 | + * @param selection (Optional) Filter used in the query. | |
| 279 | + * @param selectionArgs (Optional) Selection arguments used in the query. | |
| 280 | + * @return The value of the _data column, which is typically a file path. | |
| 281 | + */ | |
| 282 | + private static String getDataColumn(Context context, Uri uri, String selection, | |
| 283 | + String[] selectionArgs) { | |
| 284 | + Cursor cursor = null; | |
| 285 | + final String column = "_data"; | |
| 286 | + final String[] projection = {column}; | |
| 287 | + try { | |
| 288 | + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); | |
| 289 | + if (cursor != null && cursor.moveToFirst()) { | |
| 290 | + final int index = cursor.getColumnIndexOrThrow(column); | |
| 291 | + return cursor.getString(index); | |
| 292 | + } | |
| 293 | + } finally { | |
| 294 | + if (cursor != null) | |
| 295 | + cursor.close(); | |
| 296 | + } | |
| 297 | + return null; | |
| 298 | + } | |
| 299 | + | |
| 300 | + | |
| 301 | + /** | |
| 302 | + * 判断外部存储是否可用 | |
| 303 | + */ | |
| 304 | + public static boolean isExternalStorageWritable() { | |
| 305 | + String state = Environment.getExternalStorageState(); | |
| 306 | + if (Environment.MEDIA_MOUNTED.equals(state)) { | |
| 307 | + return true; | |
| 308 | + } | |
| 309 | + Log.e(TAG, "ExternalStorage not mounted"); | |
| 310 | + return false; | |
| 311 | + } | |
| 312 | + | |
| 313 | + public static boolean isMediaDocument(Uri uri) { | |
| 314 | + return "com.android.providers.media.documents".equals(uri.getAuthority()); | |
| 315 | + } | |
| 316 | + | |
| 317 | + public static boolean isExternalStorageDocument(Uri uri) { | |
| 318 | + return "com.android.externalstorage.documents".equals(uri.getAuthority()); | |
| 319 | + } | |
| 320 | + | |
| 321 | + /** | |
| 322 | + * @param uri The Uri to check. | |
| 323 | + * @return Whether the Uri authority is DownloadsProvider. | |
| 324 | + */ | |
| 325 | + public static boolean isDownloadsDocument(Uri uri) { | |
| 326 | + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); | |
| 327 | + } | |
| 328 | + | |
| 329 | + | |
| 330 | + public enum FileType { | |
| 331 | + IMG, | |
| 332 | + AUDIO, | |
| 333 | + VIDEO, | |
| 334 | + FILE, | |
| 335 | + } | |
| 336 | + | |
| 337 | + | |
| 338 | +} | ... | ... |
app/src/main/java/com/cnlive/im/util/MediaUtil.java
0 → 100644
| 1 | +package com.cnlive.im.util; | |
| 2 | + | |
| 3 | +import android.media.MediaPlayer; | |
| 4 | +import android.net.Uri; | |
| 5 | +import android.util.Log; | |
| 6 | + | |
| 7 | +import com.cnlive.im.CNLiveApplication; | |
| 8 | + | |
| 9 | +import java.io.FileInputStream; | |
| 10 | +import java.io.IOException; | |
| 11 | + | |
| 12 | +/** | |
| 13 | + * 媒体播放工具 | |
| 14 | + */ | |
| 15 | +public class MediaUtil { | |
| 16 | + | |
| 17 | + private static final String TAG = "MediaUtil"; | |
| 18 | + | |
| 19 | + private MediaPlayer player; | |
| 20 | + private EventListener eventListener; | |
| 21 | + | |
| 22 | + private MediaUtil() { | |
| 23 | + player = new MediaPlayer(); | |
| 24 | + } | |
| 25 | + | |
| 26 | + private static MediaUtil instance = new MediaUtil(); | |
| 27 | + | |
| 28 | + public static MediaUtil getInstance() { | |
| 29 | + return instance; | |
| 30 | + } | |
| 31 | + | |
| 32 | + public MediaPlayer getPlayer() { | |
| 33 | + return player; | |
| 34 | + } | |
| 35 | + | |
| 36 | + | |
| 37 | + public void setEventListener(final EventListener eventListener) { | |
| 38 | + if (player != null) { | |
| 39 | + player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { | |
| 40 | + @Override | |
| 41 | + public void onCompletion(MediaPlayer mp) { | |
| 42 | + eventListener.onStop(); | |
| 43 | + } | |
| 44 | + }); | |
| 45 | + } | |
| 46 | + this.eventListener = eventListener; | |
| 47 | + } | |
| 48 | + | |
| 49 | + public void play(FileInputStream inputStream) { | |
| 50 | + try { | |
| 51 | + if (eventListener != null) { | |
| 52 | + eventListener.onStop(); | |
| 53 | + } | |
| 54 | + player.reset(); | |
| 55 | + player.setDataSource(inputStream.getFD()); | |
| 56 | + player.prepare(); | |
| 57 | + player.start(); | |
| 58 | + } catch (IOException e) { | |
| 59 | + Log.e(TAG, "play error:" + e); | |
| 60 | + } | |
| 61 | + | |
| 62 | + | |
| 63 | + } | |
| 64 | + | |
| 65 | + | |
| 66 | + public void stop() { | |
| 67 | + if (player != null && player.isPlaying()) { | |
| 68 | + player.stop(); | |
| 69 | + } | |
| 70 | + } | |
| 71 | + | |
| 72 | + public long getDuration(String path) { | |
| 73 | + player = MediaPlayer.create(CNLiveApplication.getContext(), Uri.parse(path)); | |
| 74 | + return player.getDuration(); | |
| 75 | + } | |
| 76 | + | |
| 77 | + | |
| 78 | + /** | |
| 79 | + * 播放器事件监听 | |
| 80 | + */ | |
| 81 | + public interface EventListener { | |
| 82 | + void onStop(); | |
| 83 | + } | |
| 84 | +} | ... | ... |
app/src/main/java/com/cnlive/im/util/MessageType.java
app/src/main/java/com/cnlive/im/util/PlayerUtil.java deleted
100644 → 0
| 1 | -package com.cnlive.im.util; | |
| 2 | - | |
| 3 | -import android.content.Context; | |
| 4 | -import android.media.MediaPlayer; | |
| 5 | -import android.net.Uri; | |
| 6 | - | |
| 7 | -/** | |
| 8 | - * Created by Lynn on 2017/7/21. | |
| 9 | - */ | |
| 10 | - | |
| 11 | -public class PlayerUtil implements IVoiceManager{ | |
| 12 | - private final String TAG = "PlayerUtil"; | |
| 13 | - private String path; | |
| 14 | - private Context mContext; | |
| 15 | - | |
| 16 | - private MediaPlayer mediaPlayer; | |
| 17 | - | |
| 18 | - public PlayerUtil(Context context){ | |
| 19 | - this.mContext = context; | |
| 20 | -// mediaPlayer = new MediaPlayer(); | |
| 21 | -// mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { | |
| 22 | -// @Override | |
| 23 | -// public void onCompletion(MediaPlayer mediaPlayer) { | |
| 24 | -//// mediaPlayer.stop(); | |
| 25 | -// stop(); | |
| 26 | -// } | |
| 27 | -// }); | |
| 28 | - } | |
| 29 | - | |
| 30 | - @Override | |
| 31 | - public boolean start(Uri uri) { | |
| 32 | - try { | |
| 33 | - mediaPlayer = new MediaPlayer(); | |
| 34 | - mediaPlayer.setOnCompletionListener(onCompletionListener); | |
| 35 | - mediaPlayer.setOnPreparedListener(onPreparedListener); | |
| 36 | - mediaPlayer.setDataSource(mContext, uri); | |
| 37 | - mediaPlayer.prepare(); | |
| 38 | -// mediaPlayer.start(); | |
| 39 | - }catch (Exception e){ | |
| 40 | - e.printStackTrace(); | |
| 41 | - } | |
| 42 | - return false; | |
| 43 | - } | |
| 44 | - | |
| 45 | - @Override | |
| 46 | - public boolean stop() { | |
| 47 | - mediaPlayer.stop(); | |
| 48 | - mediaPlayer.release(); | |
| 49 | - mediaPlayer = null; | |
| 50 | - return false; | |
| 51 | - } | |
| 52 | - | |
| 53 | - @Override | |
| 54 | - public void onDestory() { | |
| 55 | - mediaPlayer.release(); | |
| 56 | - mediaPlayer = null; | |
| 57 | - } | |
| 58 | - | |
| 59 | - private MediaPlayer.OnCompletionListener onCompletionListener = new MediaPlayer.OnCompletionListener() { | |
| 60 | - @Override | |
| 61 | - public void onCompletion(MediaPlayer mediaPlayer) { | |
| 62 | - stop(); | |
| 63 | - } | |
| 64 | - }; | |
| 65 | - | |
| 66 | - private MediaPlayer.OnPreparedListener onPreparedListener = new MediaPlayer.OnPreparedListener() { | |
| 67 | - @Override | |
| 68 | - public void onPrepared(MediaPlayer mediaPlayer) { | |
| 69 | - mediaPlayer.start(); | |
| 70 | - } | |
| 71 | - }; | |
| 72 | -} |
app/src/main/jniLibs/arm64-v8a/libBugly.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/arm64-v8a/lib_imcore_group_ext_gyp.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/arm64-v8a/lib_imcore_jni_gyp.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/arm64-v8a/lib_imcore_msg_ext_gyp.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/arm64-v8a/lib_imcore_sns_ext_gyp.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/arm64-v8a/lib_imcore_ugc_ext_gyp.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/arm64-v8a/libgnustl_shared.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/arm64-v8a/libqalcodecwrapper.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/arm64-v8a/libqalmsfboot.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/arm64-v8a/libwtcrypto.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/armeabi-v7a/libBugly.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/armeabi-v7a/lib_imcore_group_ext_gyp.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/armeabi-v7a/lib_imcore_jni_gyp.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/armeabi-v7a/lib_imcore_msg_ext_gyp.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/armeabi-v7a/lib_imcore_sns_ext_gyp.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/armeabi-v7a/lib_imcore_ugc_ext_gyp.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/armeabi-v7a/libgnustl_shared.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/armeabi-v7a/libqalcodecwrapper.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/armeabi-v7a/libqalmsfboot.so
0 → 100644
No preview for this file type
app/src/main/jniLibs/armeabi-v7a/libwtcrypto.so
0 → 100644
No preview for this file type
app/src/main/res/drawable/left_voice.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<animation-list | |
| 3 | + android:oneshot="false" | |
| 4 | + xmlns:android="http://schemas.android.com/apk/res/android"> | |
| 5 | + <item android:drawable="@drawable/left_voice3" android:duration="200" /> | |
| 6 | + <item android:drawable="@drawable/left_voice1" android:duration="200" /> | |
| 7 | + <item android:drawable="@drawable/left_voice2" android:duration="200" /> | |
| 8 | + <item android:drawable="@drawable/left_voice3" android:duration="200" /> | |
| 9 | +</animation-list> | |
| 0 | 10 | \ No newline at end of file | ... | ... |
app/src/main/res/drawable/left_voice1.png
0 → 100644
1.05 KB
app/src/main/res/drawable/left_voice2.png
0 → 100644
1.31 KB
app/src/main/res/drawable/left_voice3.png
0 → 100644
1.58 KB
app/src/main/res/drawable/right_voice.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<animation-list | |
| 3 | + android:oneshot="false" | |
| 4 | + xmlns:android="http://schemas.android.com/apk/res/android"> | |
| 5 | + <item android:drawable="@drawable/right_voice3" android:duration="200" /> | |
| 6 | + <item android:drawable="@drawable/right_voice1" android:duration="200" /> | |
| 7 | + <item android:drawable="@drawable/right_voice2" android:duration="200" /> | |
| 8 | + <item android:drawable="@drawable/right_voice3" android:duration="200" /> | |
| 9 | +</animation-list> | |
| 0 | 10 | \ No newline at end of file | ... | ... |
app/src/main/res/drawable/right_voice1.png
0 → 100644
1.05 KB
app/src/main/res/drawable/right_voice2.png
0 → 100644
1.28 KB
app/src/main/res/drawable/right_voice3.png
0 → 100644
1.42 KB
app/src/main/res/drawable/voice_none_read.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | + | |
| 3 | +<shape xmlns:android="http://schemas.android.com/apk/res/android" | |
| 4 | + android:shape="oval"> | |
| 5 | + <solid android:color="#ff0000" /> | |
| 6 | + <corners android:radius="10dp"/> | |
| 7 | + <stroke | |
| 8 | + android:width="1dp" | |
| 9 | + android:color="#8a8a8a" /> | |
| 10 | +</shape> | |
| 0 | 11 | \ No newline at end of file | ... | ... |
app/src/main/res/layout/activity_groupchat.xml
| ... | ... | @@ -117,6 +117,18 @@ |
| 117 | 117 | android:layout_height="wrap_content" |
| 118 | 118 | android:text="退出" /> |
| 119 | 119 | |
| 120 | + <Button | |
| 121 | + android:id="@+id/videoBtn" | |
| 122 | + android:layout_width="wrap_content" | |
| 123 | + android:layout_height="wrap_content" | |
| 124 | + android:text="视频文件"/> | |
| 125 | + | |
| 126 | + <Button | |
| 127 | + android:id="@+id/ugcVideoBtn" | |
| 128 | + android:layout_width="wrap_content" | |
| 129 | + android:layout_height="wrap_content" | |
| 130 | + android:text="短视频"/> | |
| 131 | + | |
| 120 | 132 | </LinearLayout> |
| 121 | 133 | |
| 122 | 134 | </LinearLayout> | ... | ... |
app/src/main/res/layout/activity_image_view.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
| 3 | + android:layout_width="match_parent" | |
| 4 | + android:layout_height="match_parent" | |
| 5 | + android:background="@android:color/black" | |
| 6 | + android:orientation="vertical"> | |
| 7 | + | |
| 8 | + <ImageView | |
| 9 | + android:id="@+id/image" | |
| 10 | + android:layout_width="match_parent" | |
| 11 | + android:layout_height="match_parent" | |
| 12 | + android:scaleType="centerInside" /> | |
| 13 | + | |
| 14 | +</LinearLayout> | |
| 0 | 15 | \ No newline at end of file | ... | ... |
app/src/main/res/layout/activity_play.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
| 3 | + android:layout_width="match_parent" | |
| 4 | + android:layout_height="match_parent" | |
| 5 | + android:orientation="vertical" | |
| 6 | + android:gravity="center"> | |
| 7 | + | |
| 8 | + <VideoView | |
| 9 | + android:id="@+id/video" | |
| 10 | + android:layout_width="match_parent" | |
| 11 | + android:layout_height="match_parent" /> | |
| 12 | + | |
| 13 | +</LinearLayout> | |
| 0 | 14 | \ No newline at end of file | ... | ... |
app/src/main/res/layout/activity_private_chat.xml
| ... | ... | @@ -36,6 +36,18 @@ |
| 36 | 36 | android:layout_height="wrap_content" |
| 37 | 37 | android:text="邀请对方聊天" /> |
| 38 | 38 | |
| 39 | + <Button | |
| 40 | + android:id="@+id/videoBtn" | |
| 41 | + android:layout_width="wrap_content" | |
| 42 | + android:layout_height="wrap_content" | |
| 43 | + android:text="视频文件"/> | |
| 44 | + | |
| 45 | + <Button | |
| 46 | + android:id="@+id/ugcVideoBtn" | |
| 47 | + android:layout_width="wrap_content" | |
| 48 | + android:layout_height="wrap_content" | |
| 49 | + android:text="短视频"/> | |
| 50 | + | |
| 39 | 51 | |
| 40 | 52 | <LinearLayout |
| 41 | 53 | android:id="@+id/edit_layout_se" | ... | ... |
app/src/main/res/layout/imag_layout_item_oppsite.xml
| ... | ... | @@ -17,15 +17,15 @@ |
| 17 | 17 | android:layout_height="wrap_content" |
| 18 | 18 | android:layout_alignParentLeft="true" |
| 19 | 19 | android:layout_centerVertical="true" |
| 20 | - android:text="游客" /> | |
| 20 | + android:text="游客" | |
| 21 | + android:textColor="#d61d0c" /> | |
| 21 | 22 | |
| 22 | 23 | <ImageView |
| 23 | 24 | android:id="@+id/img_content" |
| 24 | 25 | android:layout_width="40dp" |
| 25 | 26 | android:layout_height="40dp" |
| 26 | 27 | android:layout_marginLeft="5dp" |
| 27 | - android:layout_toRightOf="@+id/img_user_name" | |
| 28 | - android:src="@drawable/vod_detail_good_on" /> | |
| 28 | + android:layout_toRightOf="@+id/img_user_name"/> | |
| 29 | 29 | |
| 30 | 30 | </RelativeLayout> |
| 31 | 31 | ... | ... |
app/src/main/res/layout/imag_layout_item_user.xml
| 1 | 1 | <?xml version="1.0" encoding="utf-8"?> |
| 2 | -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
| 2 | +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
| 3 | 3 | android:layout_width="match_parent" |
| 4 | 4 | android:layout_height="match_parent" |
| 5 | 5 | android:orientation="vertical" |
| 6 | 6 | android:paddingBottom="10dp" |
| 7 | 7 | android:paddingTop="10dp"> |
| 8 | 8 | |
| 9 | - <RelativeLayout | |
| 9 | + <LinearLayout | |
| 10 | 10 | android:layout_width="wrap_content" |
| 11 | - android:layout_height="wrap_content"> | |
| 11 | + android:layout_height="wrap_content" | |
| 12 | + android:layout_alignParentRight="true" | |
| 13 | + android:orientation="horizontal"> | |
| 12 | 14 | |
| 13 | 15 | <TextView |
| 14 | - android:layout_centerVertical="true" | |
| 15 | - android:id="@+id/img_user_name" | |
| 16 | + android:id="@+id/status" | |
| 16 | 17 | android:layout_width="wrap_content" |
| 17 | 18 | android:layout_height="wrap_content" |
| 18 | - android:layout_alignParentRight="true" | |
| 19 | - android:text="游客" /> | |
| 19 | + android:layout_gravity="center_vertical" | |
| 20 | + android:layout_marginRight="5dp" | |
| 21 | + android:gravity="right" | |
| 22 | + android:textColor="@android:color/holo_blue_light" /> | |
| 20 | 23 | |
| 21 | 24 | <ImageView |
| 22 | - android:layout_toLeftOf="@+id/img_user_name" | |
| 23 | - android:layout_marginRight="5dp" | |
| 24 | 25 | android:id="@+id/img_content" |
| 25 | 26 | android:layout_width="40dp" |
| 26 | 27 | android:layout_height="40dp" |
| 27 | - android:src="@drawable/vod_detail_good_on"/> | |
| 28 | + android:layout_marginRight="5dp" /> | |
| 29 | + | |
| 30 | + <TextView | |
| 31 | + android:id="@+id/img_user_name" | |
| 32 | + android:layout_width="wrap_content" | |
| 33 | + android:layout_height="wrap_content" | |
| 34 | + android:layout_gravity="center_vertical" | |
| 35 | + android:text="游客" | |
| 36 | + android:textColor="#d61d0c"/> | |
| 28 | 37 | |
| 29 | - </RelativeLayout> | |
| 38 | + </LinearLayout> | |
| 30 | 39 | |
| 31 | -</LinearLayout> | |
| 32 | 40 | \ No newline at end of file |
| 41 | +</RelativeLayout> | |
| 33 | 42 | \ No newline at end of file | ... | ... |
app/src/main/res/layout/string_layout_item_oppsite.xml
| ... | ... | @@ -3,8 +3,8 @@ |
| 3 | 3 | android:layout_width="wrap_content" |
| 4 | 4 | android:layout_height="wrap_content" |
| 5 | 5 | android:orientation="vertical" |
| 6 | - android:paddingTop="10dp" | |
| 7 | - android:paddingBottom="10dp"> | |
| 6 | + android:paddingBottom="10dp" | |
| 7 | + android:paddingTop="10dp"> | |
| 8 | 8 | |
| 9 | 9 | <RelativeLayout |
| 10 | 10 | android:id="@+id/re_chat_room" |
| ... | ... | @@ -24,11 +24,12 @@ |
| 24 | 24 | android:id="@+id/msg_text" |
| 25 | 25 | android:layout_width="wrap_content" |
| 26 | 26 | android:layout_height="wrap_content" |
| 27 | + android:layout_marginLeft="5dp" | |
| 27 | 28 | android:layout_toRightOf="@id/user_name" |
| 28 | 29 | android:text="vfgfgf" |
| 29 | 30 | android:textColor="@android:color/black" |
| 30 | - android:textSize="15sp" | |
| 31 | - android:layout_marginLeft="5dp"/> | |
| 31 | + android:textSize="15sp" /> | |
| 32 | + | |
| 32 | 33 | </RelativeLayout> |
| 33 | 34 | |
| 34 | 35 | </RelativeLayout> |
| 35 | 36 | \ No newline at end of file | ... | ... |
app/src/main/res/layout/string_layout_item_user.xml
| ... | ... | @@ -5,31 +5,43 @@ |
| 5 | 5 | android:paddingBottom="10dp" |
| 6 | 6 | android:paddingTop="10dp"> |
| 7 | 7 | |
| 8 | - <RelativeLayout | |
| 8 | + <LinearLayout | |
| 9 | 9 | android:id="@+id/re_chat_room" |
| 10 | 10 | android:layout_width="wrap_content" |
| 11 | - android:layout_height="wrap_content"> | |
| 11 | + android:layout_height="wrap_content" | |
| 12 | + android:layout_alignParentRight="true" | |
| 13 | + android:orientation="horizontal"> | |
| 12 | 14 | |
| 13 | 15 | <TextView |
| 14 | - android:id="@+id/user_name" | |
| 16 | + android:id="@+id/status" | |
| 15 | 17 | android:layout_width="wrap_content" |
| 16 | 18 | android:layout_height="wrap_content" |
| 17 | - android:layout_alignParentRight="true" | |
| 18 | - android:gravity="center_vertical" | |
| 19 | - android:text="ddd" | |
| 20 | - android:textColor="#d61d0c" | |
| 21 | - android:textSize="14sp" /> | |
| 19 | + android:layout_gravity="center_vertical" | |
| 20 | + android:layout_marginRight="5dp" | |
| 21 | + android:gravity="right" | |
| 22 | + android:textColor="@android:color/holo_blue_light" /> | |
| 22 | 23 | |
| 23 | 24 | <TextView |
| 24 | 25 | android:id="@+id/msg_text" |
| 25 | 26 | android:layout_width="wrap_content" |
| 26 | 27 | android:layout_height="wrap_content" |
| 27 | - android:layout_toLeftOf="@id/user_name" | |
| 28 | + | |
| 29 | + android:layout_marginRight="5dp" | |
| 28 | 30 | android:text="vfgfgf" |
| 29 | 31 | android:textColor="@android:color/black" |
| 30 | - android:textSize="15sp" | |
| 31 | - android:layout_marginRight="5dp"/> | |
| 32 | - </RelativeLayout> | |
| 32 | + android:textSize="15sp" /> | |
| 33 | + | |
| 34 | + <TextView | |
| 35 | + android:id="@+id/user_name" | |
| 36 | + android:layout_width="wrap_content" | |
| 37 | + android:layout_height="wrap_content" | |
| 38 | + android:layout_gravity="right" | |
| 39 | + android:gravity="center_vertical" | |
| 40 | + android:text="ddd" | |
| 41 | + android:textColor="#d61d0c" | |
| 42 | + android:textSize="14sp" /> | |
| 43 | + | |
| 44 | + </LinearLayout> | |
| 33 | 45 | |
| 34 | 46 | |
| 35 | 47 | </RelativeLayout> |
| 36 | 48 | \ No newline at end of file | ... | ... |
app/src/main/res/layout/video_layout_item_oppsite.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
| 3 | + android:layout_width="match_parent" | |
| 4 | + android:layout_height="match_parent" | |
| 5 | + android:orientation="vertical" | |
| 6 | + android:paddingBottom="10dp" | |
| 7 | + android:paddingTop="10dp"> | |
| 8 | + | |
| 9 | + | |
| 10 | + <RelativeLayout | |
| 11 | + android:layout_width="wrap_content" | |
| 12 | + android:layout_height="wrap_content"> | |
| 13 | + | |
| 14 | + <TextView | |
| 15 | + android:id="@+id/user_name" | |
| 16 | + android:layout_width="wrap_content" | |
| 17 | + android:layout_height="wrap_content" | |
| 18 | + android:layout_alignParentLeft="true" | |
| 19 | + android:layout_centerVertical="true" | |
| 20 | + android:layout_margin="5dp" | |
| 21 | + android:text="游客" | |
| 22 | + android:textColor="#d61d0c" /> | |
| 23 | + | |
| 24 | + <RelativeLayout | |
| 25 | + android:id="@+id/videoLayout" | |
| 26 | + android:layout_width="100dp" | |
| 27 | + android:layout_height="150dp" | |
| 28 | + android:layout_toRightOf="@+id/user_name"> | |
| 29 | + | |
| 30 | + <ImageView | |
| 31 | + android:id="@+id/img_content" | |
| 32 | + android:layout_width="100dp" | |
| 33 | + android:layout_height="150dp" | |
| 34 | + android:layout_marginLeft="5dp" | |
| 35 | + android:scaleType="centerInside" | |
| 36 | + android:src="@drawable/vod_detail_good_on" /> | |
| 37 | + | |
| 38 | + <ImageView | |
| 39 | + android:layout_width="30dp" | |
| 40 | + android:layout_height="30dp" | |
| 41 | + android:layout_centerInParent="true" | |
| 42 | + android:src="@android:drawable/ic_media_play" /> | |
| 43 | + | |
| 44 | + </RelativeLayout> | |
| 45 | + | |
| 46 | + </RelativeLayout> | |
| 47 | + | |
| 48 | +</LinearLayout> | |
| 0 | 49 | \ No newline at end of file | ... | ... |
app/src/main/res/layout/video_layout_item_user.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
| 3 | + android:layout_width="match_parent" | |
| 4 | + android:layout_height="match_parent" | |
| 5 | + android:orientation="vertical" | |
| 6 | + android:paddingBottom="10dp" | |
| 7 | + android:paddingTop="10dp"> | |
| 8 | + | |
| 9 | + <LinearLayout | |
| 10 | + android:layout_width="wrap_content" | |
| 11 | + android:layout_height="wrap_content" | |
| 12 | + android:orientation="horizontal" | |
| 13 | + android:layout_alignParentRight="true"> | |
| 14 | + | |
| 15 | + <TextView | |
| 16 | + android:id="@+id/status" | |
| 17 | + android:layout_width="wrap_content" | |
| 18 | + android:layout_height="wrap_content" | |
| 19 | + android:layout_gravity="center_vertical" | |
| 20 | + android:layout_marginRight="5dp" | |
| 21 | + android:gravity="right" | |
| 22 | + android:textColor="@android:color/holo_blue_light" /> | |
| 23 | + | |
| 24 | + <RelativeLayout | |
| 25 | + android:id="@+id/videoLayout" | |
| 26 | + android:layout_width="100dp" | |
| 27 | + android:layout_height="150dp" | |
| 28 | + android:layout_toLeftOf="@+id/user_name"> | |
| 29 | + | |
| 30 | + <ImageView | |
| 31 | + android:id="@+id/img_content" | |
| 32 | + android:layout_width="100dp" | |
| 33 | + android:layout_height="150dp" | |
| 34 | + android:layout_marginRight="5dp" | |
| 35 | + android:scaleType="centerInside" | |
| 36 | + android:src="@drawable/vod_detail_good_on" /> | |
| 37 | + | |
| 38 | + <ImageView | |
| 39 | + android:layout_width="30dp" | |
| 40 | + android:layout_height="30dp" | |
| 41 | + android:layout_centerInParent="true" | |
| 42 | + android:src="@android:drawable/ic_media_play" /> | |
| 43 | + | |
| 44 | + </RelativeLayout> | |
| 45 | + | |
| 46 | + <TextView | |
| 47 | + android:id="@+id/user_name" | |
| 48 | + android:layout_width="wrap_content" | |
| 49 | + android:layout_height="wrap_content" | |
| 50 | + android:layout_gravity="center_vertical" | |
| 51 | + android:layout_margin="5dp" | |
| 52 | + android:text="游客" | |
| 53 | + android:textColor="#d61d0c" /> | |
| 54 | + | |
| 55 | + </LinearLayout> | |
| 56 | + | |
| 57 | +</RelativeLayout> | |
| 0 | 58 | \ No newline at end of file | ... | ... |
app/src/main/res/layout/voice_layout_item_oppsite.xml
| ... | ... | @@ -16,15 +16,26 @@ |
| 16 | 16 | android:layout_height="wrap_content" |
| 17 | 17 | android:layout_alignParentLeft="true" |
| 18 | 18 | android:layout_centerVertical="true" |
| 19 | - android:text="游客" /> | |
| 19 | + android:text="游客" | |
| 20 | + android:textColor="#d61d0c" /> | |
| 20 | 21 | |
| 21 | - <TextView | |
| 22 | + <RelativeLayout | |
| 22 | 23 | android:id="@+id/voice_content" |
| 23 | - android:layout_width="wrap_content" | |
| 24 | - android:layout_height="50dp" | |
| 24 | + android:layout_width="71dp" | |
| 25 | + android:layout_height="48dp" | |
| 26 | + android:layout_marginLeft="5dp" | |
| 25 | 27 | android:layout_toRightOf="@+id/voice_user_name" |
| 26 | - android:background="@drawable/voice_bg_left" | |
| 27 | - android:layout_marginLeft="5dp"/> | |
| 28 | + android:background="@drawable/voice_bg_left"> | |
| 29 | + | |
| 30 | + <ImageView | |
| 31 | + android:id="@+id/voiceAnim" | |
| 32 | + android:layout_width="11dp" | |
| 33 | + android:layout_height="17dp" | |
| 34 | + android:layout_centerVertical="true" | |
| 35 | + android:layout_marginLeft="10dp" | |
| 36 | + android:background="@drawable/left_voice" /> | |
| 37 | + | |
| 38 | + </RelativeLayout> | |
| 28 | 39 | |
| 29 | 40 | <TextView |
| 30 | 41 | android:id="@+id/voice_duration" |
| ... | ... | @@ -33,6 +44,15 @@ |
| 33 | 44 | android:layout_centerVertical="true" |
| 34 | 45 | android:layout_toRightOf="@id/voice_content" /> |
| 35 | 46 | |
| 47 | + <View | |
| 48 | + android:id="@+id/noneRead" | |
| 49 | + android:layout_width="10dp" | |
| 50 | + android:layout_height="10dp" | |
| 51 | + android:layout_centerVertical="true" | |
| 52 | + android:layout_marginLeft="2dp" | |
| 53 | + android:layout_toRightOf="@+id/voice_duration" | |
| 54 | + android:background="@drawable/voice_none_read" /> | |
| 55 | + | |
| 36 | 56 | |
| 37 | 57 | </RelativeLayout> |
| 38 | 58 | ... | ... |
app/src/main/res/layout/voice_layout_item_user.xml
| ... | ... | @@ -5,33 +5,52 @@ |
| 5 | 5 | android:paddingBottom="10dp" |
| 6 | 6 | android:paddingTop="10dp"> |
| 7 | 7 | |
| 8 | - <RelativeLayout | |
| 8 | + <LinearLayout | |
| 9 | 9 | android:layout_width="wrap_content" |
| 10 | - android:layout_height="wrap_content"> | |
| 10 | + android:layout_height="wrap_content" | |
| 11 | + android:layout_alignParentRight="true"> | |
| 11 | 12 | |
| 12 | 13 | <TextView |
| 13 | - android:id="@+id/voice_user_name" | |
| 14 | + android:id="@+id/status" | |
| 14 | 15 | android:layout_width="wrap_content" |
| 15 | 16 | android:layout_height="wrap_content" |
| 16 | - android:layout_alignParentRight="true" | |
| 17 | - android:layout_centerVertical="true" | |
| 18 | - android:text="游客" /> | |
| 17 | + android:layout_gravity="center_vertical" | |
| 18 | + android:layout_marginRight="5dp" | |
| 19 | + android:gravity="right" | |
| 20 | + android:textColor="@android:color/holo_blue_light" /> | |
| 19 | 21 | |
| 20 | 22 | <TextView |
| 21 | - android:id="@+id/voice_content" | |
| 23 | + android:id="@+id/voice_duration" | |
| 22 | 24 | android:layout_width="wrap_content" |
| 23 | - android:layout_height="50dp" | |
| 24 | - android:layout_toLeftOf="@+id/voice_user_name" | |
| 25 | - android:background="@drawable/voice_bg_right" | |
| 26 | - android:layout_marginRight="5dp"/> | |
| 25 | + android:layout_height="wrap_content" | |
| 26 | + android:layout_gravity="center_vertical" /> | |
| 27 | + | |
| 28 | + <RelativeLayout | |
| 29 | + android:id="@+id/voice_content" | |
| 30 | + android:layout_width="71dp" | |
| 31 | + android:layout_height="48dp" | |
| 32 | + android:layout_marginRight="5dp" | |
| 33 | + android:background="@drawable/voice_bg_right"> | |
| 34 | + | |
| 35 | + <ImageView | |
| 36 | + android:id="@+id/voiceAnim" | |
| 37 | + android:layout_width="11dp" | |
| 38 | + android:layout_height="17dp" | |
| 39 | + android:layout_alignParentRight="true" | |
| 40 | + android:layout_centerVertical="true" | |
| 41 | + android:layout_marginRight="10dp" | |
| 42 | + android:background="@drawable/right_voice" /> | |
| 43 | + | |
| 44 | + </RelativeLayout> | |
| 27 | 45 | |
| 28 | 46 | <TextView |
| 29 | - android:id="@+id/voice_duration" | |
| 47 | + android:id="@+id/voice_user_name" | |
| 30 | 48 | android:layout_width="wrap_content" |
| 31 | 49 | android:layout_height="wrap_content" |
| 32 | - android:layout_centerVertical="true" | |
| 33 | - android:layout_toLeftOf="@id/voice_content" /> | |
| 50 | + android:layout_gravity="center_vertical" | |
| 51 | + android:text="游客" | |
| 52 | + android:textColor="#d61d0c" /> | |
| 34 | 53 | |
| 35 | - </RelativeLayout> | |
| 54 | + </LinearLayout> | |
| 36 | 55 | |
| 37 | 56 | </RelativeLayout> |
| 38 | 57 | \ No newline at end of file | ... | ... |