如何在表单中获取相机的结果 uri 在数据文件夹中?

我创建了一个我想要捕获图像的应用程序,然后我想发送此图像 email 作为一个附件。

我打开相机
android.provider.MediaStore.ACTION_IMAGE_CAPTURE

intent action 并传达 Uri 文件作为参数
EXTRA_OUTPUT

, 将图像返回给文件。 它正常工作,如果我使用,我可以获得捕获的图像
external storage uri

作为
EXTRA_OUTPUT

, 但如果我使用数据文件夹 uri, 它不起作用,相机不会关闭,所有按钮都不工作。

这是我的代码,以获得外部存储目录的结果


Intent i = new Intent/android.provider.MediaStore.ACTION_IMAGE_CAPTURE/;
File out = Environment.getExternalStorageDirectory//;
out = new File/out, imagename/;
i.putExtra/MediaStore.EXTRA_OUTPUT, Uri.fromFile/out//;
startActivityForResult/i, CAMERA_RESULT/;


此代码旨在在数据文件夹中获取图像。


Intent i = new Intent/android.provider.MediaStore.ACTION_IMAGE_CAPTURE/;
File out = getFilesDir//;
out = new File/out, MyPharmacyOptions.PRESCRIPTION_IMAGE_NAME/;
i.putExtra/MediaStore.EXTRA_OUTPUT, Uri.fromFile/out//;
startActivityForResult/i, CAMERA_RESULT/;


我知道

数据文件夹不适用于第三个应用程序

, 因此,它可能会导致问题,因此我必须创建一个内容提供商来共享文件。

这是我们班上更好的资源。


public class MyContentProvider extends ContentProvider {
private static final String Tag = RingtonContentProvider.class.getName//;
public static final Uri CONTENT_URI = Uri
.parse/"content://x.y.z/"/;
private static final HashMap<string, string=""> MIME_TYPES = new HashMap<string, string="">//;

static {
MIME_TYPES.put/".mp3", "audio/mp3"/;
MIME_TYPES.put/".wav", "audio/mp3"/;
MIME_TYPES.put/".jpg", "image/jpeg"/;
}

@Override
public boolean onCreate// {
return true;
}

@Override
public String getType/Uri uri/ {
String path = uri.toString//;

for /String extension : MIME_TYPES.keySet/// {
if /path.endsWith/extension// {
return /MIME_TYPES.get/extension//;
}
}

return /null/;
}

@Override
public ParcelFileDescriptor openFile/Uri uri, String mode/
throws FileNotFoundException {
File f = new File/getContext//.getFilesDir//, uri.getPath///;

if /f.exists/// {
return /ParcelFileDescriptor.open/f, ParcelFileDescriptor.MODE_READ_ONLY//;
}

throw new FileNotFoundException/uri.getPath///;
}

@Override
public Cursor query/Uri url, String[] projection, String selection,
String[] selectionArgs, String sort/ {
throw new RuntimeException/"Operation not supported"/;
}

@Override
public Uri insert/Uri uri, ContentValues initialValues/ {
File file = new File/getContext//.getFilesDir//, uri.getPath///;
if/file.exists/// file.delete//;
try {
file.createNewFile//;
} catch /IOException e/ {
// TODO Auto-generated catch block
e.printStackTrace//;
}

return Uri.fromFile/file/;
}

@Override
public int update/Uri uri, ContentValues values, String where,
String[] whereArgs/ {
throw new RuntimeException/"Operation not supported"/;
}

@Override
public int delete/Uri uri, String where, String[] whereArgs/ {
File f = new File/getContext//.getFilesDir//, "image1.jpg"/;
if/f.exists/// f.delete//;
f = new File/getContext//.getFilesDir//, "image2.jpg"/;
if/f.exists/// f.delete//;

getContext//.getContentResolver//.notifyChange/CONTENT_URI, null/;

}
}


因此,要使用此内容,我使用以下代码进行传输 uri 行动相机


Intent i = new Intent/android.provider.MediaStore.ACTION_IMAGE_CAPTURE/;
Uri uri = MyContentProvider.CONTENT_URI;
uri = Uri.withAppendedPath/uri, imagename/;
getContentResolver//.insert/uri, null/;
getContentResolver//.notifyChange/RingtonContentProvider.CONTENT_URI, null/;
Log.d/Tag, uri.toString///;
i.putExtra/MediaStore.EXTRA_OUTPUT, uri/;

startActivityForResult/i, CAMERA_RESULT/;


现在,如果我通过 url 另一个,不是外部存储目录,相机将打开,但不会在仿真器中关闭,并在设备中,相机关闭,但我不会得到结果。

我宣布在清单文件中提供的此内容


<provider android:authorities="x.y.z" android:name=".contentproviders.MyContentProvider"></provider>


我也得到了许可

记录外部驱动器

, 以及

使用相机

.

我可以使用外部存储捕获图像,但我想在数据目录中保存图像而不是外部存储,因为如果不可用外部存储,我想捕获图像并发送邮件。

如果我创建内容,那么我也可以使用应用程序共享我的映像 email.

如果我们不提供相机的意图提供额外,它将返回图像 byte[] 作为额外数据的动作的结果,但这是为缩放完成的,因此我无法以这种方式获得高分辨率图像。
</string,></string,>
已邀请:

三叔

赞同来自:

有两种方法可以解决这个问题。

1. 救 bitmap, 你从方法中得到了

onActivityResult

您可以使用下面的代码捕获照片来运行相机。


Intent cameraIntent=new Intent/android.provider.MediaStore.ACTION_IMAGE_CAPTURE/;
startActivityForResult/cameraIntent, CAMERA_REQUEST/;


在捕获照片后,你会得到 bitmap 在方法中 onActivityResult


if /requestCode == CAMERA_REQUEST/ { 
Bitmap photo = /Bitmap/ data.getExtras//.get/"data"/;
}


现在你可以保存这个 bitmap 在内部存储中

注意:这是对象 bitmap 由拇指的图像组成,它不会有一个完整分辨率的图像

2. 救 bitmap 使用内容提供商直接进入内部存储器

在这里,我们将创建一个课程 content provider, 允许本地存储目录访问相机活动

根据下面的这种供应商的示例


public class MyFileContentProvider extends ContentProvider {
public static final Uri CONTENT_URI = Uri.parse
/"content://com.example.camerademo/"/;
private static final HashMap<string, string=""> MIME_TYPES =
new HashMap<string, string="">//;

static {
MIME_TYPES.put/".jpg", "image/jpeg"/;
MIME_TYPES.put/".jpeg", "image/jpeg"/;
}

@Override
public boolean onCreate// {

try {
File mFile = new File/getContext//.getFilesDir//, "newImage.jpg"/;
if/!mFile.exists/// {
mFile.createNewFile//;
}
getContext//.getContentResolver//.notifyChange/CONTENT_URI, null/;
return /true/;
} catch /Exception e/ {
e.printStackTrace//;
return false;
}

}

@Override
public String getType/Uri uri/ {
String path = uri.toString//;

for /String extension : MIME_TYPES.keySet/// {
if /path.endsWith/extension// {
return /MIME_TYPES.get/extension//;
}
}
return /null/;
}

@Override
public ParcelFileDescriptor openFile/Uri uri, String mode/
throws FileNotFoundException {

File f = new File/getContext//.getFilesDir//, "newImage.jpg"/;
if /f.exists/// {
return /ParcelFileDescriptor.open/f,
ParcelFileDescriptor.MODE_READ_WRITE//;
}
throw new FileNotFoundException/uri.getPath///;
}
}


之后你可以使用 URI 使用下面的代码转到相机活动


Intent i = new Intent/android.provider.MediaStore.ACTION_IMAGE_CAPTURE/;
i.putExtra/MediaStore.EXTRA_OUTPUT, MyFileContentProvider.CONTENT_URI/;
startActivityForResult/i, CAMERA_RESULT/;


如果您不想创建自己的提供商,可以使用
https://developer.android.com/ ... .html
的 support-library-v4. 有关详细帮助,您可以调查
https://coderoad.ru/10042695/
</string,></string,>

君笑尘

赞同来自:

我找到的最好的解决方案是: FileProvider /需要 support-library-v4/
它使用内存!
https://developer.android.com/ ... .html

确定你的 FileProvider 在应用程序元素中的宣言中:


<provider android:authorities="your.package.name.fileprovider" android:exported="false" android:granturipermissions="true" android:name="android.support.v4.content.FileProvider">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/image_path"></meta-data>
</provider>


在Manifesta的根元素中添加权限:


<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-feature android:name="android.hardware.camera" android:required="false"></uses-feature>


确定图像的路径,例如, res/xml/image_path.xml:


<paths xmlns:android="[url=http://schemas.android.com/apk/res/android">]http://schemas.android.com/apk ... gt%3B[/url]
<files-path name="captured_image" path="your/path/"></files-path>
</paths>


Java:


private static final int IMAGE_REQUEST_CODE = 1;
// your authority, must be the same as in your manifest file
private static final String CAPTURE_IMAGE_FILE_PROVIDER = "your.package.name.fileprovider";


4.1 捕获的意图:


File path = new File/activity.getFilesDir//, "your/path"/;
if /!path.exists/// path.mkdirs//;
File image = new File/path, "image.jpg"/;
Uri imageUri = FileProvider.getUriForFile/activity, CAPTURE_IMAGE_FILE_PROVIDER, image/;
Intent intent = new Intent/MediaStore.ACTION_IMAGE_CAPTURE/;
intent.putExtra/MediaStore.EXTRA_OUTPUT, imageUri/;
startActivityForResult/intent, IMAGE_REQUEST_CODE/;


4.2 onActivityResult//:


@Override
public void onActivityResult/int requestCode, int resultCode, Intent intent/ {
if /requestCode == IMAGE_REQUEST_CODE/ {
if /resultCode == Activity.RESULT_OK/ {
File path = new File/getFilesDir//, "your/path"/;
if /!path.exists/// path.mkdirs//;
File imageFile = new File/path, "image.jpg"/;
// use imageFile to open your image
}
}
super.onActivityResult/requestCode, resultCode, intent/;
}

卫东

赞同来自:

打电话拍照的意图


Intent cameraIntent = new Intent/android.provider.MediaStore.ACTION_IMAGE_CAPTURE/; 
startActivityForResult/cameraIntent, CAMERA_REQUEST/;


然后服用 Bitmap 在
ActivityResult



if /requestCode == CAMERA_REQUEST/ { 
Bitmap photo = /Bitmap/ data.getExtras//.get/"data"/;
}


然后写下来
https://coderoad.ru/4135927/

// The openfileOutput// method creates a file on the phone/internal storage in the context of your application 
final FileOutputStream fos = openFileOutput/"my_new_image.jpg", Context.MODE_PRIVATE/;

// Use the compress method on the BitMap object to write image to the OutputStream
bm.compress/CompressFormat.JPEG, 90, fos/;


然后下次阅读此文件,


Bitmap bitmap = BitmapFactory.decodeFile/file/;

三叔

赞同来自:

首先将照片保存在外部存储中,然后尝试。 -


@Override
public void onCreate/Bundle savedInstanceState/ {
super.onCreate/savedInstanceState/;
setContentView/R.layout.main/;
this.imageView = /ImageView/this.findViewById/R.id.imageView1/;
Button photoButton = /Button/ this.findViewById/R.id.button1/;
photoButton.setOnClickListener/new View.OnClickListener// {

@Override
public void onClick/View v/ {
Intent cameraIntent = new Intent/android.provider.MediaStore.ACTION_IMAGE_CAPTURE/;
startActivityForResult/cameraIntent, CAMERA_REQUEST/;
}
}/;
}

protected void onActivityResult/int requestCode, int resultCode, Intent data/ {
if /requestCode == CAMERA_REQUEST/ {
Bitmap bmp = intent.getExtras//.get/"data"/;
ByteArrayOutputStream stream = new ByteArrayOutputStream//;

bmp.compress/Bitmap.CompressFormat.PNG, 100, stream/;
byte[] byteArray = stream.toByteArray//; // convert camera photo to byte array

// save it in your external storage.
FileOutputStream fo = new FileOutputStream/new File/Environment.getExternalStorageDirectory// + "/_camera.png"//;

fo.write/byteArray/;
fo.flush//;
fo.close//;
}
}


下一个目标 -


File cameraFile = new File/Environment.getExternalStorageDirectory// + "/_camera.png"/; 
startActivityForResult/Intent.createChooser/new Intent/Intent.ACTION_SEND/
.setType/"image/jpg"/
.putExtra/Intent.EXTRA_SUBJECT, "Subject"/
.putExtra/Intent.EXTRA_STREAM, Uri.fromFile/cameraFile//
.putExtra/Intent.EXTRA_TEXT, textBody/, "Send your message using"/, Constant.EMAIL/;

喜特乐

赞同来自:

您也可以在不使用内容提供商的情况下执行此操作,因为您仍需要一个SD卡以打开捕获相机图像的意图。 当然,你可以破解SD卡的存在,但不是相机的意图 capture....So 您检查外部存储的可用性,但目前您需要的.... FYI 您还必须检查修剪库,例如 crop-image, 而不是使用 native, 由于它在不同的设备上不是很好的支持。


File mediaStorageDir;
String photoFileName = "photo.jpg";


public void onCreate/Bundle savedInstanceState/ {
super.onCreate/savedInstanceState/;

// page = getArguments//.getInt/"someInt", 0/;
// title = getArguments//.getString/"someTitle"/;
// Get safe storage directory for photos
mediaStorageDir = new File/
Environment .getExternalStoragePublicDirectory/Environment.DIRECTORY_PICTURES/,
APP_TAG/;
// Create the storage directory if it does not exist
if /!mediaStorageDir.exists// && !mediaStorageDir.mkdirs/// {
Log.d/APP_TAG, "Directory exists: " + mediaStorageDir.isDirectory///;
Log.d/APP_TAG, "Directory exists: " + mediaStorageDir.getPath///;
Log.d/APP_TAG,
"Directory exists: "
+ Environment.getExternalStorageState///;
Log.d/APP_TAG, "failed to create directory"/;
}

}


自有,您可以采取代码 :


Intent intent = new Intent/MediaStore.ACTION_IMAGE_CAPTURE/;
intent.putExtra/MediaStore.EXTRA_OUTPUT, getPhotoFileUri/photoFileName//;


...


public Uri getPhotoFileUri/String fileName/ {

return Uri.fromFile/new File/mediaStorageDir.getPath// + File.separator
+ fileName//;
}

董宝中

赞同来自:

检查此错误一段时间后,我注意到才能在手机以手机结束时重新启动所造成摄像机的动作。
因此,由于动作重新启动,因此包含路径或的对象 Uri 到捕获的图像,更新 /重置/

所以我会建议你 catch/ 检测对象 null 在 onActivityResult 并提供用户在设备上释放位置或重新启动手机以进行快速临时校正。

要回复问题请先登录注册