안드로이드 웹뷰로 파일 업로드를 구현할 경우가 있다.

웹뷰에서 "파일선택" 버튼을 누르면 안드로이드 카메라나 갤러리가 뜨도록 하는 것인데..

이 때 카메라 or 갤러리 선택버튼이 떴을 때 안드로이드 Back버튼을 누르면 동작이 취소되면서

그다음부터는 아무리 "파일선택" 버튼을 눌러도 아무런 동작을 안할 경우가 있다.

 

원인은 아래와 같다.

안드로이드 카메라나 갤러리 선택창일 떴을 때, 취소버튼을 누르면

onActivityResult() 메쏘드가 콜백을 받을 때 resultCode의 값이 RESULT_OK가 아니게 된다.

이렇게 RESULT_OK가 아닐 때에 대한 처리를 하지 않으면

위와 같이 카메라 or 갤러리에서의 취소버튼 후 "파일첨부" 버튼을 아무리 눌러도

mFilePathCallback이 초기화가 되어있지 않기 때문에

앱을 재실행 하지 않는 한 "파일첨부"기능이 먹통이 되는 것이다.

 

결론은

onActivityResult 에서 RESULT_OK와 그 외에 대한 처리를 잘 해 주어야 한다는 것!

나만 몰랐나? - _-;;

 

소스는 아래를 참고(빨간색)

Stackoverflow에서 해답을 찾았는데

Stackoverflow는 시간이 지나면 글이 없어져버리더라고 - _-;;

그래서 코드까지 첨부하니 참고하기 바란다.

빨간색으로 표시한 것이 문제의 코드 및 솔루션이다.

 


Cancel a file upload in a Webview

I implemented this solution for a file uploader in a webview. When I click on the "select file" button in the HTML, the first time it launches the "Select Source" option (like camera, gallery, documents, etc) and everything goes right. If I do it again (after doing it good), it works normally. But if I cancel this operation, pressing the Android's back button, I can't upload a file again until I restart the app. This was tested with many html file uploader forms and always I have the same problem.

This is my implementation:

@Override
protected void onActivityResult(int requestCode, int resultCode,
                                Intent intent) {

    if (resultCode == RESULT_OK) {

        // This is for Android 4.4.4- (JellyBean & KitKat)
        if (requestCode == FILECHOOSER_RESULTCODE) {

            if (null == mUploadMessage) {
                super.onActivityResult(requestCode, resultCode, intent);
                return;
            }

            final boolean isCamera;

            if (intent == null) {
                isCamera = true;
            } else {
                final String action = intent.getAction();
                if (action == null) {
                    isCamera = false;
                } else {
                    isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                }
            }

            Uri selectedImageUri;

            if (isCamera) {

                selectedImageUri = mOutputFileUri;
                mUploadMessage.onReceiveValue(selectedImageUri);
                mUploadMessage = null;

                return;

            } else {

                try {

                    Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), intent.getData());
                    selectedImageUri = intent == null ? null : ImageUtility.savePicture(this, bitmap, 1400);

                    mUploadMessage.onReceiveValue(selectedImageUri);
                    mUploadMessage = null;

                    return;

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            // And this is for Android 5.0+ (Lollipop)
        } else if (requestCode == INPUT_FILE_REQUEST_CODE) {

            Uri[] results = null;

            // Check that the response is a good one
            if (resultCode == Activity.RESULT_OK) {
                if (intent == null) {
                    // If there is not data, then we may have taken a photo
                    if (mCameraPhotoPath != null) {
                        results = new Uri[]{Uri.parse(mCameraPhotoPath)};
                    }
                } else {

                    Bitmap bitmap = null;

                    try {
                        bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), intent.getData());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    Uri dataUri = ImageUtility.savePicture(this, bitmap, 1400);

                    if (dataUri != null) {
                        results = new Uri[]{dataUri};
                    }
                }
            }

            mFilePathCallback.onReceiveValue(results);
            mFilePathCallback = null;

            return;
        }
    } else {

        super.onActivityResult(requestCode, resultCode, intent);
        return;
    }
}

 


2 Answers


 

I found the solution. In the onActivityResult() method is necessary give a null object to the uri callback, when the resultCode is not RESULT_OK

@Override
protected void onActivityResult(int requestCode, int resultCode,
                                Intent intent) {

    if (resultCode == RESULT_OK) {

        // This is for Android 4.4.4- (JellyBean & KitKat)
        if (requestCode == FILECHOOSER_RESULTCODE) {

            if (null == mUploadMessage) {
                super.onActivityResult(requestCode, resultCode, intent);
                return;
            }

            final boolean isCamera;

            if (intent == null) {
                isCamera = true;
            } else {
                final String action = intent.getAction();
                if (action == null) {
                    isCamera = false;
                } else {
                    isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                }
            }

            Uri selectedImageUri;

            if (isCamera) {

                selectedImageUri = mOutputFileUri;
                mUploadMessage.onReceiveValue(selectedImageUri);
                mUploadMessage = null;

                return;

            } else {

                try {

                    Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), intent.getData());
                    selectedImageUri = intent == null ? null : ImageUtility.savePicture(this, bitmap, 1400);

                    mUploadMessage.onReceiveValue(selectedImageUri);
                    mUploadMessage = null;

                    return;

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            // And this is for Android 5.0+ (Lollipop)
        } else if (requestCode == INPUT_FILE_REQUEST_CODE) {

            Uri[] results = null;

            // Check that the response is a good one
            if (resultCode == Activity.RESULT_OK) {
                if (intent == null) {
                    // If there is not data, then we may have taken a photo
                    if (mCameraPhotoPath != null) {
                        results = new Uri[]{Uri.parse(mCameraPhotoPath)};
                    }
                } else {

                    Bitmap bitmap = null;

                    try {
                        bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), intent.getData());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    Uri dataUri = ImageUtility.savePicture(this, bitmap, 1400);

                    if (dataUri != null) {
                        results = new Uri[]{dataUri};
                    }
                }
            }

            mFilePathCallback.onReceiveValue(results);
            mFilePathCallback = null;

            return;
        }
    } else {

        //for Android 5.0+
        if (mFilePathCallback != null) {
            mFilePathCallback.onReceiveValue(null);
            mFilePathCallback = null;

        }

        //for Android 4.4.4-
        if (mUploadMessage != null) {
            mUploadMessage.onReceiveValue(null);
            mUploadMessage = null;

        }

        return;
    }
} 

'IT디벨럽 > 안드로이드' 카테고리의 다른 글

안드로이드 웹뷰 카메라 취소시 처리 방법  (0) 2017.06.18

+ Recent posts