Android 静默拍摄

引言:
在做用户的头像时,忽然想到前段时间(可能是很久以前了),支付宝传出偷偷拍摄用户的生活照,真实头像,被喷的很厉害。然而作为Android开发者的我第一反应竟然是握草,他是怎么实现的。在我印象中,iOS对权限的控制是很严格的,偷偷调起摄像头这种行为应该是很困难的。然而Android4.2之前可以说开发者几乎拥有了系统权限,能力之强简直可怕。而现在Android已经到了7.0,虽然大多说用户还是在4.4到6.0的。我想我也来做一个静默拍摄的app。

正文:
所谓静默拍摄就是在用户毫无感知的情况下拍摄。
一般的拍照都会有预览区域,拍照声。去掉这些东西才算是真正意义上的静默拍摄。
首先,做了一个非常正常的自拍软件,就一个按钮。拍完之后存到文件夹的一个位置。然后我试了一下,完全ok并没有什么难度。然后就是清空surfaceView了。我首先想到的就是setVisiblity为gone,然后就报错了。很尴尬。下一个方案就是用高度和宽度都是0的方法,然而并没有什么卵用,更加尴尬。
然后想想没有有什么好办法了那就把这个surfaceView盖住好了,非常完美,随便搞一搞就盖住了,然后照片照样拍。合理。
但是“咔嚓”一声的拍照声实在令人尴尬,然后我就想到了静音,在页面打开的时候就设置静音。看上去这是一个非常稳健的方法,然后就发生了更加尴尬的事情。设置静音的时候,手机振动了一下,震一下也就算了,关键是还没有把拍照的声音去除。然后我就去查了查了相机音量应该是哪个。之后悲催的事情就发生了:
Google的Android开发者为了Android用户的用户体验,也为了避免开发者开发出静默拍摄的app从而侵犯了隐私,他们就把快门声音的播放函数写在了拍照的方法里面,还是写在framework层的。瞬间我就很难过了。作为一个平凡的第三方开发者,我并没有那么多权限去改变framework层的方法。
然后智慧的我决定曲线救国。因为在预览的时候,并没有进行拍照,但实际上我们已经拿到了相机带来的图片流。这很关键。然后我就把这个图片流变成了bitmap,然后保存到了本地,接着就把相机关了。神不知鬼不觉地把自拍拿到了。当然其中有一点小问题,比如图片编码,图片旋转,本地存储,获取帧图像都是各种各样的问题。但这些都是可以解决的。思路依旧是我上面提到的思路,各种表现方式可以由大家自己搞。

public class MainActivity extends AppCompatActivity {
   
    static final String TAG =  "CAMERA ACTIVITY";

    //Camera object
    Camera mCamera;
    //Preview surface
    SurfaceView surfaceView;
    //Preview surface handle for callback
    SurfaceHolder surfaceHolder;
    //Camera button
    Button btnCapture;
    //Note if preview windows is on.
    boolean previewing;

    int mCurrentCamIndex = 0;
    private AudioManager manager;
    private int volumn;
    private boolean canTake=false;
    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnCapture = (Button) findViewById(R.id.btn_capture);
        imageView =(ImageView)findViewById(R.id.iv);
        btnCapture.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View arg0) {
               canTake=true;
            }
        });

        surfaceView = (SurfaceView) findViewById(R.id.surfaceView1);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(new SurfaceViewCallback());
        //surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    }

    public void getSurfacePic(byte[] data, Camera camera,String name){
        Camera.Size size = camera.getParameters().getPreviewSize();
        YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
        if(image!=null){
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            image.compressToJpeg(new Rect(0, 0, size.width, 
  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值