首先先说明一下,鉴于网上搜android调用系统相机,得到的内容一大把都是:调用系统相机然后获得图片(网上一大把这样的东西,抄过来抄过去,有些人根本就不加以验证是否有效,很不提倡这种做法),如果需要这样功能的请自行百度,我待会介绍的是单纯调用系统相机,但不需要获取图片。
就单纯调用系统相机而言,先说说几个问题
1、系统版本
这个问题在这个帖子中说明了
http://www.eoeandroid.com/thread-536075-1-1.html
在不同版本的系统中,调用的方法似乎不一样,上述的方法在我的小米2S手机上试了不行
2、大部分机型可以,其他机型目前只测试了小米和三星。
3、机型
我在我手机上常使用的方法是
ComponentName comp = new ComponentName("com.android.camera",
"com.android.camera.Camera");
intent.setComponent(comp);
intent.setAction("android.intent.action.VIEW");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivity(intent);
这个方法确实可行,但是当我在nexus 5上使用时,程序崩溃了........
无意间得到这个帖子的一点启示
http://www.apkbus.com/android-182775-1-1.html
可以先通过找到包名再调用相机,因为我发现,之前小米可用的那个方法虽然在别的机型上不行,但是如果Intent的Action是MediaStore.ACTION_IMAGE_CAPTURE。虽然网上很多说“调用系统相机拍照返回照片”用的都是这个,但是确实在很多机型上都可以打开相机
于是我想到了,既然相机包名找到了,那可以通过包名启动相机
Intent infoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
ResolveInfo res = getPackageManager().
resolveActivity(infoIntent, 0);
if (res != null) {
//启动相机
startApplicationByPackageName(res.activityInfo.packageName);
}
其中startApplicationByPackageName方法如下
//通过包名启动应用
private void startApplicationByPackageName(String packName)
{
PackageInfo packageInfo=null;
try{
packageInfo=getPackageManager().getPackageInfo(packName, 0);
}catch(Exception e){
e.printStackTrace();
}
if(null==packageInfo){
return;
}
Intent resolveIntent=new Intent();
resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
resolveIntent.setPackage(packageInfo.packageName);
List<ResolveInfo> resolveInfoList =getPackageManager().queryIntentActivities(resolveIntent, 0);
if(null==resolveInfoList){
return;
}
Iterator<ResolveInfo> iter=resolveInfoList.iterator();
while(iter.hasNext()){
ResolveInfo resolveInfo=(ResolveInfo) iter.next();
if(null==resolveInfo){
return;
}
String packageName=resolveInfo.activityInfo.packageName;
String className=resolveInfo.activityInfo.name;
Intent intent=new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ComponentName cn=new ComponentName(packageName, className);
intent.setComponent(cn);
startActivity(intent);
}//while
}//method
考虑到三星的部分机型不吃MediaStore.ACTION_IMAGE_CAPTURE这套,但是却吃MediaStore.ACTION_IMAGE_CAPTURE_SECURE,前后只是多了一个SECURE。因此稍作修改,完整方法如下(目前我手上的机型都支持,包括Vivo、魅族、三星、锤子、小米、Nexus、索尼、HTC)
//启动相机
private void launchCamera()
{
try{
//获取相机包名
Intent infoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
ResolveInfo res = mContext.getPackageManager().
resolveActivity(infoIntent, 0);
if (res != null)
{
String packageName=res.activityInfo.packageName;
if(packageName.equals("android"))
{
infoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE_SECURE);
res = mContext.getPackageManager().
resolveActivity(infoIntent, 0);
if (res != null)
packageName=res.activityInfo.packageName;
}
//启动相机
startApplicationByPackageName(packageName);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
//通过包名启动应用
private void startApplicationByPackageName(String packName)
{
PackageInfo packageInfo=null;
try{
packageInfo=mContext.getPackageManager().getPackageInfo(packName, 0);
}catch(Exception e){
e.printStackTrace();
}
if(null==packageInfo){
return;
}
Intent resolveIntent=new Intent();
resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
resolveIntent.setPackage(packageInfo.packageName);
List<ResolveInfo> resolveInfoList =mContext.getPackageManager().queryIntentActivities(resolveIntent, 0);
if(null==resolveInfoList){
return;
}
Iterator<ResolveInfo> iter=resolveInfoList.iterator();
while(iter.hasNext()){
ResolveInfo resolveInfo=(ResolveInfo) iter.next();
if(null==resolveInfo){
return;
}
String packageName=resolveInfo.activityInfo.packageName;
String className=resolveInfo.activityInfo.name;
Intent intent=new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ComponentName cn=new ComponentName(packageName, className);
intent.setComponent(cn);
mContext.startActivity(intent);
}//while
}//method