Android ACTION_IMAGE_CAPTURE 意图

发布于 2024-08-15 08:37:59 字数 347 浏览 9 评论 0原文

我们正在尝试使用本机相机应用程序让用户拍摄新照片。如果我们省略 EXTRA_OUTPUT extra 并返回小位图图像,它就可以正常工作。但是,如果我们在启动意图之前 putExtra(EXTRA_OUTPUT,...) ,那么一切都会正常,直到您尝试点击相机应用中的“确定”按钮。 “确定”按钮什么也不做。相机应用程序保持打开状态,没有任何锁定。我们可以取消它,但文件永远不会被写入。我们究竟需要做什么才能让 ACTION_IMAGE_CAPTURE 将拍摄的图片写入文件?

编辑:这是通过 MediaStore.ACTION_IMAGE_CAPTURE 意图完成的,只是为了清楚起见

We are trying to use the native camera app to let the user take a new picture. It works just fine if we leave out the EXTRA_OUTPUT extra and returns the small Bitmap image. However, if we putExtra(EXTRA_OUTPUT,...) on the intent before starting it, everything works until you try to hit the "Ok" button in the camera app. The "Ok" button just does nothing. The camera app stays open and nothing locks up. We can cancel out of it, but the file never gets written. What exactly do we have to do to get ACTION_IMAGE_CAPTURE to write the picture taken to a file?

Edit: This is done via the MediaStore.ACTION_IMAGE_CAPTURE intent, just to be clear

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

岁月流歌 2024-08-22 08:37:59

这是某些 Android 版本中的有据可查的错误。也就是说,在 Android 的 google experience 版本中,图像捕获无法按照记录进行。我通常在实用程序类中使用类似的东西。

public boolean hasImageCaptureBug() {

    // list of known devices that have the bug
    ArrayList<String> devices = new ArrayList<String>();
    devices.add("android-devphone1/dream_devphone/dream");
    devices.add("generic/sdk/generic");
    devices.add("vodafone/vfpioneer/sapphire");
    devices.add("tmobile/kila/dream");
    devices.add("verizon/voles/sholes");
    devices.add("google_ion/google_ion/sapphire");

    return devices.contains(android.os.Build.BRAND + "/" + android.os.Build.PRODUCT + "/"
            + android.os.Build.DEVICE);

}

然后,当我启动图像捕获时,我创建一个意图来检查错误。

Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
if (hasImageCaptureBug()) {
    i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File("/sdcard/tmp")));
} else {
    i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
startActivityForResult(i, mRequestCode);

然后在我返回的活动中,我根据设备做不同的事情。

protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
     switch (requestCode) {
         case GlobalConstants.IMAGE_CAPTURE:
             Uri u;
             if (hasImageCaptureBug()) {
                 File fi = new File("/sdcard/tmp");
                 try {
                     u = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), fi.getAbsolutePath(), null, null));
                     if (!fi.delete()) {
                         Log.i("logMarker", "Failed to delete " + fi);
                     }
                 } catch (FileNotFoundException e) {
                     e.printStackTrace();
                 }
             } else {
                u = intent.getData();
            }
    }

这使您不必编写新的相机应用程序,但此代码也不是很好。最大的问题是

  1. 你永远无法获得完整尺寸的图像
    存在错误的设备。你得到
    宽度为 512px 的图片
    被插入到图像内容中
    提供者。在没有的设备上
    bug,一切都像文档一样工作,
    你会得到一张大的正常图片。

  2. 您必须维护该列表。作为
    书面的,对于设备来说是可能的
    用以下版本进行刷新
    android(比如 cyanogenmod 的
    构建
    ),已修复该错误。
    如果发生这种情况,您的代码将
    碰撞。修复方法是使用整个
    设备指纹。

this is a well documented bug in some versions of android. that is, on google experience builds of android, image capture doesn't work as documented. what i've generally used is something like this in a utilities class.

public boolean hasImageCaptureBug() {

    // list of known devices that have the bug
    ArrayList<String> devices = new ArrayList<String>();
    devices.add("android-devphone1/dream_devphone/dream");
    devices.add("generic/sdk/generic");
    devices.add("vodafone/vfpioneer/sapphire");
    devices.add("tmobile/kila/dream");
    devices.add("verizon/voles/sholes");
    devices.add("google_ion/google_ion/sapphire");

    return devices.contains(android.os.Build.BRAND + "/" + android.os.Build.PRODUCT + "/"
            + android.os.Build.DEVICE);

}

then when i launch image capture, i create an intent that checks for the bug.

Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
if (hasImageCaptureBug()) {
    i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File("/sdcard/tmp")));
} else {
    i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
startActivityForResult(i, mRequestCode);

then in activity that i return to, i do different things based on the device.

protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
     switch (requestCode) {
         case GlobalConstants.IMAGE_CAPTURE:
             Uri u;
             if (hasImageCaptureBug()) {
                 File fi = new File("/sdcard/tmp");
                 try {
                     u = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), fi.getAbsolutePath(), null, null));
                     if (!fi.delete()) {
                         Log.i("logMarker", "Failed to delete " + fi);
                     }
                 } catch (FileNotFoundException e) {
                     e.printStackTrace();
                 }
             } else {
                u = intent.getData();
            }
    }

this saves you having to write a new camera app, but this code isn't great either. the big problems are

  1. you never get full sized images from
    the devices with the bug. you get
    pictures that are 512px wide that
    are inserted into the image content
    provider. on devices without the
    bug, everything works as document,
    you get a big normal picture.

  2. you have to maintain the list. as
    written, it is possible for devices
    to be flashed with a version of
    android (say cyanogenmod's
    builds
    ) that has the bug fixed.
    if that happens, your code will
    crash. the fix is to use the entire
    device fingerprint.

远昼 2024-08-22 08:37:59

我知道这个问题之前已经被回答过,但我知道很多人都被这个问题绊倒了,所以我要添加一条评论。

我的 Nexus One 上也出现了同样的问题。这是来自相机应用程序启动之前磁盘上不存在的文件。因此,我在启动相机应用程序之前确保该文件存在。以下是我使用的一些示例代码:

String storageState = Environment.getExternalStorageState();
        if(storageState.equals(Environment.MEDIA_MOUNTED)) {

            String path = Environment.getExternalStorageDirectory().getName() + File.separatorChar + "Android/data/" + MainActivity.this.getPackageName() + "/files/" + md5(upc) + ".jpg";
            _photoFile = new File(path);
            try {
                if(_photoFile.exists() == false) {
                    _photoFile.getParentFile().mkdirs();
                    _photoFile.createNewFile();
                }

            } catch (IOException e) {
                Log.e(TAG, "Could not create file.", e);
            }
            Log.i(TAG, path);

            _fileUri = Uri.fromFile(_photoFile);
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE );
            intent.putExtra( MediaStore.EXTRA_OUTPUT, _fileUri);
            startActivityForResult(intent, TAKE_PICTURE);
        }   else {
            new AlertDialog.Builder(MainActivity.this)
            .setMessage("External Storeage (SD Card) is required.\n\nCurrent state: " + storageState)
            .setCancelable(true).create().show();
        }

我首先使用 MD5 哈希创建一个唯一(某种程度上)的文件名,并将其放入适当的文件夹中。然后我检查它是否存在(不应该,但无论如何检查都是一个很好的做法)。如果它不存在,我会获取父目录(一个文件夹)并创建直至其的文件夹层次结构(因此,如果通向文件位置的文件夹不存在,它们将在此行之后。然后在那之后创建文件后,我会获取 Uri 并将其传递给意图,然后“确定”按钮将按预期工作,

现在,当按下相机应用程序上的“确定”按钮时,该文件将被创建。存在于给定位置,在此示例中为 /sdcard/Android/data/com.example.myapp/files/234asdioue23498ad.jpg

无需复制上面发布的“onActivityResult”中的文件。

I know this has been answered before but I know a lot of people get tripped up on this, so I'm going to add a comment.

I had this exact same problem happen on my Nexus One. This was from the file not existing on the disk before the camera app started. Therefore, I made sure that the file existing before started the camera app. Here's some sample code that I used:

String storageState = Environment.getExternalStorageState();
        if(storageState.equals(Environment.MEDIA_MOUNTED)) {

            String path = Environment.getExternalStorageDirectory().getName() + File.separatorChar + "Android/data/" + MainActivity.this.getPackageName() + "/files/" + md5(upc) + ".jpg";
            _photoFile = new File(path);
            try {
                if(_photoFile.exists() == false) {
                    _photoFile.getParentFile().mkdirs();
                    _photoFile.createNewFile();
                }

            } catch (IOException e) {
                Log.e(TAG, "Could not create file.", e);
            }
            Log.i(TAG, path);

            _fileUri = Uri.fromFile(_photoFile);
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE );
            intent.putExtra( MediaStore.EXTRA_OUTPUT, _fileUri);
            startActivityForResult(intent, TAKE_PICTURE);
        }   else {
            new AlertDialog.Builder(MainActivity.this)
            .setMessage("External Storeage (SD Card) is required.\n\nCurrent state: " + storageState)
            .setCancelable(true).create().show();
        }

I first create a unique (somewhat) file name using an MD5 hash and put it into the appropriate folder. I then check to see if it exists (shouldn't, but its good practice to check anyway). If it does not exist, I get the parent dir (a folder) and create the folder hierarchy up to it (therefore if the folders leading up to the location of the file don't exist, they will after this line. Then after that I create the file. Once the file is created I get the Uri and pass it to the intent and then the OK button works as expected and all is golden.

Now,when the Ok button is pressed on the camera app, the file will be present in the given location. In this example it would be /sdcard/Android/data/com.example.myapp/files/234asdioue23498ad.jpg

There is no need to copy the file in the "onActivityResult" as posted above.

琉璃繁缕 2024-08-22 08:37:59

我尝试过多种照片拍摄策略,但似乎总有一种情况、某个平台或某些设备,上述策略中的部分或全部会以意想不到的方式失败。我找到了一种使用下面的 URI 生成代码的策略,该策略似乎适用于大多数情况(如果不是所有情况)。

mPhotoUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
            new ContentValues());
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoUri);
startActivityForResult(intent,CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE_CONTENT_RESOLVER);

为了进一步促进讨论并帮助新手,我创建了一个示例/测试应用程序,其中显示了几种不同的照片捕获实施策略。绝对鼓励其他实现的贡献加入到讨论中。

https://github.com/deepwinter/AndroidCameraTester

I've been through a number of photo capture strategies, and there always seems to be a case, a platform or certain devices, where some or all of the above strategies will fail in unexpected ways. I was able to find a strategy that uses the URI generation code below which seems to work in most if not all cases.

mPhotoUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
            new ContentValues());
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoUri);
startActivityForResult(intent,CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE_CONTENT_RESOLVER);

To contribute further to the discussion and help out newcomers I've created a sample/test app that shows several different strategies for photo capture implementation. Contributions of other implementations are definitely encouraged to add to the discussion.

https://github.com/deepwinter/AndroidCameraTester

御弟哥哥 2024-08-22 08:37:59

我遇到了同样的问题,相机应用程序中的“确定”按钮没有任何反应,无论是在模拟器上还是在 Nexus One 上。

在 MediaStore.EXTRA_OUTPUT 中指定一个没有空格、没有特殊字符的安全文件名后,问题就消失了。此外,如果您指定的文件位于尚未创建的目录中,你必须先创建它。相机应用程序不会为您执行 mkdir 操作。

I had the same problem where the OK button in camera app did nothing, both on emulator and on nexus one.

The problem went away after specifying a safe filename that is without white spaces, without special characters, in MediaStore.EXTRA_OUTPUT Also, if you are specifying a file that resides in a directory that has not yet been created, you have to create it first. Camera app doesn't do mkdir for you.

夏末 2024-08-22 08:37:59

您描述的工作流程应该按照您所描述的方式工作。如果您可以向我们展示有关创建 Intent 的代码,可能会有所帮助。一般来说,以下模式应该可以让您做您正在尝试的事情。

private void saveFullImage() {
  Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  File file = new File(Environment.getExternalStorageDirectory(), "test.jpg");
  outputFileUri = Uri.fromFile(file);
  intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
  startActivityForResult(intent, TAKE_PICTURE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if ((requestCode == TAKE_PICTURE) && (resultCode == Activity.RESULT_OK)) {
    // Check if the result includes a thumbnail Bitmap
    if (data == null) {    
      // TODO Do something with the full image stored
      // in outputFileUri. Perhaps copying it to the app folder
    }
  }
}

请注意,相机 Activity 将创建并保存文件,它实际上并不是应用程序的一部分,因此它不具有对应用程序文件夹的写入权限。要将文件保存到您的应用文件夹,请在 SD 卡上创建一个临时文件,并将其移至 onActivityResult 处理程序中的应用文件夹。

The workflow you describe should work as you've described it. It might help if you could show us the code around the creation of the Intent. In general, the following pattern should let you do what you're trying.

private void saveFullImage() {
  Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  File file = new File(Environment.getExternalStorageDirectory(), "test.jpg");
  outputFileUri = Uri.fromFile(file);
  intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
  startActivityForResult(intent, TAKE_PICTURE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if ((requestCode == TAKE_PICTURE) && (resultCode == Activity.RESULT_OK)) {
    // Check if the result includes a thumbnail Bitmap
    if (data == null) {    
      // TODO Do something with the full image stored
      // in outputFileUri. Perhaps copying it to the app folder
    }
  }
}

Note that it is the Camera Activity that will be creating and saving the file, and it's not actually part of your application, so it won't have write permission to your application folder. To save a file to your app folder, create a temporary file on the SD card and move it to your app folder in the onActivityResult handler.

感情旳空白 2024-08-22 08:37:59

为了跟进Yenchi上面的评论,如果相机应用程序无法写入有问题的目录,那么“确定”按钮也不会执行任何操作。

这意味着您无法在只能由您的应用程序写入的位置创建文件(例如 getCacheDir() 下的某些内容) getExternalFilesDir() 下的某些内容应该然而,工作。

如果相机应用程序无法写入指定的 EXTRA_OUTPUT 路径,那么如果相机应用程序在日志中打印一条错误消息,那就太好了,但我没有找到。

To follow up on Yenchi's comment above, the OK button will also do nothing if the camera app can't write to the directory in question.

That means that you can't create the file in a place that's only writeable by your application (for instance, something under getCacheDir()) Something under getExternalFilesDir() ought to work, however.

It would be nice if the camera app printed an error message to the logs if it could not write to the specified EXTRA_OUTPUT path, but I didn't find one.

§对你不离不弃 2024-08-22 08:37:59

要让相机写入 SD 卡,但保留在图库应用程序上的新相册中,我使用以下方法:

 File imageDirectory = new File("/sdcard/signifio");
          String path = imageDirectory.toString().toLowerCase();
           String name = imageDirectory.getName().toLowerCase();


            ContentValues values = new ContentValues(); 
            values.put(Media.TITLE, "Image"); 
            values.put(Images.Media.BUCKET_ID, path.hashCode());
            values.put(Images.Media.BUCKET_DISPLAY_NAME,name);

            values.put(Images.Media.MIME_TYPE, "image/jpeg");
            values.put(Media.DESCRIPTION, "Image capture by camera");
           values.put("_data", "/sdcard/signifio/1111.jpg");
         uri = getContentResolver().insert( Media.EXTERNAL_CONTENT_URI , values);
            Intent i = new Intent("android.media.action.IMAGE_CAPTURE"); 

            i.putExtra(MediaStore.EXTRA_OUTPUT, uri);

            startActivityForResult(i, 0); 

请注意,您每次都需要生成唯一的文件名并替换我编写的 1111.jpg。
这是用 Nexus 1 进行测试的。
uri 在私有类中声明,因此在活动结果中,如果需要,我可以将图像从 uri 加载到 imageView 进行预览。

to have the camera write to sdcard but keep in a new Album on the gallery app I use this :

 File imageDirectory = new File("/sdcard/signifio");
          String path = imageDirectory.toString().toLowerCase();
           String name = imageDirectory.getName().toLowerCase();


            ContentValues values = new ContentValues(); 
            values.put(Media.TITLE, "Image"); 
            values.put(Images.Media.BUCKET_ID, path.hashCode());
            values.put(Images.Media.BUCKET_DISPLAY_NAME,name);

            values.put(Images.Media.MIME_TYPE, "image/jpeg");
            values.put(Media.DESCRIPTION, "Image capture by camera");
           values.put("_data", "/sdcard/signifio/1111.jpg");
         uri = getContentResolver().insert( Media.EXTERNAL_CONTENT_URI , values);
            Intent i = new Intent("android.media.action.IMAGE_CAPTURE"); 

            i.putExtra(MediaStore.EXTRA_OUTPUT, uri);

            startActivityForResult(i, 0); 

Please note that you will need to generate a unique filename every time and replace teh 1111.jpg that I wrote.
This was tested with nexus one.
the uri is declared in the private class , so on activity result I am able to load the image from the uri to imageView for preview if needed.

半窗疏影 2024-08-22 08:37:59

我遇到了同样的问题,我用以下方法修复了它:

问题是,当您指定只有您的应用程序有权访问的文件时(例如通过调用 getFileStreamPath("file");),

那就是为什么我只是确保给定的文件确实存在并且每个人都对其具有写访问权限。

Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File outFile = getFileStreamPath(Config.IMAGE_FILENAME);
outFile.createNewFile();
outFile.setWritable(true, false);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,Uri.fromFile(outFile));
startActivityForResult(intent, 2);

这样,相机应用程序就可以对给定的 Uri 进行写入访问,并且“确定”按钮可以正常工作:)

I had the same issue and i fixed it with the following:

The problem is that when you specify a file that only your app has access to (e.g. by calling getFileStreamPath("file");)

That is why i just made sure that the given file really exists and that EVERYONE has write access to it.

Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File outFile = getFileStreamPath(Config.IMAGE_FILENAME);
outFile.createNewFile();
outFile.setWritable(true, false);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,Uri.fromFile(outFile));
startActivityForResult(intent, 2);

This way, the camera app has write access to the given Uri and the OK button works fine :)

暮光沉寂 2024-08-22 08:37:59

我建议您按照 Android 培训帖子拍摄照片。他们在示例中展示了如何拍摄小照片和大照片。您还可以从此处下载源代码

I recommend you to follow the android trainning post for capturing a photo. They show in an example how to take small and big pictures. You can also download the source code from here

许久 2024-08-22 08:37:59

我创建了简单的库,它将管理从不同来源(图库、相机)选择图像,也许将其保存到某个位置(SD 卡或内部存储器)并将图像返回,因此请随意使用它并改进它 - Android-ImageChooser

I created simple library which will manage choosing images from different sources (Gallery, Camera), maybe save it to some location (SD-Card or internal memory) and return the image back so please free to use it and improve it - Android-ImageChooser.

看轻我的陪伴 2024-08-22 08:37:59

正如 Praveen 指出的那样,该文件需要可由相机写入。

在我的使用中,我想将文件存储在内部存储中。我是这样做的:

Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (i.resolveActivity(getPackageManager()!=null)){
    try{
        cacheFile = createTempFile("img",".jpg",getCacheDir());
        cacheFile.setWritavle(true,false);
    }catch(IOException e){}
    if(cacheFile != null){
        i.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(cacheFile));
        startActivityForResult(i,REQUEST_IMAGE_CAPTURE);
    }
}

这里 cacheFile 是一个全局文件,用于引用写入的文件。
然后在result方法中返回的intent为null。
那么处理意图的方法如下所示:

protected void onActivityResult(int requestCode,int resultCode,Intent data){
    if(requestCode != RESULT_OK){
        return;
    }
    if(requestCode == REQUEST_IMAGE_CAPTURE){
        try{
            File output = getImageFile();
            if(output != null && cacheFile != null){
                copyFile(cacheFile,output);

                //Process image file stored at output

                cacheFile.delete();
                cacheFile=null;
            }
        }catch(IOException e){}
    }
}

这里 getImageFile() 是一个实用方法,用于命名和创建应存储图像的文件,而 copyFile()是一种复制文件的方法。

The file needs be writable by the camera, as Praveen pointed out.

In my usage I wanted to store the file in internal storage. I did this with:

Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (i.resolveActivity(getPackageManager()!=null)){
    try{
        cacheFile = createTempFile("img",".jpg",getCacheDir());
        cacheFile.setWritavle(true,false);
    }catch(IOException e){}
    if(cacheFile != null){
        i.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(cacheFile));
        startActivityForResult(i,REQUEST_IMAGE_CAPTURE);
    }
}

Here cacheFile is a global file used to refer to the file which is written.
Then in the result method the returned intent is null.
Then the method for processing the intent looks like:

protected void onActivityResult(int requestCode,int resultCode,Intent data){
    if(requestCode != RESULT_OK){
        return;
    }
    if(requestCode == REQUEST_IMAGE_CAPTURE){
        try{
            File output = getImageFile();
            if(output != null && cacheFile != null){
                copyFile(cacheFile,output);

                //Process image file stored at output

                cacheFile.delete();
                cacheFile=null;
            }
        }catch(IOException e){}
    }
}

Here getImageFile() is a utility method to name and create the file in which the image should be stored, and copyFile() is a method to copy a file.

落叶缤纷 2024-08-22 08:37:59

您可以使用此代码

private Intent getCameraIntent() {

    PackageManager packageManager = mContext.getPackageManager();
    List<ApplicationInfo> list = packageManager.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
    Intent main = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    List<ResolveInfo> launchables = packageManager.queryIntentActivities(main, 0);
    if (launchables.size() == 1)
        return packageManager.getLaunchIntentForPackage(launchables.get(0).activityInfo.packageName);
    else
        for (int n = 0; n < list.size(); n++) {
            if ((list.get(n).flags & ApplicationInfo.FLAG_SYSTEM) == 1) {
                Log.d("TAG", "Installed Applications  : " + list.get(n).loadLabel(packageManager).toString());
                Log.d("TAG", "package name  : " + list.get(n).packageName);
                String defaultCameraPackage = list.get(n).packageName;


                if (launchables.size() > 1)
                    for (int i = 0; i < launchables.size(); i++) {
                        if (defaultCameraPackage.equals(launchables.get(i).activityInfo.packageName)) {
                            return packageManager.getLaunchIntentForPackage(defaultCameraPackage);
                        }
                    }
            }
        }
    return null;
}

You can use this code

private Intent getCameraIntent() {

    PackageManager packageManager = mContext.getPackageManager();
    List<ApplicationInfo> list = packageManager.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
    Intent main = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    List<ResolveInfo> launchables = packageManager.queryIntentActivities(main, 0);
    if (launchables.size() == 1)
        return packageManager.getLaunchIntentForPackage(launchables.get(0).activityInfo.packageName);
    else
        for (int n = 0; n < list.size(); n++) {
            if ((list.get(n).flags & ApplicationInfo.FLAG_SYSTEM) == 1) {
                Log.d("TAG", "Installed Applications  : " + list.get(n).loadLabel(packageManager).toString());
                Log.d("TAG", "package name  : " + list.get(n).packageName);
                String defaultCameraPackage = list.get(n).packageName;


                if (launchables.size() > 1)
                    for (int i = 0; i < launchables.size(); i++) {
                        if (defaultCameraPackage.equals(launchables.get(i).activityInfo.packageName)) {
                            return packageManager.getLaunchIntentForPackage(defaultCameraPackage);
                        }
                    }
            }
        }
    return null;
}
调妓 2024-08-22 08:37:59

使用 Activity Result Code 解决这个问题非常简单,简单尝试一下这个方法

if (reqCode == RECORD_VIDEO) {
   if(resCode == RESULT_OK) {
       if (uri != null) {
           compress();
       }
    } else if(resCode == RESULT_CANCELED && data!=null){
       Toast.makeText(MainActivity.this,"No Video Recorded",Toast.LENGTH_SHORT).show();
   }
}

It is very simple to solve this problem with Activity Result Code Simple try this method

if (reqCode == RECORD_VIDEO) {
   if(resCode == RESULT_OK) {
       if (uri != null) {
           compress();
       }
    } else if(resCode == RESULT_CANCELED && data!=null){
       Toast.makeText(MainActivity.this,"No Video Recorded",Toast.LENGTH_SHORT).show();
   }
}
情未る 2024-08-22 08:37:59
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_CANCELED)
    {
        //do not process data, I use return; to resume activity calling camera intent
        enter code here
    }
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_CANCELED)
    {
        //do not process data, I use return; to resume activity calling camera intent
        enter code here
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文