Android 监听截屏获取图像

最近有人问我微信发送截屏图像的功能,有人问我怎么实现,这里记录分享下。

我的做法就是用FileObserver。先摘一段FileOberver的介绍:

       FileObserver类是一个用于监听文件访问、创建、修改、删除、移动等操作的监听器,基于linux的inotify。 
FileObserver 是个抽象类,必须继承它才能使用。每个FileObserver对象监听一个单独的文件或者文件夹,如果监视的是一个文件夹,那么文件夹下所有的文件和级联子目录的改变都会触发监听的事件。其实不然,经过测试并不支持递归,对于监听目录的子目录中的文件改动,FileObserver 对象是无法收到事件回调的,不仅这样,监听目录的子目录本身的变动也收不到事件回调。原因是由 linux 的 inotify 机制本身决定的,基于 inotify 实现的 FileObserver 自然也不支持递归监听。
  FileObserver 是个抽象类,必须继承它才能使用

可以监听的事件类型:
ACCESS : 即文件被访问
MODIFY : 文件被修改
ATTRIB : 文件属性被修改,如 chmod、chown、touch 等
CLOSE_WRITE : 可写文件被 close
CLOSE_NOWRITE : 不可写文件被 close
OPEN : 文件被 open
MOVED_FROM : 文件被移走,如 mv
MOVED_TO : 文件被移来,如 mv、cp
CREATE : 创建新文件
DELETE : 文件被删除,如 rm
DELETE_SELF : 自删除,即一个可执行文件在执行时删除自己
MOVE_SELF : 自移动,即一个可执行文件在执行时移动自己
CLOSE : 文件被关闭,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
ALL_EVENTS : 包括上面的所有事件

接下来我们自定义自己的FileObserver来实现截屏文件存储好之后的监听。

public class ScreenshotObserver extends FileObserver {
    private static final String TAG = "ScreenshotObserver"; 
    private static final String PATH = Environment.getExternalStorageDirectory().toString() + "/Pictures/Screenshots/";

    private OnScreenshotTakenListener listener;
    private String lastTakenPath;

    public ScreenshotObserver(OnScreenshotTakenListener listener) {
        super(PATH, FileObserver.CLOSE_WRITE);
        this.listener = listener;
    }

    @Override
    public void onEvent(int event, String path) {
        if (path==null || event!=FileObserver.CLOSE_WRITE){
            //dont care
        }
        else if (lastTakenPath!=null && path.equalsIgnoreCase(lastTakenPath)){
            //had observer,ignore this
        }
        else {
            lastTakenPath = path;
            File file = new File(PATH+path);
            listener.onScreenshotTaken(Uri.fromFile(file));
            Log.i(TAG, "Send event to listener.");
        }
    }

    public void start() {
        super.startWatching();
    }

    public void stop() {
        super.stopWatching();
    }
}

OnScreenshotTakenListener的代码很简单,就是一个接口:

public interface OnScreenshotTakenListener {
    void onScreenshotTaken(Uri uri);
}

下面贴出测试的Activity代码:

public class TestScreenShotActivity extends Activity implements OnScreenshotTakenListener{
    private ImageView image;
    private ScreenshotObserver screenShotObserver;
    
    private static final int DEFAULT_WIDTH = 512;
    private static final int DEFAULT_HEIGHT = 384;
 
    private int width ;
    private int height;
    private int sampleSize = 1;
    private ContentResolver contentResolver ;
    private Handler hanlder = new Handler();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_screen_shot);
        image = (ImageView)findViewById(R.id.imageview);
        contentResolver = getContentResolver();
        screenShotObserver = new ScreenshotObserver(this);
        screenShotObserver.start();
    }
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        screenShotObserver.stop();
    }
    @Override
    public void onScreenshotTaken(Uri uri) {//not UI Thread
        // TODO Auto-generated method stub
        getBitmapSize(uri);
        final Bitmap bitmap = getBitmap(uri);
        if(bitmap != null){
            hanlder.post(new Runnable(){

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    image.setImageBitmap(bitmap);
                }
                
            });
            
        }
    }
    private void getBitmapSize(Uri uri){//get bitmap size before draw
        InputStream is = null;
        try {
           
            is = getInputStream(uri);
            
            BitmapFactory.Options options = new BitmapFactory.Options();  
            options.inJustDecodeBounds = true;  
            BitmapFactory.decodeStream(is, null, options); 
            
            width = options.outWidth;  
            height = options.outHeight;  
           
        }catch(IOException e) {
            e.printStackTrace();
        }finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException ignored) {
                }
            }
        }
    }
    private Bitmap getBitmap(Uri uri){
        Bitmap bitmap = null;
        InputStream is = null;
        try {
           
            try {
                is = getInputStream(uri);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            while ((width / sampleSize > DEFAULT_WIDTH * 2) || (height / sampleSize > DEFAULT_HEIGHT * 2)) {  
                sampleSize *= 2;  
            }  
            
            BitmapFactory.Options options = new BitmapFactory.Options();  
            options.inSampleSize = sampleSize;  
        
            bitmap = BitmapFactory.decodeStream(is, null, options);  
           
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException ignored) {
                }
            }
        }
        
        return bitmap;
    }
    
    private InputStream getInputStream(Uri mUri) throws IOException{
        try {
            if (mUri.getScheme().equals("file")) {
                return new java.io.FileInputStream(mUri.getPath());
            } else {//from database
                return contentResolver.openInputStream(mUri);
            }
        } catch (FileNotFoundException ex) {
            return null;
        }
    }
}

Note:别忘了加读写存储的权限,layout很简单,就一个imageview。

有问题交流~

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值