web-dev-qa-db-ja.com

Android webview(Android 4.4、KitKat)で入力されたHTMLファイル

Android webview。で<input type="file">を使用していました。このスレッドのおかげで動作しました: File Viewでのファイルのアップロード

しかし、受け入れられた答え(またはその他)は、Android 4.4 KitKat webview。

誰もそれを修正する方法を知っていますか?

ターゲット18でも機能しません。

私はいくつかのAndroid 4.4ソースコードを探しており、WebChromeClientは変更されていないようですが、setWebChromeClientはKitKatウェブビューでは動作しません、または少なくともopenFileChooser関数ではありません。

43
jcesarmobile

更新2:phonegap/cordovaで使用するよりシンプルなプラグインがあります

https://github.com/MaginSoft/MFileChooser

更新:Cesidio DiBenedettoプラグインを使用したサンプルプロジェクト

https://github.com/jcesarmobile/FileBrowserAndroidTest

Androidオープンソースプロジェクトで issue を開いたところ、答えは次のとおりでした。

ステータス:WorkingAsIntended

残念ながら、openFileChooserはパブリックAPIではありません。 Androidの将来のリリースでは、パブリックAPIに取り組んでいます。

Phonegap/cordovaを使用している場合、この回避策はバグトラッカーに投稿されています。

Cesidio DiBenedettoがコメントを追加しました-28/Mar/14 01:27

ちょっと、私もこの問題を経験しているので、とりあえず「バンドエイド」にCordova FileChooserプラグインを書きました。基本的に、Android 4.4(KitKat)では、前述のコメントで述べたように、ファイルダイアログは開かれません。ただし、onClickイベントは引き続き発生するため、FileChooserプラグインを呼び出してファイルを開くことができますダイアログで選択すると、ファイルへのフルパスを含む変数を設定できますこの時点で、FileTransferプラグインを使用してサーバーにアップロードし、onprogressイベントにフックして進行状況を表示できます。 Android 4.4なので、以前のバージョンのAndroidのネイティブファイルダイアログを引き続き使用することをお勧めします。多くのデバイスですべてのシナリオを完全にテストしていないため、プラグインに問題がある可能性がありますが、 Nexus 5にインストールしましたが、正常に機能しました。

https://github.com/cdibened/filechooser

独自の回避策を構築したため、テストしていません

クロム開発者からのコメント

ファイルリクエストを処理するために、次のメジャーリリースでWebViewClientにパブリックAPIを追加します。

彼らは今それをバグと考えており、彼らはそれを修正しようとしているようです

30
jcesarmobile

前述の Cesidio DiBenedettoの回避策 をアプリに実装できました。それはうまく機能していますが、 PhoneGap/Cordove 以前(私のように)使用したことがない人にとっては少し難しいかもしれません。そのため、実装中にまとめた小さなハウツーを次に示します。

Apache Cordovaは、Webテクノロジーを使用してマルチプラットフォームモバイルアプリを構築できるプラットフォームです。主な機能は、ネイティブAPIをJavaScriptにエクスポートするため、Webサイトとネイティブアプリケーションの間で通信する方法を提供することです。典型的なPhoneGap/Cordovaアプリは、静的なWebサイトであり、1つのAPKにCordovaレイヤーとバンドルされています。ただし、Cordovaを使用してリモートWebサイトを表示することができます。

回避策は次のように機能します。標準のWebViewの代わりにCordovaWebViewを使用してWebサイトを表示します。ユーザーが参照をクリックしてファイルを選択すると、標準のJavaScript(jQuery ...)を使用してそのクリックをキャッチし、Cordova APIを使用して、Niceファイルブラウザーを開くネイティブ側でCesidio DiBenedettoのfilechooserプラグインをアクティブにします。ユーザーがファイルを選択すると、ファイルはJavaScript側に送り返され、そこからWebサーバーにアップロードされます。

重要なことは、WebサイトにCordovaサポートを追加する必要があることです。さて、実際のハウツー...

まず、既存のアプリにCordovaを追加する必要があります。私は このドキュメント に従いました。いくつかのステップは私には不明瞭だったので、私はさらに説明しようとします:

  1. アプリの外部のどこかにCordovaをダウンロードして展開し、説明に従ってcordova-3.4.0.jarをビルドします。 local.propertiesファイルがないため、おそらく初めて失敗します。エラー出力でそれを作成する方法が指示されます。 Androidアプリをビルドするために使用するSDKを指す必要があります。

  2. コンパイル済みのjarファイルをアプリlibディレクトリにコピーし、jarをライブラリとして追加します。 Android私のようなStudioを使用する場合は、dependencies内にcompile fileTree(dir: 'libs', include: ['*.jar', '*.aar'])があることを確認してくださいbuild.gradle。次に、プロジェクトをGradleファイルと同期するボタンを押すだけで大丈夫です。

  3. / res/xml/main.xmlファイルを作成する必要はありません。 CordovaWebViewは、標準のWebViewと同じ方法で処理できるため、レイアウトファイルに直接配置できます。

  4. 元のドキュメントの手順5〜7に従って、Activityが実行される独自のCordobaWebViewを作成します。ダウンロードしたCordovaパッケージの_/framework/src/org/Apache/cordova/CordovaActivity.Java_を確認することをお勧めします。実装に必要なほとんどのメソッドを簡単にコピーできます。 6.ステップは、filechooserプラグインを使用できるようにするため、私たちの目的にとって本当に重要です。

  5. HTMLファイルやJavaScriptファイルはどこにもコピーしないでください。後でWebサイトに追加します。

  6. config.xmlファイルをコピーすることを忘れないでください(変更する必要はありません)。

ウェブサイトをCordovaWebViewに読み込むには、そのURLをcwv.loadUrl()ではなくConfig.getStartUrl()に渡すだけです。

次に、アプリに FileChooserプラグイン を追加する必要があります。標準のCordovaセットアップを使用していないため、 READMEの指示に従って_cordova plugin add_を押すだけで、手動で追加する必要があります。

  1. リポジトリをダウンロードし、ソースファイルをアプリにコピーします。 resフォルダーのコンテンツがアプリresフォルダーに移動することを確認します。今のところ、JavaScriptファイルは無視できます。

  2. アプリに_READ_EXTERNAL_STORAGE_権限を追加します。

  3. 次のコードを/ res/xml/config.xmlに追加します。

_<feature name="FileChooser">
    <param name="Android-package" value="com.cesidiodibenedetto.filechooser.FileChooser" />
</feature>
_

今はあなたのウェブサイトにCordovaサポートを追加するときです。それは思ったより簡単です、あなたはcordovaをリンクするだけです。 jsをWebサイトに追加しますが、知っておくべきことが2つあります。

まず、各プラットフォーム(Android、iOS、WP)には独自のcordova.jsがあるため、必ずAndroidバージョン( / framework/assets/www)でダウンロードしたCordovaパッケージで見つけてください。

第二に、CordovaWebViewと標準ブラウザ(デスクトップまたはモバイル)の両方からWebサイトにアクセスする場合、一般にcordova.jsを読み込むのは良い考えですページはCordovaWebViewに表示されます。 CordovaWebViewを検出する方法をいくつか見つけましたが、次の方法でうまくいきました。ウェブサイトの完全なコードは次のとおりです。

_function getAndroidVersion(ua) {
    var ua = ua || navigator.userAgent; 
    var match = ua.match(/Android\s([0-9\.]*)/);
    return match ? parseFloat(match[1]) : false;
};

if (window._cordovaNative && getAndroidVersion() >= 4.4) {
    // We have to use this ugly way to get cordova working
    document.write('<script src="/js/cordova.js" type="text/javascript"></script>');
}
_

Androidバージョンもチェックしていることに注意してください。この回避策はKitKatにのみ必要です。

この時点で、WebサイトからFileChooserプラグインを手動で呼び出すことができるはずです。

_var cordova = window.PhoneGap || window.Cordova || window.cordova;
cordova.exec(function(data) {}, function(data) {}, 'FileChooser', 'open', [{}]);
_

これにより、ファイルブラウザが開き、ファイルを選択できるようになります。これは、イベントdevicereadyが起動された後にのみ実行できることに注意してください。テストするには、jQueryを使用してこのコードをボタンにバインドします。

最後の手順は、これをすべてまとめてアップロードフォームを機能させることです。これを達成するには、[〜#〜] readme [〜#〜]。ユーザーがFileChooserでファイルを選択すると、ファイルパスが別のCordovaプラグインからJavaScript側に返されますFileTransferは、実際のアップロードを実行するために使用されます。つまり、ファイルはCordovaWebViewではなく、ネイティブ側でアップロードされます(正しく理解できれば)。

アプリケーションに別のCordovaプラグインを追加する気がなかったし、Cookieでどのように機能するのかも確信できませんでした(認証されたユーザーのみがファイルのアップロードを許可されているため、リクエストと共にCookieを送信する必要があります)それは私のやり方です。 FileChooserプラグインを変更して、パスではなくファイル全体を返すようにしました。ユーザーがファイルを選択すると、その内容を読み取り、_base64_を使用してエンコードし、JSONとしてクライアント側に渡し、そこでデコードしてJavaScriptを使用してサーバーに送信します。それは機能しますが、base64はかなりCPUを要求するため、大きなファイルがアップロードされるとアプリが少しフリーズする可能性があるため、明らかな欠点があります。

それを行うには、まずこのメソッドをFileUtilsに追加します。

_public static byte[] readFile(final Context context, final Uri uri) throws IOException {
    File file = FileUtils.getFile(context, uri);
    return org.Apache.commons.io.FileUtils.readFileToByteArray(file);
}
_

Apache Commons libraryを使用するので、それを含めるか、外部ライブラリを必要としない他の方法でファイルを読み込むことを忘れないでください。

次に、FileChooser.onActivityResultメソッドを変更して、パスではなくファイルコンテンツを返します。

_// Get the URI of the selected file
final Uri uri = data.getData();
Log.i(TAG, "Uri = " + uri.toString());
JSONObject obj = new JSONObject();
try {
    obj.put("filepath", FileUtils.getPath(this.cordova.getActivity(), uri));
    obj.put("name", FileUtils.getFile(this.cordova.getActivity(), uri).getName());
    obj.put("type", FileUtils.getMimeType(this.cordova.getActivity(), uri));

    // attach the actual file content as base64 encoded string
    byte[] content = FileUtils.readFile(this.cordova.getActivity(), uri);
    String base64Content = Base64.encodeToString(content, Base64.DEFAULT);
    obj.put("content", base64Content);

    this.callbackContext.success(obj);
} catch (Exception e) {
    Log.e("FileChooser", "File select error", e);
    this.callbackContext.error(e.getMessage());
}
_

最後に、これはWebサイトで使用するコードです(jQueryが必要です)。

_var cordova = window.PhoneGap || window.Cordova || window.cordova;
if (cordova) {
    $('form.fileupload input[type="file"]', context).on("click", function(e) {    
        cordova.exec(
            function(data) { 
                var url = $('form.fileupload', context).attr("action");

                // decode file from base64 (remove traling = first and whitespaces)
                var content = atob(data.content.replace(/\s/g, "").replace(/=+$/, ""));

                // convert string of bytes into actual byte array
                var byteNumbers = new Array(content.length);
                for (var i = 0; i < content.length; i++) {
                    byteNumbers[i] = content.charCodeAt(i);
                }
                var byteContent = new Uint8Array(byteNumbers);

                var formData = new FormData();
                var blob = new Blob([byteContent], {type: data.type}); 
                formData.append('file', blob, data.name);

                $.ajax({
                    url: url,
                    data: formData,
                    processData: false,
                    contentType: false,
                    type: 'POST',
                    success: function(data, statusText, xhr){
                        // do whatever you need
                    }
                });
            },
            function(data) { 
                console.log(data);
                alert("error");
            },
            'FileChooser', 'open', [{}]);
    });
}
_

まあ、それがすべてです。これを機能させるのに数時間かかったので、誰かに役立つかもしれないと謙虚に願って知識を共有しています。

21
tobik

KitKatのWebビューを使用してファイル入力のソリューションを探している人がまだいる場合。

openFileChooserがクリックされたときに呼び出されないAndroid 4.4
https://code.google.com/p/Android/issues/detail?id=6222

Crosswalkと呼ばれるクロムベースのライブラリを使用してこれを解決できます
https://crosswalk-project.org/documentation/downloads.html

手順
1。 xwalk_core_libraryAndroid上記のリンクからダウンロードしたプロジェクトをライブラリとしてプロジェクトにインポートします
2。レイアウトxmlに以下を追加します

       <org.xwalk.core.XWalkView
            Android:id="@+id/webpage_wv"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"          
        />

3.アクティビティのonCreateメソッドで、以下を実行します

mXwalkView = (XWalkView) context.findViewById(R.id.webpage_wv);
mXwalkView.setUIClient(new UIClient(mXwalkView));
mXwalkView.load(navigateUrl, null); //navigate url is your page URL
  1. アクティビティクラス変数を追加する

    private ValueCallback mFilePathCallback;プライベートXWalkView mXwalkView

  2. ファイル入力ダイアログが表示されます。ただし、ファイルを取得してサーバーに送信するには、コールバックを提供する必要があります。

  3. アクティビティのonActivityResultをオーバーライドする必要があります

    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
      super.onActivityResult(requestCode, resultCode, intent);
    
    if (mXwalkView != null) {
    
        if (mFilePathCallback != null) {
            Uri result = intent == null || resultCode != Activity.RESULT_OK ? null
                    : intent.getData();
            if (result != null) {
                String path = MediaUtility.getPath(getActivity(), result);
                Uri uri = Uri.fromFile(new File(path));
                mFilePathCallback.onReceiveValue(uri);
            } else {
                mFilePathCallback.onReceiveValue(null);
            }
        }
    
        mFilePathCallback = null;
    }
    mXwalkView.onActivityResult(requestCode, resultCode, intent);
    
    }
    
  4. MediaUtilityクラスは次の場所にあります
    RIから実際のパスを取得、Android KitKat new storage access framework
    ポール・バークの答えを参照

  5. mFilePathCallbackのデータオブジェクトを取得するには、アクティビティにサブクラスを作成します

    class UIClient extends XWalkUIClient {
    public UIClient(XWalkView xwalkView) {
        super(xwalkView);
    }
    
    public void openFileChooser(XWalkView view,
            ValueCallback<Uri> uploadFile, String acceptType, String capture) {
        super.openFileChooser(view, uploadFile, acceptType, capture);
    
        mFilePathCallback = uploadFile;
        Log.d("fchooser", "Opened file chooser.");
    }
    

    }

  6. 以上で完了です。これで、fileuploadが機能するはずです。 Crosswalkに必要なアクセス許可をマニフェストに追加することを忘れないでください。

    uses-permission Android:name = "Android.permission.ACCESS_FINE_LOCATION"
    uses-permission Android:name = "Android.permission.ACCESS_NETWORK_STATE"
    uses-permission Android:name = "Android.permission.ACCESS_WIFI_STATE"
    uses-permission Android:name = "Android.permission.CAMERA"
    uses-permission Android:name = "Android.permission.INTERNET"
    uses-permission Android:name = "Android.permission.MODIFY_AUDIO_SETTINGS"
    uses-permission Android:name = "Android.permission.RECORD_AUDIO"
    uses-permission Android:name = "Android.permission.WAKE_LOCK"
    uses-permission Android:name = "Android.permission.WRITE_EXTERNAL_STORAGE"

8
agomes

WebViewのFile Chooserは、最新のAndroidリリース4.4.3。

Nexus 5を使用して自分で試しました。

5

ライブラリ、Cordovaプラグイン、カスタムWebViewを使用せずにこの問題に対する独自のソリューションを構築しましたが、すべてのAndroidバージョンで正常に動作しています。

このソリューションには、WebViewのWebサイトとAndroidアプリとの間で通信するための非常に単純なJavascriptの使用、およびAndroidアプリケーションからのファイル選択と直接アップロードの実行、openFileChooser()、showFileChooser()、onShowFileChooser()をすべて削除 WebChromeClientメソッド。

最初のステップは、ユーザーがファイル入力をクリックしたときにWebサイトからjavascriptコンソールメッセージをトリガーにすることです。一意のコードを書くは、一意のファイルをアップロードするために使用されます名前またはパス。たとえば、完全な日時と巨大な乱数を連結する場合:

<input type="file" name="user_file" onclick="console.log('app.upload=20170405173025_456743538912');">

その後、アプリでWebChromeClientのonConsoleMessage()をオーバーライドするこのメッセージを読むメソッド、そのメッセージを検出、コードを読む、およびトリガーファイルの選択

webview.setWebChromeClient(new WebChromeClient() {
    // Overriding this method you can read messages from JS console.
    public boolean onConsoleMessage(ConsoleMessage message){          
        String messageText = message.message();
        // Check if received message is a file upload and get the unique code
        if(messageText.length()>11 && messageText.substring(0,11).equals("app.upload=")) {
           String code = messageText.substring(11);
           triggerFileUploadSelection(code);
           return true;
        }
        return false;
    }
});

ファイル選択の場合、単純なAndroid ACTION_PICKインテントを次のように使用できます。

public void triggerFileUploadSelection(String code){
    // For Android 6.0+ you must check for permissions in runtime to read from external storage
    checkOrRequestReadPermission();

    // Store code received from Javascript to use it later (code could also be added to the intent as an extra)
    fileUploadCode = code;

    // Build a simple intent to pick any file, you can replace "*/*" for "image/*" to upload only images if needed
    Intent filePickerIntent = new Intent(Intent.ACTION_PICK);
    filePickerIntent.setType("*/*");

    // FILE_UPLOAD_CODE is just any unique integer request code to identify the activity result when the user selects the file
    startActivityForResult( Intent.createChooser(filePickerIntent, getString(R.string.chooseFileToUpload) ), FILE_UPLOAD_CODE );
}

ユーザーがファイルを選択した後(または選択しなかった場合)、次の方法でファイルUriを受信、および実際のファイルパスに変換を実行できます。

@Override
public void onActivityResult (int requestCode, int resultCode, Intent data) {
    if(requestCode==FILE_UPLOAD_CODE) {
        if(data != null && resultCode == RESULT_OK){
            // user selected a file
            try{
                Uri selectedFileUri = data.getData();
                if(selectedFileUri!=null) {
                    // convert file URI to a real file path with an auxiliary function (below)
                    String filePath = getPath(selectedFileUri);
                    if(filePath!=null) {
                        // I got the file path, I can upload the file to the server (I pass webview as an argument to be able to update it when upload is completed)
                        uploadSelectedFile(getApplicationContext(), filePath, fileUploadCode, webview);
                    }else{
                        showToastFileUploadError();
                    }
                }else{
                    showToastFileUploadError();
                }
            }catch (Exception e){
                e.printStackTrace();
                showToastFileUploadError();
            }
        }else{
            // user didn't select anything
        }
    }
}

// I used this method for images, and it uses MediaStore.Images so you should probably 
// use another method to get the path from the Uri if you are working with any kind of file
public String getPath(Uri uri) {
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    if(cursor==null)return null;
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}

UploadSelectedFileメソッドは、内部にすべての情報(filePath、fileUploadCode、およびWebView)を含むオブジェクトを作成し、ファイルをアップロードするAsyncTaskをトリガーその情報を使用して、完了時にWebViewを更新します。

public static void uploadSelectedFile(Context c, String filePath, String code, WebView webView){
    // YOU CAN SHOW A SPINNER IN THE WEB VIEW EXECUTING ANY JAVASCRIPT YOU WANT LIKE THIS:
    webView.loadUrl("javascript: Element.show('my_upload_spinner');void 0"); 
    // void 0 avoids at the end avoids some browser redirection problems when executing javascript commands like this

    // CREATE A REQUEST OBJECT (you must also define this class with those three fields and a response field that we will use later):
    FileUploadRequest request = new FileUploadRequest(filePath, code, webView);

    // Trigger an async task to upload the file, and pass on the request object with all needed data
    FileUploadAsyncTask task = new FileUploadAsyncTask();
    task.execute(request);
}

AsyncTaskは、すべての情報を含むリクエストオブジェクトを受信し、MultipartUtilityを使用してマルチパートリクエストを作成し、サーバーに送信するを簡単に実行します。多くのJava Multipart Utilitiesを多くの場所から入手できます。そのうちの1つは次のとおりです。 http://www.codejava.net/Java-se/networking/upload-files -by-sending-multipart-request-programmatically

public class FileUploadAsyncTask extends AsyncTask<FileUploadRequest, Void, FileUploadRequest> {
    @Override
    protected FileUploadRequest doInBackground(FileUploadRequest... requests) {
        FileUploadRequest request = requests[0];

        try {
            // Generate a multipart request pointing to the URL where you will receive uploaded file
            MultipartUtility multipart = new MultipartUtility("http://www.example.com/file_upload.php", "UTF-8");
            // Add a field called file_code, to send the code to the server script
            multipart.addFormField("file_code", request.code);
            // Add the file to the request
            multipart.addFilePart("file_path", new File(request.filePath));

            // Send the request to the server and get the response and save it back in the request object
            request.response = multipart.finish(); // response from server.
        } catch (IOException e) {
            request.response = "FAILED";
            e.printStackTrace();
        }
        return request;
    }

これで、ファイルをサーバーにアップロードし、AsyncTaskのonPostExecuteメソッドから再度Javascriptを使用してWebサイトを更新できます。最も重要なことは、フォームの非表示フィールドにファイルコードを設定するであるため、ユーザーがフォームを送信するときにそのコードを取得できます。サイトにメッセージを表示したり、アップロードされた画像(画像の場合)を簡単に表示することもできます。

@Override
protected void onPostExecute(FileUploadRequest request) {
    super.onPostExecute(request);

    // check for a response telling everything if upload was successful or failed
    if(request.response.equals("OK")){
        // set uploaded file code field in a hidden field in your site form (ESSENTIAL TO ASSOCIATE THE UPLOADED FILE WHEN THE USER SENDS THE WEBSITE FORM)
        request.webView.loadUrl("javascript: document.getElementById('app_upload_code_hidden').value = '"+request.code+"';void 0");

        // Hide spinner (optional)
        //request.webView.loadUrl("javascript: Element.hide('my_upload_spinner');void 0");

        // show a message in the website, or the uploaded image in an image tag setting the src attribute 
        // to the URL of the image you just uploaded to your server. 
        // (you must implement your own fullUrl method in your FileUploadRequest class)
        // request.webView.loadUrl("javascript: document.getElementById('app_uploaded_image').src = '"+request.fullUrl()+"';void 0");
        // request.webView.loadUrl("javascript: Element.show('app_uploaded_image');void 0");
    }
}

これでAndroid部分が完了しました。作業する必要がありますサーバー側でファイルを受信します Android app AsyncTask必要な場所に保存します。

また、ユーザーが送信したときにWebサイトフォームを処理するを実行し、ユーザーがアプリからアップロードしたファイルを使用して必要な処理を行う必要があります。これを行うには、フォームでファイルコードを取得し(onPostExecute()のフィールドで完了しました)、そのファイルコードを使用して、アプリがアップロードしたファイルを見つけます toサーバー。これを実現するには、そのコードをファイル名として使用してパスにファイルを保存するか、データベースでファイルをアップロードしたコードとパスを保存します。

このソリューションは、利用可能なすべてのAndroidバージョンと互換性がある要素のみに依存しているため、どのデバイスでも動作するはずです(これについてユーザーからの苦情はもうありません)。

同じページに複数のファイル入力がある場合を使用できますフィールド番号または追加の識別子を送信初期javascriptメッセージ内の一意のファイルコードと一緒に、その識別子を渡しますすべてのアプリコードで使用し、それを使用してonPostExecute()の適切な要素を更新します。

ここで実際のコードを少し変更したので、何かが失敗した場合、おそらくいくつかの名前を変更するときにタイプミスまたはいくつかの小さな詳細になるでしょう。

処理する情報は非常に多いため、説明が必要な場合や提案や修正がある場合は教えてください。

1

KitKatバージョンはwebview type = fileフォームフィールドと互換性がないという事実にもかかわらず、webviewのaddJavascriptInterfaceメソッドを使用してファイルアップロードタスクを実行できます。サーバー側はAndroidのバージョンを判断する必要があります。それが4.4よりも低い場合、WebViewChromeClientプライベートメソッドを使用し、4.4以上の場合、サーバーコールAndroidメソッド互いに(例:ファイルコンテンツの非同期アップロード)

//コード

webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new WebViewJavaScriptInterface(this), "app");


ここに役立つリンクがあります...

call-Android-methods-from-javascript

1
tounaobun

KitKatの新しいファイルブラウザはChromeでも同様に狂っています。WebViewがChromiumをどのように使用しているかは、関連する問題である可能性があります。カメラから直接ファイルをアップロードすることはできますが、「Images」フォルダーからはアップロードできないことがわかりました。代わりに「ギャラリー」からアップロードする場合、同じファイルにアクセスできます。ああ。

修正は準備ができているが、リリースを待っているようです:

https://code.google.com/p/chromium/issues/detail?id=27864

0
Igor Zinken

webViewラッパーをWebサイトの周りに追加してアプリとして起動する場合は、デフォルトのAndroid webviewで見回してはいけません。私にとっては、2つのことがうまくいきませんでした。1.入力ファイル2.ストライプチェックアウト整数化(高度なJS APIを使用)

暗闇から抜け出すために私がしたこと

Cordovaを使用してサンプルアプリを作成しました。私たちが考えるのはもっと簡単です。

  1. 公式ページからCordovaをインストールし、サンプルアプリをビルドします。
  2. Apkファイルが提供されます。 (あなたはそれを得た)
  3. 作成したアプリからwwwフォルダーに移動し、index.jsを開き、onDeviceReadyの行を見つけて置き換えます:function(){window.open( ' http://yourdomain.com/yourpage ') }アプリを再度実行すると、サイトが開きます

  4. これがマスターステップです。これまでのところ、Cordovaは中程度のWebビューのみを使用しています。すべてがいつか変わるはずです。 Cordovaアプリに横断歩道プラグインを追加します。これにより、緩慢なWebビューが真新しいクロムビューに置き換えられます https://crosswalk-project.org/documentation/cordova.html

  5. 実行cordova clean、次にcordova build --release古いビルドをクリーンアップします。

  6. Cordvaアプリによって指定されたアプリディレクトリ内のconfig.xmlを開き、<allow-navigation href="http://yourdomain.com/*" />
  7. アプリを再度実行します。魔法!。
0
Code Tree