투케이2K

676. (Android/Java) [안드로이드 13] 웹뷰 (Webview) onShowFileChooser 사용해 input file 태그 이벤트 감지 및 갤러리 이미지 선택 본문

Android

676. (Android/Java) [안드로이드 13] 웹뷰 (Webview) onShowFileChooser 사용해 input file 태그 이벤트 감지 및 갤러리 이미지 선택

투케이2K 2023. 10. 27. 09:39

[개발 환경 설정]

개발 툴 : AndroidStudio

 

[소스 코드]

// --------------------------------------------------------------------------------------------------
[이벤트 감지 및 인텐트 전환 : 소스 코드]
// --------------------------------------------------------------------------------------------------

                // TODO [웹뷰 input file 태그 확인]
                @Override
                public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) {
                    S_Log._F_(A_Webview.this, "웹뷰 input file 태그 이벤트 동작 감지", new String[]{
                            "URL :: " + String.valueOf(main_webview.getUrl()),
                            "ValueCallback :: " + String.valueOf(filePathCallback.toString()),
                            "FileChooserParams :: " + String.valueOf(Arrays.toString(fileChooserParams.getAcceptTypes()))
                    });


                    /**
                     * ------------------------------------
                     * TODO [네이티브 추가 설정 사항]
                     * ------------------------------------
                     * 2. 전역 변수 선언 실시 : ValueCallback mFilePathCallback;
                     * ------------------------------------
                     * */


                    // ------------------------------------
                    // TODO [웹뷰 파일 콜백 지정 실시 : onActivity()]
                    mFilePathCallback = filePathCallback;
                    // ------------------------------------
                    // TODO [이미지 파일만 지정 시 사용 : <input type="file" accept="image/*" multiple>]
                    // ------------------------------------
                    if (Arrays.toString(fileChooserParams.getAcceptTypes()).contains("image")){
                        Intent intent = new Intent(Intent.ACTION_PICK); // 갤러리 지정
                        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true); // 사진 다중 선택 지정
                        intent.setType("image/*"); // 이미지 파일 타입 지정
                        intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI); // 미디어 스토어 사용 [이미지]
                        resultLauncher.launch(intent); // [startActivityForResult]
                    }
                    // ------------------------------------
                    // TODO [모든 형식 파일 지정 시 사용 : <input type="file" multiple>]
                    // ------------------------------------
                    else {
                        Intent intent = new Intent(Intent.ACTION_GET_CONTENT); // 파일 지정 (image, txt, pdf ...)
                        intent.addCategory(Intent.CATEGORY_OPENABLE); // 카테고리 지정
                        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true); // 파일 다중 선택 지정
                        intent.setType("*/*"); // 모든 파일 지정
                        resultLauncher.launch(intent); // [startActivityForResult]
                    }
                    // ----------------------------------
                    return true;
                    // ----------------------------------
                    //return super.onShowFileChooser(webView, filePathCallback, fileChooserParams);
                    // ----------------------------------
                }







// --------------------------------------------------------------------------------------------------
[사용자가 중도 취소 버튼 클릭 처리 : 소스 코드]
// --------------------------------------------------------------------------------------------------

    @Override
    public void onResume(){
        super.onResume();
        // ===============================================================
        S_Log._F_(A_Webview.this, S_FinalMsg.LOG_Activity_onResume, null);
        // ===============================================================


        // ---------------------------------------------------------------
        // [외부 브라우저 복귀 시 화면 전환 애니메이션 없애기 위함]
        // ---------------------------------------------------------------
        try { overridePendingTransition(0, 0); }  catch (Exception e){ S_Log._printStackTrace_(null, S_FinalMsg.LOG_BUG_STATE, null, e); }


        // ---------------------------------------------------------------
        // [웹뷰 파일 선택 취소 체크]
        // ---------------------------------------------------------------
        try {
            if (mFilePathCallback != null){
                mFilePathCallback.onReceiveValue(null);
                mFilePathCallback = null;
            }
        }
        catch (Exception e){}

    }








// --------------------------------------------------------------------------------------------------
[이미지 선택 완료 콜백 응답 처리 : 소스 코드]
// --------------------------------------------------------------------------------------------------

    ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult(

            new ActivityResultContracts.StartActivityForResult(),
            new ActivityResultCallback<ActivityResult>() {
                @Override
                public void onActivityResult(ActivityResult result){
                    S_Log._F_(A_Webview.this, "ActivityResultLauncher :: 인텐트 응답 결과 확인", new String[]{
                            "RESULT :: " + String.valueOf(result)
                    });


                    // -----------------------------------------
                    // TODO [정상적으로 응답을 받은 경우]
                    // -----------------------------------------
                    if(result.getResultCode() == RESULT_OK){

                        // -----------------------------------------
                        // [인텐트 데이터 얻어 온다]
                        // -----------------------------------------
                        Intent intent = result.getData();
                        // -----------------------------------------


                        // -----------------------------------------
                        // TODO [선택한 파일 전송] : onResume 에서 [취소] 한 경우 null 처리 필요
                        // -----------------------------------------
                        // TODO [onResume 에서 null 전송 처리를 안해 주면 input file 이벤트 동작 안됨]
                        // -----------------------------------------
                        if (mFilePathCallback != null){

                            if (intent == null){
                                S_Log._E_("[SEND] :: [파일 전송] :: intent :: null", null);

                                mFilePathCallback.onReceiveValue(null); // 웹으로 데이터 null 전송
                                mFilePathCallback = null; // 초기화
                            }
                            else {
                                ClipData clipData = intent.getClipData(); // 선택한 파일 데이터 얻어온다
                                int fileCount = clipData.getItemCount(); // 선택한 파일 개수 확인

                                if (fileCount > 0){ // 선택한 파일 있음

                                    Uri[] filePathArray = new Uri[fileCount]; // 다중 파일을 담기 위한 배열 선언 실시
                                    String stringData = "";

                                    for (int i = 0; i < fileCount; i++) { // for 문을 돌면서 배열에 uri 데이터 삽입
                                        filePathArray[i] = intent.getClipData().getItemAt(i).getUri();
                                        stringData += "\n" + "\n" + String.valueOf(intent.getClipData().getItemAt(i).getUri());
                                    }

                                    S_Log._W_("[SEND] :: [파일 전송] :: mFilePathCallback :: getClipData", new String[]{
                                            "File Count :: " + String.valueOf(fileCount),
                                            "File Path :: " + String.valueOf(stringData)
                                    });

                                    mFilePathCallback.onReceiveValue(filePathArray); // 웹으로 데이터 전송 실시
                                    mFilePathCallback = null; // 초기화
                                }
                                else {
                                    S_Log._E_("[SEND] :: [파일 전송] :: fileCount :: null", null);

                                    mFilePathCallback.onReceiveValue(null); // 웹으로 데이터 null 전송
                                    mFilePathCallback = null; // 초기화
                                }

                            }

                        }
                        else {
                            S_Log._E_("[SEND] :: [파일 전송] :: mFilePathCallback :: null", null);
                        }
                        // -----------------------------------------
                    }

                }
            });
 

[결과 출력]


 

반응형
Comments