android camera intent 在某些手机上崩溃应用程序(约 20%)
Posted
技术标签:
【中文标题】android camera intent 在某些手机上崩溃应用程序(约 20%)【英文标题】:android camera intent crashes app on some phones (about 20% of them) 【发布时间】:2012-12-12 06:25:25 【问题描述】:我对这个问题做了很多研究,看到了一些很好的反应,并找到了一些很好的资源来解决这个问题。然而不幸的是,我仍然在某些设备上遇到很多应用程序崩溃。崩溃发生在有人拍照后,相机意图应该将信息传递回调用活动。就我的应用程序而言,我只是用新拍摄的照片覆盖任何现有照片,因此我几乎可以使用文件位置的静态路径。我是这样称呼意图的:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// get the file path from an external class (necessary for galaxy nexus)
imageFileAndPath = ImageServices.getOutputImageFileUri(cont);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageFileAndPath);
startActivityForResult(intent, CAMERA_REQUEST_CODE);
imageFileAndPath 只是一个 URI 变量,我从一个单独的类创建它,因为这解决了另一个问题,即按“完成”或复选标记或在特定设备上关闭相机意图不是在几种设备类型上做任何事情。通过从一个单独的类创建 URI,它解决了一些未知原因的问题。
我的 onActivityResult 看起来像这样:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
if(resultCode == Activity.RESULT_OK)
if (requestCode == CAMERA_REQUEST_CODE)
setupImageView();
imageView = (ImageView) findViewById(R.id.image_view);
webView.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE);
button.setVisibility(View.GONE);
reTakePicButton.setVisibility(View.VISIBLE);
rl.setVisibility(View.VISIBLE);
因为我不需要动态路径来保存我的照片(因为它会覆盖现有照片),所以我只需在我的活动中调用另一个方法来调整照片的大小并相应地旋转它。该方法如下:
private void setupImageView()
imageLocation = Environment.getExternalStorageDirectory().getAbsolutePath() + "/myappphoto/myappphoto.jpg";
// Get the dimensions of the View
Display display = getWindowManager().getDefaultDisplay();
Point size = getDisplaySize(display);
int targetW = size.x;
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imageLocation, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW / targetW, photoH / targetW);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(imageLocation, bmOptions);
int rotationForImage = getRotationForImage(imageLocation);
if (rotationForImage != 0)
int targetWidth = rotationForImage == 90 || rotationForImage == 270 ? bitmap.getHeight() : bitmap.getWidth();
int targetHeight = rotationForImage == 90 || rotationForImage == 270 ? bitmap.getWidth() : bitmap.getHeight();
Bitmap rotatedBitmap = Bitmap.createBitmap(targetWidth, targetHeight, bitmap.getConfig());
Canvas canvas = new Canvas(rotatedBitmap);
Matrix matrix = new Matrix();
matrix.setRotate(rotationForImage, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
canvas.drawBitmap(bitmap, matrix, new Paint());
bitmap.recycle();
bitmap = rotatedBitmap;
Bitmap resized;
if(bitmap.getWidth() >= 900 || bitmap.getHeight() >=900)
int newWidth = Math.round(bitmap.getWidth()/2);
int newHeight = Math.round(bitmap.getHeight()/2);
resized = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
else
resized = bitmap;
//bitmap.recycle();
bitmap = resized;
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 70, bytes);
try
File f = new File(imageLocation);
f.createNewFile();
//write the bytes in file
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
catch(java.io.IOException e)
imageView.setImageBitmap(bitmap);
您可以在该方法的顶部看到从相机意图保存的图像文件的静态路径。
我想调整大小、旋转方法可能会导致崩溃,但我不明白为什么会这样,这对我来说都是非常标准的 java 编码。
有人能看出我在这里所做的事情有什么明显的错误吗?正如我在这个线程的标题中所说,我的代码导致大约 20% 的运行它的设备崩溃,这是不可接受的。我可以处理 5%,但不能处理 20%。
我意识到 android 开发在这方面有点像一场噩梦,因为您必须考虑这么多不同的设备类型(制造商、android 版本等),但我认为相机活动应该比这更好地标准化。正如我在该主题的顶部所说,我已经对这个问题进行了很多研究,并看到几个人与我的问题相似,但没有涵盖大多数设备的良好解决方案。我真的不想从零开始写(我也不认为我应该写)我自己的相机。 Android设备上必须有一个更好的默认内置摄像头意图实现......我只是还没有找到它。正如你所看到的,我什至不关心动态创建图像,这会使这个项目变得更容易。
TIA
编辑:根据下面的评论,我添加了来自故障相机的堆栈跟踪。它看起来像一个空指针异常。我拍了大约 6 张照片,然后继续使用调用相机意图的按钮返回,直到最终失败。这是堆栈跟踪:
STACK_TRACE
"java.lang.RuntimeException: Unable to resume activity com.myapp/com.myapp.MyActivity: java.lang.RuntimeException: Failure delivering result ResultInfowho=null, request=904, result=-1, data=null to activity com.myapp/com.myapp.MyActivity: java.lang.NullPointerException
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2124)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2139)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1672)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2836)
at android.app.ActivityThread.access$1600(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Failure delivering result ResultInfowho=null, request=904, result=-1, data=null to activity com.myapp/com.myapp.MyActivity: java.lang.NullPointerException
at android.app.ActivityThread.deliverResults(ActivityThread.java:2536)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2111)
... 13 more
Caused by: java.lang.NullPointerException
at com.myapp.MyActivity.onActivityResult(EnterContest.java:257)
at android.app.Activity.dispatchActivityResult(Activity.java:3908)
at android.app.ActivityThread.deliverResults(ActivityThread.java:2532)
... 14 more
java.lang.RuntimeException: Failure delivering result ResultInfowho=null, request=904, result=-1, data=null to activity com.myapp/com.myapp.MyActivity: java.lang.NullPointerException
at android.app.ActivityThread.deliverResults(ActivityThread.java:2536)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2111)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2139)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1672)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2836)
at android.app.ActivityThread.access$1600(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.myapp.MyActivity.onActivityResult(EnterContest.java:257)
at android.app.Activity.dispatchActivityResult(Activity.java:3908)
at android.app.ActivityThread.deliverResults(ActivityThread.java:2532)
... 14 more
java.lang.NullPointerException
at com.myapp.MyActivity.onActivityResult(EnterContest.java:257)
at android.app.Activity.dispatchActivityResult(Activity.java:3908)
at android.app.ActivityThread.deliverResults(ActivityThread.java:2532)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2111)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2139)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1672)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2836)
at android.app.ActivityThread.access$1600(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
【问题讨论】:
请发布相关的堆栈跟踪,显示您的“崩溃”的性质。 @CommonsWare 不幸的是我没有他们可以发布。崩溃发生在我无法测试的设备上。此应用程序目前处于测试阶段,一些用户正在经历崩溃,而大多数用户则没有。如何设置日志记录以从已经崩溃的“现场”设备获取堆栈跟踪信息 “我如何设置日志记录以从已经崩溃的“现场”设备获取堆栈跟踪信息”——使用 ACRA 或类似库:acra.ch。 @CommonsWare 好的,我在我的 OP 中发布了堆栈跟踪。为什么它会工作几次,然后得到一个 NPE? 您的堆栈跟踪与您的源代码不匹配。onActivityResult()
中没有直接可以引发NullPointerException
的行。您正在运行 onActivityResult()
的其他一些实现,我们无法知道其中可能包含什么,更不用说它为什么会崩溃。
【参考方案1】:
也许是一个猜测,但我认为我遇到了同样的问题,我修复了它在新的 AsyncTask 中读取位图,而不是在 UI 线程中。
异常发生(显然以随机方式)调用
getContentResolver().notifyChange(selectedImage, null);
其中 selectedImage 是之前在
中设置的 URIintent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
你在 com.myapp.MyActivity.onActivityResult(EnterContest.java:257) 中调用了什么?
我有一个使用 ACRA 收集的堆栈跟踪:
java.lang.RuntimeException: Unable to resume activity com.infonair.meetme.app/com.infonair.meetme.activity.photo.TakePhotoActivity: java.lang.RuntimeException: Failure delivering result ResultInfowho=null, request=7898789, result=-1, data=Intent dat=content://media/external/images/media/9 to activity com.infonair.meetme.app/com.infonair.meetme.activity.photo.TakePhotoActivity: java.lang.NullPointerException
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2126)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2141)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1674)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2838)
at android.app.ActivityThread.access$1600(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3737)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:894)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Failure delivering result ResultInfowho=null, request=7898789, result=-1, data=Intent dat=content://media/external/images/media/9 to activity com.infonair.meetme.app/com.infonair.meetme.activity.photo.TakePhotoActivity: java.lang.NullPointerException
at android.app.ActivityThread.deliverResults(ActivityThread.java:2538)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2113)
... 13 more
Caused by: java.lang.NullPointerException
at android.os.Parcel.readException(Parcel.java:1328)
at android.os.Parcel.readException(Parcel.java:1276)
at android.content.IContentService$Stub$Proxy.notifyChange(IContentService.java:458)
at android.content.ContentResolver.notifyChange(ContentResolver.java:912)
at android.content.ContentResolver.notifyChange(ContentResolver.java:898)
at com.infonair.meetme.activity.photo.TakePhotoActivity.onActivityResult(TakePhotoActivity.java:154)
at android.app.Activity.dispatchActivityResult(Activity.java:3908)
at android.app.ActivityThread.deliverResults(ActivityThread.java:2534)
... 14 more
java.lang.RuntimeException: Failure delivering result ResultInfowho=null, request=7898789, result=-1, data=Intent dat=content://media/external/images/media/9 to activity com.infonair.meetme.app/com.infonair.meetme.activity.photo.TakePhotoActivity: java.lang.NullPointerException
at android.app.ActivityThread.deliverResults(ActivityThread.java:2538)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2113)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2141)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1674)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2838)
at android.app.ActivityThread.access$1600(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3737)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:894)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at android.os.Parcel.readException(Parcel.java:1328)
at android.os.Parcel.readException(Parcel.java:1276)
at android.content.IContentService$Stub$Proxy.notifyChange(IContentService.java:458)
at android.content.ContentResolver.notifyChange(ContentResolver.java:912)
at android.content.ContentResolver.notifyChange(ContentResolver.java:898)
at com.infonair.meetme.activity.photo.TakePhotoActivity.onActivityResult(TakePhotoActivity.java:154)
at android.app.Activity.dispatchActivityResult(Activity.java:3908)
at android.app.ActivityThread.deliverResults(ActivityThread.java:2534)
... 14 more
java.lang.NullPointerException
at android.os.Parcel.readException(Parcel.java:1328)
at android.os.Parcel.readException(Parcel.java:1276)
at android.content.IContentService$Stub$Proxy.notifyChange(IContentService.java:458)
at android.content.ContentResolver.notifyChange(ContentResolver.java:912)
at android.content.ContentResolver.notifyChange(ContentResolver.java:898)
at com.infonair.meetme.activity.photo.TakePhotoActivity.onActivityResult(TakePhotoActivity.java:154)
at android.app.Activity.dispatchActivityResult(Activity.java:3908)
at android.app.ActivityThread.deliverResults(ActivityThread.java:2534)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2113)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2141)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1674)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2838)
at android.app.ActivityThread.access$1600(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3737)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:894)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)
at dalvik.system.NativeStart.main(Native Method)
【讨论】:
我遇到了这个问题。使用此意图时,有几台设备(全部为 SG)随机崩溃,同一行 (getContent().notifyChange(uri,null) ) 出现空指针异常。 @Frank 你试过用 AsyncTask 来做这个操作吗?【参考方案2】:在此处查看此帖子 Content uri crashes camera on Android KitKat
一些较旧的相机应用程序不正确支持 content:// URI,并且在传递不是 file:// URI 的 EXTRA_OUTPUT 时会崩溃。在更新我的代码以支持 Android N+ 中的 FileProviders 时,我注意到了这个错误。如果您将 URI 更改为 SDK 小于 Android N 的应用程序的 file:// URI,您应该能够解决此问题。
【讨论】:
【参考方案3】:在与这个问题作斗争时,我注意到在某些设备中拍摄的图片太大,甚至无法显示在 ImageView 上(有一个警告说图像太宽而无法纹理),所以我开始努力调整它的大小服务器可用的大小。
我会发布整个代码(至少是关于拍摄和处理图片的代码)以防万一
这是调用意图的代码
public void takePhoto()
String directoryPath = DCIM_PATH;
this.pictureFileName = Long.toHexString(System.currentTimeMillis())+".jpg";
String filePath = directoryPath + pictureFileName ;
File directory = new File(directoryPath);
if (!directory.exists())
directory.mkdirs();
this.imageUri = Uri.parse(filePath);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(
MediaStore.EXTRA_OUTPUT,Uri.fromFile( new File(filePath) )
);
startActivityForResult(intent, TAKE_PICTURE);
在onActivityResult
我调用了一个方法来处理新拍的图片
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode)
case TAKE_PICTURE:
if (resultCode == Activity.RESULT_OK)
loadImageJustTaken(imageUri);
break;
这是说的方法
public void loadImageJustTaken(Uri selectedImage)
mActivity.getApplicationContext().getContentResolver().notifyChange(selectedImage, null);
/*
* process image to make its wide equals IMG_WIDTH constant, so that larger images will fit in ImageView
*/
Bitmap b = BitmapHelper.decodeFileToScaledBitmap(new File(imageUri.getPath()), Tapabook.IMG_WIDTH);
ivPicture.setImageBitmap(b);
ivPicture.setVisibility(View.VISIBLE);
System.gc();
这是我的代码 BitmapHelper
class
public class BitmapHelper
private static final String LOGTAG = "BitmapHelper";
public static File scaleBitmapFile(File f, int WIDTH) throws IOException
Log.d(LOGTAG, "scaleBitmapFile to WIDTH: " + WIDTH);
Bitmap b2 = decodeFileToScaledBitmap( f, WIDTH);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
Log.d(LOGTAG, "scaleBitmapFile compress bitmap to jpg ");
b2.compress(Bitmap.CompressFormat.JPEG,70 , outStream);
File scaledBitmapFile = new File(Environment.getExternalStorageDirectory()
+ File.separator + "temp.jpg");
Log.d(LOGTAG, "scaleBitmapFile file: temp.jpg" );
scaledBitmapFile.createNewFile();
Log.d(LOGTAG, "scaleBitmapFile file CREATED" );
//write the bytes in file
FileOutputStream fo = new FileOutputStream(scaledBitmapFile);
fo.write(outStream.toByteArray());
Log.d(LOGTAG, "scaleBitmapFile file WRITTEN" );
// remember close de FileOutput
fo.close();
Log.d(LOGTAG, "scaleBitmapFile file CLOSED" );
return scaledBitmapFile;
public static Bitmap decodeFileToScaledBitmap(File f, int WIDTH)
Log.d(LOGTAG, "decodeFileToScaledBitmap to WIDTH: " + WIDTH);
try
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//The new size we want to scale to
final int REQUIRED_WIDTH=WIDTH;
final int ORIG_WIDTH = o.outWidth;
final int ORIG_HEIGHT = o.outHeight;
Log.d(LOGTAG, "decodeFileToScaledBitmap original width: [" + ORIG_WIDTH + "] original height: [" + ORIG_HEIGHT+ "]");
final int REQUIRED_HEIGHT = ORIG_HEIGHT/( ORIG_WIDTH / REQUIRED_WIDTH ) ;
//Decode with scaled height
Log.d(LOGTAG, "decodeFileToScaledBitmap returning scaled bitmap ");
return Bitmap.createScaledBitmap(
BitmapFactory.decodeFile(f.getAbsolutePath()),
REQUIRED_WIDTH,
REQUIRED_HEIGHT,
false);
catch (FileNotFoundException e)
Log.e(LOGTAG, "decodeFileToScaledBitmap FileNotFoundException: " +e.getMessage());
return null;
public static Bitmap scaleBitmap(Bitmap b, int WIDTH)
final int REQUIRED_WIDTH=WIDTH;
final int ORIG_WIDTH = b.getWidth();
final int ORIG_HEIGHT = b.getHeight();
Log.d(LOGTAG, "scaleBitmap original width: [" + ORIG_WIDTH + "] original height: [" + ORIG_HEIGHT+ "]");
final int REQUIRED_HEIGHT = ORIG_HEIGHT/( ORIG_WIDTH / REQUIRED_WIDTH ) ;
Log.d(LOGTAG, "scaleBitmap returning scaled bitmap ");
return Bitmap.createScaledBitmap(
b,
REQUIRED_WIDTH,
REQUIRED_HEIGHT,
false);
使用它,我在使用三星设备拍照时不再有问题,无论是像 SG3/Apollo 这样的旧手持设备还是像 SGTab 10.1 这样的新平板电脑 希望对你有帮助:)
【讨论】:
以上是关于android camera intent 在某些手机上崩溃应用程序(约 20%)的主要内容,如果未能解决你的问题,请参考以下文章
在某些设备上拍照后,Camera Intent 显示模糊的图像预览
Android Camera Intent 与 Android L 崩溃
Android:权限拒绝:以撤销权限启动 Intent android.permission.CAMERA
未找到处理 Intent act=com.android.camera.action.CROP 的 Activity
Android MediaStore.ACTION_IMAGE_CAPTURE 和 Intent.ACTION_PICK