【发布时间】:2011-11-25 09:08:45
【问题描述】:
我正在使用意图 new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 来捕获图像以在我的应用程序中使用。我的设备上安装了两个可以执行此功能的应用程序,但希望我的应用程序仅使用默认相机。
有没有办法做到这一点?
【问题讨论】:
标签: android camera android-intent
我正在使用意图 new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 来捕获图像以在我的应用程序中使用。我的设备上安装了两个可以执行此功能的应用程序,但希望我的应用程序仅使用默认相机。
有没有办法做到这一点?
【问题讨论】:
标签: android camera android-intent
正如 Dr_sulli 建议的那样,我只是将其转换为代码,它对我很有效,如果情况下访问直接相机应用程序,其他部分是允许用户选择其他相机应用程序以及系统相机。
protected static final int CAMERA_ACTIVITY = 100;
Intent mIntent = null;
if(isPackageExists("com.google.android.camera")){
mIntent= new Intent();
mIntent.setPackage("com.google.android.camera");
mIntent.setAction(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
mIntent.putExtra("output", Uri.fromFile(new File(Environment
.getExternalStorageDirectory(), "/myImage" + ".jpg")));
}else{
mIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
mIntent.putExtra("output", Uri.fromFile(new File(Environment
.getExternalStorageDirectory(), "/myImage" + ".jpg")));
Log.i("in onMenuItemSelected",
"Result code = "
+ Environment.getExternalStorageDirectory());
}
startActivityForResult(mIntent, CAMERA_ACTIVITY);
在 onActivityResult 里面做你的事情
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
Log.i("in onActivityResult", "Result code = " + resultCode);
if (resultCode == -1) {
switch (requestCode) {
case CAMERA_ACTIVITY:
//do your stuff here, i am just calling the path of stored image
String filePath = Environment.getExternalStorageDirectory()
+ "/myImage" + ".jpg";
}
}
}
isPackageExists 将确认包是否存在。
public boolean isPackageExists(String targetPackage){
List<ApplicationInfo> packages;
PackageManager pm;
pm = getPackageManager();
packages = pm.getInstalledApplications(0);
for (ApplicationInfo packageInfo : packages) {
if(packageInfo.packageName.equals(targetPackage)) return true;
}
return false;
}
或者你可以用我的方式更容易做到这一点,这将过滤所有系统应用程序,然后你比较名称,因此它适用于所有手机,但由于硬编码,上述技术不适用于每部手机。稍后您可以使用此包名称启动相机活动,如上所述。
PackageManager pm = this.getPackageManager();
List<ApplicationInfo> list = getPackageManager().getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
for (int n=0;n<list.size();n++) {
if((list.get(n).flags & ApplicationInfo.FLAG_SYSTEM)==1)
{
Log.d("Installed Applications", list.get(n).loadLabel(pm).toString());
Log.d("package name", list.get(n).packageName);
if(list.get(n).loadLabel(pm).toString().equalsIgnoreCase("Camera"))
break;
}
}
【讨论】:
OR you can do it in my way its much easier 是否总是会在所有设备上返回正确的默认相机应用程序包名称?目前你在list.get(n).loadLabel(pm).toString().equalsIgnoreCase("Camera") 时打破循环,所有设备都会这样吗?
List<ApplicationInfo> list = packageManager.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
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);
if(list.get(n).loadLabel(packageManager).toString().equalsIgnoreCase("Camera")) {
defaultCameraPackage = list.get(n).packageName;
break;
}
}
}
我发现以下解决方案及其完美运行。
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.setPackage(defaultCameraPackage);
startActivityForResult(takePictureIntent, actionCode);
您可以通过在上述意图中设置包来过滤默认相机。我通过安装两个应用程序 Line Camera 和 Paper Camera 对其进行了测试,这两个应用程序都显示选择器,但过滤打包上面的代码只打开默认摄像头。
【讨论】:
我准备了一个几乎适用于所有解决方案的解决方案:
private void openCamera() {
String systemCamera;
if (isPackageExists("com.google.android.camera")) {
systemCamera = "com.google.android.camera";
} else {
systemCamera = findSystemCamera();
}
if (systemCamera != null) {
Log.d(TAG, "System Camera: " + systemCamera);
Intent mIntent = new Intent();
mIntent.setPackage(systemCamera);
File f = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), ("IMG_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".jpg"));
mIntent.setAction(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
mIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(mIntent, IMAGE_CODE_PICKER);
} else {
//Unable to find default camera app
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == IMAGE_CODE_PICKER && resultCode == RESULT_OK) {
}
}
private boolean isPackageExists(String targetPackage) {
List<ApplicationInfo> packages;
PackageManager pm;
pm = getPackageManager();
packages = pm.getInstalledApplications(0);
for (ApplicationInfo packageInfo : packages) {
if (packageInfo.packageName.equals(targetPackage)) {
return true;
}
}
return false;
}
private String findSystemCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
PackageManager packageManager = this.getPackageManager();
List<ResolveInfo> listCam = packageManager.queryIntentActivities(intent, 0);
for (ResolveInfo info :
listCam) {
if (isSystemApp(info.activityInfo.packageName)) {
return info.activityInfo.packageName;
}
}
return null;
}
boolean isSystemApp(String packageName) {
ApplicationInfo ai;
try {
ai = this.getPackageManager().getApplicationInfo(packageName, 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return false;
}
int mask = ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
return (ai.flags & mask) != 0;
}
您可能需要在 onCreate 方法中添加以下代码:
StrictMode.VmPolicy.Builder newbuilder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(newbuilder.build());
【讨论】:
findSystemCamera() 将始终返回设备的默认相机应用程序,无论设备如何?
我不确定您要实现的目标是否可以在所有设备上移植。 Android 的目标之一是允许轻松替换服务请求的活动,例如图像捕获。话虽如此,如果您只想为您的设备执行此操作,您可以简单地将意图中的组件名称设置为媒体捕获活动的名称。
【讨论】:
默认的相机应用是第一个安装的应用。因此,camlist 中的第一个元素是默认应用程序
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
PackageManager packageManager = MapsActivity.this.getPackageManager();
List<ResolveInfo> listCam = packageManager.queryIntentActivities(intent, 0);
intent.setPackage(listCam.get(0).activityInfo.packageName);
startActivityForResult(intent,INTENT_REQUESTCODE1);
【讨论】: