android调用摄像头导致activity销毁的解决办法

APP里有一个上传头像,可以直接从相册选择图片上传,也可以使用照相机拍照上传。这个功能在大部分机器下都正常,然而在部分机器(例如三星)却失败,另外独立写了个测试例子检查这个问题。

package com.penngo.camera;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import java.io.File;

public class MainActivity extends Activity {
    private final static String tag = "MainActivity-->";
    ImageView imageView;
    Button photo_btn;
    Button camera_btn;
    private static int createTime = 1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e(tag, "onCreate=========" + (createTime++));
        setContentView(R.layout.activity_main);

        imageView = (ImageView)(this.findViewById(R.id.imageView));
        photo_btn = (Button)this.findViewById(R.id.photo_btn);
        photo_btn.setOnClickListener(new View.OnClickListener(){
            public void onClick(View var){
                Intent intent1 = new Intent(Intent.ACTION_PICK);
                intent1.setDataAndType(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                startActivityForResult(intent1, 1);
            }
        });
        camera_btn = (Button)this.findViewById(R.id.camera_btn);
        camera_btn.setOnClickListener(new View.OnClickListener(){
            public void onClick(View var1){
                Log.e(tag, "OnClickListener==============MediaStore.ACTION_IMAGE_CAPTURE");
                String path = getImagePath(MainActivity.this);
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT,
                        Uri.fromFile(new File(path, "/touxiang.jpg")));
                startActivityForResult(intent, 2);
            }
        });

    }

    public static String getImagePath(Context context) {
        String path = "";
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            path = context.getExternalCacheDir().getAbsolutePath() + "/images";
        }
        else{
            path = context.getCacheDir().getAbsolutePath() + "/images";
        }
        File dir = new File(path);
        if(dir.exists() == false){
            dir.mkdirs();
        }
        return path;

    }
    /**
     * 裁剪图片
     */
    public void startPhotoZoom(Uri uri) {
        Log.e(tag, "startPhotoZoom==============com.android.camera.action.CROP");
        String path = getImagePath(MainActivity.this);
        //Uri cutUri = Uri.fromFile(new File(IMAGE_PATH, "touxiang_cut.jpg"));
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");

        // 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
        intent.putExtra("crop", "true");
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪图片宽高
        intent.putExtra("outputX", 144);
        intent.putExtra("outputY", 144);
        intent.putExtra("return-data", true);
        intent.putExtra("noFaceDetection", true);
        intent.putExtra("scale", true); // 黑边
        intent.putExtra("scaleUpIfNeeded", true); // 黑边
        //intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(path, "/touxiang_cut.jpg")));
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        startActivityForResult(intent, 3);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.e(tag, "onActivityResult============= requestCode=" + requestCode + " resultCode:" + resultCode + " data:" + data);
        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
                case 1:
                    if (data != null)
                        startPhotoZoom(data.getData());
                    break;
                case 2:
                    startPhotoZoom(Uri
                            .fromFile(new File(getImagePath(MainActivity.this), "touxiang.jpg")));
                    break;
                case 3:
                    if (data != null) {
                        setPicToView(data);
                    }
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 保存裁剪之后的图片数据
     */
    private void setPicToView(Intent picdata) {
        Bundle extras = picdata.getExtras();
        if (extras != null) {
            final Bitmap image = extras.getParcelable("data");
            imageView.setImageBitmap(image);
        }
    }
    @Override
    protected void onResume() {
        super.onResume();
        Log.e(tag, "onResume==============");
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e(tag, "onDestroy==============");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.e(tag, "onSaveInstanceState==============");

    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.e(tag, "onRestoreInstanceState==============");
    }
    /**
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }
    **/
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
    <ImageView
        android:layout_width="200dip"
        android:layout_height="200dip"
        android:id="@+id/imageView"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="相册"
        android:id="@+id/photo_btn"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginLeft="34dp"
        android:layout_marginStart="34dp" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="拍照"
        android:id="@+id/camera_btn"
        android:layout_alignBottom="@+id/photo_btn"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_marginRight="34dp"
        android:layout_marginEnd="34dp" />
</RelativeLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.penngo.camera" >
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
正常机子的locat输出如下
09-08 17:14:45.657  23452-23452/com.penngo.camera E/MainActivity-->﹕ onCreate=========1
09-08 17:14:45.691  23452-23452/com.penngo.camera E/MainActivity-->﹕ onResume==============
09-08 17:14:58.350  23452-23452/com.penngo.camera E/MainActivity-->﹕ OnClickListener==============MediaStore.ACTION_IMAGE_CAPTURE
09-08 17:14:59.744  23452-23452/com.penngo.camera E/MainActivity-->﹕ onSaveInstanceState==============
09-08 17:15:03.187  23452-23452/com.penngo.camera E/MainActivity-->﹕ onActivityResult============= requestCode=2 resultCode:-1 data:null
09-08 17:15:03.209  23452-23452/com.penngo.camera E/MainActivity-->﹕ startPhotoZoom==============com.android.camera.action.CROP
09-08 17:15:03.222  23452-23452/com.penngo.camera E/MainActivity-->﹕ onResume==============
09-08 17:15:04.212  23452-23452/com.penngo.camera E/MainActivity-->﹕ onSaveInstanceState==============
09-08 17:15:05.775  23452-23452/com.penngo.camera E/MainActivity-->﹕ onActivityResult============= requestCode=3 resultCode:-1 data:Intent { (has extras) }
09-08 17:15:05.777  23452-23452/com.penngo.camera E/MainActivity-->﹕ onResume==============
失败机子的logcat输出
09-08 17:16:24.391  11453-11453/com.penngo.camera E/MainActivity-->﹕ onCreate=========1
09-08 17:16:24.421  11453-11453/com.penngo.camera E/MainActivity-->﹕ onResume==============
09-08 17:18:59.491  11453-11453/com.penngo.camera E/MainActivity-->﹕ OnClickListener==============MediaStore.ACTION_IMAGE_CAPTURE
09-08 17:19:01.081  11453-11453/com.penngo.camera E/MainActivity-->﹕ onSaveInstanceState==============
09-08 17:19:07.441  11453-11453/com.penngo.camera E/MainActivity-->﹕ onDestroy==============
09-08 17:19:07.461  11453-11453/com.penngo.camera E/MainActivity-->﹕ onCreate=========2
09-08 17:19:07.471  11453-11453/com.penngo.camera E/MainActivity-->﹕ onRestoreInstanceState==============
09-08 17:19:07.471  11453-11453/com.penngo.camera E/MainActivity-->﹕ onActivityResult============= requestCode=2 resultCode:-1 data:null
09-08 17:19:07.471  11453-11453/com.penngo.camera E/MainActivity-->﹕ startPhotoZoom==============com.android.camera.action.CROP
09-08 17:19:07.491  11453-11453/com.penngo.camera E/MainActivity-->﹕ onResume==============
09-08 17:19:07.561  11453-11453/com.penngo.camera E/MainActivity-->﹕ onSaveInstanceState==============
09-08 17:19:10.381  11453-11453/com.penngo.camera E/MainActivity-->﹕ onDestroy==============
09-08 17:19:10.391  11453-11453/com.penngo.camera E/MainActivity-->﹕ onCreate=========3
09-08 17:19:10.401  11453-11453/com.penngo.camera E/MainActivity-->﹕ onRestoreInstanceState==============
09-08 17:19:10.401  11453-11453/com.penngo.camera E/MainActivity-->﹕ onActivityResult============= requestCode=3 resultCode:-1 data:Intent { (has extras) }
09-08 17:19:10.411  11453-11453/com.penngo.camera E/MainActivity-->﹕ onResume==============

失败机子在调用MediaStore.ACTION_IMAGE_CAPTURE拍照时,会导致一次MainActivity onDestroy;拍照完成后,又重新MainActivity onCreate,并执行MainActivity onActivityResult;

在调用com.android.camera.action.CROP时,也导致MainActivity触发同样的事件执行。

通过比较看出失败每次调用摄像头时,都会先触发所在activity onDestroy,调用摄像头结束后,又会触发所在activity重新onCreate,

再比较拍照正常机子和失败机子,发现失败机子在调用摄像头时,会触发一次屏幕旋转,导致activity onDestroy的执行。

两个解决方法:

方法1、在activity销毁前,保存当前activity的状态,重载onSaveInstanceState、onRestoreInstanceState方法,在销毁前保存activity的数据状态

方法2、由于访问的出现是由于部分机器在调用摄像头时自动横竖屏切换造成的,修改AndroidManifest.xml配置,加入android:configChanges="orientation|keyboard|keyboardHidden|screenSize"限制activity屏幕切换

<!--  android:configChanges="orientation|keyboard|keyboardHidden|screenSize" -->
<activity
	android:name=".MainActivity"
	android:configChanges="orientation|keyboard|keyboardHidden|screenSize"
	android:label="@string/app_name" >
	<intent-filter>
		<action android:name="android.intent.action.MAIN" />
		<category android:name="android.intent.category.LAUNCHER" />
	</intent-filter>
</activity>
时间: 2024-11-07 19:03:36

android调用摄像头导致activity销毁的解决办法的相关文章

Android 底部弹出提示框的解决办法(使用Activity以及PopupWindow)

本片文章主要谈探讨了如何实现在底部弹出提示框背景为半透明效果的实现.想要实现此种效果一般有两种方式一个是使用Activity设置Theme另一种方式就是使用PopupWindow设置样式实现效果. 一,使用Activity 首先是此activity的布局文件: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.andro

Android无法生成R文件的终极解决办法

今天从svn中检出项目的时候,项目里的文件一直报错,R文件也没办法生成,于是开始盘查: R文件如果在clean项目(Project->Clean)和 Fix Project Properties(如下图): 都无法解决的的时候,那唯一的原因就是资源文件调用的错误,比如资源文件命名不规范,多余的资源引用等,有时候很难排查,这就要求心细了. 我今天碰到的还算比较简单,新建项目的时候自带v_7的jar包,然后所有的activity都集成了ActionBarActivity了,但是我将需要的另外一个项目

WPF循环加载图片导致内存溢出的解决办法

程序场景:一系列的图片,从第一张到最后一张依次加载图片,形成"动画". 生成BitmapImage的方法有多种: 1. var source=new BitmapImage(new Uri("图片路径",UriKind.xxx)); 一般的场景使用这种方法还是比较方便快捷,但是对于本场景,内存恐怕得爆. 2. var data =File.ReadAllBytes("图片路径"); var ms = new System.IO.MemoryStr

Android主线程不能访问网络异常解决办法

从两个方面说下这个问题: 1. 不让访问网络的原因 2. 解决该问题的办法 不让访问网络的原因: 由于对于网络状况的不可预见性,很有可能在网络访问的时候造成阻塞,那么这样一来我们的主线程UI线程 就会出现假死的现象,产生很不好的用户体验.所以,默认的情况下如果直接在主线程中访问就报出了这个异常,名字是NetworkOnMainThreadException 解决该问题的办法 1. 独立线程 2. 异步线程AsyncTask 3. StrictMode修改默认的策略 1) 独立线程的办法 启动一个

所有Android开发者都会出现的错误及解决办法

我们知道作为开发者需要有丰富的专业知识,还要有严谨的思维,我们在开发时会出现这样或那样的错误,通过在扣丁学堂在线学习Android的知识,我列出了9个常见的Android开发错误及解决办法: 1. 如果你的项目的R文件不见的话,可以试下改版本号在保存,R文件不见一般都是布局文本出错导致. 2. 布局文件不可以有大写字母 3. 抛出如下错误WARNING: Application does not specify an API level requirement!, 是由于没有指定users sd

中兴U960E修改系统文件导致无法开机的解决办法

中兴的手机开启飞行模式时不能开启wifi,用惯了三星手机之后真的不习惯这一点.昨晚躺着床上终于忍受不了,照着网上的教程修改了一下.教程复制如下:------------------------------------------------------------------------------------------------------[转]中兴的手机开启飞行模式时无法开启WIFI.蓝牙很蛋疼!我喜欢开飞行,但却还会用手机开WIFI上会网.玩游戏1.手机安装RE管理器:2.手机安装SQ

Android软键盘隐藏,遮挡EidtText解决办法

一.自动弹出软键盘 Timer timer=new Timer(); timer.schedule(new TimerTask() { public void run() { InputMethodManager inputMethodManager=(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); inputMethodManager.toggleSoftInput(0, InputMethodManage

android 关于InputDispatcher出现Consumer错误的解决办法

原地址:http://www.educity.cn/wenda/158744.html android 关于InputDispatcher出现Consumer异常的解决方法10-23 03:24:46.346: ERROR/InputDispatcher(61): channel '40774ac8 coinv.panfa/coinv.panfa.activities.MeinvFlashActivity (server)' ~ Consumer closed input channel or

Android开发:ScrollView嵌套GridView的解决办法

Android开发:ScrollView嵌套GridView的解决办法 前些日子在开发中用到了需要ScrollView嵌套GridView的情况,由于这两款控件都自带滚动条,当他们碰到一起的时候便会出问题,即GridView会显示不全. 解决办法,自定义一个GridView控件 public class MyGridView extends GridView {      public MyGridView(Context context, AttributeSet attrs) {