先在 manifest 里添加权限
<uses-permission android:name="android.permission.CAMERA" /> <!-- 调用摄像头权限 --> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- 录制视频/音频权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- sd卡读写权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <!-- 挂载sd卡 -->
layout 布局预览窗口 camera.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <SurfaceView android:id="@+id/arc_hf_video_view" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <TextView android:id="@+id/arc_hf_video_timer" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="40dp" android:textColor="#ffff0000" android:textSize="35dp" android:textStyle="bold" > </TextView> <LinearLayout android:id="@+id/arc_hf_video_btn" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentRight="true" android:gravity="center" android:orientation="vertical" > <Button android:id="@+id/arc_hf_video_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/arc_hf_btn_video_start" /> <Button android:id="@+id/arc_hf_img_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/arc_hf_btn_img" /> </LinearLayout> </RelativeLayout>
主Activity MCamera.java
public class MCamera extends Activity { private Button mVideoStartBtn; private SurfaceView mSurfaceview; private MediaRecorder mMediaRecorder; private SurfaceHolder mSurfaceHolder; private File mRecVedioPath; private File mRecAudioFile; private TextView timer; private int hour = 0; private int minute = 0; private int second = 0; private boolean bool; private int parentId; protected Camera camera; protected boolean isPreview; private Drawable iconStart; private Drawable iconStop; private boolean isRecording = true; // true表示没有录像,点击开始;false表示正在录像,点击暂停 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /* * 全屏显示 */ this.requestWindowFeature(Window.FEATURE_NO_TITLE); this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().setFormat(PixelFormat.TRANSLUCENT); setContentView(R.layout.map_video); iconStart = getResources().getDrawable( R.drawable.arc_hf_btn_video_start); iconStop = getResources().getDrawable(R.drawable.arc_hf_btn_video_stop); parentId = getIntent().getIntExtra("parentId", 0); timer = (TextView) findViewById(R.id.arc_hf_video_timer); mVideoStartBtn = (Button) findViewById(R.id.arc_hf_video_start); mSurfaceview = (SurfaceView) this.findViewById(R.id.arc_hf_video_view); // 设置计时器不可见 timer.setVisibility(View.GONE); // 设置缓存路径 mRecVedioPath = new File(Environment.getExternalStorageDirectory() .getAbsolutePath() + "/hfdatabase/video/temp/"); if (!mRecVedioPath.exists()) { mRecVedioPath.mkdirs(); } // 绑定预览视图 SurfaceHolder holder = mSurfaceview.getHolder(); holder.addCallback(new Callback() { @Override public void surfaceDestroyed(SurfaceHolder holder) { if (camera != null) { if (isPreview) { camera.stopPreview(); isPreview = false; } camera.release(); camera = null; // 记得释放 } mSurfaceview = null; mSurfaceHolder = null; mMediaRecorder = null; } @Override public void surfaceCreated(SurfaceHolder holder) { try { camera = Camera.open(); Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewFrameRate(5); // 每秒5帧 parameters.setPictureFormat(PixelFormat.JPEG);// 设置照片的输出格式 parameters.set("jpeg-quality", 85);// 照片质量 camera.setParameters(parameters); camera.setPreviewDisplay(holder); camera.startPreview(); isPreview = true; } catch (Exception e) { e.printStackTrace(); } mSurfaceHolder = holder; } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mSurfaceHolder = holder; } }); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); mVideoStartBtn.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { if (isRecording) { /* * 点击开始录像 */ if (isPreview) { camera.stopPreview(); camera.release(); camera = null; } second = 0; minute = 0; hour = 0; bool = true; if (mMediaRecorder == null) mMediaRecorder = new MediaRecorder(); else mMediaRecorder.reset(); mMediaRecorder.setPreviewDisplay(mSurfaceHolder .getSurface()); mMediaRecorder .setVideoSource(MediaRecorder.VideoSource.CAMERA); mMediaRecorder .setAudioSource(MediaRecorder.AudioSource.MIC); mMediaRecorder .setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mMediaRecorder .setVideoEncoder(MediaRecorder.VideoEncoder.H264); mMediaRecorder .setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); mMediaRecorder.setVideoSize(320, 240); mMediaRecorder.setVideoFrameRate(15); try { mRecAudioFile = File.createTempFile("Vedio", ".3gp", mRecVedioPath); } catch (IOException e) { e.printStackTrace(); } mMediaRecorder.setOutputFile(mRecAudioFile .getAbsolutePath()); try { mMediaRecorder.prepare(); timer.setVisibility(View.VISIBLE); handler.postDelayed(task, 1000); mMediaRecorder.start(); } catch (Exception e) { e.printStackTrace(); } showMsg("开始录制"); mVideoStartBtn.setBackgroundDrawable(iconStop); isRecording = !isRecording; } else { /* * 点击停止 */ try { bool = false; mMediaRecorder.stop(); timer.setText(format(hour) + ":" + format(minute) + ":" + format(second)); mMediaRecorder.release(); mMediaRecorder = null; videoRename(); } catch (Exception e) { e.printStackTrace(); } isRecording = !isRecording; mVideoStartBtn.setBackgroundDrawable(iconStart); showMsg("录制完成,已保存"); try { camera = Camera.open(); Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewFrameRate(5); // 每秒5帧 parameters.setPictureFormat(PixelFormat.JPEG);// 设置照片的输出格式 parameters.set("jpeg-quality", 85);// 照片质量 camera.setParameters(parameters); camera.setPreviewDisplay(mSurfaceHolder); camera.startPreview(); isPreview = true; } catch (Exception e) { e.printStackTrace(); } } } }); Button btnImgStart = (Button) findViewById(R.id.arc_hf_img_start); btnImgStart.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mMediaRecorder != null) { try { bool = false; mMediaRecorder.stop(); timer.setText(format(hour) + ":" + format(minute) + ":" + format(second)); mMediaRecorder.release(); mMediaRecorder = null; videoRename(); } catch (Exception e) { e.printStackTrace(); } isRecording = !isRecording; mVideoStartBtn.setBackgroundDrawable(iconStart); showMsg("录制完成,已保存"); try { camera = Camera.open(); Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewFrameRate(5); // 每秒5帧 parameters.setPictureFormat(PixelFormat.JPEG);// 设置照片的输出格式 parameters.set("jpeg-quality", 85);// 照片质量 camera.setParameters(parameters); camera.setPreviewDisplay(mSurfaceHolder); camera.startPreview(); isPreview = true; } catch (Exception e) { e.printStackTrace(); } } if (camera != null) { camera.autoFocus(null); camera.takePicture(null, null, new PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); Matrix matrix = new Matrix(); // 设置缩放 matrix.postScale(5f, 4f); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); String path = Environment .getExternalStorageDirectory() .getAbsolutePath() + "/hfdatabase/img/" + String.valueOf(parentId) + "/"; String fileName = new SimpleDateFormat( "yyyyMMddHHmmss").format(new Date()) + ".jpg"; File out = new File(path); if (!out.exists()) { out.mkdirs(); } out = new File(path, fileName); try { FileOutputStream outStream = new FileOutputStream( out); bitmap.compress(CompressFormat.JPEG, 100, outStream); outStream.close(); camera.startPreview(); } catch (Exception e) { e.printStackTrace(); } showMsg("拍照成功"); } }); // 拍照 } } }); } /* * 消息提示 */ private Toast toast; public void showMsg(String arg) { if (toast == null) { toast = Toast.makeText(this, arg, Toast.LENGTH_SHORT); } else { toast.cancel(); toast.setText(arg); } toast.show(); } /* * 生成video文件名字 */ protected void videoRename() { String path = Environment.getExternalStorageDirectory() .getAbsolutePath() + "/hfdatabase/video/" + String.valueOf(parentId) + "/"; String fileName = new SimpleDateFormat("yyyyMMddHHmmss") .format(new Date()) + ".3gp"; File out = new File(path); if (!out.exists()) { out.mkdirs(); } out = new File(path, fileName); if (mRecAudioFile.exists()) mRecAudioFile.renameTo(out); } /* * 定时器设置,实现计时 */ private Handler handler = new Handler(); private Runnable task = new Runnable() { public void run() { if (bool) { handler.postDelayed(this, 1000); second++; if (second >= 60) { minute++; second = second % 60; } if (minute >= 60) { hour++; minute = minute % 60; } timer.setText(format(hour) + ":" + format(minute) + ":" + format(second)); } } }; /* * 格式化时间 */ public String format(int i) { String s = i + ""; if (s.length() == 1) { s = "0" + s; } return s; } /* * 覆写返回键监听 */ @Override public void onBackPressed() { if (mMediaRecorder != null) { mMediaRecorder.stop(); mMediaRecorder.release(); mMediaRecorder = null; videoRename(); } finish(); } @Override protected void onPause() { super.onPause(); onBackPressed(); } }
浏览图片/视频 FileShow.java
public class FileShow extends Activity { private static final int MENU_DELETE = Menu.FIRST; private static final int MENU_RENAME = Menu.FIRST + 1; private File[] files; private String[] names; private String[] paths; private GridView fileGrid; private BaseAdapter adapter = null; private String path; private EditText etRename; private File file; protected void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.map_file_show); path = getIntent().getStringExtra("path"); File file = new File(path); files = file.listFiles(); fileGrid = (GridView) findViewById(R.id.arc_hf_file_show); adapter = new fileAdapter(this); fileGrid.setAdapter(adapter); showFileItems(); fileGrid.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { File f = new File(paths[arg2]); Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(android.content.Intent.ACTION_VIEW); String type = thisFileType(names[arg2]); intent.setDataAndType(Uri.fromFile(f), type); startActivity(intent); } }); // 注册上下文菜单 registerForContextMenu(fileGrid); } /* * 覆写上下文菜单 */ @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); AdapterView.AdapterContextMenuInfo info = null; try { info = (AdapterView.AdapterContextMenuInfo) menuInfo; } catch (ClassCastException e) { return; } menu.setHeaderTitle(names[info.position]); menu.add(0, MENU_DELETE, 1, "删除"); menu.add(0, MENU_RENAME, 2, "重命名"); } /* * 上下文菜单监听 */ @Override public boolean onContextItemSelected(MenuItem item) { AdapterContextMenuInfo info = (AdapterContextMenuInfo) item .getMenuInfo(); File file = new File(paths[info.position]); switch (item.getItemId()) { case MENU_DELETE: file.delete(); showFileItems(); return true; case MENU_RENAME: fileRename(file); return true; default: return super.onContextItemSelected(item); } } /* * 获取文件 */ private void showFileItems() { File file = new File(path); files = file.listFiles(); int count = files.length; names = new String[count]; paths = new String[count]; for (int i = 0; i < count; i++) { File f = files[i]; names[i] = f.getName(); paths[i] = f.getPath(); } adapter.notifyDataSetChanged(); } /* * 获取文件类型 */ public static String thisFileType(String name) { String type = ""; String end = name.substring(name.lastIndexOf(".") + 1, name.length()) .toLowerCase(); if (end.equals("jpg")) { type = "image"; } else if (end.equals("3gp")) { type = "video"; } else { type = "*"; } type += "/*"; return type; } /** * 重命名 */ private void fileRename(File file) { this.file = file; View view = getLayoutInflater().inflate(R.layout.map_file_rename, null); etRename = (EditText) view.findViewById(R.id.arc_hf_file_rename); new AlertDialog.Builder(this).setView(view) .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String newName = etRename.getText().toString().trim(); File newFile = new File(path, newName); if (newFile.exists()) { showMsg(newName + "已经存在,请重新输入"); } else FileShow.this.file.renameTo(newFile); showFileItems(); } }).setNegativeButton("取消", null).show(); } /* * 消息提示 */ private Toast toast; public void showMsg(String arg) { if (toast == null) { toast = Toast.makeText(this, arg, Toast.LENGTH_SHORT); } else { toast.cancel(); toast.setText(arg); } toast.show(); } /* * File adapter设置 */ class fileAdapter extends BaseAdapter { Context context; public fileAdapter(Context context) { this.context = context; } @Override public int getCount() { return files.length; } @Override public Object getItem(int arg0) { // return files[arg0]; return names[arg0]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { String type = thisFileType(names[position]); convertView = getLayoutInflater().inflate(R.layout.map_file_item, null); ImageView icon = (ImageView) convertView .findViewById(R.id.arc_hf_file_icon); TextView name = (TextView) convertView .findViewById(R.id.arc_hf_file_name); if (type.equals("video/*")) { Bitmap videoIcon = ThumbnailUtils.createVideoThumbnail( paths[position], Video.Thumbnails.MINI_KIND); icon.setImageBitmap(videoIcon); } else if (type.equals("image/*")) { Bitmap bitmap = BitmapFactory.decodeFile(paths[position]); Bitmap imgIcon = ThumbnailUtils.extractThumbnail(bitmap, 150, 120); icon.setImageBitmap(imgIcon); } name.setText(names[position]); return convertView; } } }
缩略图加载这一块速度特别慢,希望会异步加载缩略图的同学能功能交流一下
完整代码下载