一个关于startActivityForResult的小问题

来源:互联网 发布:移动支付数据 编辑:程序博客网 时间:2024/06/11 12:55

之前开发需求时,需要调用系统相机拍照.并将拍照照片上传服务端.但拍照后死活获取不到返回的result.

@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) {if (requestCode == CAMERA_REQUEST_CODE && resultCode == Activity.RESULT_OK) {if (mCurrentCameraFile != null && mCurrentCameraFile.exists()) {....Log.v( TAG,"onActivityResult get pic success ");//通知MediaScan进行扫描添加数据库BitmapUtils.notifyAddPictureToSDCard(mContext, mCurrentCameraFile);}}}
怎么都不打印日志:onActivityResult get pic success.这里我打印日志比较片面,仅打印了成功的日志....

为了这个破问题折腾了好几个小时.太菜了呃...

         首先上传调用相机的代码

<span style="white-space:pre"></span>mCurrentCameraFile = Utils.getOutputMediaFile();Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);        Uri outputFileUri = Uri.fromFile(mCurrentCameraFile);        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);cameraIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);mParentFragment.startActivityForResult(cameraIntent, CAMERA_REQUEST_CODE);
        无意中发现,只要去掉cameraIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)这一行,就立马可以得到正确的ActivityResult了.为啥啊?不就是新起一个栈来启动相机吗?

直接看看startActivity的源码怎么对这个FLAG_ACTIVITY_NEW_TASK怎么处理的吧,源码位于(android4.4.2)frameworks\base\services\java\com\android\server\am\ActivityStackSupervisor.java


final int startActivityUncheckedLocked(ActivityRecord r,            ActivityRecord sourceRecord, int startFlags, boolean doResume,            Bundle options) {        final Intent intent = r.intent;        final int callingUid = r.launchedFromUid;        int launchFlags = intent.getFlags();        ...        if (sourceRecord == null) {            // This activity is not being started from another...  in this            // case we -always- start a new task.            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {                Slog.w(TAG, "startActivity called from non-Activity context; forcing " +                        "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);                <span style="color:#ff0000;">launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;</span>            }        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {            // The original activity who is starting us is running as a single            // instance...  this new activity it is starting must go on its            // own task.            <span style="color:#ff0000;">launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;</span>        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {            // The activity being started is a single instance...  it always            // gets launched into its own task.            <span style="color:#ff0000;">launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;</span>        }        ActivityInfo newTaskInfo = null;        Intent newTaskIntent = null;        final ActivityStack sourceStack;        if (sourceRecord != null) {            if (sourceRecord.finishing) {                // If the source is finishing, we can't further count it as our source.  This                // is because the task it is associated with may now be empty and on its way out,                // so we don't want to blindly throw it in to that task.  Instead we will take                // the NEW_TASK flow and try to find a task for it. But save the task information                // so it can be used when creating the new task.                if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {                    Slog.w(TAG, "startActivity called from finishing " + sourceRecord                            + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);                    <span style="color:#ff0000;">launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;</span>                    newTaskInfo = sourceRecord.info;                    newTaskIntent = sourceRecord.task.intent;                }                sourceRecord = null;                sourceStack = null;            } else {                sourceStack = sourceRecord.task.stack;            }        } else {            sourceStack = null;        }        if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {            // For whatever reason this activity is being launched into a new            // task...  yet the caller has requested a result back.  Well, that            // is pretty messed up, so instead immediately send back a cancel            // and let the new task continue launched as normal without a            // dependency on its originator.            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");            <span style="color:#ff0000;">r.resultTo.task.stack.sendActivityResultLocked(-1,                    r.resultTo, r.resultWho, r.requestCode,                Activity.RESULT_CANCELED, null);</span>            r.resultTo = null;        }        .....        if (newTask) {            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);        }        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);        targetStack.mLastPausedActivity = null;        <span style="color:#ff0000;">targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);</span>        mService.setFocusedActivityLocked(r);        return ActivityManager.START_SUCCESS;    }

上面的startActivityUncheckedLocked()方法我主要截取了前面对FLAG_ACTIVITY_NEW_TASK的处理.

1.对于一下场景,都会对intent的FLAG_ACTIVITY_NEW_TASK标志位置1.

(1)sourceRecord为空,即执行startActivity的哪个ActvityRecord为空;

                (2)sourceRecord.launchMode为ActivityInfo.LAUNCH_SINGLE_INSTANCE;

                (3)待启动的新ActivityRecord的launchMode为LAUNCH_SINGLE_INSTANCE或者LAUNCH_SINGLE_TASK;

2.若需要返回result,且intent的FLAG_ACTIVITY_NEW_TASK标志位为1,则首先给ResultToActivity一个RESULT_CANCELED(即-1)结果.这个逻辑比较简单,直接让ActivityThread来分发onActivityResult()

        3.初始化好目标targetStack后,继续执行startActivity,具体可以参见老罗的android之旅Android应用程序内部启动Activity过程(startActivity)的源代码分析.


通过上面startActivityUncheckedLocked()方法的分析,直到只要设置了FLAG_ACTIVITY_NEW_TASK,源Activity就会收到RESULT_CANCELED结果回调.下面用demo测试下.

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {Log.e("onActivityResult ", "requestCode:" + requestCode + "resultCode:" + resultCode + ",data" + data);Toast.makeText(this, "onActivityResult resultCode " + resultCode, Toast.LENGTH_SHORT).show();super.onActivityResult(requestCode, resultCode, data);}public static final int CAMERA_REQUEST_CODE = 111;@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btn1:Intent intent = getContentProviderActivityIntent();intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);if (intent != null) {startActivityForResult(intent, CAMERA_REQUEST_CODE);}break;case R.id.btn2:Intent intent1 = getContentProviderActivityIntent();if (intent1 != null) {startActivityForResult(intent1, CAMERA_REQUEST_CODE);}break;}}private File mCurrentCameraFile;public Intent getContentProviderActivityIntent() {mCurrentCameraFile = getOutputMediaFile();if (mCurrentCameraFile != null) {return getCameraAppIntent(mCurrentCameraFile);} else {return null;}}public static Intent getCameraAppIntent(File outFile) {Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);        Uri outputFileUri = Uri.fromFile(outFile);        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);return cameraIntent;}public static File getOutputMediaFile() {File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "Camera");if (!mediaStorageDir.exists()) {if (!mediaStorageDir.mkdirs()) {return null;}}// Create a media file nameString timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(new Date());File mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");return mediaFile;}


两个按钮,分别为添加和不添加FLAG_ACTIVITY_NEW_TASK标志.打印日志如下:

btn1:在相机页面还没起来前就打印了:12-31 09:51:39.566: E/onActivityResult(20938): requestCode:111resultCode:0,datanull

btn2:在相机页面结束后才打印了:12-31 09:53:01.880: E/onActivityResult(20938): requestCode:111resultCode:-1,datanull


就这样了,startActivityForResult时不能设置FLAG_ACTIVITY_NEW_TASK标志

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 父母离婚小孩没有出生证该怎么办 离婚。父母一直在劝说该怎么办 老婆跟人跑了怎么办啊 父母50了要离婚怎么办 父母吵架了我该怎么办 父母看孩子总是吵架怎么办 20岁父母离婚我怎么办 碰到没素质的人怎么办 父母抛弃了我该怎么办 父母说家里没钱困难怎么办 遇到素质低的老婆怎么办 孩子考试心里素质差怎么办 5岁儿童脾气不好怎么办 有一个素质差的父母怎么办 孩子对什么都无所谓怎么办 孩子在学习上无所谓怎么办 孩子对学习无所谓的态度怎么办 孩子不上进什么都无所谓怎么办 倔强的学生不理老师怎么办 一岁宝宝特别犟怎么办 孩子遇到问题喜欢发脾气怎么办 企业培养新人跑了怎么办 二年级学生读不懂题目怎么办 6岁宝宝有鼻炎怎么办 外地儿童怎么办北京医保卡 江苏联宝投资的钱怎么办 银行叫开了证券怎么办 中班心理健康我不开心了怎么办 大学生心理健康课总是抢不到怎么办 孩子成绩提不上去怎么办 孩子数学不开窍怎么办 二年级 初中孩子语文不开窍怎么办 分到的班级都是差生怎么办 初三了英语差怎么办呀 初三了英语差的很怎么办 五年级英语太差怎么办 听课效率没有自学效率高怎么办 小学生不好好写作业怎么办 带的家教成绩没有提高怎么办 学生出国学校成绩证明怎么办 学生成绩考差了班主任怎么办