欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现调用系统摄像机拍照、录像,选取系统图片。

程序员文章站 2022-03-12 21:49:32
MainActivity:public class MainActivity extends AppCompatActivity { private ImageView iv; private VideoView videoView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); set...

MainActivity:

public class MainActivity extends AppCompatActivity {

    private ImageView iv;

    private VideoView videoView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv = (ImageView) findViewById(R.id.iv);
        videoView = (VideoView) findViewById(R.id.video);
    }

    public void doClick(View view) {
        switch (view.getId()) {
            case R.id.btn_pick_image:
                // TODO 选取系统相册图片
                doPickImageFromSystem();
                break;
            case R.id.btn_open_camera_for_image:
                // TODO 打开相机拍照
                doOpenCameraForImage();
                break;
            case R.id.btn_open_camera_for_video:
                // TODO 打开相机录像
                doOpenCameraForVideo();
                break;
        }
    }

    private void doPickImageFromSystem() {
        /**
         * 参数一:打开系统相册的ACTION
         * 参数二:返回数据的方式(从系统相册的数据库获取)
         */
        CameraUtils.pickImageFromSystem(this);
    }

    private void doOpenCameraForImage() {

        CameraUtils.openCameraForImage(this);
    }

    private void doOpenCameraForVideo() {

        CameraUtils.openCameraForVideo(this);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //当结果码为RESULT_OK时,表示用户有效
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case CameraUtils.RequestCode.FLAG_REQUEST_SYSTEM_IMAGE:

                    String path = CameraUtils.getImagePathFromSystem(this, data);
                    if (path != null) {
                        iv.setImageBitmap(BitmapFactory.decodeFile(path));
                    }
                    break;
                case CameraUtils.RequestCode.FLAG_REQUEST_CAMERA_IMAGE:
                    //TODO 处理从相机返回的图片数据
                    if (data != null) {
                        Bitmap bm = data.getParcelableExtra("data");

                        iv.setImageBitmap(bm);
                    } else {
                        Bitmap bm = BitmapFactory.decodeFile(CameraUtils.CAMERA_IMAGE);
                        iv.setImageBitmap(bm);
                    }

                    break;
                case CameraUtils.RequestCode.FLAG_REQUEST_CAMERA_VIDEO:
                    //TODO 处理从相机返回的视频数据
                    videoView.setVideoURI(data.getData());
                    videoView.start();
                    break;
            }
        } else {
            Log.i("info", "取消用户操作");
        }
    }
}

CameraUtils:

public class CameraUtils
{
    public static final String CAMERA_IMAGE = "/sdcard/test.jpg";

    public static final String CAMERA_VIDEO = "/sdcard/test.mp4";

    public static void pickImageFromSystem(Activity activity)
    {
        /**
         * 参数一:打开系统相册的ACTION 参数二:返回数据的方式(从系统相册的数据库获取)
         */
        Intent intent = new Intent(Intent.ACTION_PICK,
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        activity.startActivityForResult(intent,
                RequestCode.FLAG_REQUEST_SYSTEM_IMAGE);
    }

    public static String getImagePathFromSystem(Activity activity, Intent data)
    {
        // TODO 处理从相册返回的图片数据
        Uri uri = data.getData();// 使用getData方法获取要调用的接口
        // 第二个参数表示要查询的数据的字段名
        Cursor c = activity.getContentResolver().query(uri,
                new String[]{MediaStore.Images.Media.DATA}, null, null, null);
        if (c != null)
        {
            c.moveToFirst();
            // 通过游标来获取名为MediaStore.Images.Media.DATA字段的值
            String path = c.getString(c
                    .getColumnIndex(MediaStore.Images.Media.DATA));
            return path;
        }
        return null;
    }

    public static void openCameraForImage(Activity activity)
    {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // 仅当设置了MediaStore.EXTRA_OUTPUT参数时,系统将不再返回缩略图,而是会被完整保存以下路径
        intent.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(new File(CAMERA_IMAGE)));
        activity.startActivityForResult(intent,
                CameraUtils.RequestCode.FLAG_REQUEST_CAMERA_IMAGE);
    }

    public static void openCameraForVideo(Activity activity)
    {
        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        // 仅当设置了MediaStore.EXTRA_OUTPUT参数时,系统将不再返回缩略图,而是会被完整保存以下路径
        intent.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(new File(CAMERA_VIDEO)));
        activity.startActivityForResult(intent,
                RequestCode.FLAG_REQUEST_CAMERA_VIDEO);
    }

    public interface RequestCode
    {
        int FLAG_REQUEST_SYSTEM_IMAGE = 0;

        int FLAG_REQUEST_CAMERA_IMAGE = 1;

        int FLAG_REQUEST_CAMERA_VIDEO = 2;
    }
}

App:

public class App extends Application {
    public static final String LOG_FILE = Environment.getExternalStorageDirectory() + "/logs/SystemTest/" + DateUtils.getDate1() + ".log";
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    @Override
    public void onCreate() {
        super.onCreate();
        // android 7.0系统解决拍照的问题
        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
        StrictMode.setVmPolicy(builder.build());
        builder.detectFileUriExposure();
        LogHandler.initLogFile(new File(LOG_FILE));
    }
}

LocalLog:

final class LocalLog {

    private Date mLogTime;
    private String mLogTag;
    private String mLogMessage;

    public LocalLog(String logTag, String logMessage) {
        mLogTag = logTag;
        mLogMessage = logMessage;
        mLogTime = new Date();
    }

    @SuppressLint("SimpleDateFormat")
    private SimpleDateFormat format1 = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");


    @Override
    public String toString() {
        String date = format1.format(mLogTime);
        return "[" + date + "] [" + mLogTag + "] " + " " + mLogMessage;
    }
}

LogHandler:

public class LogHandler {

    private static final Lock sLock = new ReentrantLock();
    private static ExecutorService mService = Executors.newFixedThreadPool(2);
    private static ConcurrentLinkedQueue<String> mQueue = new ConcurrentLinkedQueue<>();

    private static File mLogFile;

    private LogHandler() {
    }

    public static void initLogFile(File file) {
        //删除目录
        if (file.exists() && file.isDirectory()) {
            try {
                FileUtils.deleteDirectory(file);
            } catch (IOException e) {
                //
            }
        }
        //创建文件
        if (!file.exists()) {
            try {
                file.getParentFile().mkdirs();
                file.createNewFile();
                Log.i("LOGHANDLER","创建日志文件成功");
                LogHandler.writeFile("LOGHANDLER","创建日志文件成功");
            } catch (IOException e) {
                //
                LogHandler.writeFile("LOGHANDLER","创建日志文件失败" + e.getMessage());
            }
        }

        if (file.exists() && file.isFile()) mLogFile = file;
        else throw new RuntimeException("is not file :" + file);
    }

    public static void writeFile(String tag, String string) {
//        if (mLogFile == null)
//            throw new RuntimeException("please init logFile , file is null");
        mQueue.add(new LocalLog(tag, string).toString() + "\r\n");
        mService.execute(mRunnable);
    }

    private static Runnable mRunnable = new Runnable() {
        @Override
        public void run() {
            sLock.lock();
            try {
                StringBuilder msg = new StringBuilder();
                while (!mQueue.isEmpty()) {
                    msg.append(mQueue.poll());
                }
                if (!TextUtils.isEmpty(msg.toString())) {
                    FileUtils.writeStringToFile(mLogFile, msg.toString(), true);
                    msg.delete(0, msg.length());
                }
            } catch (IOException e) {
                e.printStackTrace();
                LogHandler.writeFile("LOGHANDLER","创建日志文件失败" + e.getMessage());
            } finally {
                sLock.unlock();
            }
        }
    };

}

xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_pick_image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="doClick"
        android:text="选取系统相册图片" />

    <Button
        android:id="@+id/btn_open_camera_for_image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="doClick"
        android:text="打开相机拍照" />

    <Button
        android:id="@+id/btn_open_camera_for_video"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="doClick"
        android:text="打开相机录像" />

    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="120dp" />

    <VideoView
        android:id="@+id/video"
        android:layout_width="match_parent"
        android:layout_height="200dp" />
</LinearLayout>

Android实现调用系统摄像机拍照、录像,选取系统图片。

我这里加了日志文件。

本文地址:https://blog.csdn.net/zhaochengfang/article/details/110533100

相关标签: android