实训第八周(2)

李晨晨:

本次主要实现点击图片消息显示原图(ShowImageActivity)非常简单的界面

[java]  view plain  copy
  1. public class ShowImageActivity extends BaseActivity {  
  2.   
  3.     private static final String TAG = ShowImageActivity.class.getSimpleName();  
  4.   
  5.     @BindView(R.id.image_view)  
  6.     PhotoView mIvImage;  
  7.   
  8.     private IMMessage mMessage;  
  9.     private Bitmap bitmap;  
  10.   
  11.   
  12.   
  13.     @Override  
  14.     protected void onCreate(@Nullable Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         //隐藏系统状态栏  
  17.         if (getSupportActionBar() != null) {  
  18.             getSupportActionBar().hide();  
  19.         }  
  20.         //requestWindowFeature(Window.FEATURE_NO_TITLE);  
  21.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
  22.                 WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  23.         setContentView(R.layout.activity_show_image);  
  24.         ButterKnife.bind(this);  
  25.         initImage();  
  26.   
  27.     }  
  28.   
  29.   
  30.     private void initImage() {  
  31.         mIvImage.setMaxScale(4);  
  32.         mIvImage.enable();  
  33.   
  34.         mMessage = (IMMessage) getIntent().getSerializableExtra("IMMessage");  
  35.   
  36.         if (mMessage == null) {  
  37.             ToastUtils.showMessage(this"图片无法显示,请重试~");  
  38.             finish();  
  39.             return;  
  40.         }  
  41.   
  42.         String path = ((ImageAttachment) mMessage.getAttachment()).getPath();  
  43.   
  44.         // 原图已经下载,显示原图  
  45.         if (mMessage.getAttachStatus() == AttachStatusEnum.transferred  
  46.                 && !TextUtils.isEmpty(path)) {  
  47.             Bitmap origin_bitmap = BitmapFactory.decodeFile(path);  
  48.             int height = (int) (origin_bitmap.getHeight() * (512.0 / origin_bitmap.getWidth()));  
  49.             bitmap = Bitmap.createScaledBitmap(origin_bitmap, 512, height, true);  
  50.             if (bitmap != null) {  
  51.                 mIvImage.setImageBitmap(bitmap);  
  52.             } else {  
  53.                 ToastUtils.showMessage(ShowImageActivity.this"原图 下载/显示 失败,请重试~");  
  54.                 finish();  
  55.             }  
  56.         }  
  57.     }  
  58.   
  59.   
  60.   
  61.     @Override  
  62.     protected void onResume() {  
  63.         super.onResume();  
  64.     }  
  65.   
  66.     @Override  
  67.     protected void onDestroy() {  
  68.         if (bitmap != null && !bitmap.isRecycled())  
  69.             bitmap.recycle();//防止图片过大造成java.lang.OutOfMemoryError  
  70.         super.onDestroy();  
  71.     }  
  72. }  

有的图片比较大,在显示是会报错,通过上网搜素解决方法,最终决定缩放原图在显示:

[java]  view plain  copy
  1. int height = (int) (origin_bitmap.getHeight() * (512.0 / origin_bitmap.getWidth()));  
  2.             bitmap = Bitmap.createScaledBitmap(origin_bitmap, 512, height, true);  

最终效果如下图,因为用的PhotoView,所以自带两指缩放:


界面应该是隐藏系统状态栏的,但因为此手机截屏要下拉菜单,所以显示出了状态栏。




仝心:

本次的工作对整个工程中我负责的部分进行了收尾。

首先将ChatInputLayout中的所有功能进行了完善,首先是语音识别功能的输出形式,系统键盘模式下正常输出,自定义键盘模式下需要将识别出的句子的字母与个性化字体库中的字体进行匹配。

给开始识别按钮添加的监听器

[java]  view plain  copy
  1. btStart.setOnClickListener(new View.OnClickListener() {  
  2.             @Override  
  3.             public void onClick(View v) {  
  4.                 checkSoIsInstallSucceed();  
  5.                 //mEtInput.setText("");  
  6.                 //mIatResults.clear();  
  7.                 // 设置参数  
  8.                 setParam();  
  9.                 boolean isShowDialog = mSharedPreferences.getBoolean(  
  10.                         getResources().getString(R.string.pref_key_iat_show), true);  
  11.                 if(isShowDialog){  
  12.                     ret=mIat.startListening(mRecognizerListener);  
  13.                     if(ret!= ErrorCode.SUCCESS)  
  14.                     {  
  15.                         showTip("听写失败,错误码:"+ret);  
  16.                     }else{  
  17.                         showTip("请开始说话");  
  18.                     }  
  19.                 }  
  20.             }  
  21.         });  

其中showTip用来显示提示文字

[java]  view plain  copy
  1. private void showTip(final String str) {  
  2.         mToast.setText(str);  
  3.         mToast.show();  
  4.     }  
mIat是一个语音听写对象,setParam方法就是用来在听写前设置其参数,来自讯飞语音识别
[java]  view plain  copy
  1. private SpeechRecognizer mIat;  
[java]  view plain  copy
  1. public void setParam() {  
  2.         //参数设置  
  3.         // 清空参数  
  4.         mIat.setParameter(SpeechConstant.PARAMS, null);  
  5.         // 设置听写引擎  
  6.         mIat.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);  
  7.         // 设置返回结果格式  
  8.         mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");  
  9.         mIat.setParameter(SpeechConstant.LANGUAGE,"en_us");  
  10.         // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理  
  11.         mIat.setParameter(SpeechConstant.VAD_BOS, mSharedPreferences.getString("iat_vadbos_preference""4000"));  
  12.   
  13.         // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音  
  14.         mIat.setParameter(SpeechConstant.VAD_EOS, mSharedPreferences.getString("iat_vadeos_preference""1000"));  
  15.   
  16.         // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点  
  17.         mIat.setParameter(SpeechConstant.ASR_PTT, mSharedPreferences.getString("iat_punc_preference""1"));  
  18.   
  19.         // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限  
  20.         // 注:AUDIO_FORMAT参数语记需要更新版本才能生效  
  21.         mIat.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");  
  22.         mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/iat.wav");  
  23.     }  

最后根据不同的输入模式来确定识别后的文本的输出形式,如果是自定义键盘模式,得到语音识别的文本后对文本进行的字母逐个判断并与字体库对应,根据音量进行粗细的变形。

[java]  view plain  copy
  1. private RecognizerListener mRecognizerListener = new RecognizerListener() {  
  2.   
  3.         @Override  
  4.         public void onBeginOfSpeech() {  
  5.             // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入  
  6.             showTip("开始说话");  
  7.         }  
  8.   
  9.         @Override  
  10.         public void onError(SpeechError error) {  
  11.             // Tips:  
  12.             // 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。  
  13.             // 如果使用本地功能(语记)需要提示用户开启语记的录音权限。  
  14.             showTip(error.getPlainDescription(true));  
  15.         }  
  16.   
  17.         @Override  
  18.         public void onEndOfSpeech() {  
  19.             // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入  
  20.             showTip("结束说话");  
  21.         }  
  22.   
  23.         @Override  
  24.         public void onResult(RecognizerResult results, boolean isLast) {  
  25.             //Log.L(results.getResultString());  
  26.             System.out.println("间断结果——————————————————————————————————");  
  27.             printResult(results);  
  28.             if(isLast){  
  29.                 //因为是last,所以new_piece稳定到了最终结果,不再变化。  
  30.                 result_string+=new_piece;  
  31.                 //针对不同的文本显示方式,系统字体,手写个性化字体  
  32.                 String tag=mChangeModeLayout.getTag().toString();  
  33.                 switch (tag){  
  34.                     case "1":  
  35.                         //系统字体  
  36.                         mEtInput.setText(result_string);  
  37.                         break;  
  38.                     case "2":  
  39.                         //手写个性化字体  
  40.                         //音量  
  41.                         sound=sound/soundCount;  
  42.                         showTip("平均音量"+sound);  
  43.                         if(sound<=18){  
  44.                             sound=2;  
  45.                         }else{  
  46.                             sound=sound/3;  
  47.                         }  
  48.   
  49.                         for(int i=0;i<new_piece.length();i++){  
  50.                             int start=mEtInput.getSelectionStart();  
  51.                             char singleLetter=new_piece.charAt(i);  
  52.                             int pos=singleLetter-33;  
  53.                             Bitmap bmp;  
  54.                             if(pos==-1){  
  55.                                 //空格键  
  56.                                 bmp = Bitmap.createBitmap(MY_COL/2,MY_ROW, Bitmap.Config.ARGB_8888);//空白图片  
  57.                             }else if(myImageArrays[pos]!=null){  
  58.                                 bmp = paintNewImage(myImageArrays[pos],10,sound,0);  
  59.   
  60.                             }else{  
  61.                                 bmp = Bitmap.createBitmap(MY_COL/2,MY_ROW, Bitmap.Config.ARGB_8888);//空白图片  
  62.                                 showTip("个人字体库不完整!");  
  63.                             }  
  64.                             SpannableString ss=getBitmapMime1(bmp);  
  65.                             insertPhotoToEditText(ss);  
  66.                             count++;  
  67.                             inputBmpList.add(start,bmp);  
  68.                         }  
  69.                         sound=0;  
  70.                         soundCount=0;  
  71.                         break;  
  72.                     default:  
  73.                         break;  
  74.                 }  
  75.             }  
  76.         }  
  77.   
  78.         @Override  
  79.         public void onVolumeChanged(int volume, byte[] data) {  
  80.             showTip("当前正在说话,音量大小:" + volume);  
  81.             //LogUtil.L("返回音频数据:"+data.length);  
  82.             if(volume>5){  
  83.                 sound+=volume;  
  84.                 soundCount+=1;  
  85.             }  
  86.   
  87.         }  
  88.   
  89.         @Override  
  90.         public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {  
  91.         }  
  92.     };  



张静:

接下来完成MyApplication

1. onCreate

因为引用的包过多,实现多包问题(加载MultiDex)

解决7.0(VERSION_CODES为N)以上系统照相机启动失败导致APP崩溃问题:虚拟机策略

SDK初始化,启动后台服务,若已存在用户登陆信息,SDK将完成自动登陆

[java]  view plain  copy
  1. public void onCreate() {  
  2.     super.onCreate();  
  3.     mContext = getApplicationContext();  
  4.   
  5.     MultiDex.install(this);  
  6.     instance = this;  
  7.     // 解决7.0 以上系统照相机启动失败导致 APP 崩溃问题  
  8.     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {  
  9.         StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();  
  10.         StrictMode.setVmPolicy(builder.build());  
  11.     }  
  12.     sActivityStack = new Stack<>();  
  13.   
  14.     // 初始化网易云通讯 SDK  
  15.     NIMClient.init(this,getLoginInfo(),getOptions());  
  16. }  


2. 获得SDK配置信息

SDK配置外置存储根目录内置SD卡

SDK配置用户资料提醒(用户资料)

SDK配置状态栏提醒的配置:不需响铃,点击通知栏跳转到MainActivity,需要振动

[java]  view plain  copy
  1. private SDKOptions getOptions(){  
  2.      SDKOptions options = new SDKOptions();  
  3.   
  4.      // 该目录目前包含 log, file, image, audio, video, thumb 这6个目录。  
  5.      // 如果第三方 APP 需要缓存清理功能, 清理这个目录下面个子目录的内容即可。  
  6.      if (!new File(Constant.APP_CACHE_PATH).exists()){  
  7.          FileUtils.mkDir(Constant.APP_CACHE_PATH);  
  8.      }  
  9.      options.sdkStorageRootPath = Constant.APP_CACHE_PATH;  
  10.   
  11.      // 用户资料提供者, 目前主要用于提供用户资料,用于新消息通知栏中显示消息来源的头像和昵称  
  12.      options.userInfoProvider = new UserInfoProvider() {  
  13.          @Override  
  14.          public UserInfo getUserInfo(String account) {  
  15.              return null;  
  16.          }  
  17.   
  18.          @Override  
  19.          public int getDefaultIconResId() {  
  20.              return R.mipmap.app_logo_main;  
  21.          }  
  22.   
  23.          @Override  
  24.          public Bitmap getAvatarForMessageNotifier(String account) {  
  25.              return null;  
  26.          }  
  27.   
  28.          @Override  
  29.          public String getDisplayNameForMessageNotifier(String account, String sessionId,  
  30.                                                         SessionTypeEnum sessionType) {  
  31.             return account;  
  32.          }  
  33.   
  34.          @Override  
  35.          public Bitmap getTeamIcon(String tid) {  
  36.              return null;  
  37.          }  
  38.      };  
  39.   
  40.      // 配置是否需要预下载附件缩略图,默认为 true  
  41.      options.preloadAttach = true;  
  42.      StatusBarNotificationConfig config = new StatusBarNotificationConfig();  
  43.      config.ring = false;  
  44.      config.notificationEntrance = MainActivity.class;  
  45.      config.vibrate = true;  
  46.   
  47.      options.statusBarNotificationConfig = config;  
  48.      return options;  
  49.  }  

其中,FileUtils(文件工具类)

[java]  view plain  copy
  1. package com.ezreal.ezchat.commonlibrary.utils;  
  2.   
  3. import java.io.File;  
  4.   
  5. /** 
  6.  * 文件工具类 
  7.  * Created by 张静 
  8.  */  
  9.   
  10. public class FileUtils {  
  11.   
  12.     /** 
  13.      * 递归创建文件夹,从最上层文件夹开始,只要不存在就会新建 
  14.      * @param dirPath 文件夹完整路径 
  15.      */  
  16.     public static void mkDir(String dirPath) {  
  17.         String[] dirArray = dirPath.split("/");  
  18.         String pathTemp = "";  
  19.         for (int i = 1; i < dirArray.length; i++) {  
  20.             pathTemp = pathTemp + "/" + dirArray[i];  
  21.             File newF = new File(dirArray[0] + pathTemp);  
  22.             if (!newF.exists()) {  
  23.                 newF.mkdir();  
  24.             }  
  25.         }  
  26.     }  
  27. }  


3. 登陆用户信息

如果已经存在登陆用户信息,通过NimUserHandler后台自动登陆

否则返回null

[java]  view plain  copy
  1. private LoginInfo getLoginInfo(){  
  2.     String account = SharedPreferencesUtil.getStringSharedPreferences(this,  
  3.             Constant.LOCAL_LOGIN_TABLE, Constant.LOCAL_USER_ACCOUNT);  
  4.     String token = SharedPreferencesUtil.getStringSharedPreferences(this,  
  5.             Constant.LOCAL_LOGIN_TABLE, Constant.LOCAL_USER_TOKEN);  
  6.     if (!TextUtils.isEmpty(account) && !TextUtils.isEmpty(token)){  
  7.         LoginInfo info = new LoginInfo(account,token);  
  8.         NimUserHandler.getInstance().setMyAccount(account);  
  9.         return info;  
  10.     }  
  11.     return null;  
  12. }  


4.结束一个Activity

从堆栈中移除该activity,并finish该activity

[java]  view plain  copy
  1. public void finishActivity(Activity activity){  
  2.     sActivityStack.remove(activity);  
  3.     activity.finish();  
  4. }  


5. 结束所有Activity

[java]  view plain  copy
  1. public void finishAllActivity(){  
  2.     for (int i=0;i<sActivityStack.size();i++){  
  3.         if (sActivityStack.get(i) != null){  
  4.             sActivityStack.get(i).finish();  
  5.         }  
  6.     }  
  7. }  

6. 退出APP

结束进程,并释放资源

[java]  view plain  copy
  1. public void AppExit(){  
  2.     try {  
  3.         finishAllActivity();  
  4.         Process.killProcess(Process.myPid());  
  5.         System.exit(0);  
  6.     }catch (Exception e){  
  7.         e.printStackTrace();  
  8.     }  
  9. }  


附上完整MyApplication.java

[java]  view plain  copy
  1. package com.ezreal.ezchat;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.Application;  
  5. import android.content.Context;  
  6. import android.graphics.Bitmap;  
  7. import android.os.Build;  
  8. import android.os.Environment;  
  9. import android.os.Process;  
  10. import android.os.StrictMode;  
  11. import android.support.multidex.MultiDex;  
  12. import android.text.TextUtils;  
  13.   
  14. import com.ezreal.ezchat.activity.MainActivity;  
  15. import com.ezreal.ezchat.handler.NimUserHandler;  
  16. import com.ezreal.ezchat.utils.Constant;  
  17. import com.netease.nimlib.sdk.NIMClient;  
  18. import com.netease.nimlib.sdk.SDKOptions;  
  19. import com.netease.nimlib.sdk.StatusBarNotificationConfig;  
  20. import com.netease.nimlib.sdk.auth.LoginInfo;  
  21. import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;  
  22. import com.netease.nimlib.sdk.uinfo.UserInfoProvider;  
  23. import com.ezreal.ezchat.commonlibrary.utils.FileUtils;  
  24. import com.ezreal.ezchat.commonlibrary.utils.SharedPreferencesUtil;  
  25.   
  26.   
  27. import java.io.File;  
  28. import java.util.Stack;  
  29.   
  30. /** 
  31.  * Created by 张静 
  32.  */  
  33.   
  34. public class MyApplication extends Application {  
  35.     // 默认存放图片的路径  
  36.     public final static String DEFAULT_SAVE_IMAGE_PATH = Environment.getExternalStorageDirectory() + File.separator + "CircleDemo" + File.separator + "Images"  
  37.             + File.separator;  
  38.   
  39.     private static Context mContext;  
  40.     private static MyApplication instance;  
  41.     private static Stack<Activity> sActivityStack;  
  42.   
  43.     @Override  
  44.     public void onCreate() {  
  45.         super.onCreate();  
  46.         mContext = getApplicationContext();  
  47.   
  48.         MultiDex.install(this);  
  49.         instance = this;  
  50.         // 解决7.0 以上系统照相机启动失败导致 APP 崩溃问题  
  51.         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {  
  52.             StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();  
  53.             StrictMode.setVmPolicy(builder.build());  
  54.         }  
  55.         sActivityStack = new Stack<>();  
  56.   
  57.         // 初始化网易云通讯 SDK  
  58.         NIMClient.init(this,getLoginInfo(),getOptions());  
  59.     }  
  60.   
  61.     @Override  
  62.     protected void attachBaseContext(Context base) {  
  63.         super.attachBaseContext(base);  
  64.         MultiDex.install(this);  
  65.     }  
  66.   
  67.     private SDKOptions getOptions(){  
  68.         SDKOptions options = new SDKOptions();  
  69.   
  70.         // 该目录目前包含 log, file, image, audio, video, thumb 这6个目录。  
  71.         // 如果第三方 APP 需要缓存清理功能, 清理这个目录下面个子目录的内容即可。  
  72.         if (!new File(Constant.APP_CACHE_PATH).exists()){  
  73.             FileUtils.mkDir(Constant.APP_CACHE_PATH);  
  74.         }  
  75.         options.sdkStorageRootPath = Constant.APP_CACHE_PATH;  
  76.   
  77.         // 用户资料提供者, 目前主要用于提供用户资料,用于新消息通知栏中显示消息来源的头像和昵称  
  78.         options.userInfoProvider = new UserInfoProvider() {  
  79.             @Override  
  80.             public UserInfo getUserInfo(String account) {  
  81.                 return null;  
  82.             }  
  83.   
  84.             @Override  
  85.             public int getDefaultIconResId() {  
  86.                 return R.mipmap.app_logo_main;  
  87.             }  
  88.   
  89.             @Override  
  90.             public Bitmap getAvatarForMessageNotifier(String account) {  
  91.                 return null;  
  92.             }  
  93.   
  94.             @Override  
  95.             public String getDisplayNameForMessageNotifier(String account, String sessionId,  
  96.                                                            SessionTypeEnum sessionType) {  
  97.                return account;  
  98.             }  
  99.   
  100.             @Override  
  101.             public Bitmap getTeamIcon(String tid) {  
  102.                 return null;  
  103.             }  
  104.         };  
  105.   
  106.         // 配置是否需要预下载附件缩略图,默认为 true  
  107.         options.preloadAttach = true;  
  108.         StatusBarNotificationConfig config = new StatusBarNotificationConfig();  
  109.         config.ring = false;  
  110.         config.notificationEntrance = MainActivity.class;  
  111.         config.vibrate = true;  
  112.   
  113.         options.statusBarNotificationConfig = config;  
  114.         return options;  
  115.     }  
  116.   
  117.     private LoginInfo getLoginInfo(){  
  118.         String account = SharedPreferencesUtil.getStringSharedPreferences(this,  
  119.                 Constant.LOCAL_LOGIN_TABLE, Constant.LOCAL_USER_ACCOUNT);  
  120.         String token = SharedPreferencesUtil.getStringSharedPreferences(this,  
  121.                 Constant.LOCAL_LOGIN_TABLE, Constant.LOCAL_USER_TOKEN);  
  122.         if (!TextUtils.isEmpty(account) && !TextUtils.isEmpty(token)){  
  123.             LoginInfo info = new LoginInfo(account,token);  
  124.             NimUserHandler.getInstance().setMyAccount(account);  
  125.             return info;  
  126.         }  
  127.         return null;  
  128.     }  
  129.   
  130.     public static MyApplication getInstance(){  
  131.         return instance;  
  132.     }  
  133.   
  134.     public void addActivity(Activity activity){  
  135.         sActivityStack.add(activity);  
  136.     }  
  137.   
  138.     public void finishActivity(Activity activity){  
  139.         sActivityStack.remove(activity);  
  140.         activity.finish();  
  141.     }  
  142.   
  143.     public void finishAllActivity(){  
  144.         for (int i=0;i<sActivityStack.size();i++){  
  145.             if (sActivityStack.get(i) != null){  
  146.                 sActivityStack.get(i).finish();  
  147.             }  
  148.         }  
  149.     }  
  150.   
  151.     public void AppExit(){  
  152.         try {  
  153.             finishAllActivity();  
  154.             Process.killProcess(Process.myPid());  
  155.             System.exit(0);  
  156.         }catch (Exception e){  
  157.             e.printStackTrace();  
  158.         }  
  159.     }  
  160.     public static Context getContext(){  
  161.         return mContext;  
  162.     }  
  163.   
  164. }  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值