Android:调用相机拍照存为JPEG,获取路径用于cURL命令
解决Android Camera Intent自定义拍照路径并获取路径的问题
我来帮你搞定这个问题——默认的相机Intent确实只会把照片存到系统默认的图库位置,要自定义保存路径并拿到路径变量,你需要提前创建目标文件,把文件的URI传递给相机Intent,这样拍完后照片就会直接写入你指定的路径,你也能直接获取到这个路径用于后续的cURL命令。下面是完整的实现步骤和代码:
一、核心思路
- 提前在你想要的位置创建一个JPEG格式的空文件
- 根据Android版本(Android 7.0+需要用FileProvider)生成文件的URI
- 启动Camera Intent时,通过
MediaStore.EXTRA_OUTPUT参数传递这个URI,让相机把照片写入该文件 - 在
onActivityResult中直接使用你提前创建的文件路径即可
二、完整代码实现
1. 配置FileProvider(针对Android 7.0+)
首先在AndroidManifest.xml中添加FileProvider的配置:
<application ...> <!-- 其他配置 --> <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application>
然后在res/xml目录下创建file_paths.xml文件(如果没有xml目录就新建一个):
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 这里配置你要共享的文件路径,比如APP私有外部存储的图片目录 --> <external-files-path name="my_images" path="Pictures" /> </paths>
2. MainActivity完整代码
package project.com; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.util.Log; import android.view.View; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.FileProvider; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; public class MainActivity extends AppCompatActivity { // 用于存储拍照后的照片路径 private String mPhotoPath; private static final int REQUEST_IMAGE_CAPTURE = 1; private static final int REQUEST_STORAGE_PERMISSION = 2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } // 点击按钮触发拍照的方法(绑定到你的按钮点击事件) public void takePhoto(View view) { // 检查权限(如果是存到APP私有目录可以跳过权限申请) if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_STORAGE_PERMISSION); return; } dispatchTakePictureIntent(); } private void dispatchTakePictureIntent() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 确保有相机应用可以处理这个Intent if (takePictureIntent.resolveActivity(getPackageManager()) != null) { // 创建用于保存照片的文件 File photoFile = null; try { photoFile = createImageFile(); } catch (IOException ex) { // 创建文件失败的处理 Toast.makeText(this, "创建照片文件失败", Toast.LENGTH_SHORT).show(); ex.printStackTrace(); } // 如果文件创建成功,传递URI给相机Intent if (photoFile != null) { Uri photoURI; // 区分Android版本处理URI if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { // Android 7.0+使用FileProvider photoURI = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", photoFile); } else { // 旧版本直接用Uri.fromFile photoURI = Uri.fromFile(photoFile); } takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); } } } // 创建JPEG照片文件的方法 private File createImageFile() throws IOException { // 生成唯一的文件名,避免重复 String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; // 这里选择APP的私有外部存储图片目录,不需要存储权限(Android 10+也适用) File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); // 创建临时文件,后缀为.jpg File image = File.createTempFile( imageFileName, /* 前缀 */ ".jpg", /* 后缀 */ storageDir /* 存储目录 */ ); // 保存文件路径到全局变量,后续可以用这个路径给cURL mPhotoPath = image.getAbsolutePath(); Log.d("PhotoPath", "照片路径:" + mPhotoPath); return image; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { // 拍照成功,mPhotoPath就是照片的完整路径,你可以在这里用它执行cURL命令 Toast.makeText(this, "照片已保存至:" + mPhotoPath, Toast.LENGTH_LONG).show(); // 示例:打印路径,后续替换成你的cURL逻辑 Log.d("CameraResult", "准备用于cURL的照片路径:" + mPhotoPath); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_STORAGE_PERMISSION) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限申请通过,启动拍照 dispatchTakePictureIntent(); } else { Toast.makeText(this, "需要存储权限才能保存照片", Toast.LENGTH_SHORT).show(); } } } }
三、关键说明
- 自定义路径选择:上面的代码把照片存在APP的私有外部存储目录
getExternalFilesDir(Environment.DIRECTORY_PICTURES),这个路径不需要申请存储权限(Android 10+也无需特殊处理),如果要存到公共目录(比如DCIM),则需要处理Android 10+的Scoped Storage,建议优先用私有目录,更简单。 - 路径使用:拍照成功后,
mPhotoPath就是照片的完整绝对路径,你可以直接把这个变量传入你的cURL命令中,比如用Runtime.getRuntime().exec()执行cURL时带上这个路径参数。 - FileProvider的作用:Android 7.0+禁止直接传递
file://URI给其他应用,所以必须用FileProvider生成content://URI来安全共享文件。
内容的提问来源于stack exchange,提问作者Jay1995
相关产品推荐
相关产品推荐

