转发自eoehttp://www.eoeandroid.com/thread-278012-1-1.html

package com.example.backstagecamera;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.util.List;

import java.util.Timer;

import java.util.TimerTask;

import android.annotation.TargetApi;

import android.app.Activity;

import android.content.Context;

import android.content.Intent;

import android.content.res.Configuration;

import android.graphics.PixelFormat;

import android.hardware.Camera;

import android.hardware.Camera.Parameters;

import android.hardware.Camera.PictureCallback;

import android.hardware.Camera.ShutterCallback;

import android.hardware.Camera.Size;

import android.media.AudioManager;

import android.media.ToneGenerator;

import android.net.Uri;

import android.os.Build;

import android.os.Environment;

import android.util.Log;

import android.view.MotionEvent;

import android.view.Surface;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

import android.view.View;

import android.view.WindowManager;

import android.widget.Toast;

public class FloatView {

private static WindowManager wm;

private static WindowManager.LayoutParams params;

private Camera mCamera;

private CameraPreview mPreview ;

private Context context;

private ToneGenerator mTone;

public FloatView(Context context) {

super();

this.context = context;

}

public void mFloatView(){

wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

params = new WindowManager.LayoutParams();

System.out.println("进入悬浮窗!!!!!!!!");

/*

* 如果设置为params.type = WindowManager.LayoutParams.TYPE_PHONE;

* 那么优先级会降低一些, 即拉下通知栏不可见

*/

params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;

params.format = PixelFormat.RGBA_8888; // 设置图片格式,效果为背景透明

/*

* 下面的flags属性的效果形同“锁定”。

* 悬浮窗不可触摸,不接受任何事件,同时不影响后面的事件响应。

* */

params.flags=WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL

| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

// params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL

// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

// 设置悬浮窗的长得宽

params.width = 1;

params.height = 1;

mPreview = new CameraPreview(context);

wm.addView(mPreview, params);

Timer timer = new Timer();

timer.schedule(new TimerTask() {

int index = 0;

@Override

public void run() {

//第一个参数设置为null,就可以静音拍照了

mCamera.takePicture(shutterCallback, null, jpegCallback);

}

}, 1000); //延迟1秒拍照

}

//照相机的快门监听,一般用来播放拍照声音

private ShutterCallback shutterCallback = new ShutterCallback(){

public void onShutter() {

if(mTone == null){

mTone = new ToneGenerator(AudioManager.STREAM_MUSIC,ToneGenerator.MAX_VOLUME);

}

mTone.startTone(ToneGenerator.TONE_PROP_BEEP2);

}

};

//得到jpeg图片并且保存

private PictureCallback jpegCallback = new PictureCallback(){

public void onPictureTaken(byte[] data, Camera camera) {

Parameters ps = camera.getParameters();

if(ps.getPictureFormat() == PixelFormat.JPEG){

String path = save(data);

Uri uri = Uri.fromFile(new File(path));

// Intent intent = new Intent();

// intent.setAction("android.intent.action.VIEW");

// intent.setDataAndType(uri, "image/jpeg");

// startActivity(intent);

}

}

};

//设置保存地址

private String save(byte[] data){

String saveDir = Environment.getExternalStorageDirectory().toString()+"/backstageCamera/image/";

String fileName = System.currentTimeMillis()+".jpg";

try {

File dirFile = new File(saveDir);

if (!dirFile.exists()) {

dirFile.mkdirs();

}

File file = new File(saveDir, fileName);

if (!file.exists()) {

file.createNewFile();

}

FileOutputStream fos = new FileOutputStream(file,true);

fos.write(data);

} catch (Exception e) {

e.printStackTrace();

return null;

}

return saveDir+fileName;

}

//预览界面CameraPreview

@TargetApi(9)

class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

SurfaceHolder mHolder;

public CameraPreview(Context context) {

super(context);

System.out.println("进入CameraPreview!!!!!!!!");

mHolder = getHolder();

mHolder.addCallback(this);

//mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // 4.0+ auto

}

int cameraCount = 0;

public void surfaceCreated(SurfaceHolder holder) {

try {

mCamera = Camera.open(1); //第二次创建失败

} catch (RuntimeException e) {

e.printStackTrace();

mCamera = null;

}

}

public void surfaceDestroyed(SurfaceHolder holder) {

mCamera.stopPreview();

mCamera.release();

mCamera = null;

}

public void surfaceChanged(SurfaceHolder holder, int format, int w,

int h) {

//已经获得Surface的width和height,设置Camera的参数

System.out.println("mCamera = "+ mCamera); //第二次是null,这是个bug

Camera.Parameters parameters = mCamera.getParameters();

parameters.setPreviewSize(w, h);

mCamera.setParameters(parameters);

//开始预览

mCamera.startPreview();

}

}

}

拍照实现真正的无预览是不现实的,因为把预览界面去掉,Camera是不同意你这么干的,那这咋办呢? 这个好解决...无法做到真正的无预览,那就把预览界面做到足够小,用户看不见就行了.实现后台操作,一般想法是用service,但是有么有想过...service是不让设置界面的~~~但是Camera又要有一个预览界面,这咋办?!我想过用service做一个中介,调用其他的某个东西实现在Luncher拍摄,这个东西要可以设置界面,而且又出现在Luncher~我用的是悬浮窗(受到启发的),所以在代码里,我用到了悬浮窗,并且把悬浮窗的大小设置成足够小,这就解决问题了.

其实这个demo里,我没有用service,因为这只是一个demo,我是在activity的ondestory中调用的,这里出现一个bug~~~在第一次回到Luncher的时候,拍摄正常,当再次打开程序并再次回到Luncher的时候,拍摄会出现这个问题:java.lang.RuntimeException: Fail to connect to camera service,说我的Camera连接失败,网上搜了一下,别人的答案好像不太实用,所以有知道怎么解决的人能帮帮忙告诉一下,还有一个问题,就是拍照结束以后,照片是横向的,因为项目比较急,老大还要我研究别的东西,所以这个问题就暂时没解决,希望有人解决了能告诉我......

这个东东具体怎么用~~~打开应用后,按下back回到Luncher,几秒钟后听到快门的声音,这就搞定了,快门声音可以在代码里去掉

本人菜鸟,代码很笨,厉害的多指导一下...由于需求是无预览,然后上传照片到服务器,所以压根就没打算把拍好的照片展示出来,如果想看拍照结果的,就连上USB,到第三方手机助手中打开文件拖出来看吧...

更多相关文章

  1. android > 屏蔽掉返回键
  2. Android(安卓)跳转到应用设置详情界面
  3. android 刷新View
  4. android 图片点击一下就放大到全屏,再点一下就回到原界面
  5. Android界面编程——Android高级UI组件(三)
  6. Android仿腾讯视频实现悬浮窗效果
  7. Android之应用首次使用的欢迎界面实例
  8. android的全屏和屏幕高宽的获取
  9. Google用户登录界面 Android实现

随机推荐

  1. 【Android】loadData与loadDataWithBaseU
  2. Android(安卓)System Bring Up
  3. 智能手机软件平台 Android(安卓)VS iPhon
  4. Android(安卓)目录选择器实现
  5. Building Android(安卓)notifications 2.
  6. Android(安卓)之获取图片及视频缩略图
  7. android字母导航条实现(原创)
  8. android bluetooth UUID蓝牙查询表
  9. android 简单的音乐播放
  10. android sdk 版本以及对应 API level