Android ACTION_IMAGE_CAPTURE Intent 在返回 onActivityResult 之前拍照时间歇性崩溃

Posted

技术标签:

【中文标题】Android ACTION_IMAGE_CAPTURE Intent 在返回 onActivityResult 之前拍照时间歇性崩溃【英文标题】:Android ACTION_IMAGE_CAPTURE intent crashing intermittently when taking picture before returning to onActivityResult 【发布时间】:2017-01-12 19:16:06 【问题描述】:

我的应用使用 MediaStore.ACTION_IMAGE_CAPTURE Intent 拍照。问题是,在我按下快门按钮后但在显示允许我重新拍摄或接受照片的“确定”和“取消”按钮之前,应用程序会间歇性地崩溃。确定和取消按钮选择是意图的一部分,而不是我的代码,因此崩溃似乎不是由我的代码直接引起的。

应用程序刚刚关闭,没有显示错误消息,logcat 没有反应,cpu/网络/内存监视器突然停止并显示“监视器已禁用”。

private void dispatchTakePictureIntent() 

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, getPhotoFileUri(photoFileName));

    if (intent.resolveActivity(getPackageManager()) != null) 
        startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
    

photoFileName 始终为 file:///storage/emulated/0/android/data/com.companyname.appname/files/Pictures/AppName/myphoto.jpg

拍照后由这段代码处理

private List<Bitmap> myImages;
enter code here
protected void onActivityResult(int requestCode, int resultCode, Intent data) 

    if (resultCode != RESULT_CANCELED) 

        if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) 

            if (resultCode == RESULT_OK) 
                Uri takenPhotoUri = getPhotoFileUri(photoFileName);
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 4;
                Bitmap takenImage = BitmapFactory.decodeFile(takenPhotoUri.getPath(), options);

                //Store image in memory
                myImages.add(takenImage);

                if (myImagesAdapter == null) 
                    myImagesAdapter = new MyImagesListViewAdapter(this, myImages);

                    GridView myListView = (GridView) findViewById(R.id.my_images_view);
                    myListView.setAdapter(myImagesAdapter);
                    myImagesAdapter.notifyDataSetChanged();
                 else 
                    myImagesAdapter.notifyDataSetChanged();
                

             else  // Result was a failure
                Toast.makeText(this, "Picture wasn't taken!", Toast.LENGTH_SHORT).show();
            
        
    

此外,这似乎更频繁/仅在调试模式下(在 android studio 中按下错误)而不是在我运行它时(按下播放按钮)发生。

在拍摄第一张照片时会发生这种情况,但在第二、第三和第四张照片中也会发生这种情况。

更新 1 当我将 logcat 更改为 ha No Filters 我得到这些行

09-06 22:30:26.961 990-1473/? I/WindowState: WIN DEATH: Window296d6791 u0 com.mycompany.myapp/com.mycompany.myapp.MyFirstActivity

09-06 22:30:26.965 990-1473/? D/InputDispatcher:窗口消失:Window296d6791 u0 com.mycompany.myapp/com.mycompany.myapp.MyFirstActivity

09-06 22:30:26.968 990-2174/? I/WindowState: WIN DEATH: Window3ac0ee0b u0 com.mycompany.myapp/com.mycompany.myapp.MySecondActivity

09-06 22:30:26.971 990-2174/? D/InputDispatcher:窗口消失:Window3ac0ee0b u0 com.mycompany.myapp/com.mycompany.myapp.MySecondActivity

09-06 22:30:27.059 990-1819/? I/ActivityManager: 进程 com.mycompany.myapp (pid 8623) 已经死亡

09-06 22:30:27.626 990-2174/? I/ActivityManager: 强制停止 com.mycompany.myapp appid=10170 user=0: from pid 9949

09-06 22:30:27.627 990-2174/? I/ActivityManager:强制完成活动ActivityRecord18ca1aa0 u0 com.mycompany.myapp/.MyFirstActivity t254

09-06 22:30:27.631 990-2174/? I/ActivityManager:强制完成活动 ActivityRecord15946ece u0 com.mycompany.myapp/.MySecondActivity t254

09-06 22:30:27.666 2249-2249/? W/NearbyMessages:ClientAppContext:0P 标识符(com.mycompany.myapp)没有 0P 前缀(0p:)

【问题讨论】:

请添加 logcat 结果以获取更多详细信息。 遗憾的是绝对没有 logcat 输出。 如果发生崩溃,则有 logcat 结果。尝试使用外部设备使应用程序崩溃。 如前所述“应用程序刚刚关闭,没有显示错误消息,logcat 没有反应,cpu/网络/内存监视器突然停止并显示‘监视器已禁用’”。所以没有崩溃,突然之间,应用程序就从设备屏幕上消失了。 虽然这个问题是 5 年前发布的,但我已经开始面临这种问题。当我捕获图像并按确定时,它会被最小化并再次启动。你有什么发现吗? 【参考方案1】:

如果我删除任何具有相同名称的预先存在的文件,问题似乎不太频繁发生(未解决),因此我将第一种方法更改为

private void dispatchTakePictureIntent() 
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    Uri filename = getPhotoFileUri(photoFileName);

    File imageFile = new File(filename.getPath());
    if (imageFile.exists()) 
        imageFile.delete();
    

    intent.putExtra(MediaStore.EXTRA_OUTPUT, filename);

    if (intent.resolveActivity(getPackageManager()) != null) 
        startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
    

第二种方法

protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    ...
                Bitmap takenImage = BitmapFactory.decodeFile(takenPhotoUri.getPath(), options);

                File imageFile = new File(takenPhotoUri.getPath());
                if (imageFile.exists()) 
                    imageFile.delete();
                

                myImages.add(takenImage);
    ...

【讨论】:

【参考方案2】:

不知何故,这只发生在调试模式下。使用“Run 'app'”运行应用程序时,它永远不会崩溃。不知道为什么会这样。

在 logcat 中,如果我过滤到选定的应用程序(详细),我会得到第一行,然后是下一行的几行

10-07 13:54:48.538 16352-16352/com.mycompany.myapp W/ContextImpl:无法确保目录:/storage/external_SD/Android/data/com.mycompany.myapp/files/Pictures 10-07 13:54:50.282 16352-16352/com.mycompany.myapp D/BubblePopupHelper: isShowingBubblePopup : false

当我启动相机意图时,我会得到这些,然后什么都没有。因此,当我按下快门并且应用程序崩溃时,logcat 不会显示当前应用程序的任何内容。如果我删除过滤器,则会记录如此多的日志,以至于无法找到与崩溃同时发出的行。

【讨论】:

以上是关于Android ACTION_IMAGE_CAPTURE Intent 在返回 onActivityResult 之前拍照时间歇性崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )

android 21 是啥版本

Android逆向-Android基础逆向(2-2)

【Android笔记】android Toast

图解Android - Android核心机制

Android游戏开发大全的目录