Browse Source

完成基础聊天功能

Junqin Wang 8 years ago
parent
commit
c86365fe1a
100 changed files with 1227 additions and 2 deletions
  1. 3 0
      .gitignore
  2. 0 2
      README.md
  3. 496 0
      app/AndroidManifest.xml
  4. 307 0
      app/README.md
  5. BIN
      app/aars/HMS-SDK-2.4.0.300.aar
  6. 150 0
      app/app.iml
  7. 199 0
      app/assets/js/page.html
  8. 72 0
      app/assets/js/page.js
  9. BIN
      app/assets/sticker/ajmd/ajmd001.png
  10. BIN
      app/assets/sticker/ajmd/ajmd002.png
  11. BIN
      app/assets/sticker/ajmd/ajmd003.png
  12. BIN
      app/assets/sticker/ajmd/ajmd004.png
  13. BIN
      app/assets/sticker/ajmd/ajmd005.png
  14. BIN
      app/assets/sticker/ajmd/ajmd006.png
  15. BIN
      app/assets/sticker/ajmd/ajmd007.png
  16. BIN
      app/assets/sticker/ajmd/ajmd008.png
  17. BIN
      app/assets/sticker/ajmd/ajmd009.png
  18. BIN
      app/assets/sticker/ajmd/ajmd010.png
  19. BIN
      app/assets/sticker/ajmd/ajmd011.png
  20. BIN
      app/assets/sticker/ajmd/ajmd012.png
  21. BIN
      app/assets/sticker/ajmd/ajmd013.png
  22. BIN
      app/assets/sticker/ajmd/ajmd014.png
  23. BIN
      app/assets/sticker/ajmd/ajmd015.png
  24. BIN
      app/assets/sticker/ajmd/ajmd016.png
  25. BIN
      app/assets/sticker/ajmd/ajmd017.png
  26. BIN
      app/assets/sticker/ajmd/ajmd018.png
  27. BIN
      app/assets/sticker/ajmd/ajmd019.png
  28. BIN
      app/assets/sticker/ajmd/ajmd020.png
  29. BIN
      app/assets/sticker/ajmd/ajmd021.png
  30. BIN
      app/assets/sticker/ajmd/ajmd022.png
  31. BIN
      app/assets/sticker/ajmd/ajmd023.png
  32. BIN
      app/assets/sticker/ajmd/ajmd024.png
  33. BIN
      app/assets/sticker/ajmd/ajmd025.png
  34. BIN
      app/assets/sticker/ajmd/ajmd026.png
  35. BIN
      app/assets/sticker/ajmd/ajmd027.png
  36. BIN
      app/assets/sticker/ajmd/ajmd028.png
  37. BIN
      app/assets/sticker/ajmd/ajmd029.png
  38. BIN
      app/assets/sticker/ajmd/ajmd030.png
  39. BIN
      app/assets/sticker/ajmd/ajmd031.png
  40. BIN
      app/assets/sticker/ajmd/ajmd032.png
  41. BIN
      app/assets/sticker/ajmd/ajmd033.png
  42. BIN
      app/assets/sticker/ajmd/ajmd034.png
  43. BIN
      app/assets/sticker/ajmd/ajmd035.png
  44. BIN
      app/assets/sticker/ajmd/ajmd036.png
  45. BIN
      app/assets/sticker/ajmd/ajmd037.png
  46. BIN
      app/assets/sticker/ajmd/ajmd038.png
  47. BIN
      app/assets/sticker/ajmd/ajmd039.png
  48. BIN
      app/assets/sticker/ajmd/ajmd040.png
  49. BIN
      app/assets/sticker/ajmd/ajmd041.png
  50. BIN
      app/assets/sticker/ajmd/ajmd042.png
  51. BIN
      app/assets/sticker/ajmd/ajmd043.png
  52. BIN
      app/assets/sticker/ajmd/ajmd044.png
  53. BIN
      app/assets/sticker/ajmd/ajmd045.png
  54. BIN
      app/assets/sticker/ajmd/ajmd046.png
  55. BIN
      app/assets/sticker/ajmd/ajmd047.png
  56. BIN
      app/assets/sticker/ajmd/ajmd048.png
  57. BIN
      app/assets/sticker/ajmd_s_normal.png
  58. BIN
      app/assets/sticker/ajmd_s_pressed.png
  59. BIN
      app/assets/sticker/lt/lt001.png
  60. BIN
      app/assets/sticker/lt/lt002.png
  61. BIN
      app/assets/sticker/lt/lt003.png
  62. BIN
      app/assets/sticker/lt/lt004.png
  63. BIN
      app/assets/sticker/lt/lt005.png
  64. BIN
      app/assets/sticker/lt/lt006.png
  65. BIN
      app/assets/sticker/lt/lt007.png
  66. BIN
      app/assets/sticker/lt/lt008.png
  67. BIN
      app/assets/sticker/lt/lt009.png
  68. BIN
      app/assets/sticker/lt/lt010.png
  69. BIN
      app/assets/sticker/lt/lt011.png
  70. BIN
      app/assets/sticker/lt/lt012.png
  71. BIN
      app/assets/sticker/lt/lt013.png
  72. BIN
      app/assets/sticker/lt/lt014.png
  73. BIN
      app/assets/sticker/lt/lt015.png
  74. BIN
      app/assets/sticker/lt/lt016.png
  75. BIN
      app/assets/sticker/lt/lt017.png
  76. BIN
      app/assets/sticker/lt/lt018.png
  77. BIN
      app/assets/sticker/lt/lt019.png
  78. BIN
      app/assets/sticker/lt/lt020.png
  79. BIN
      app/assets/sticker/lt_s_normal.png
  80. BIN
      app/assets/sticker/lt_s_pressed.png
  81. BIN
      app/assets/sticker/xxy/xxy001.png
  82. BIN
      app/assets/sticker/xxy/xxy002.png
  83. BIN
      app/assets/sticker/xxy/xxy003.png
  84. BIN
      app/assets/sticker/xxy/xxy004.png
  85. BIN
      app/assets/sticker/xxy/xxy005.png
  86. BIN
      app/assets/sticker/xxy/xxy006.png
  87. BIN
      app/assets/sticker/xxy/xxy007.png
  88. BIN
      app/assets/sticker/xxy/xxy008.png
  89. BIN
      app/assets/sticker/xxy/xxy009.png
  90. BIN
      app/assets/sticker/xxy/xxy010.png
  91. BIN
      app/assets/sticker/xxy/xxy011.png
  92. BIN
      app/assets/sticker/xxy/xxy012.png
  93. BIN
      app/assets/sticker/xxy/xxy013.png
  94. BIN
      app/assets/sticker/xxy/xxy014.png
  95. BIN
      app/assets/sticker/xxy/xxy015.png
  96. BIN
      app/assets/sticker/xxy/xxy016.png
  97. BIN
      app/assets/sticker/xxy/xxy017.png
  98. BIN
      app/assets/sticker/xxy/xxy018.png
  99. BIN
      app/assets/sticker/xxy/xxy019.png
  100. BIN
      app/assets/sticker/xxy/xxy020.png

+ 3 - 0
.gitignore

@@ -32,3 +32,6 @@ proguard/
 # Android Studio captures folder
 captures/
 
+
+#IDEA
+.idea/

+ 0 - 2
README.md

@@ -1,2 +0,0 @@
-# sheishuoAPP
-

+ 496 - 0
app/AndroidManifest.xml

@@ -0,0 +1,496 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.sheishuo.app">
+
+    <!-- 加入应用需要的权限 -->
+    <!-- 网络相关 -->
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+
+    <!-- 手机状态 -->
+    <uses-permission android:name="android.permission.GET_TASKS" />
+    <uses-permission android:name="android.permission.FLASHLIGHT" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+
+    <!-- 读写文件 -->
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <!-- 多媒体 -->
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+
+    <!-- SDK权限申明, 第三方APP接入时,请将com.sheishuo.app替换为自己的包名 -->
+    <!-- 和下面的uses-permission一起加入到你的AndroidManifest文件中。 -->
+    <permission
+        android:name="com.sheishuo.app.permission.RECEIVE_MSG"
+        android:protectionLevel="signature" />
+
+    <!-- 接受SDK消息广播权限, 第三方APP接入时,请将com.sheishuo.app替换为自己的包名 -->
+    <uses-permission android:name="com.sheishuo.app.permission.RECEIVE_MSG" />
+
+    <!-- 小米推送 -->
+    <permission
+        android:name="com.sheishuo.app.permission.MIPUSH_RECEIVE"
+        android:protectionLevel="signature" />
+    <uses-permission android:name="com.sheishuo.app.permission.MIPUSH_RECEIVE" />
+
+    <application
+        android:name="com.sheishuo.app.SheishuoApplication"
+        android:allowBackup="true"
+        android:icon="@drawable/ic_logo"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme.NoActionBar">
+
+        <!-- 如果IDE是Eclipse,此处可将build.gradle中的AMAP_KEY定义拷贝过来。 -->
+        <meta-data
+            android:name="com.amap.api.v2.apikey"
+            android:value="${AMAP_KEY}" />
+
+        <!--7b8c319e77664d91d28520b83840b221-->
+        <meta-data
+            android:name="com.netease.nim.appKey"
+			android:value="7b8c319e77664d91d28520b83840b221" />
+
+        <uses-library
+            android:name="com.google.android.maps"
+            android:required="false" />
+
+        <!--测试Activity-->
+
+        <!-- 登录界面 -->
+        <activity android:name=".login.LoginActivity"/>
+        <activity android:name=".login.LoginAndRegActivity" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+                <category android:name="android.intent.category.MULTIWINDOW_LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+
+        <!-- 导航页 -->
+        <activity
+            android:name=".main.activity.WelcomeActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:hardwareAccelerated="true"
+            android:label="@string/app_name"
+            android:launchMode="singleTop"
+            android:screenOrientation="portrait"
+            android:theme="@style/WelcomeEntranceActionBarTheme"
+            android:windowSoftInputMode="adjustPan">
+
+        </activity>
+
+        <!-- 主界面 -->
+        <activity
+            android:name="com.sheishuo.app.main.activity.MainActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:hardwareAccelerated="true"
+            android:launchMode="singleTop"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="adjustPan"/>
+
+        <!-- 多端登录管理 -->
+        <activity
+            android:name="com.sheishuo.app.main.activity.MultiportActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="adjustResize|stateHidden"/>
+
+
+
+        <!-- 关于 -->
+        <activity
+            android:name="com.sheishuo.app.main.activity.AboutActivity"
+            android:configChanges="orientation"
+            android:label="@string/about"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="adjustUnspecified|stateHidden" />
+
+        <activity
+            android:name="com.sheishuo.app.main.activity.SettingsActivity"
+            android:configChanges="orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="stateAlwaysHidden" />
+
+        <activity
+            android:name="com.sheishuo.app.main.activity.NoDisturbActivity"
+            android:configChanges="orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="adjustUnspecified|stateHidden" />
+
+        <activity
+            android:name="com.sheishuo.app.contact.activity.AddFriendActivity"
+            android:configChanges="orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="adjustUnspecified|stateHidden" />
+
+        <activity
+            android:name="com.sheishuo.app.contact.activity.UserProfileActivity"
+            android:configChanges="orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="adjustUnspecified|stateHidden" />
+
+        <activity
+            android:name="com.sheishuo.app.contact.activity.UserProfileSettingActivity"
+            android:configChanges="orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="adjustUnspecified|stateHidden" />
+
+        <activity
+            android:name="com.sheishuo.app.contact.activity.UserProfileEditItemActivity"
+            android:configChanges="orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="adjustUnspecified|stateHidden" />
+
+        <activity
+            android:name="com.sheishuo.app.contact.activity.BlackListActivity"
+            android:configChanges="orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="adjustUnspecified|stateHidden" />
+
+        <!-- 文件管理器 -->
+        <activity
+            android:name="com.sheishuo.app.file.browser.FileBrowserActivity"
+            android:configChanges="orientation"
+            android:label="@string/file_browser"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="adjustUnspecified|stateHidden" />
+
+        <activity
+            android:name="com.sheishuo.app.main.activity.SystemMessageActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="stateHidden|adjustResize" />
+        <activity
+            android:name="com.sheishuo.app.main.activity.CustomNotificationActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="stateHidden|adjustResize" />
+        <activity
+            android:name="com.sheishuo.app.session.activity.MessageHistoryActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="stateHidden|adjustResize" />
+        <activity
+            android:name="com.sheishuo.app.session.activity.MessageInfoActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="stateHidden|adjustResize" />
+
+        <activity
+            android:name="com.sheishuo.app.team.activity.AdvancedTeamSearchActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="stateHidden|adjustResize" />
+
+        <activity
+            android:name="com.sheishuo.app.team.activity.AdvancedTeamJoinActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="stateHidden|adjustResize" />
+
+        <activity
+            android:name="com.sheishuo.app.main.activity.TeamListActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="stateHidden|adjustPan" />
+
+        <!-- 全局搜索 -->
+        <activity
+            android:name="com.sheishuo.app.main.activity.GlobalSearchActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/global_search_bg"
+            android:windowSoftInputMode="stateUnspecified"></activity>
+
+        <activity
+            android:name="com.sheishuo.app.main.activity.GlobalSearchDetailActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"></activity>
+
+        <activity
+            android:name="com.sheishuo.app.main.activity.GlobalSearchDetailActivity2"
+            android:configChanges="keyboardHidden|orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"></activity>
+
+        <!-- 查看阅后即焚 -->
+        <activity
+            android:name="com.sheishuo.app.session.activity.WatchSnapChatPictureActivity"
+            android:configChanges="keyboardHidden"
+            android:theme="@style/AppTheme.NoActionBar" />
+
+        <!-- 下载文件 -->
+        <activity
+            android:name="com.sheishuo.app.session.activity.FileDownloadActivity"
+            android:configChanges="keyboardHidden"
+            android:theme="@style/AppTheme.NoActionBar" />
+
+        <!-- map -->
+        <activity
+            android:name="com.sheishuo.app.location.activity.LocationAmapActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:label="@string/location_map"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar" />
+        <activity
+            android:name="com.sheishuo.app.location.activity.NavigationAmapActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:label="@string/location_navigate"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar" />
+
+        <!-- 音视频 -->
+        <activity
+            android:name="com.sheishuo.app.avchat.activity.AVChatActivity"
+            android:launchMode="singleInstance"
+            android:screenOrientation="portrait"
+            android:theme="@style/FullScreenTheme"
+            android:windowSoftInputMode="stateAlwaysHidden" />
+
+        <activity
+            android:name="com.sheishuo.app.teamavchat.activity.TeamAVChatActivity"
+            android:launchMode="singleInstance"
+            android:screenOrientation="portrait"
+            android:theme="@style/FullScreenTheme"
+            android:windowSoftInputMode="stateAlwaysHidden" />
+
+        <!-- 白板 -->
+        <activity
+            android:name="com.sheishuo.app.rts.activity.RTSActivity"
+            android:launchMode="singleInstance"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="stateAlwaysHidden" />
+
+        <!-- 消息历史搜索 -->
+        <activity
+            android:name="com.sheishuo.app.session.search.SearchMessageActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/global_search_bg"
+            android:windowSoftInputMode="adjustPan|stateUnspecified" />
+
+        <activity
+            android:name="com.sheishuo.app.session.search.DisplayMessageActivity"
+            android:configChanges="keyboardHidden|orientation"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="stateHidden|adjustResize" />
+
+        <!-- 聊天室 -->
+        <activity
+            android:name="com.sheishuo.app.chatroom.activity.ChatRoomActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="stateHidden|adjustResize" />
+
+        <activity
+            android:name="com.sheishuo.app.jsbridge.JsBridgeActivity"
+            android:label="@string/js_bridge"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar"
+            android:windowSoftInputMode="adjustUnspecified|stateHidden" />
+
+        <!-- 机器人 -->
+        <activity
+            android:name="com.sheishuo.app.main.activity.RobotListActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar" />
+
+        <activity
+            android:name="com.sheishuo.app.contact.activity.RobotProfileActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme.NoActionBar" />
+
+        <!-- NRTC Settings -->
+        <activity
+            android:name="com.sheishuo.app.avchat.activity.AVChatSettingsActivity"
+            android:screenOrientation="portrait" />
+
+        <!-- 声明云信后台服务 -->
+        <service
+            android:name="com.netease.nimlib.service.NimService"
+            android:process=":core" />
+
+        <!-- 运行后台辅助服务 -->
+        <service
+            android:name="com.netease.nimlib.service.NimService$Aux"
+            android:process=":core" />
+
+        <!-- 声明云信后台辅助服务 -->
+        <service
+            android:name="com.netease.nimlib.job.NIMJobService"
+            android:exported="true"
+            android:permission="android.permission.BIND_JOB_SERVICE"
+            android:process=":core" />
+
+        <!-- 云信SDK的监视系统启动和网络变化的广播接收器,用户开机自启动以及网络变化时候重新登录 -->
+        <receiver
+            android:name="com.netease.nimlib.service.NimReceiver"
+            android:exported="false"
+            android:process=":core">
+            <intent-filter>
+                <action android:name="android.intent.action.BOOT_COMPLETED" />
+                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
+            </intent-filter>
+        </receiver>
+
+        <!-- 云信进程间通信receiver -->
+        <receiver android:name="com.netease.nimlib.service.ResponseReceiver" />
+
+        <!-- 云信进程间通信service -->
+        <service android:name="com.netease.nimlib.service.ResponseService" />
+
+        <!-- 申明自定义通知的广播接收器,第三方APP集成时,action中的com.sheishuo.app请替换为自己的包名 -->
+        <!-- 需要权限申明 <uses-permission android:name="com.sheishuo.app.permission.RECEIVE_MSG"/> -->
+        <receiver
+            android:name="com.sheishuo.app.receiver.CustomNotificationReceiver"
+            android:enabled="true"
+            android:exported="false">
+            <intent-filter>
+                <action android:name="com.sheishuo.app.ACTION.RECEIVE_CUSTOM_NOTIFICATION" />
+            </intent-filter>
+        </receiver>
+
+        <!-- 申明白板会话的广播接收器,第三方APP集成时,action中的com.sheishuo.app请替换为自己的包名 -->
+        <receiver
+            android:name="com.netease.nimlib.receiver.RTSBroadcastReceiver"
+            android:enabled="true"
+            android:exported="false">
+            <intent-filter>
+                <action android:name="com.sheishuo.app.ACTION.RECEIVE_RTS_NOTIFICATION" />
+            </intent-filter>
+        </receiver>
+
+        <!-- 申明本地电话状态(通话状态)的广播接收器,第三方APP集成时音视频模块时,如果需要在App中处理网络通话与本地电话的交互请加上此接收器 -->
+        <!-- 在Demo的示例代码中是在Application进行了网络通话与本地电话的互斥处理 -->
+        <receiver android:name="com.sheishuo.app.avchat.receiver.IncomingCallReceiver">
+            <intent-filter>
+                <action android:name="android.intent.action.PHONE_STATE" />
+            </intent-filter>
+        </receiver>
+
+        <!-- 小米推送配置 -->
+        <service
+            android:name="com.xiaomi.push.service.XMJobService"
+            android:enabled="true"
+            android:exported="false"
+            android:permission="android.permission.BIND_JOB_SERVICE"
+            android:process=":mixpush" />
+
+        <service
+            android:name="com.xiaomi.push.service.XMPushService"
+            android:enabled="true"
+            android:process=":mixpush" />
+
+        <receiver
+            android:name="com.xiaomi.push.service.receivers.PingReceiver"
+            android:exported="false"
+            android:process=":mixpush">
+            <intent-filter>
+                <action android:name="com.xiaomi.push.PING_TIMER" />
+            </intent-filter>
+        </receiver>
+
+        <receiver
+            android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
+
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </receiver>
+
+        <service
+            android:name="com.xiaomi.mipush.sdk.PushMessageHandler"
+            android:enabled="true"
+            android:exported="true" />
+
+        <service
+            android:name="com.xiaomi.mipush.sdk.MessageHandleService"
+            android:enabled="true" />
+
+        <receiver
+            android:name="com.netease.nimlib.mixpush.mi.MiPushReceiver"
+            android:exported="true">
+            <intent-filter android:priority="0x7fffffff">
+                <action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE" />
+                <action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED" />
+                <action android:name="com.xiaomi.mipush.ERROR" />
+            </intent-filter>
+        </receiver>
+
+        <!--华为推送配置-->
+
+        <meta-data
+            android:name="com.huawei.hms.client.appid"
+            android:value="100006871" />
+
+        <provider
+            android:name="com.huawei.hms.update.provider.UpdateProvider"
+            android:authorities="com.sheishuo.app.hms.update.provider"
+            android:exported="false"
+            android:grantUriPermissions="true"></provider>
+
+        <!-- 第三方相关 :接收Push消息(注册、Push消息、Push连接状态)广播 -->
+        <receiver android:name="com.netease.nimlib.mixpush.hw.HWPushReceiver">
+            <intent-filter android:priority="0x7fffffff">
+                <!-- 必须,用于接收token -->
+                <action android:name="com.huawei.android.push.intent.REGISTRATION" />
+                <!-- 必须,用于接收消息 -->
+                <action android:name="com.huawei.android.push.intent.RECEIVE" />
+                <!-- 可选,用于点击通知栏或通知栏上的按钮后触发onEvent回调 -->
+                <action android:name="com.huawei.android.push.intent.CLICK" />
+                <!-- 可选,查看push通道是否连接,不查看则不需要 -->
+                <action android:name="com.huawei.intent.action.PUSH_STATE" />
+            </intent-filter>
+            <meta-data
+                android:name="CS_cloud_ablitity"
+                android:value="successRateAnalytics" />
+        </receiver>
+
+        <receiver android:name="com.huawei.hms.support.api.push.PushEventReceiver">
+            <intent-filter>
+                <!-- 接收通道发来的通知栏消息,兼容老版本Push -->
+                <action android:name="com.huawei.intent.action.PUSH" />
+            </intent-filter>
+        </receiver>
+
+    </application>
+
+</manifest>

+ 307 - 0
app/README.md

@@ -0,0 +1,307 @@
+# 网易云通信安卓 Demo 结构说明
+
+网易云通信 Demo 工程基于网易云通信 SDK,演示了 SDK 聊天、群组、白板、实时音视频等功能接口的使用方法。Demo 工程依赖于 UIKit 工程,UIKit 实现了基本的消息收发,群组服务以及通讯录等功能,包含有完整的界面显示。开发者可以直接调用UIKit 中的接口,来进行功能开发,加快开发速度。用户可参照该 Demo,将网易云通信 SDK 接入自己的 APP。
+
+## <span id="工程导入指引"> 工程导入指引</span>
+- [Eclipse导入Demo](http://note.youdao.com/groupshare/?token=7565E66468734B5C89D114AFD7AAB493&gid=14302436  "target=_blank")
+- [Eclipse导入UIKit](http://note.youdao.com/groupshare/?token=8F876090BE4E4D55B88A9ED04E8513F2&gid=14302436  "target=_blank")
+- [Android Studio导入Demo](http://note.youdao.com/groupshare/?token=94E0368010384F5FB2D6E1E2C5855AA8&gid=14302436  "target=_blank")
+- [Android Studio导入UIKit](http://note.youdao.com/groupshare/?token=9C35BEC0231C4E80B1DBF76FBDC54161&gid=14302436  "target=_blank")
+- [UIKit集成示例](http://note.youdao.com/groupshare/?token=F0EF37ECED6541E58634EF0AFBB451CF&gid=14302436  "target=_blank")
+- [Android视频教程源码及说明](http://note.youdao.com/groupshare/?token=72C14A95D15144259B5E5C01D583D639&gid=14302436  "target=_blank")
+
+## <span id="下载编译 Demo"> 下载编译 Demo</span>
+
+用户可在下载页面进行下载 Demo 源码工程。
+
+总体环境需求:
+
+- 我们的部分代码会针对不同系统版本做优化,在新的平台上使用新的 API。编译运行该 Demo 的 build tools最低版本要求为19。
+- 由于 Demo 中使用到了部分 java7 以上的特性,因此 JDK 请使用 JDK7 或以上版本。
+
+如果你使用的 IDE 是 Android Studio,可直接在 IDE 中打开 Demo 工程,然后将工程目录下 gradle.properties 文件按照注释修改,就可以直接编译运行。
+
+- 如果你是第一次使用 Android Studio,导入时会从 gradle 网站下载 gradle 发布包,在国内下载可能会比较慢。这时你也可以通过 Android Studio 设置,不使用 gradle wrapper,改为使用 local gradle distribution。
+
+如果你使用的 IDE 是 Eclipse,可直接在 IDE 中打开工程,做如下修改后,即可编译运行。
+
+- 由于在 Eclipse 配置 libs 外的 jar 包比较麻烦,且不能配置 jni 库的位置,因此你需要把 libs-sdk 的所有文件夹移动到 libs 目录下(Demo 1.5版本及以后不需要)。
+- 注释掉 AboutActivity 中 initViewData() 函数的函数体。这行使用 Android Studio 编译期添加 BuildConfig 字段的特性,在 Eclipse 上无法完成,直接注释掉即可。
+- 如果你需要试验发送地理位置功能,请将 AndroidManifest 中的 {AMAP\_KEY} 替换为 demo/build.gradle 文件中 buildTypes 内对应的值。在 Android Studio 上会在编译器自动替换。
+- 由于需要使用 JDK7 编译,旧版本的 ADT 插件仅支持到1.6,因此你需要使用最新的 ADT 版本(23.0及以上)才能正确编译 Demo。
+- 将 UIKit 下 AndoridManifeset 文件下所有 Activity 声明复制到 APP 工程的 AndoridManifeset 文件中。
+- 将 UIKit 下 assets 目录下所有资源复制到 APP工程的 assets 目录下。
+>由于 google 已经将 Android Studio 作为官方开发工具,不再提供 ADT Bundle 下载,继续使用 Eclipse 开发会让你错过很多新特性,因此我们强烈建议你使用 Android Studio 开发基于网易云通信 SDK 的 APP,该 Demo的很多自动化特性也将只有 Android Studio 才能体验到。
+
+## <span id="源码结构"> 源码结构</span>
+
+由于 Demo 依赖于 UIKit 进行开发。分为 Demo 工程和 UIKit 工程。分别介绍这两个工程的源码结构。
+
+- Demo日志地址:**/{外卡根目录}/{app\_package\_name}/log/**
+
+### <span id="Demo源码结构"> Demo源码结构</span>
+
+- Application 入口:NimApplication, 包含 SDK 的初始化,UIKit的初始化以及配置示例。
+- 登录相关:login 包,包含一个比较典型的从第三方 APP 授权,然后登录到网易云通信服务器的例子。
+- 主界面:main 包,包含最近联系人列表和好友/群组列表。该包作为各个功能的入口点,内含获取和管理最近联系人,获取群组列表,收发自定义通知等 SDK 接口使用示例。
+- 消息相关:session 包,包含消息历史,聊天信息和搜索消息界面。消息的具体展示和收发都在 UIKit 中。可以使用 NimUIKit 直接展示和使用。也可以使用 SessionHelper 进行消息界面的定制。
+- 群组相关:team 包,包含搜索群组和加入群组界面。包含创建高级群和讨论组的接口使用示例。
+- 音视频通话相关:avchat 包,包含音视频通话界面。内含网络通话功能的 SDK 接口使用示例,以及一个完整的网络通话流程示例,开发者可直接参考开发音视频通话功能。
+- 实时会话(白版):rts 包,包含白板教学的示例,支持实时音频、白板数据收发。
+
+### <span id="UIKit源码结构"> UIKit源码结构</span>
+
+- UIKit 调用接口:NimUIKit,包含构建好友和群的缓存,打开聊天窗口,打开联系人选择器,打开群资料。
+- 基础组件相关:common 包, 包含 Activity、Fragment 和 Adapter的基类,一些自定义 UI 控件以及系统工具类。
+- 消息相关:session包,包含单聊/群聊界面,内含收发消息,上传下载消息附件,使用高清语音,管理消息历史等 SDK 接口使用示例。该包还有消息展示,使用 emoji 表情,发送图片等示例代码,可供开发者参考。
+- 群组相关:team 包,包含群组信息界面。内含展示群资料,修改群资料,展示群成员列表,管理群成员列表等 SDK 接口使用示例。
+- 最近联系人相关:recent 包,包含最近联系人列表界面
+- 通讯录相关:contact_selector 包和 contact 包,包含联系人选择器和通讯录。内含用户信息等 SDK 接口使用示例。
+
+## <span id="修改Demo为己用"> 修改Demo为己用</span>
+
+网易云通信 Demo 实现了一个 IM 软件的所有基础功能,开发者可直接以 Demo 为基础开发自己的 IM 软件,也可以稍作修改,用于前期流程验证,也可以作为 SDK 开发的参考和指南。
+
+- 如果你已经在网易云通信官网上注册了 APP,你需要修改 AndroidManifest 中的 “com.netease.nim.appKey” 为你自己的 appkey,否则登录会失败。
+
+## <span id="聊天界面代码说明"> 聊天界面代码说明</span>
+
+### 结构说明
+
+- BaseMessageActivity:聊天界面基类。封装了 MessageFragment 和 actionbar 相关操作。
+- MessageFragment:聊天界面基类 Fragment。
+- MessageListPanel:消息收发模块。包括收发消息的显示,消息列表相关操作。
+- InputPanel:底部文本编辑,语音等模块。包括文本,语音的消息发送和更多中的 action 操作。
+- ActionsPanel:更多操作模块。
+- P2PMessageActivity:点对点聊天界面。
+- TeamMessageActivity: 群聊界面。
+- SessionCustomization:聊天界面定制化参数。
+- MessageLoader:MessageListPanel 中的内部类,用于加载消息。
+- MsgItemEventListener: MessageListPanel 中的内部类,用于重发消息,长按消息相关操作等。
+
+## <span id="音视频代码说明"> 音视频代码说明</span>
+
+### 结构说明
+
+- AVChatActivity::音视频界面
+- AVChatUI:音视频管理类, 音视频相关功能管理,内含音频管理,视频管理,视频绘制管理。还包括了网络连接状态等监听事件的处理,具体见开发手册。
+- AVChatAudio:音频管理, 音频界面初始化和界面相关操作管理
+- AVChatVideo:视频管理, 视频界面初始化和界面相关操作管理
+- AVChatSurface:视频绘制管理
+- AVChatNotification:音视频聊天通知栏
+- AVChatUIListener:音视频界面操作监听
+
+### <span id="初始化"> 初始化</span>
+
+在 `AVChatActivity` 的 oncreate 中,进行管理器的初始化工作
+
+```java
+avChatUI = new AVChatUI(this, root, this);
+if (!avChatUI.initiation()) {
+	this.finish();
+	return;
+}
+public boolean initiation() {
+        AVChatProfile.getInstance().setAVChatting(true);
+        avChatAudio = new AVChatAudio(root.findViewById(R.id.avchat_audio_layout), this, this);
+        avChatVideo = new AVChatVideo(context, root.findViewById(R.id.avchat_video_layout), this, this);
+        avChatSurface = new AVChatSurface(context, this, root.findViewById(R.id.avchat_surface_layout));
+
+        return true;
+    }
+```
+
+### <span id="拨打"> 拨打</span>
+
+主流程:
+
+1、传入参数,对方帐号和拨打的类型(AVChatType.AUDIO 或 AVChatType.VIDEO)。
+
+```java
+avChatUI.outGoingCalling(receiverId, AVChatType.typeOfValue(state));
+```
+
+2、通知界面刷新,详见[界面刷新](#界面刷新) 一节。
+
+```java
+if (callTypeEnum == AVChatType.AUDIO) {
+	onCallStateChange(CallStateEnum.OUTGOING_AUDIO_CALLING);
+} else {
+	onCallStateChange(CallStateEnum.OUTGOING_VIDEO_CALLING);
+}
+```
+
+3、发起通话
+
+```java
+/**
+* 发起通话
+* account 对方帐号
+* callTypeEnum 通话类型:语音、视频
+* videoParam 发起视频通话时传入,发起音频通话传null
+* AVChatCallback 回调函数,返回AVChatInfo
+*/
+AVChatManager.getInstance().call(account, callTypeEnum, videoParam, new AVChatCallback<AVChatData>() {
+            @Override
+            public void onSuccess(AVChatData data) {
+               ...
+            }
+
+            @Override
+            public void onFailed(int code) {
+                ...
+            }
+
+            @Override
+            public void onException(Throwable exception) {
+                ...
+            }
+        });
+```
+
+### <span id="接听"> 接听</span>
+
+1、传入参数 AVChatData
+
+```java
+avChatUI.inComingCalling(avChatData);
+```
+
+2、通知界面刷新,详见[界面刷新](#界面刷新) 一节。
+
+```java
+if (callTypeEnum == AVChatType.AUDIO) {
+	onCallStateChange(CallStateEnum.OUTGOING_AUDIO_CALLING);
+} else {
+	onCallStateChange(CallStateEnum.OUTGOING_VIDEO_CALLING);
+}
+```
+
+### <span id="界面刷新"> 界面刷新</span>
+
+界面刷新,详细流程如下。
+1、调用 onCallStateChange
+2、如果界面没有进行过初始化,则进行界面初始化 findViews,并为各个按钮添加响应事件。
+3、根据 CallStateEnum 判断界面布局设置和显隐性。
+
+```java
+// 有来电,界面状态更新
+onCallStateChange(CallStateEnum.INCOMING_AUDIO_CALLING);
+
+// 判断来电类型,是音频或视频
+if(CallStateEnum.isAudioMode(state))
+	findViews();
+
+// 设置信息显示和界面布局
+switch (state){
+	...
+	case INCOMING_AUDIO_CALLING://免费通话请求
+		setSwitchVideo(false);
+		showProfile();//对方的详细信息
+		showNotify(R.string.avchat_audio_call_request);
+		setMuteSpeakerHangupControl(false);
+		setRefuseReceive(true);
+		receiveTV.setText(R.string.avchat_pickup);
+		break;
+	...
+}
+```
+
+### <span id="按钮响应事件"> 按钮响应事件</span>
+
+AVChatAudio 和 AVChatVideo 中包含了挂断,拒绝,接受,禁音,开启扬声器,音视频切换和摄像头切换的操作。 按钮的点击响应事件,通过 AVChatUIListener 统一交给 AVChatUI 进行管理。示例如下:
+
+```java
+// 初始化挂断按钮
+hangup = mute_speaker_hangup.findViewById(R.id.avchat_audio_hangup);
+hangup.setOnClickListener(this);
+
+// 按钮响应事件处理
+public void onClick(View v) {
+	switch (v.getId()) {
+		case R.id.avchat_audio_hangup:
+			listener.onHangUp();
+		break;
+	...
+	}
+}
+
+// 在AVChatUI的AVChatUIListener实现中,实现挂断或取消接口。
+public void onHangUp() {
+	if (isCallEstablish.get()) {
+		hangUp(AVChatExitCode.HANGUP);
+	} else {
+		hangUp(AVChatExitCode.CANCEL);
+	}
+}
+```
+
+## <span id="聊天室代码说明"> 聊天室代码说明</span>
+
+### 结构说明
+
+- activity包:界面相关
+- adapter包:适配器相关
+- constant包:常量定义
+- fragment包:界面相关。其中包括 tab 包,定义了聊天室框架中的 tab fragment。
+- helper包:缓存管理,通知类消息字段管理等辅助功能。
+- module包:模块化相关。包括聊天室收发消息模块。
+- thirdparty包:第三方实现相关。包括网易云通信 demo 聊天室 http 客户端。
+- viewholder包:界面相关 viewholder 展示。
+- widget包:聊天室相关控件
+
+### 重点类说明
+
+- ChatRoomsFragment:直播间列表 fragment。包含向网易云通信Demo应用服务器请求聊天室列表操作。
+- ChatRoomActivity:聊天室界面。封装了 ChatRoomFragment。包括聊天室的进入/离开的操作,监听聊天室在线状态和监听聊天室被踢出状态。
+- ChatRoomTabFragment:聊天室内 tab fragment 的基类。
+- ChatRoomFragment:聊天室 Activity 包含的顶层 Fragment。包括界面上方界面和下方的 viewpager。viewpager 包含3个 tab fragment,分别是:MessageTabFragment (直播互动 tab), MasterTabFragment (主播 tab), OnlinePeopleTabFragment (在线成员 tab)。
+- MessageTabFragment:直播互动基类 fragment。内嵌 ChatRoomMessageFragment (直播互动 fragment)。
+- MasterTabFragment:主播基类 fragment。内嵌 MasterFragment(主播 fragment )。
+- OnlinePeopleTabFragment:在线成员基类 fragment。内嵌 OnlinePeopleFragment (在线成员 fragment)
+- ChatRoomMessageFragment:聊天室直播互动 fragment。包括消息的收发相关操作。
+- MasterFragment: 聊天室主播 fragment。包括获取聊天室资料等操作。
+- OnlinePeopleFragment:聊天室在线人数 fragment。包括获取聊天室成员信息等操作。
+- ChatRoomMsgViewHolderFactory:  聊天室消息项展示ViewHolder工厂类。包括消息展示 viewholder 的注册操作。
+
+## <span id="新老版本兼容问题"> 新老版本兼容问题</span>
+
+### 群通知相关
+
+问题:群通知新增的通知消息类型,可能会造成老版本崩溃。
+原因:TeamNotificationHelper#buildUpdateTeamNotification 的 a.getUpdatedFields() 的 size 为0,造成 sb 的 length为0,会抛出 StringIndexOutOfBoundsException 错误。
+解决方案:判断 sb 的length,参考demo。
+
+## <span id=" Android 6.0 权限管理"> Android 6.0 权限管理 </span>
+
+网易云通信 demo 提供 Android 6.0 权限管理示例。相关方法的实现,在 uikit 的 permission 包中。
+
+在需要相关权限的地方,发起申请并等待用户操作后的返回结果。具体实现方法:
+
+```java
+private void requestBasicPermission() {
+	MPermission.with(MainActivity.this)             
+		.addRequestCode(BASIC_PERMISSION_REQUEST_CODE)
+		.permissions(
+			Manifest.permission.WRITE_EXTERNAL_STORAGE,
+			Manifest.permission.READ_EXTERNAL_STORAGE,
+			// ……
+		)
+		.request();
+}
+
+@Override
+public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
+	MPermission.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
+}
+
+@OnMPermissionGranted(BASIC_PERMISSION_REQUEST_CODE)
+public void onBasicPermissionSuccess(){
+	Toast.makeText(this, "授权成功", Toast.LENGTH_SHORT).show();
+}
+
+@OnMPermissionDenied(BASIC_PERMISSION_REQUEST_CODE)
+public void onBasicPermissionFailed(){
+	Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show();
+}
+```

BIN
app/aars/HMS-SDK-2.4.0.300.aar


+ 150 - 0
app/app.iml

@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="android-gradle" name="Android-Gradle">
+      <configuration>
+        <option name="GRADLE_PROJECT_PATH" value=":app" />
+      </configuration>
+    </facet>
+    <facet type="android" name="Android">
+      <configuration>
+        <option name="SELECTED_BUILD_VARIANT" value="debug" />
+        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
+        <afterSyncTasks>
+          <task>generateDebugSources</task>
+        </afterSyncTasks>
+        <option name="ALLOW_USER_CONFIGURATION" value="false" />
+        <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/res" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+    <output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/res-avchat" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/res-chatroom" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-runtime-classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-safeguard" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-verifier" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-resources" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/multi-dex" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/split-apk" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
+      <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+    </content>
+    <orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" exported="" name="nim-chatroom-4.0.0" level="project" />
+    <orderEntry type="library" exported="" name="gson-2.8.1" level="project" />
+    <orderEntry type="library" exported="" name="constraint-layout-1.0.2" level="project" />
+    <orderEntry type="library" exported="" name="transition-25.3.1" level="project" />
+    <orderEntry type="library" exported="" name="video_effect" level="project" />
+    <orderEntry type="library" exported="" name="design-25.3.1" level="project" />
+    <orderEntry type="library" exported="" name="support-core-ui-25.3.1" level="project" />
+    <orderEntry type="library" exported="" name="rxandroid-2.0.1" level="project" />
+    <orderEntry type="library" exported="" name="HMS-SDK-2.4.0.300-" level="project" />
+    <orderEntry type="library" exported="" name="jsbridge-1.3.1" level="project" />
+    <orderEntry type="library" exported="" name="Android_Location_V1.3.1" level="project" />
+    <orderEntry type="library" exported="" name="support-core-utils-25.3.1" level="project" />
+    <orderEntry type="library" exported="" name="support-fragment-25.3.1" level="project" />
+    <orderEntry type="library" exported="" name="rxjava-2.1.1" level="project" />
+    <orderEntry type="library" exported="" name="glide-transformations-2.0.2" level="project" />
+    <orderEntry type="library" exported="" scope="TEST" name="multidex-instrumentation-1.0.1" level="project" />
+    <orderEntry type="library" exported="" name="reactive-streams-1.0.0" level="project" />
+    <orderEntry type="library" exported="" name="nrtc-sdk" level="project" />
+    <orderEntry type="library" exported="" name="adapter-rxjava2-2.3.0" level="project" />
+    <orderEntry type="library" exported="" name="okio-1.13.0" level="project" />
+    <orderEntry type="library" exported="" name="retrofit-2.3.0" level="project" />
+    <orderEntry type="library" exported="" name="converter-gson-2.3.0" level="project" />
+    <orderEntry type="library" exported="" name="okhttp-3.8.0" level="project" />
+    <orderEntry type="library" exported="" name="AMap_Services_V2.3.1" level="project" />
+    <orderEntry type="library" exported="" name="overscroll-decor-android-1.0.4" level="project" />
+    <orderEntry type="library" exported="" name="multidex-1.0.1" level="project" />
+    <orderEntry type="library" exported="" name="support-v4-25.3.1" level="project" />
+    <orderEntry type="library" exported="" name="support-media-compat-25.3.1" level="project" />
+    <orderEntry type="library" exported="" name="mi_push_sdk_3.2.2" level="project" />
+    <orderEntry type="library" exported="" name="Android_2DMap_V2.4.0" level="project" />
+    <orderEntry type="library" exported="" name="recyclerview-v7-25.3.1" level="project" />
+    <orderEntry type="library" exported="" name="support-annotations-25.3.1" level="project" />
+    <orderEntry type="library" exported="" name="nim-rts-4.0.0" level="project" />
+    <orderEntry type="library" exported="" name="appcompat-v7-25.3.1" level="project" />
+    <orderEntry type="library" exported="" name="support-vector-drawable-25.3.1" level="project" />
+    <orderEntry type="library" exported="" name="support-compat-25.3.1" level="project" />
+    <orderEntry type="library" exported="" name="animated-vector-drawable-25.3.1" level="project" />
+    <orderEntry type="module" module-name="uikit" exported="" />
+    <orderEntry type="library" exported="" name="nim-avchat-4.0.0" level="project" />
+    <orderEntry type="library" exported="" name="constraint-layout-solver-1.0.2" level="project" />
+    <orderEntry type="library" exported="" name="java-json" level="project" />
+    <orderEntry type="library" exported="" name="nim-basesdk-4.0.0" level="project" />
+    <orderEntry type="library" exported="" name="renderscript-v8" level="project" />
+    <orderEntry type="library" exported="" name="fastjson-1.1.34.android" level="project" />
+    <orderEntry type="library" exported="" name="glide-3.7.0" level="project" />
+    <orderEntry type="library" exported="" name="nim-lucene-4.0.0" level="project" />
+  </component>
+</module>

+ 199 - 0
app/assets/js/page.html

@@ -0,0 +1,199 @@
+<html>
+<head>
+    <meta charset="UTF-8">
+    <title>JS模拟云信聊天界面</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimal-ui" />
+    <meta name="apple-mobile-web-app-capable" content="yes" />
+    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
+    <meta name="format-detection"content="telephone=no, email=no" />
+    <style>
+        /**重置标签默认样式*/
+        * {
+        color: #000000;
+        margin: 0;
+        padding: 0;
+        list-style: none;
+        font-family: '微软雅黑'
+        }
+        html,body{
+           height:100%;
+        }
+        #container {
+        width: 100%;
+        height: 100%;
+        background: #e9ecf0;
+        margin: 0;
+        position: relative;
+        box-sizing: border-box;
+        box-shadow: 20px 20px 55px #777;
+        }
+        .footer {
+        width: 100%;
+        height: 60px;
+        background: #FFFFFF;
+        position: absolute;
+        bottom: 0;
+        padding: 10px;
+        box-sizing:border-box;
+        }
+        .footer input {
+        width: 60%;
+        height: 40px;
+        outline: none;
+        font-size: 14px;
+        text-indent: 10px;
+        position: absolute;
+        border-radius: 6px;
+        right: 80px;
+        box-sizing: border-box;
+        }
+        .footer span {
+        display: inline-block;
+        width: 60px;
+        height: 40px;
+        background: #ccc;
+        font-weight: 900;
+        line-height: 45px;
+        cursor: pointer;
+        text-align: center;
+        position: absolute;
+        right: 10px;
+        border-radius: 6px;
+        top: 10px;
+        }
+        .footer span:hover {
+        color: #fff;
+        background: #999;
+        }
+        #icon {
+        width: 40px;
+        height: 40px;
+        background-color: red;
+        border-radius: 30px;
+        float: left
+        }
+        img {
+        width: 40px;
+        height: 40px;
+        }
+        .content {
+        font-size: 14px;
+        width: 100%;
+        height:100%;
+        overflow: auto;
+        padding: 10px 20px 80px;
+        box-sizing: border-box;
+        }
+        .content li {
+        width: 100%;
+        display: block;
+        clear: both;
+        overflow: hidden;
+        margin-top: 10px;
+        }
+        .content li img {
+        float: left;
+        }
+        .content li span{
+        background: #7cfc00;
+        padding: 10px;
+        border-radius: 10px;
+        float: left;
+        margin: 3px 10px 3px 10px;
+        max-width: 310px;
+        border: 1px solid #ccc;
+        box-shadow: 0 0 3px #ccc;
+        }
+        .content li img.imgleft {
+        float: left;
+        }
+        .content li img.imgright {
+        float: right;
+        }
+        .content li span.spanleft {
+        float: left;
+        background: #fff;
+        }
+        .content li span.spanright {
+        float: right;
+        background: #3a9efb;
+        }
+    </style>
+    <script>
+        window.onload = function(){
+            var arrIcon = new Array(2);//头像容器
+            var num = 0;     //控制头像改变
+            var iNow = -1;    //用来累加改变左右浮动
+            var img = document.getElementById('img');
+            arrIcon[0] = img.src;
+            var btn = document.getElementById('btn');
+            var text = document.getElementById('text');
+            var content = document.getElementsByTagName('ul')[0];
+            var span = content.getElementsByTagName('span');
+
+            img.onclick = function(){
+                    JsBridge.picture({},function(data) {
+                        if (data.status == 200) {
+                            var base64 = data.values.image.base64;
+                            var width = data.values.image.width;
+                            var height = data.values.image.height;
+                            var w = 320.0;
+                            var h = (1.0*w*height)/width;
+                            // show
+                            img.src = "data:image/jpg;base64," + base64;
+                            img.width = w;
+                            img.height = h;
+                            if(num==0){
+                                arrIcon[1] = img.src;
+                                num = 1;
+                            }else if(num==1){
+                                arrIcon[0] = img.src;
+                                num = 0;
+                            }
+                        }else{
+                            console.log('"picture" bridge called failed; on response:' + JSON.stringify(data));
+                        }
+                    });
+            }
+
+            btn.onclick = function(){
+                if(text.value ==''){
+                    alert('文本不能为空');
+                }else {
+                    // js->java
+                    JsBridge.notification(text.value);
+                    content.innerHTML += '<li><img src="'+arrIcon[num]+'" class="imgTag"><span class="spanTag">'+text.value+'</span></li>';
+                    iNow++;
+                    var imgs = document.getElementsByClassName("imgTag");
+                    var spans = document.getElementsByClassName("spanTag");
+                    if(num==0){
+                        imgs[iNow].className = 'imgTag imgright';
+                        spans[iNow].className = 'spanTag spanright';
+                    }
+                    else {
+                        imgs[iNow].className = 'imgTag imgleft';
+                        spans[iNow].className = 'spanTag spanleft';
+                    }
+                    text.value ='';
+                    // 内容过多时,将滚动条放置到最底端
+                    contentcontent.scrollTop=content.scrollHeight;
+                }
+            }
+        }
+    </script>
+    <script src="file:///android_asset/js/page.js"></script>
+</head>
+<body>
+<div id="container">
+    <ul class="content">
+    </ul>
+    <div class="footer">
+        <div id="icon">
+            <img id="img" class="imgTag" src="file:///android_res/drawable/nim_avatar_default.png">
+        </div>
+        <input id="text" type="text" placeholder="说点什么吧...">
+        <span id="btn">发送</span>
+    </div>
+</div>
+</body>
+</html>

+ 72 - 0
app/assets/js/page.js

@@ -0,0 +1,72 @@
+(function (root, factory) {
+	root.JsBridge = factory(root);
+}(typeof window == "undefined" ? this : window, function (win) {
+	if (!win.document) { return {};}
+
+	var doc = win.document,
+	title = doc.title,
+	ua = navigator.userAgent.toLowerCase(),
+	platform = navigator.platform.toLowerCase(),
+	isMacorWin = !(!platform.match("mac") && !platform.match("win")),
+	isandroid = -1 != ua.indexOf("android"),
+	isphoneorpad = -1 != ua.indexOf("iphone") || -1 != ua.indexOf("ipad"),
+	JsBridge = {
+		usable: false,
+		init: function (bridge) {
+			return this;
+		},
+
+		callJavaAsync: function(methodName, params, cb) {
+			if (!window._JSNativeBridge) {
+				//JS not be injected success
+				cb({
+					status: "-1",
+					msg: "window._JSNativeBridge is undefined"
+				}, {});
+				return;
+			}
+
+			try {
+                window._JSNativeBridge._doSendRequest(methodName, params, cb);
+			} catch (e) {
+				cb({status: "-1", msg: e},{});
+			}
+		},
+
+		callJavaSync: function(methodName, params) {
+            if (!window._JSNativeBridge) {
+				return "error:JS not be injected success";
+			}
+
+            var result;
+			try {
+                result = window._JSNativeBridge._doSendRequestSync(methodName, params);
+			} catch (e) {
+				result = "error:" + e;
+			}
+
+			return result;
+		},
+
+        notification: function(params) {
+            return this.callJavaSync("notification",{"msg": params});
+        },
+
+        picture: function(params,cb){
+           	this.callJavaAsync("picture",{},cb);
+        },
+	};
+
+	if (window._JSNativeBridge) {
+		JsBridge.init(window._JSNativeBridge);
+	} else {
+		document.addEventListener(
+			'JsBridgeInit',
+			function(event) {
+				JsBridge.init(event.bridge);
+		    }
+		);
+	}
+
+	return JsBridge;
+}));

BIN
app/assets/sticker/ajmd/ajmd001.png


BIN
app/assets/sticker/ajmd/ajmd002.png


BIN
app/assets/sticker/ajmd/ajmd003.png


BIN
app/assets/sticker/ajmd/ajmd004.png


BIN
app/assets/sticker/ajmd/ajmd005.png


BIN
app/assets/sticker/ajmd/ajmd006.png


BIN
app/assets/sticker/ajmd/ajmd007.png


BIN
app/assets/sticker/ajmd/ajmd008.png


BIN
app/assets/sticker/ajmd/ajmd009.png


BIN
app/assets/sticker/ajmd/ajmd010.png


BIN
app/assets/sticker/ajmd/ajmd011.png


BIN
app/assets/sticker/ajmd/ajmd012.png


BIN
app/assets/sticker/ajmd/ajmd013.png


BIN
app/assets/sticker/ajmd/ajmd014.png


BIN
app/assets/sticker/ajmd/ajmd015.png


BIN
app/assets/sticker/ajmd/ajmd016.png


BIN
app/assets/sticker/ajmd/ajmd017.png


BIN
app/assets/sticker/ajmd/ajmd018.png


BIN
app/assets/sticker/ajmd/ajmd019.png


BIN
app/assets/sticker/ajmd/ajmd020.png


BIN
app/assets/sticker/ajmd/ajmd021.png


BIN
app/assets/sticker/ajmd/ajmd022.png


BIN
app/assets/sticker/ajmd/ajmd023.png


BIN
app/assets/sticker/ajmd/ajmd024.png


BIN
app/assets/sticker/ajmd/ajmd025.png


BIN
app/assets/sticker/ajmd/ajmd026.png


BIN
app/assets/sticker/ajmd/ajmd027.png


BIN
app/assets/sticker/ajmd/ajmd028.png


BIN
app/assets/sticker/ajmd/ajmd029.png


BIN
app/assets/sticker/ajmd/ajmd030.png


BIN
app/assets/sticker/ajmd/ajmd031.png


BIN
app/assets/sticker/ajmd/ajmd032.png


BIN
app/assets/sticker/ajmd/ajmd033.png


BIN
app/assets/sticker/ajmd/ajmd034.png


BIN
app/assets/sticker/ajmd/ajmd035.png


BIN
app/assets/sticker/ajmd/ajmd036.png


BIN
app/assets/sticker/ajmd/ajmd037.png


BIN
app/assets/sticker/ajmd/ajmd038.png


BIN
app/assets/sticker/ajmd/ajmd039.png


BIN
app/assets/sticker/ajmd/ajmd040.png


BIN
app/assets/sticker/ajmd/ajmd041.png


BIN
app/assets/sticker/ajmd/ajmd042.png


BIN
app/assets/sticker/ajmd/ajmd043.png


BIN
app/assets/sticker/ajmd/ajmd044.png


BIN
app/assets/sticker/ajmd/ajmd045.png


BIN
app/assets/sticker/ajmd/ajmd046.png


BIN
app/assets/sticker/ajmd/ajmd047.png


BIN
app/assets/sticker/ajmd/ajmd048.png


BIN
app/assets/sticker/ajmd_s_normal.png


BIN
app/assets/sticker/ajmd_s_pressed.png


BIN
app/assets/sticker/lt/lt001.png


BIN
app/assets/sticker/lt/lt002.png


BIN
app/assets/sticker/lt/lt003.png


BIN
app/assets/sticker/lt/lt004.png


BIN
app/assets/sticker/lt/lt005.png


BIN
app/assets/sticker/lt/lt006.png


BIN
app/assets/sticker/lt/lt007.png


BIN
app/assets/sticker/lt/lt008.png


BIN
app/assets/sticker/lt/lt009.png


BIN
app/assets/sticker/lt/lt010.png


BIN
app/assets/sticker/lt/lt011.png


BIN
app/assets/sticker/lt/lt012.png


BIN
app/assets/sticker/lt/lt013.png


BIN
app/assets/sticker/lt/lt014.png


BIN
app/assets/sticker/lt/lt015.png


BIN
app/assets/sticker/lt/lt016.png


BIN
app/assets/sticker/lt/lt017.png


BIN
app/assets/sticker/lt/lt018.png


BIN
app/assets/sticker/lt/lt019.png


BIN
app/assets/sticker/lt/lt020.png


BIN
app/assets/sticker/lt_s_normal.png


BIN
app/assets/sticker/lt_s_pressed.png


BIN
app/assets/sticker/xxy/xxy001.png


BIN
app/assets/sticker/xxy/xxy002.png


BIN
app/assets/sticker/xxy/xxy003.png


BIN
app/assets/sticker/xxy/xxy004.png


BIN
app/assets/sticker/xxy/xxy005.png


BIN
app/assets/sticker/xxy/xxy006.png


BIN
app/assets/sticker/xxy/xxy007.png


BIN
app/assets/sticker/xxy/xxy008.png


BIN
app/assets/sticker/xxy/xxy009.png


BIN
app/assets/sticker/xxy/xxy010.png


BIN
app/assets/sticker/xxy/xxy011.png


BIN
app/assets/sticker/xxy/xxy012.png


BIN
app/assets/sticker/xxy/xxy013.png


BIN
app/assets/sticker/xxy/xxy014.png


BIN
app/assets/sticker/xxy/xxy015.png


BIN
app/assets/sticker/xxy/xxy016.png


BIN
app/assets/sticker/xxy/xxy017.png


BIN
app/assets/sticker/xxy/xxy018.png


BIN
app/assets/sticker/xxy/xxy019.png


BIN
app/assets/sticker/xxy/xxy020.png


Some files were not shown because too many files changed in this diff