Dha*_*dra 65 android android-contentprovider android-camera
我正在创建一个应用程序,我想在其中捕获图像,然后我想将该图像作为附件发送到电子邮件中.
我正在使用android.provider.MediaStore.ACTION_IMAGE_CAPTURE
intent动作打开相机,我将文件的Uri作为参数EXTRA_OUTPUT
传递给图像以将图像恢复到文件中.这是完美的工作,如果我使用external storage uri
as作为a 我能够获取捕获的图像, 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);
Run Code Online (Sandbox Code Playgroud)
此代码用于获取数据文件夹中的图像
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);
Run Code Online (Sandbox Code Playgroud)
我知道第三个应用程序无法访问数据文件夹,因此可能会导致问题,因此我创建了一个内容提供程序来共享该文件.
这是我的内容提供课程
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);
}
}
Run Code Online (Sandbox Code Playgroud)
因此,要使用此内容,我将使用以下代码将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);
Run Code Online (Sandbox Code Playgroud)
现在如果我传递其他外部存储目录的网址,相机正在打开,但它没有在模拟器中关闭,但在设备中相机将关闭,但我没有得到结果.
我已在清单文件中声明了此内容
<provider
android:name=".contentproviders.MyContentProvider"
android:authorities="x.y.z" />
Run Code Online (Sandbox Code Playgroud)
此外,我已经允许写入外部存储器以及使用相机.
我能够使用外部存储捕获图像,但我想将图像存储在数据目录而不是外部存储中,因为如果外部存储不可用,我想捕获图像并想要发送邮件.
如果我创建内容提供,那么我也可以将我的图像共享到电子邮件应用程序.
如果我们不提供相机意图的附加功能,它会将图像作为活动结果中的byte []返回为额外的数据,但这是为了缩略图的目的,所以我无法使用这种方式获得高分辨率图像.
Dha*_*dra 68
有两种方法可以解决这个问题.
1.保存从onActivityResult方法收到的位图
您可以通过使用以下代码捕获照片的意图启动相机
Intent cameraIntent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
Run Code Online (Sandbox Code Playgroud)
捕获照片后,您将获得onActivityResult方法中的位图
if (requestCode == CAMERA_REQUEST) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
}
Run Code Online (Sandbox Code Playgroud)
现在您只需将此位图保存到内部存储即可
注意:这里的位图对象由拇指图像组成,它不会有完整的分辨率图像
2.使用内容提供程序将位图直接保存到内部存储
在这里,我们将创建内容提供程序类,以允许本地存储目录对摄像机活动的许可
示例提供程序示例如下所示
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());
}
}
Run Code Online (Sandbox Code Playgroud)
之后,您可以使用以下代码简单地使用URI传递给相机活动
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(MediaStore.EXTRA_OUTPUT, MyFileContentProvider.CONTENT_URI);
startActivityForResult(i, CAMERA_RESULT);
Run Code Online (Sandbox Code Playgroud)
如果您不想创建自己的提供程序,则可以使用support-library-v4中的FileProvider.有关详细帮助,您可以查看这篇文章
Har*_*rry 20
我发现的最佳解决方案是:FileProvider(需要support-library-v4)它使用内部存储! https://developer.android.com/reference/android/support/v4/content/FileProvider.html
在Application元素中的Manifest中定义FileProvider:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="your.package.name.fileprovider"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/image_path" />
</provider>
Run Code Online (Sandbox Code Playgroud)在清单根元素中添加权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
Run Code Online (Sandbox Code Playgroud)在res/xml/image_path.xml中定义映像路径:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="captured_image" path="your/path/"/>
</paths>
Run Code Online (Sandbox Code Playgroud)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";
Run Code Online (Sandbox Code Playgroud)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);
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
意图打电话来拍摄照片,
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
Run Code Online (Sandbox Code Playgroud)
然后进入位图 ActivityResult
if (requestCode == CAMERA_REQUEST) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
}
Run Code Online (Sandbox Code Playgroud)
然后把它写入内部存储器,看看这个
// 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);
Run Code Online (Sandbox Code Playgroud)
然后下次读取该文件,
Bitmap bitmap = BitmapFactory.decodeFile(file);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
84638 次 |
最近记录: |