Android 拍照和打开相册

package com.unity3d.player;

import android.app.Activity;
import android.content.ClipData;
import android.content.Intent;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.FileUtils;
import android.provider.MediaStore;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.os.Process;
import android.widget.ImageView;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import android.support.v4.content.FileProvider;
import android.widget.ImageView;

public class UnityPlayerActivity extends Activity implements IUnityPlayerLifecycleEvents
{
    protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code

    // Override this in your custom UnityPlayerActivity to tweak the command line arguments passed to the Unity Android Player
    // The command line arguments are passed as a string, separated by spaces
    // UnityPlayerActivity calls this from 'onCreate'
    // Supported: -force-gles20, -force-gles30, -force-gles31, -force-gles31aep, -force-gles32, -force-gles, -force-vulkan
    // See https://docs.unity3d.com/Manual/CommandLineArguments.html
    // @param cmdLine the current command line arguments, may be null
    // @return the modified command line string or null
    protected String updateUnityCommandLineArguments(String cmdLine)
    {
        return cmdLine;
    }

    // Setup activity layout
    @Override protected void onCreate(Bundle savedInstanceState)
    {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);

        String cmdLine = updateUnityCommandLineArguments(getIntent().getStringExtra("unity"));
        getIntent().putExtra("unity", cmdLine);

        mUnityPlayer = new UnityPlayer(this, this);
        setContentView(mUnityPlayer);
        mUnityPlayer.requestFocus();
    }

    // When Unity player unloaded move task to background
    @Override public void onUnityPlayerUnloaded() {
        moveTaskToBack(true);
    }

    // Callback before Unity player process is killed
    @Override public void onUnityPlayerQuitted() {
    }

    @Override protected void onNewIntent(Intent intent)
    {
        // To support deep linking, we need to make sure that the client can get access to
        // the last sent intent. The clients access this through a JNI api that allows them
        // to get the intent set on launch. To update that after launch we have to manually
        // replace the intent with the one caught here.
        setIntent(intent);
        mUnityPlayer.newIntent(intent);
    }

    // Quit Unity
    @Override protected void onDestroy ()
    {
        mUnityPlayer.destroy();
        super.onDestroy();
    }

    // If the activity is in multi window mode or resizing the activity is allowed we will use
    // onStart/onStop (the visibility callbacks) to determine when to pause/resume.
    // Otherwise it will be done in onPause/onResume as Unity has done historically to preserve
    // existing behavior.
    @Override protected void onStop()
    {
        super.onStop();
        mUnityPlayer.onStop();
    }

    @Override protected void onStart()
    {
        super.onStart();
        mUnityPlayer.onStart();
    }

    // Pause Unity
    @Override protected void onPause()
    {
        super.onPause();
        mUnityPlayer.onPause();
    }

    // Resume Unity
    @Override protected void onResume()
    {
        super.onResume();
        mUnityPlayer.onResume();
    }

    // Low Memory Unity
    @Override public void onLowMemory()
    {
        super.onLowMemory();
        mUnityPlayer.lowMemory();
    }

    // Trim Memory Unity
    @Override public void onTrimMemory(int level)
    {
        super.onTrimMemory(level);
        if (level == TRIM_MEMORY_RUNNING_CRITICAL)
        {
            mUnityPlayer.lowMemory();
        }
    }

    // This ensures the layout will be correct.
    @Override public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        mUnityPlayer.configurationChanged(newConfig);
    }

    // Notify Unity of the focus change.
    @Override public void onWindowFocusChanged(boolean hasFocus)
    {
        super.onWindowFocusChanged(hasFocus);
        mUnityPlayer.windowFocusChanged(hasFocus);
    }

    // For some reason the multiple keyevent type is not supported by the ndk.
    // Force event injection by overriding dispatchKeyEvent().
    @Override public boolean dispatchKeyEvent(KeyEvent event)
    {
        if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
            return mUnityPlayer.injectEvent(event);
        return super.dispatchKeyEvent(event);
    }

    // Pass any events not handled by (unfocused) views straight to UnityPlayer
    @Override public boolean onKeyUp(int keyCode, KeyEvent event)     { return mUnityPlayer.onKeyUp(keyCode, event); }
    @Override public boolean onKeyDown(int keyCode, KeyEvent event)   { return mUnityPlayer.onKeyDown(keyCode, event); }
    @Override public boolean onTouchEvent(MotionEvent event)          { return mUnityPlayer.onTouchEvent(event); }
    @Override public boolean onGenericMotionEvent(MotionEvent event)  { return mUnityPlayer.onGenericMotionEvent(event); }

    private static final String TAG = "UnityPlayerActivity";
    IPhotoCallback photoCallback;
    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HHmmss", Locale.CHINA);
    private File file = null;
    private ImageView ivAvatar;
    private final int REQUEST_CAMERA = 110;
    private Intent takeIntent = null;
    private Uri takeUriFirFile;

    // 拍照
    public void TakePhoto(IPhotoCallback callback){
        Log.d(TAG, "--------------------------TakePhoto1-------------------------------");
        photoCallback = callback;
        takeIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        file = new File(getExternalCacheDir(), simpleDateFormat.format(new Date()) + ".png");
        takeUriFirFile = FileProvider.getUriForFile(this, "com.DefaultCompany.ElectronicWorkOrder", file);
        takeIntent.putExtra(MediaStore.EXTRA_OUTPUT, takeUriFirFile);
        startActivityForResult(takeIntent, REQUEST_CAMERA, takeIntent.getExtras());
        Log.d(TAG, "--------------------------TakePhoto2-------------------------------");
    }

    // 打开相册
    public void OpenAlbum(IPhotoCallback callback){
        Log.d(TAG, "--------------------------OpenAlbum1-------------------------------");
        photoCallback = callback;
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("image/*");
        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
        startActivityForResult(intent, 1001);
        Log.d(TAG, "--------------------------OpenAlbum2-------------------------------");
    }

    @Override
    protected  void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);
        Log.d(TAG, "onActivityResult: resultCode:" + resultCode + "; requestCode:" + requestCode);
        switch(requestCode) {
            /*case 1001:
                Uri uri = data.getData();
                List<String> paths = new ArrayList<>();
                if(uri!=null){
                    Log.d(TAG, "onActivityResult: get photo uri=" + uri);
                    paths.add(getPhotoPath(uri));
                }else{
                    ClipData clipData = data.getClipData();
                    Log.d(TAG, "onActivityResult: photo count=" + clipData.getItemCount());
                    for (int i = 0; i < clipData.getItemCount(); i++){
                        paths.add(getPhotoPath(clipData.getItemAt(i).getUri()));
                    }
                }
                for(String path: paths){
                    Log.d(TAG, "onActivityResult: get paths count=" + paths.size() + "; path=" + path);
                }
                photoCallback.onPhotoSelected(paths.toArray(new String[paths.size()]));
                break;*/
            case REQUEST_CAMERA:
                if(resultCode == RESULT_OK){
                    Log.d(TAG, "--------------------------4-------------------------------");
                    /*String destinationFolderPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath();
                    String fileName = "saved_image_" + System.currentTimeMillis() + ".png";
                    String destinationPath = destinationFolderPath + File.separator + fileName;
                    Log.d(TAG, destinationFolderPath);
                    Log.d(TAG, fileName);
                    Log.d(TAG, destinationPath);
                    saveImageFromContentUri(takeUriFirFile, destinationPath);
                    List<String> paths2 = new ArrayList<>();
                    paths2.add(getPhotoPath(takeUriFirFile));
                    photoCallback.onPhotoSelected(paths2.toArray(new String[paths2.size()]));*/

                    Log.d(TAG, "--------------------------4-------------------------------");
                    String destinationFolderPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath();
                    String fileName = "saved_image_" + System.currentTimeMillis() + ".jpg";
                    String destinationPath = destinationFolderPath + File.separator + fileName;
                    Log.d(TAG, destinationFolderPath);
                    Log.d(TAG, fileName);
                    Log.d(TAG, destinationPath);

                    // 调用新的压缩图片保存方法
                    saveCompressedImageFromContentUri(takeUriFirFile, destinationPath);
                    photoCallback.onPhotoSelected(destinationPath);
                }
                break;
        }
    }

    String getPhotoPath(Uri uri)
    {
        String path = "";
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);
        if(cursor!=null){
            cursor.moveToFirst();
            try{
                path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
            }catch (IllegalArgumentException e){
                Log.d(TAG, "getPhotoPath: exception " + e.getMessage());
            }
            cursor.close();
        }
        if(path.isEmpty()){
            path = copyUriContent(uri);
        }

        return path;
    }

    String copyUriContent(Uri uri){
        String path = getCacheDir() + "temp_" + System.currentTimeMillis();
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try{
            inputStream = getContentResolver().openInputStream(uri);
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }
        if(inputStream!=null){
            try{
                outputStream = new FileOutputStream(path);
            }catch (FileNotFoundException e){
                e.printStackTrace();
            }
            try{
                if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
                    FileUtils.copy(inputStream, outputStream);
                    return path;
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        return "";
    }

    private void saveImageToGallery(Bitmap imageBitmap){
        Log.d(TAG, "--------------------------5-------------------------------");
        Log.d(TAG, String.valueOf(imageBitmap));
        String path = Environment.getExternalStorageDirectory() + "/CameraApp/";
        File dir = new File(path);
        if(!dir.exists()){
            dir.mkdirs();
        }
        File file = new File((path + System.currentTimeMillis() + ".jpg"));
        try{
            OutputStream fOut = new FileOutputStream(file);
            imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
            fOut.flush();
            fOut.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void saveImageFromContentUri(Uri contentUri, String destinationPath) {
        try {
            // 使用内容解析器打开输入流读取图片数据
            InputStream inputStream = getContentResolver().openInputStream(contentUri);
            if (inputStream != null) {
                // 创建输出流指向你希望保存图片的路径
                OutputStream outputStream = new FileOutputStream(destinationPath);

                // 使用FileUtils.copy()方法或其他方式复制数据
                byte[] buffer = new byte[1024];
                int length;
                while ((length = inputStream.read(buffer)) > 0) {
                    outputStream.write(buffer, 0, length);
                }

                // 关闭流
                outputStream.flush();
                outputStream.close();
                inputStream.close();

                // 通知系统图库更新
                sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(destinationPath))));
                Log.d(TAG, "图片已保存至: " + destinationPath);
            } else {
                Log.e(TAG, "无法打开输入流");
            }
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG, "保存图片时发生错误: " + e.getMessage());
        }
    }

    private void saveCompressedImageFromContentUri(Uri contentUri, String destinationPath) {
        try {
            // 使用内容解析器打开输入流读取图片数据
            InputStream inputStream = getContentResolver().openInputStream(contentUri);
            if (inputStream != null) {
                // 解码图片
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                inputStream.close();

                // 创建输出流指向你希望保存图片的路径
                OutputStream outputStream = new FileOutputStream(destinationPath);

                // 将Bitmap压缩为JPEG格式,质量设为80%(可以根据需要调整这个值)
                boolean result = bitmap.compress(Bitmap.CompressFormat.JPEG, 30, outputStream);

                // 关闭流
                outputStream.flush();
                outputStream.close();

                // 检查压缩是否成功
                if (result) {
                    // 通知系统图库更新
                    sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(destinationPath))));
                    Log.d(TAG, "压缩后的图片已保存至: " + destinationPath);
                } else {
                    Log.e(TAG, "图片压缩失败");
                }
            } else {
                Log.e(TAG, "无法打开输入流");
            }
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG, "保存图片时发生错误: " + e.getMessage());
        }
    }
}

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Android Studio中拍照相册的实现方法: 1.添加权限 在AndroidManifest.xml文件中添加以下权限: ```xml <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.CAMERA"/> ``` 2.在布局文件中添加按钮 在布局文件中添加两个按钮,一个用于打开相机,一个用于打开相册。 ```xml <Button android:id="@+id/btn_camera" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="打开相机"/> <Button android:id="@+id/btn_gallery" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="打开相册"/> ``` 3.在Activity中实现打开相机和相册的功能 在Activity中实现打开相机和相册的功能,可以使用Intent来启动系统相机和相册应用。 ```java public class MainActivity extends AppCompatActivity { private static final int REQUEST_CODE_CAMERA = 1; private static final int REQUEST_CODE_GALLERY = 2; private Button btnCamera; private Button btnGallery; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnCamera = findViewById(R.id.btn_camera); btnGallery = findViewById(R.id.btn_gallery); btnCamera.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, REQUEST_CODE_CAMERA); } }); btnGallery.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, REQUEST_CODE_GALLERY); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { if (requestCode == REQUEST_CODE_CAMERA) { // 处理拍照结果 Bundle bundle = data.getExtras(); Bitmap bitmap = (Bitmap) bundle.get("data"); // TODO: 处理拍照结果 } else if (requestCode == REQUEST_CODE_GALLERY) { // 处理相册选择结果 Uri uri = data.getData(); // TODO: 处理相册选择结果 } } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值