編輯:關於Android編程
最近比較忙,很久沒更新博客,今天我們仿一個美拍或者糗事百科的錄像功能。
首先確認步奏:
1、打開攝像頭;
2、開始錄制;
3、支持分段錄制,並支持分段刪除;
4、把分段錄制的視頻進行合並;
不說廢話了先上圖:
其實布局沒什麼好看的,布局就不看了,直接上代碼。
package com.example.shipin;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnErrorListener;
import android.media.MediaRecorder.OnInfoListener;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.Toast;
public class VideoNewActivity extends BaseActivity implements SurfaceHolder.Callback {
/** 視頻最大支持15秒 */
public static final int VIDEO_TIME_END = 15;
/** 視頻最少必須5秒 */
public static final int VIDEO_TIME = 5;
/** 最少得錄制多少秒 */
private ImageView img_at_last;
/** 閃現光標圖片 */
private ImageView img_shan;
/** 刪除錄制 */
private ImageView img_delete;
/** 開始錄制 */
private ImageButton img_start;
/** 確認 */
private ImageView img_enter;
/** 閃光燈切換 */
private ImageView img_flashlight;
/** 攝像頭切換 */
private ImageView img_camera;
/** 選擇錄像 */
private ImageView img_video;
/** 返回按鈕 */
private ImageView img_back;
/** 計時器 */
private TimeCount timeCount;
/** 錄制了多少秒 */
private int now;
/** 每次錄制結束時是多少秒 */
private int old;
/** 錄制進度控件 */
private LinearLayout linear_seekbar;
/** 屏幕寬度 */
private int width;
/** 偶數才執行 */
private int even;
/** 是否點擊刪除了一次 */
private boolean isOnclick = false;
/** 錄制視頻集合 */
private ArrayList list;
/** 錄制bean */
private VideoNewBean bean;
/** 為了能保存到bundler 錄制bean */
private VideoNewParentBean parent_bean;
/** 錄制視頻保存文件 */
private String vedioPath;
/** 合並之後的視頻文件 */
private String videoPath_merge;
/** 是否滿足視頻的最少播放時長 */
private boolean isMeet = false;
/** 錄制視頻的類 */
private MediaRecorder mMediaRecorder;
/** 攝像頭對象 */
private Camera mCamera;
/** 顯示的view */
private SurfaceView surfaceView;
/** 攝像頭參數 */
private Parameters mParameters;
// /** 視頻輸出質量 */
private CamcorderProfile mProfile;
/** 文本屬性獲取器 */
private SharedPreferences mPreferences;
/** 刷新界面的回調 */
private SurfaceHolder mHolder;
/** 1表示後置,0表示前置 */
private int cameraPosition = 1;
/** 路徑 */
private String Ppath = Environment.getExternalStorageDirectory().getAbsolutePath() + /videoTest/;
// /** 壓縮jni */
// private LoadJNI vk;
@Override
protected int getContentViewId() {
return R.layout.activity_video_new;
}
@SuppressWarnings(deprecation)
@Override
protected void findViews() {
img_camera = (ImageView) findViewById(R.id.video_new_img_right);
img_flashlight = (ImageView) findViewById(R.id.video_new_img_flashlight);
surfaceView = (SurfaceView) findViewById(R.id.video_new_surfaceview);
img_at_last = (ImageView) findViewById(R.id.video_new_img_time_atlast);
img_shan = (ImageView) findViewById(R.id.video_new_img_time_start);
img_delete = (ImageView) findViewById(R.id.video_new_img_delete);
img_start = (ImageButton) findViewById(R.id.video_new_img_start);
img_enter = (ImageView) findViewById(R.id.video_new_img_enter);
img_back = (ImageView) findViewById(R.id.video_new_img_back);
img_video = (ImageView) findViewById(R.id.video_new_img_video);
linear_seekbar = (LinearLayout) findViewById(R.id.video_new_seekbar);
width = getWindowManager().getDefaultDisplay().getWidth();
LayoutParams layoutParam = (LayoutParams) surfaceView.getLayoutParams();
// 高:寬 4 : 3
layoutParam.height = width / 3 * 4;
// 隱藏多少dp才能讓屏幕顯示正常像素
layoutParam.topMargin = -(width / 3 * 4 - width - DisplayUtil.dip2px(VideoNewActivity.this, 44));
surfaceView.setLayoutParams(layoutParam);
LayoutParams layoutParams = (LayoutParams) img_at_last.getLayoutParams();
layoutParams.leftMargin = width / VIDEO_TIME_END * VIDEO_TIME;
img_at_last.setLayoutParams(layoutParams);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
parent_bean.setList(list);
outState.putSerializable(parent_bean, parent_bean);
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
parent_bean = (VideoNewParentBean) savedInstanceState.getSerializable(parent_bean);
list = parent_bean.getList();
super.onRestoreInstanceState(savedInstanceState);
}
@SuppressWarnings(deprecation)
@Override
protected void init() {
handler.postDelayed(runnable, 0);
even = 0;
old = 0;
// 創建文件夾
File file = new File(Ppath);
if (!file.exists()) {
file.mkdir();
}
list = new ArrayList();
parent_bean = new VideoNewParentBean();
// 安裝一個SurfaceHolder.Callback
mHolder = surfaceView.getHolder();
mHolder.addCallback(this);
// 針對低於3.0的Android
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
readVideoPreferences();
}
@Override
protected void onStart() {
super.onStart();
// 獲取Camera實例
mCamera = getCamera();
if (mCamera != null) {
// 因為android不支持豎屏錄制,所以需要順時針轉90度,讓其游覽器顯示正常
mCamera.setDisplayOrientation(90);
mCamera.lock();
initCameraParameters();
}
}
@Override
protected void onPause() {
super.onPause();
releaseCamera();
}
/**
* 獲取攝像頭實例
*
* @version 1.0
* @createTime 2015年6月16日,上午10:44:11
* @updateTime 2015年6月16日,上午10:44:11
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此處輸入修改內容,若無修改可不寫.)
*
* @return
*/
private Camera getCamera() {
Camera camera = null;
try {
camera = Camera.open();
} catch (Exception e) {
camera = null;
}
return camera;
}
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
@Override
public void run() {
if (img_shan.isShown()) {
img_shan.setVisibility(View.GONE);
} else {
img_shan.setVisibility(View.VISIBLE);
}
handler.postDelayed(runnable, 500);
}
};
@SuppressLint(ClickableViewAccessibility)
@Override
protected void widgetListener() {
img_start.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (isOnclick) {
((ImageView) linear_seekbar.getChildAt(linear_seekbar.getChildCount() - 2)).setBackgroundColor(getResources().getColor(
R.color.ff1f8fe4));
}
even = 1;
img_delete.setVisibility(View.VISIBLE);
img_enter.setVisibility(View.VISIBLE);
img_video.setVisibility(View.GONE);
img_camera.setVisibility(View.GONE);
addView_Red();
// 構造CountDownTimer對象
timeCount = new TimeCount(30000 - old, 50);
timeCount.start();// 開始計時
startRecord();
break;
case MotionEvent.ACTION_UP:
old = now + old;
if (old >= VIDEO_TIME * 1000) {
isMeet = true;
}
timeCount.cancel();
addView_black();
stopRecord();
break;
}
return false;
}
});
/** 刪除按鈕 */
img_delete.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
isOnclick = false;
if (even % 2 == 0) {
if (linear_seekbar.getChildCount() > 1) {
linear_seekbar.removeViewAt(linear_seekbar.getChildCount() - 1);
linear_seekbar.removeViewAt(linear_seekbar.getChildCount() - 1);
}
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
File file = new File(list.get(list.size() - 1).getPath());
if (file.exists()) {
file.delete();
}
}
old -= list.get(list.size() - 1).getTime();
list.remove(list.size() - 1);
if (old < VIDEO_TIME * 1000) {
isMeet = false;
}
if (list.size() <= 0) {
img_delete.setVisibility(View.GONE);
img_enter.setVisibility(View.GONE);
img_video.setVisibility(View.VISIBLE);
img_camera.setVisibility(View.VISIBLE);
}
}
} else {
if (linear_seekbar.getChildCount() > 1) {
isOnclick = true;
((ImageView) linear_seekbar.getChildAt(linear_seekbar.getChildCount() - 2)).setBackgroundColor(getResources().getColor(
R.color.ff135689));
}
}
even++;
}
});
/** 開啟或關閉閃光燈 */
img_flashlight.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (cameraPosition != 0) {// 前置攝像頭的時候不能切換閃光燈
if (mParameters != null) {
if (mParameters.getFlashMode() != null && mParameters.getFlashMode().equals(Parameters.FLASH_MODE_TORCH)) {
mParameters.setFlashMode(Parameters.FLASH_MODE_OFF);
img_flashlight.setImageResource(R.drawable.img_video_new_flashlight_close);
} else if (mParameters.getFlashMode() != null && mParameters.getFlashMode().equals(Parameters.FLASH_MODE_OFF)) {
mParameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
img_flashlight.setImageResource(R.drawable.img_video_new_flashlight_open);
}
if (mCamera != null) {
mCamera.setParameters(mParameters);
}
}
}
}
});
/** 攝像頭切換 */
img_camera.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
switchCamera();
}
});
/** 確認按鈕 */
img_enter.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (isMeet) {
int size = list.size();
String[] strs = new String[size];
videoPath_merge = Ppath + System.currentTimeMillis() + .mp4;
for (int i = 0; i < size; i++) {
strs[i] = list.get(i).getPath();
}
try {
FUckTest.appendVideo(strs, videoPath_merge);
for (int i = size - 1; i >= 0; i--) {
File file = new File(list.get(i).getPath());
if (file.exists()) {
file.delete();
}
list.remove(i);
}
Intent it = new Intent(VideoNewActivity.this,VideoActivity.class);
it.putExtra(path, videoPath_merge);
startActivity(it);
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(VideoNewActivity.this, 視頻最少必須錄制5秒以上才能用!, Toast.LENGTH_LONG).show();
}
}
});
/** 選擇錄像按鈕 */
img_video.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//下一篇博客將會加進來
}
});
img_back.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (list.size() > 0) {
exitVideoNewDialog();
} else {
releaseCamera();
finish();
}
}
});
surfaceView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mParameters != null && mCamera != null) {
mParameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
try {
mCamera.setParameters(mParameters);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
if (list.size() > 0) {
exitVideoNewDialog();
} else {
releaseCamera();
finish();
}
}
return true;
}
return super.dispatchKeyEvent(event);
}
/**
* 彈出對話框
*
* @version 1.0
* @createTime 2015年6月16日,下午3:45:35
* @updateTime 2015年6月16日,下午3:45:35
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此處輸入修改內容,若無修改可不寫.)
*
*/
private void exitVideoNewDialog() {
AlertDialog.Builder builder = new Builder(VideoNewActivity.this);
builder.setMessage(確定放棄這段視頻嗎?);
builder.setTitle(溫馨提示);
builder.setPositiveButton(確認, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
for (int i = 0; i < list.size(); i++) {
File file = new File(list.get(i).getPath());
if (file.exists()) {
file.delete();
}
}
finish();
}
});
builder.create().show();
}
/**
* 切換攝像頭
*
* @version 1.0
* @createTime 2015年6月16日,上午10:40:17
* @updateTime 2015年6月16日,上午10:40:17
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此處輸入修改內容,若無修改可不寫.)
*
*/
@SuppressLint(NewApi)
private void switchCamera() {
// 切換前後攝像頭
int cameraCount = 0;
CameraInfo cameraInfo = new CameraInfo();
cameraCount = Camera.getNumberOfCameras();// 得到攝像頭的個數
for (int i = 0; i < cameraCount; i++) {
Camera.getCameraInfo(i, cameraInfo);// 得到每一個攝像頭的信息
if (cameraPosition == 1) {
// 現在是後置,變更為前置
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {// 代表攝像頭的方位,CAMERA_FACING_FRONT前置
// CAMERA_FACING_BACK後置
// 前置攝像頭時必須關閉閃光燈,不然會報錯
if (mParameters != null) {
if (mParameters.getFlashMode() != null && mParameters.getFlashMode().equals(Parameters.FLASH_MODE_TORCH)) {
mParameters.setFlashMode(Parameters.FLASH_MODE_OFF);
img_flashlight.setImageResource(R.drawable.img_video_new_flashlight_close);
}
if (mCamera != null) {
mCamera.setParameters(mParameters);
}
}
// 釋放Camera
releaseCamera();
// 打開當前選中的攝像頭
mCamera = Camera.open(i);
mCamera.setDisplayOrientation(90);
mCamera.lock();
// 通過surfaceview顯示取景畫面
setStartPreview(mHolder);
cameraPosition = 0;
break;
}
} else {
// 現在是前置, 變更為後置
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {// 代表攝像頭的方位,CAMERA_FACING_FRONT前置
// CAMERA_FACING_BACK後置
// 釋放Camera
releaseCamera();
// 打開當前選中的攝像頭
mCamera = Camera.open(i);
mCamera.setDisplayOrientation(90);
mCamera.lock();
// 通過surfaceview顯示取景畫面
setStartPreview(mHolder);
cameraPosition = 1;
break;
}
}
}
}
/**
* 定義一個倒計時的內部類
*
* @Description
* @author
* @version 1.0
* @date 2015-5-25
* @Copyright: Copyright (c) 2015 Shenzhen Utoow Technology Co., Ltd.
* All rights reserved.
*/
private class TimeCount extends CountDownTimer {
public TimeCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);// 參數依次為總時長,和計時的時間間隔
}
@Override
public void onFinish() {// 計時完畢時觸發
}
@Override
public void onTick(long millisUntilFinished) {// 計時過程顯示
now = (int) (30000 - millisUntilFinished - old);
if ((old > 0 && old > VIDEO_TIME * 1000) || (old == 0 && now > VIDEO_TIME * 1000)) {
img_enter.setEnabled(true);
}
if (linear_seekbar.getChildCount() > 0) {
ImageView img = (ImageView) linear_seekbar.getChildAt(linear_seekbar.getChildCount() - 1);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) img.getLayoutParams();
layoutParams.width = (int) (((float) now / 1000f) * (width / VIDEO_TIME_END)) + 1;
img.setLayoutParams(layoutParams);
}
}
}
/**
* 初始化攝像頭參數
*
* @version 1.0
* @createTime 2015年6月15日,下午4:53:41
* @updateTime 2015年6月15日,下午4:53:41
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此處輸入修改內容,若無修改可不寫.)
*
*/
@SuppressWarnings(deprecation)
private void initCameraParameters() {
// 初始化攝像頭參數
mParameters = mCamera.getParameters();
mParameters.setPreviewSize(mProfile.videoFrameWidth, mProfile.videoFrameHeight);
mParameters.setPreviewFrameRate(mProfile.videoFrameRate);
mParameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
// 設置白平衡參數。
String whiteBalance = mPreferences.getString(pref_camera_whitebalance_key, auto);
if (isSupported(whiteBalance, mParameters.getSupportedWhiteBalance())) {
mParameters.setWhiteBalance(whiteBalance);
}
// 參數設置顏色效果。
String colorEffect = mPreferences.getString(pref_camera_coloreffect_key, none);
if (isSupported(colorEffect, mParameters.getSupportedColorEffects())) {
mParameters.setColorEffect(colorEffect);
}
try {
mCamera.setParameters(mParameters);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 開始錄制
*
* @version 1.0
* @createTime 2015年6月15日,下午4:48:49
* @updateTime 2015年6月15日,下午4:48:49
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此處輸入修改內容,若無修改可不寫.)
*
*/
@SuppressLint(NewApi)
private void startRecord() {
try {
bean = new VideoNewBean();
vedioPath = Ppath + System.currentTimeMillis() + .mp4;
bean.setPath(vedioPath);
mCamera.unlock();
mMediaRecorder = new MediaRecorder();// 創建mediaRecorder對象
mMediaRecorder.setCamera(mCamera);
// 設置錄制視頻源為Camera(相機)
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setProfile(mProfile);
// mMediaRecorder.setVideoSize(560,560);//設置視頻大小(分辨率)
mMediaRecorder.setVideoEncodingBitRate(1024 * 1024);// 設置視頻一次寫多少字節(可調節視頻空間大小)
// 最大期限
mMediaRecorder.setMaxDuration(35 * 1000);
// 第4步:指定輸出文件 , 設置視頻文件輸出的路徑
mMediaRecorder.setOutputFile(vedioPath);
mMediaRecorder.setPreviewDisplay(mHolder.getSurface());
// // 設置保存錄像方向
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
if (cameraPosition == 1) {
//由於不支持豎屏錄制,後置攝像頭需要把視頻順時針旋轉90度、、但是視頻本身在電腦上看還是逆時針旋轉了90度
mMediaRecorder.setOrientationHint(90);
} else if (cameraPosition == 0) {
//由於不支持豎屏錄制,前置攝像頭需要把視頻順時針旋轉270度、、而前置攝像頭在電腦上則是順時針旋轉了90度
mMediaRecorder.setOrientationHint(270);
}
}
mMediaRecorder.setOnInfoListener(new OnInfoListener() {
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
}
});
mMediaRecorder.setOnErrorListener(new OnErrorListener() {
@Override
public void onError(MediaRecorder mr, int what, int extra) {
recodError();
}
});
// 第6步:根據以上配置准備MediaRecorder
mMediaRecorder.prepare();
mMediaRecorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
recodError();
} catch (IOException e) {
e.printStackTrace();
recodError();
} catch (RuntimeException e) {
e.printStackTrace();
recodError();
}
}
/**
* 異常處理
*
* @version 1.0
* @createTime 2015年6月16日,上午10:49:18
* @updateTime 2015年6月16日,上午10:49:18
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此處輸入修改內容,若無修改可不寫.)
*
*/
private void recodError() {
AlertDialog.Builder builder = new Builder(VideoNewActivity.this);
builder.setMessage(該設備暫不支持視頻錄制);
builder.setTitle(出錯啦);
builder.setPositiveButton(確認, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
builder.create().show();
}
/**
* 結束錄制
*
* @version 1.0
* @createTime 2015年6月15日,下午4:48:53
* @updateTime 2015年6月15日,下午4:48:53
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此處輸入修改內容,若無修改可不寫.)
*
*/
private void stopRecord() {
if (bean != null) {
if (list.size() > 0) {
bean.setTime(now - list.get(list.size() - 1).getTime());
} else {
bean.setTime(now);
}
bean.setCameraPosition(cameraPosition);
list.add(bean);
}
if (mMediaRecorder != null) {
try {
// 停止錄像,釋放camera
mMediaRecorder.setOnErrorListener(null);
mMediaRecorder.setOnInfoListener(null);
mMediaRecorder.stop();
// 清除recorder配置
mMediaRecorder.reset();
// 釋放recorder對象
mMediaRecorder.release();
mMediaRecorder = null;
// 沒超過3秒就刪除錄制所有數據
if (old < 3000) {
clearList();
}
} catch (Exception e) {
clearList();
}
}
}
/**
* 清楚數據
*
* @version 1.0
* @createTime 2015年6月25日,下午6:04:28
* @updateTime 2015年6月25日,下午6:04:28
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此處輸入修改內容,若無修改可不寫.)
*
*/
private void clearList() {
Toast.makeText(VideoNewActivity.this, 單次錄制視頻最少3秒, Toast.LENGTH_LONG).show();
if (linear_seekbar.getChildCount() > 1) {
linear_seekbar.removeViewAt(linear_seekbar.getChildCount() - 1);
linear_seekbar.removeViewAt(linear_seekbar.getChildCount() - 1);
}
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
File file = new File(list.get(list.size() - 1).getPath());
if (file.exists()) {
file.delete();
}
}
list.remove(list.size() - 1);
if (list.size() <= 0) {
img_delete.setVisibility(View.GONE);
img_enter.setVisibility(View.GONE);
img_video.setVisibility(View.VISIBLE);
img_camera.setVisibility(View.VISIBLE);
}
}
}
private static boolean isSupported(String value, List supported) {
return supported == null ? false : supported.indexOf(value) >= 0;
}
public static boolean getVideoQuality(String quality) {
return youtube.equals(quality) || high.equals(quality);
}
/**
* 設置攝像頭參數
*
* @version 1.0
* @createTime 2015年6月15日,下午5:12:31
* @updateTime 2015年6月15日,下午5:12:31
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此處輸入修改內容,若無修改可不寫.)
*
*/
private void readVideoPreferences() {
String quality = mPreferences.getString(pref_video_quality_key, high);
boolean videoQualityHigh = getVideoQuality(quality);
// 設置視頻質量。
Intent intent = getIntent();
if (intent.hasExtra(MediaStore.EXTRA_VIDEO_QUALITY)) {
int extraVideoQuality = intent.getIntExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
videoQualityHigh = (extraVideoQuality > 0);
}
videoQualityHigh = false;
mProfile = CamcorderProfile.get(videoQualityHigh ? CamcorderProfile.QUALITY_HIGH : CamcorderProfile.QUALITY_LOW);
mProfile.videoFrameWidth = (int) (mProfile.videoFrameWidth * 2.0f);
mProfile.videoFrameHeight = (int) (mProfile.videoFrameHeight * 2.0f);
mProfile.videoBitRate = 256000 * 3;
CamcorderProfile highProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
mProfile.videoCodec = highProfile.videoCodec;
mProfile.audioCodec = highProfile.audioCodec;
mProfile.fileFormat = MediaRecorder.OutputFormat.MPEG_4;
}
/**
* 添加紅色進度條
*
* @version 1.0
* @createTime 2015年6月15日,下午3:04:21
* @updateTime 2015年6月15日,下午3:04:21
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此處輸入修改內容,若無修改可不寫.)
*
*/
private void addView_Red() {
ImageView img = new ImageView(VideoNewActivity.this);
img.setBackgroundColor(getResources().getColor(R.color.ff1f8fe4));
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(DisplayUtil.dip2px(VideoNewActivity.this, 1), LinearLayout.LayoutParams.MATCH_PARENT);
img.setLayoutParams(layoutParams);
linear_seekbar.addView(img);
}
/**
* 添加黑色斷條
*
* @version 1.0
* @createTime 2015年6月15日,下午3:03:52
* @updateTime 2015年6月15日,下午3:03:52
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此處輸入修改內容,若無修改可不寫.)
*
*/
private void addView_black() {
ImageView img = new ImageView(VideoNewActivity.this);
img.setBackgroundColor(Color.BLACK);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(DisplayUtil.dip2px(VideoNewActivity.this, 2), LinearLayout.LayoutParams.MATCH_PARENT);
img.setLayoutParams(layoutParams);
linear_seekbar.addView(img);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
setStartPreview(holder);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// 先開啟在關閉 先開啟錄制在關閉可以 解決游覽的時候比較卡頓的現象,但是會有視頻開啟時聲音。打開這個功能時較慢
// startRecord();
// stopRecord();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
releaseCamera();
}
/**
* 設置camera顯示取景畫面,並預覽
*
* @version 1.0
* @createTime 2015年6月16日,上午10:48:15
* @updateTime 2015年6月16日,上午10:48:15
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此處輸入修改內容,若無修改可不寫.)
*
* @param holder
*/
private void setStartPreview(SurfaceHolder holder) {
try {
if (mCamera != null) {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
} catch (IOException e) {
}
}
/**
* 釋放Camera
*
* @version 1.0
* @createTime 2015年6月16日,上午10:38:08
* @updateTime 2015年6月16日,上午10:38:08
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此處輸入修改內容,若無修改可不寫.)
*
*/
private void releaseCamera() {
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCamera.stopPreview();// 停掉原來攝像頭的預覽
mCamera.release();
mCamera = null;
}
}
}
核心代碼就這麼點。bean之類的其他工具類的沒貼出來,如果需要看效果的朋友可以去下載demo;
希望大家多多關注我的博客,多多支持我。
如有好意見或更好的方式歡迎留言談論。
指紋識別已經成為智能手機新一代必備功能,指紋識別讓你的手指有了更多用途。除了免輸密碼解鎖,它還有更多便捷功能,例如:指紋支付購物,查看私密文件等
Android平台版本和設備碎片化很嚴重,因此從Win32平台移植到Android平台會有很多問題,下面是我們歸納的從Win32平台移植到Android平台遇到的一些問題
先來看下效果:控件內容比較簡單,就是一個普通的折線圖,上下分別帶有數字,點擊的時候顯示當天溫度的差值。 創建一個類繼承自View,並添加兩個構造方法:publi
由於項目需要做一個仿通訊錄搜索聯系人的功能,並且需要選中聯系人,即推薦好友的功能。所以就想寫一遍blog來介紹它是怎麼實現,以及是怎麼用的。好的,接下來,讓我為大家講解一