Android仿微信录制小视频

本文实例为大家分享了Android仿微信录制小视频的具体代码,供大家参考,具体内容如下

先上张图片看看效果

简单叙述下

  • 首先通过Camera类调用系统相机
  • 通过surfaceview绘制出来
  • 通过MediaRecorder来录制视频
  • 闪光灯 和 切换摄像头 需要重新配置Camera的参数
  • Camera预览界面画面拉升的原因是因为Surfaceview的大小与设定的比例不一致的

**本次版本更新了 切换前置摄像头录制视频问题
Android部分手机录制视频适配IOS手机问题 (OPPO手机部分不适配 目前启用的H264格式)**

完整的代码

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.media.MediaMetadataRetriever;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.tongxun.atongmu.dialog.CommonDialog;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class CircleViedoActivity extends Activity implements View.OnClickListener,MediaRecorder.OnErrorListener {

 private SurfaceView mSurfaceView;
 private SurfaceHolder mSurfaceHolder;
 private ProgressBar mProgressBar;
 private Button shoot_button;
 private ImageView circle_light_btn;
 private ImageView circle_change_camera_btn;
 private TextView circle_camera_time;

 private MediaRecorder mMediaRecorder;
 private Camera mCamera;
 private Timer mTimer;// 计时器
 private OnRecordFinishListener mOnRecordFinishListener;// 录制完成回调接口
 private int mWidth;// 视频分辨率宽度
 private int mHeight;// 视频分辨率高度
 private boolean isOpenCamera;// 是否一开始就打开摄像头
 private int mRecordMaxTime;// 一次拍摄最长时间
 private int mTimeCount;// 时间计数
 private int mNumberOfCameras=0;//手机摄像头的数量
 Bitmap bitmap;//图片缩略图
 private int screenWidth;
 public static File mVecordFile = null;// 文件
 private boolean isOpenFlash=false;
 private boolean isBackCamera=true;
 private int mbackCamera;
 private int mfrontCamera;
 private CommonDialog commonDialog;

 private static final int MOVICE_SUCCESS=1000;//录制完成
 private static final int MOVICE_FILE=1001;//录制失败

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_super_video);
  init_datas();
  init_view();
  set_datas();
  init_event();
 }

 private void init_datas() {
  isOpenCamera=true;//默认一开始就打开相机
  mRecordMaxTime=10;//设置录制的时间

  //获取手机摄像头的数量
  Camera.CameraInfo cameraInfo=new Camera.CameraInfo();
  mNumberOfCameras=Camera.getNumberOfCameras();
  for(int camidx=0;camidx<mNumberOfCameras;camidx++){
   Camera.getCameraInfo(camidx, cameraInfo);
   if(cameraInfo.facing==Camera.CameraInfo.CAMERA_FACING_BACK){
    mbackCamera=camidx;
   }else if(cameraInfo.facing==Camera.CameraInfo.CAMERA_FACING_FRONT){
    mfrontCamera=camidx;
   }
  }

 }

 private void init_view() {
  mWidth=640;
  mHeight=480;

  //获取屏幕的宽度
  screenWidth = getWindowManager().getDefaultDisplay().getWidth();
  mSurfaceView = (SurfaceView) findViewById(R.id.surfaceview);//预览界面
  mProgressBar = (ProgressBar) findViewById(R.id.progressBar);//进度条
  shoot_button = (Button) findViewById(R.id.shoot_button);//拍摄按钮
  circle_camera_time= (TextView) findViewById(R.id.circle_camera_time);
  circle_change_camera_btn= (ImageView) findViewById(R.id.circle_change_camera_btn);//切换摄像头
  circle_light_btn= (ImageView) findViewById(R.id.circle_light_btn);//开启闪光灯
  ViewGroup.LayoutParams params=mSurfaceView.getLayoutParams();
  params.height=(screenWidth*4)/3;
  params.width=screenWidth;
  mSurfaceView.setLayoutParams(params);

  top_model2_left_img= (ImageView)findViewById(R.id.top_model2_left_img);
  top_model2_left_img.setOnClickListener(this);
  top_model2_right_img= (ImageView)findViewById(R.id.top_model2_right_img);
  top_model2_right_img.setVisibility(View.INVISIBLE);
  top_model2_txt= (TextView)findViewById(R.id.top_model2_txt);
  top_model2_txt.setText("视频录制");
 }

 private void set_datas() {
  mSurfaceHolder = mSurfaceView.getHolder();
  mProgressBar.setMax(mRecordMaxTime);// 设置进度条最大量
  mSurfaceHolder.setKeepScreenOn(true);//设置屏幕常亮
  mSurfaceHolder.addCallback(new CustomCallBack());
  mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  circle_camera_time.setText("");
 }

 private void init_event() {
  circle_light_btn.setOnClickListener(this);
  circle_change_camera_btn.setOnClickListener(this);
  shoot_button.setOnTouchListener(new View.OnTouchListener() {
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
     record(new OnRecordFinishListener() {
      @Override
      public void onRecordFinish() {
       //录制时间达到最大值
       handler.sendEmptyMessage(MOVICE_SUCCESS);
      }
     });
    } else if (event.getAction() == MotionEvent.ACTION_UP) {
     if (mTimeCount > 1 && mTimeCount<10) { //防止达到最大值up事件
      //录制时间大于一秒
      handler.sendEmptyMessage(MOVICE_SUCCESS);
     } else if(mTimeCount<=1) {
      //删除小于一秒的视频
      if (getmVecordFile() != null) {
       getmVecordFile().delete();
      }
      handler.sendEmptyMessage(MOVICE_FILE);

     }
    }
    return true;
   }
  });
 }

 @Override
 protected void onResume() {
  super.onResume();
  if(mCamera!=null){
   freeCameraResource();
  }
  try {
   initCamera();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

 @Override
 public void onSaveInstanceState(Bundle outState) {
  super.onSaveInstanceState(outState);
  // mRecorderView.stop();
 }

 private Handler handler = new Handler() {
  @Override
  public void handleMessage(Message msg) {
   //停止拍摄
   stopRecord();
   switch (msg.what){
    case MOVICE_SUCCESS:
     String msgs = "确认上传吗?";
     commonDialog = new CommonDialog(CircleViedoActivity.this, new CommonDialog.GoCommonDialog() {
      @Override
      public void go() {
       finishActivity();
       commonDialog.dismiss();
      }
      @Override
      public void cancel() {
       //删除没有上传的视频
       if (getmVecordFile() != null) {
        getmVecordFile().delete();
       }
       commonDialog.dismiss();
      }
     }, msgs, "确定", "取消");
     commonDialog.show();

     break;
    case MOVICE_FILE:
     Toast.makeText(CircleViedoActivity.this, "视频录制时间太短", Toast.LENGTH_SHORT).show();
     break;
   }

  }
 };

 private void finishActivity() {
  stop();
  Bitmap bitmap = null;
  if (getmVecordFile() != null) {
   //得到文件 File类型
   File mfile = getmVecordFile();
   bitmap = getVideoThumbnail(mfile.toString());
  }

 /**
  * 部分Android手机缩略图拉不到,找到一种解决办法不是太满意 有没有大神提供思路
  */

  // VideoPlayerActivity.startActivity(this, mRecorderView.getVecordFile().toString());
  Intent intent = new Intent();
  intent.putExtra("bitmap",bitmap);
  setResult(RESULT_OK,intent);
  finish();
 }

 @Override
 public void onError(MediaRecorder mr, int what, int extra) {
  try {
   if (mr != null)
    mr.reset();
  } catch (IllegalStateException e) {
   e.printStackTrace();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 @Override
 public void onClick(View v) {
  switch (v.getId()){
   case R.id.circle_light_btn:
    //开启关闭闪光灯 默认关闭
    if(isOpenFlash){
     isOpenFlash=false;
     circle_light_btn.setImageResource(R.drawable.camera_light);
    }else {
     isOpenFlash=true;
     circle_light_btn.setImageResource(R.drawable.camera_no_light);
    }
    try {
     initCamera();
    } catch (IOException e) {
     e.printStackTrace();
    }
    break;
   case R.id.circle_change_camera_btn:
    if(isBackCamera){
     isBackCamera=false;
    }else {
     isBackCamera=true;
    }
    try {
     initCamera();
    } catch (IOException e) {
     e.printStackTrace();
    }
    break;
   case R.id.top_model2_left_img:
    stop();
    finish();
    break;
  }
 }

 private class CustomCallBack implements SurfaceHolder.Callback {
  @Override
  public void surfaceCreated(SurfaceHolder holder) {
   if (!isOpenCamera)
    return;
   try {
    initCamera();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }

  @Override
  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

  }

  @Override
  public void surfaceDestroyed(SurfaceHolder holder) {

  }
 }
 /**
  * 初始化摄像头
  */
 private void initCamera() throws IOException {
  if (mCamera != null) {
   freeCameraResource();
  }
  try {
   if(isBackCamera){
    mCamera = Camera.open(mbackCamera);//打开后摄像头
    setCameraParams(isOpenFlash);
   }else {
    mCamera=Camera.open(mfrontCamera);//打开前摄像头
   }
  } catch (Exception e) {
   e.printStackTrace();
   freeCameraResource();
  }
  if (mCamera == null)
   return;

  mCamera.setDisplayOrientation(90);
  mCamera.setPreviewDisplay(mSurfaceHolder);
  mCamera.startPreview();
  mCamera.unlock();
 }

 /**
  * 设置摄像头为竖屏
  */
 private void setCameraParams(Boolean isOpenFlash) {
  if (mCamera != null) {
   Camera.Parameters params = mCamera.getParameters();
   //获取预览的各种分辨率
   List<Camera.Size> supportedPreviewSizes = params.getSupportedPreviewSizes();
   params.set("orientation", "portrait");//竖屏录制
   params.setPreviewSize(mWidth, mHeight);//默认640*480
   params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);//持续对焦
   if(isBackCamera){
    if(isOpenFlash){
     //开启闪光灯
     params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);

    }else {
     //关闭闪光灯
     params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
    }

   }else {

   }
   mCamera.setParameters(params);
  }
 }

 /**
  * 释放摄像头资源
  */
 private void freeCameraResource() {
  if (mCamera != null) {
   mCamera.setPreviewCallback(null);
   mCamera.stopPreview();
   mCamera.lock();
   mCamera.release();
   mCamera = null;
  }
 }

 private void createRecordDir() {
  File sampleDir = new File(Environment.getExternalStorageDirectory() + File.separator + "ATOMImg/video/");
  if (!sampleDir.exists()) {
   sampleDir.mkdirs();
  }
  File vecordDir = sampleDir;
  // 创建文件
  try {
   mVecordFile = File.createTempFile("recording", ".mp4", vecordDir);//mp4格式

  } catch (IOException e) {
  }
 }

 /**
  * 初始化
  */
 private void initRecord() throws IOException {
  mMediaRecorder = new MediaRecorder();
  mMediaRecorder.reset();
  if (mCamera != null)
   mMediaRecorder.setCamera(mCamera);
  mMediaRecorder.setOnErrorListener(this);
  mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
  mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);// 视频源
  mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 音频源
  mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// 视频输出格式
  mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);// 音频格式
  mMediaRecorder.setVideoSize(mWidth, mHeight);// 设置分辨率:
  // mMediaRecorder.setVideoFrameRate(16);// 这个我把它去掉了,感觉没什么用
  mMediaRecorder.setVideoEncodingBitRate(1 * 1024 * 1024);// 设置帧频率,然后就清晰了
  if(isBackCamera) {
   mMediaRecorder.setOrientationHint(90);// 输出旋转90度,保持竖屏录制
  }else {
   mMediaRecorder.setOrientationHint(270);
  }mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);// 视频录制格式

----------

/**
  这里是配置摄像头的重点 因为我们录制视频需要适配IOS开发和Android不同版本的手机 而IOS和Android通配的视频格式不多 我们这里采用H264格式 它的兼容范围更广阔 主要解决的就是部分OPPO手机不适配问题
*/

----------

  // mediaRecorder.setMaxDuration(Constant.MAXVEDIOTIME * 1000);
  mMediaRecorder.setOutputFile(mVecordFile.getAbsolutePath());
  mMediaRecorder.prepare();
  try {
   mMediaRecorder.start();
  } catch (IllegalStateException e) {
   e.printStackTrace();
  } catch (RuntimeException e) {
   e.printStackTrace();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 /**
  * 录制完成回调接口
  */
 public interface OnRecordFinishListener {
  public void onRecordFinish();
 }

 /**
  * 录制
  * @param onRecordFinishListener
  */
 public void record(final OnRecordFinishListener onRecordFinishListener) {
  this.mOnRecordFinishListener = onRecordFinishListener;
  createRecordDir();//创建目录

  try {
   if (!isOpenCamera)// 如果未打开摄像头,则打开
    initCamera();//初始化摄像头
   initRecord();//初始化录制参数
   mTimeCount = 0;// 时间计数器重新赋值

   mTimer = new Timer();//创建一个定时器

   mTimer.schedule(new TimerTask() {

    @Override
    public void run() {
     // TODO Auto-generated method stub
     mTimeCount++;
     mProgressBar.setProgress(mTimeCount);// 设置进度条
     // handler.sendEmptyMessage(TIME_CHANGW);
     runOnUiThread(new Runnable() {
      @Override
      public void run() {
       circle_camera_time.setText(mTimeCount + "″");
      }
     });
     if (mTimeCount == mRecordMaxTime) {// 达到指定时间,停止拍摄
      //录制完成调用录制回调接口
      if (mOnRecordFinishListener != null)
       mOnRecordFinishListener.onRecordFinish();
     }
    }
   }, 0, 1000);
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
 /**
  * 停止拍摄
  */
 public void stop() {
  stopRecord();
  releaseRecord();
  freeCameraResource();
 }

 /**
  * 停止录制
  */
 public void stopRecord() {
  mProgressBar.setProgress(0);
  circle_camera_time.setText("");
  if (mTimer != null)
   mTimer.cancel();
  if (mMediaRecorder != null) {
   // 设置后不会崩
   mMediaRecorder.setOnErrorListener(null);
   mMediaRecorder.setPreviewDisplay(null);
   try {
    mMediaRecorder.stop();
   } catch (IllegalStateException e) {
    e.printStackTrace();
   } catch (RuntimeException e) {
    e.printStackTrace();
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 }

 /**
  * 获取的视频的位置
  * @return
  */
 public File getmVecordFile() {
  return mVecordFile;
 }

 /**
  * 释放资源
  */
 private void releaseRecord() {
  if (mMediaRecorder != null) {
   mMediaRecorder.setOnErrorListener(null);
   try {
    mMediaRecorder.release();
   } catch (IllegalStateException e) {
    e.printStackTrace();
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
  mMediaRecorder = null;
 }

 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
  if ((keyCode == KeyEvent.KEYCODE_BACK)) {
   stop();
   finish();
   return false;
  }else {
   return super.onKeyDown(keyCode, event);
  }

 }

 /**
  * 获取视频缩略图
  * @param filePath
  * @return
  */
 public Bitmap getVideoThumbnail(String filePath) {
  Bitmap bitmap = null;
  MediaMetadataRetriever retriever = new MediaMetadataRetriever();
  try {
   retriever.setDataSource(filePath);
   bitmap = retriever.getFrameAtTime();
  }
  catch(IllegalArgumentException e) {
   e.printStackTrace();
  }
  catch (RuntimeException e) {
   e.printStackTrace();
  }
  finally {
   try {
    retriever.release();
   }
   catch (RuntimeException e) {
    e.printStackTrace();
   }
  }
  return bitmap;
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();
  if(bitmap!=null){
   try {
    bitmap.recycle();
   } catch (Exception e) {
    e.printStackTrace();
   }
   bitmap=null;
  }

 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • Android仿微信拍摄短视频
  • Android实现微信朋友圈发本地视频功能
  • Android 微信小视频录制功能实现详细介绍
  • Android 录制手机屏幕视频生成GIF图片实例详解
  • Android自定义录制视频功能
  • 解决Android MediaRecorder录制视频过短问题
  • 汇总Android视频录制中常见问题
  • Android使用MediaRecorder类进行录制视频
(0)

相关推荐

  • Android实现微信朋友圈发本地视频功能

    一.前言 前一篇文章已经详细介绍了如何使用Xposed框架编写第一个微信插件:摇骰子和猜拳作弊器 本文继续来介绍如何使用Xposed框架编写第二个微信插件,可以将本地小视频发布到朋友圈的功能.在这之前我们还是要有老套路,准备工作要做好,这里还是使用微信6.3.9版本进行操作,准备工作: 1.使用apktool工具进行反编译,微信没有做加固防护,所以这个版本的微信包反编译是没有任何问题的. 2.借助于可视化反编译工具Jadx打开微信包,后续几乎重要分析都是借助这个工具来操作的. 二.猜想与假设 做

  • 解决Android MediaRecorder录制视频过短问题

    具体表现: 调用MediaRecorder的start()与stop()间隔不能小于1秒(有时候大于1秒也崩),否则必崩.  错误信息: java.lang.RuntimeException: stop failed. at android.media.MediaRecorder.stop(Native Method)  解决办法: 在stop以前调用setOnErrorListener(null);就行了! 相关代码: /** 开始录制 */ @Override public MediaPar

  • Android仿微信拍摄短视频

    近期做项目需要添加上传短视频功能,功能设置为类似于微信,点击开始拍摄,设置最长拍摄时间,经过研究最终实现了这个功能,下面就和大家分享一下,希望对你有帮助. 1.视频录制自定义控件: /** * 视频播放控件 */ public class MovieRecorderView extends LinearLayout implements OnErrorListener { private SurfaceView mSurfaceView; private SurfaceHolder mSurfa

  • Android使用MediaRecorder类进行录制视频

    我们提醒大家使用MediaRecorder录音录像的设置代码步骤一定要按照API指定的顺序来设置,否则报错 步骤为: 1.设置视频源,音频源,即输入源 2.设置输出格式 3.设置音视频的编码格式 一.首先看布局文件,这里有一个SurfaceView,这是一个绘制容器,可以直接从内存或者DMA等硬件接口取得图像数据, <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tool

  • Android自定义录制视频功能

    Android录制视频MediaRecorder+SurfaceView的使用方法,供大家参考,具体内容如下 先看效果图: <1>将视频动画显示到SurfaceView控件上 <2>使用MediaRecorder类进行视频的录制 常用的方法: mediaRecorder.reset(); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); //从照相机采集视频 mediaRecorder.setAudioS

  • 汇总Android视频录制中常见问题

    本文分享自己在视频录制播放过程中遇到的一些问题,主要包括: 视频录制流程 视频预览及SurfaceHolder 视频清晰度及文件大小 视频文件旋转 一.视频录制流程     以微信为例,其录制触发为按下(住)录制按钮,结束录制的触发条件为松开录制按钮或录制时间结束,其流程大概可以用下图来描述. 1.1.开始录制    根据上述流程及项目的编程惯例,可在onCreate()定义如下函数来完成功能: 初始化过程主要包括View,Data以及Listener三部分.在初始化View时,添加摄像头预览,

  • Android 录制手机屏幕视频生成GIF图片实例详解

    Android 录制手机屏幕视频生成GIF图片实例详解 无图无真相,在我们日常的网络交流中往往需要给交流对象提供直观的显示,而视频是一个很好的方式,但是视频需要播放器,还需要当做文件进行对点传输,并不是很方便.想CSDN这样的博客网站也并不支持在博客里放视频这种方式,除非你贴外链,太烦了不是么.最好是如下图这种gif方式,直观 今天来教大家一个易操作的录制方式.当然,一般只适合Android开发者.因为你需要有AndroidStudio 工具 AndroidStudio(完成手机屏幕的视频录制,

  • Android 微信小视频录制功能实现详细介绍

    Android 微信小视频录制功能 开发之前 这几天接触了一下和视频相关的控件, 所以, 继之前的微信摇一摇, 我想到了来实现一下微信小视频录制的功能, 它的功能点比较多, 我每天都抽出点时间来写写, 说实话, 有些东西还是比较费劲, 希望大家认真看看, 说得不对的地方还请大家在评论中指正. 废话不多说, 进入正题. 开发环境 最近刚更新的, 没更新的小伙伴们抓紧了 Android Studio 2.2.2 JDK1.7 API 24 Gradle 2.2.2 相关知识点 视频录制界面 Surf

  • Android仿微信录制小视频

    本文实例为大家分享了Android仿微信录制小视频的具体代码,供大家参考,具体内容如下 先上张图片看看效果 简单叙述下 首先通过Camera类调用系统相机 通过surfaceview绘制出来 通过MediaRecorder来录制视频 闪光灯 和 切换摄像头 需要重新配置Camera的参数 Camera预览界面画面拉升的原因是因为Surfaceview的大小与设定的比例不一致的 **本次版本更新了 切换前置摄像头录制视频问题 Android部分手机录制视频适配IOS手机问题 (OPPO手机部分不适

  • java制作仿微信录制小视频控件

    本文为用 MediaRecorder 录制小视频的控件,可以设置视频录制的时间.空间大小.初始时是否打开摄像头等. 此控件为组合控件,继承自 LinearLayout ,为防止出错,需实现 android.media.MediaRecorder.OnErrorListener 接口. 小视频录制界面 MovieRecorderView.java import java.io.File; import java.io.IOException; import java.util.Timer; imp

  • Android仿微信录制语音功能

    本文实例为大家分享了Android仿微信录制语音的具体代码,供大家参考,具体内容如下 前言 我把录音分成了两部分 1.UI界面,弹窗读秒 2.一个类(包含开始.停止.创建文件名功能) 第一部分 由于6.0权限问题,点击按钮申请权限通过则弹窗,如何申请权限 弹窗布局popw_record.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http:

  • Android仿微信长按录制视频并播放功能

    本文实例为大家分享了Android仿微信长按录制视频并播放功能的具体代码,供大家参考,具体内容如下 一.点击按钮进行录制 首先要获取摄像拍照的权限和读取权限 <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <use

  • Android仿微信语音消息的录制和播放功能

    一.简述 效果: 实现功能: 长按Button时改变Button显示文字,弹出Dialog(动态更新音量),动态生成录音文件,开始录音: 监听手指动作,规定区域.录音状态下手指划出规定区域取消录音,删除生成的录音文件: 监听手指动作.当手指抬起时,判断是否开始录音,录音时长是否过短,符合条件则提示录音时长过短:正常结束时通过回调返回该次录音的文件路径和时长. 4.点击录音列表的item时,播放动画,播放对应的音频文件. 主要用到4个核心类: 自定义录音按钮(AudioRecordButton):

  • Android 仿微信小程序入口动画

    目录 效果对比 流程分析 自定义ViewGroup 小程序缩放比例值计算 动画遮罩 MainActivity 效果对比 微信原版 仿照效果 流程分析 自定义ViewGroup 整个布局是通过自定义ViewGroup来管理的,在自定义ViewGroup中,子布局一共有两个,一个是小程序布局,一个是会话列表布局,然后按照上下分别摆放就可以了. package com.example.kotlindemo.widget.weixin import android.content.Context imp

  • Android仿微信键盘切换效果

    Android 仿微信的键盘切换(录音,表情,文字,其他),IM通讯,类似朋友圈只要涉及到文字等相关的app都会要涉及到键盘的处理,今天就给大家分享一下Android 仿微信的键盘切换. 效果图如下: Android 仿微信的键盘切换,实现了录音.表情.其他和软键盘显示之间的切换,其中解决了很多博客介绍的键盘切换时,软键盘显示切换到表情(其他)时,出现屏幕晃动的情况,以及点击和滑动键盘显示区域外时,软键盘隐藏的功能等,废话不多说直接上代码,以供大家参考: xml: <?xml version=&qu

  • Android仿微信录音功能(录音后的raw文件转mp3文件)

    现在很多时候需要用到录音,然后如果我们的App是ios和android两端的话,就要考虑录音的文件在两端都能使用,这个时候就需要适配,两端的录音文件都要是mp3文件,这样才能保证两边都能播放. 针对这个,封装了一个简单可用的录音控件. 使用方法: 1.在xml文件中添加 <ant.muxi.com.audiodemo.view.SoundTextView android:id="@+id/record_audio" android:text="按住开始录音"

  • Android仿微信进度弹出框的实现方法

    MainActivity: package com.ruru.dialogproject; import android.app.Activity; import android.os.Bundle; import android.view.View; public class MainActivity extends Activity implements Runnable { LoadingDialog dialog; @Override protected void onCreate(Bu

随机推荐