web-dev-qa-db-ja.com

リモートページからPhoneGap APIにアクセスする方法

私は次の状況に対応しなければなりません。既存のリモートWebページがあり、このページを使用するアプリを開発したいと考えています。ここまでは順調ですね。アプリを起動すると、ローカルindex.htmlが読み込まれ、外部ウェブサイトにリダイレクトされます(window.open target: _self)。このWebサイトは、phonegap webviewで開かれます。外部Webサイトで、ネイティブのPhoneGap APIにアクセスするためにcordova.jsを追加しました。しかし、それは正しく機能しません。 deviceReadyイベントは正しくトリガーされますが、navigator.cameraなどのphonegap APIにアクセスできません。

APIにアクセスするにはどうすればよいですか?

AppStore等で拒否されることはコメントしないでください。

ご協力ありがとうございました!

25
riedelinho

さて、私にとっての解決策はいくつかのソースの混合でしたが、ほとんどの解決策は見つかりました here

あなたがすべきことは次のとおりです:

  1. リモートconfig.xmlを直接指すようにindex.htmlを定義します。

    <content src="http://your-remote-location/index.html" />
    
  2. index.htmlでは、ローカルへの参照Androidデバイスリソースは**injection**のような一意のプレフィックスが前に付加されます。たとえば、cordova.jsの場合は、何かのようなもの:

    <script type="text/javascript" src="**injection**www/cordova.js"></script>
    
  3. 次の場所でSystemWebViewClient.Javaを見つけます:your-project-location\platforms\Android\CordovaLib\src\org\Apache\cordova\engine

  4. 上部のクラスのプライベートメンバーセクションに次の列挙型宣言を追加します。

    private enum WebExtension {
        PNG, MP3, MP4, TTF, SVG, JS, ICO, HTML, CSS, EOT, WOFF, JSON;
    }
    
  5. shouldInterceptRequestメソッドを見つけ、try {行の直後に次の行を追加します。

    if(url != null && url.contains(INJECTION_TOKEN)) {
        String assetPath = url.substring(url.indexOf(INJECTION_TOKEN) + INJECTION_TOKEN.length(), url.length());
        try {
            String mimeType = "text/plain";
    
            String ext = assetPath.substring(assetPath.lastIndexOf(".") + 1, assetPath.length());
            WebExtension extension = WebExtension.valueOf(ext.toUpperCase());
    
            switch(extension) {
                case PNG:
                    mimeType = "image/png";
                    break;
                case MP3:
                    mimeType = "audio/mpeg";
                    break;
                case MP4:
                    mimeType = "video/mp4";
                    break;
                case TTF:
                    mimeType = "application/x-font-ttf";
                    break;
                case SVG:
                    mimeType = "image/svg+xml";
                    break;
                case JS:
                    mimeType = "application/javascript";
                    break;
                case ICO:
                    mimeType = "image/x-icon";
                    break;
                case HTML:
                    mimeType = "text/html";
                    break;
                case CSS:
                    mimeType = "text/css";
                    break;
                case EOT:
                    mimeType = "application/vnd.ms-fontobject";
                    break;
                case WOFF:
                    mimeType = "application/x-font-woff";
                    break;
                case JSON:
                    mimeType = "application/json";
                    break;
            }
    
            WebResourceResponse response = new WebResourceResponse(
                mimeType,
                "UTF-8",
                parentEngine.webView.getContext().getAssets().open(assetPath)
            );
            return response;
        } catch (IOException e) {
            e.printStackTrace(); // Failed to load asset file
        }
    }
    

すべての結果は、すべてのリソース要求のインターセプトとなり、**injection**文字列が含まれる場合、リソースの場所を削減し、アプリケーションが実行されているローカルデバイスの場所から要求します。 。 mimeTypeは、アプリブラウザがリソースを正しい方法でロードするために必要です。

それが誰かを助けることを願っています。

13
Lentyai

Cordova.jsスクリプトをリモートサイトに含めるのは、プラットフォームごとに異なるcordova.jsがあるため、注意が必要です。ユーザーエージェントに基づいて正しいcordova.jsを返すようにサーバーを変更することもできますが、モバイルブラウザーからサイトを表示するときにこのスクリプトが含まれるため、これも注意が必要です。JavaScriptエラーが発生する可能性があるため、これは望ましくありません。ユーザーに表示されます。デスクトップコンピューターからサイトを表示する場合も同様ですが、cordova.jsは含めないでください。

ローカルWebページ(cordovaスクリプトが含まれている)があり、そこからリモートページ(スクリプトも含まれている)に移動しているように見えます。このページの変更が機能するかどうかはわかりません。それが機能した場合は、2番目のdevicereadyイベントを待つ必要があります。

ただし、リモートサイトページをCordovaアプリのルートページとして設定するだけで、中間の「ローダー」ページは必要ありません。 config.xmlファイルに設定するだけです。

<content src="http://your.website.fake/index.html" />

アプリへのサイトの読み込みを許可する必要があります。この同じファイルに、以下を追加する必要があります。

<access Origin="http://your.website.fake" subdomains="true"/> 
10
Mister Smith

このプラグインは、Androidソリューションを自分でコーディングする必要なく、問題を解決します。

https://www.npmjs.com/package/cordova-plugin-remote-injection

https://github.com/TruckMovers/cordova-plugin-remote-injection

リモートインジェクションプラグインを使用すると、リモートサイトがCordovaアプリ内に読み込まれたときに、CordovaのJavaScript APIとやり取りできます。

  • CordovaとインストールされたプラグインJSをリモートで閲覧されるページのWebビューに挿入し、パッケージ化されたCordovaアプリと同じようにCordovaオブジェクトとそのプラグインにアクセスできるようにします。

  • IOSおよびAndroidプラットフォームのサポート。

私はそれをテストし、それはうまく動作します。次のように、覚えておく必要があるのは、コルドバの準備ができるまで待つ必要があることだけです。

<html>
  <head>
  </head>
  <body>
    <script>
      document.addEventListener("deviceready", function() {
          document.write("Now you can use plugins"); 
      }, false);
    </script>
  </body>
</html>
9
jperelli

私にもこの問題があり、config.xml(コンテンツおよびアクセスタグ)の変更が機能しませんでした。電話で実行中にアプリを検査したところ、リモートサイトを読み込んだときに、いくつかのファイルが欠落していることがわかりました。

まず、それはcordova_plugins.jsと呼ばれるファイルで、プラットフォームフォルダ内の各プラットフォームで見つけることができます。次に、いくつかのプラグイン固有のファイルも必要です。ビルドを実行してそこから抽出することで、これらを見つけることができます。 Androidの場合、パスはAPK/assets/www/pluginsです。サーバーにコンテンツをコピーするだけで問題ありません。

[〜#〜] note [〜#〜]:プラットフォームフォルダーでプラグイン固有のファイルを見つけることもできますが、cordova.define( "...が見つからないため、不完全ですこれは必須moduleが未定義になるので、ビルドを行ってそこから取得するだけです。

7
sorin7486

これはCordova/PhoneGapによる制限です here

    if (startFilePath == nil) {
        loadErr = [NSString stringWithFormat:@"ERROR: Start Page at '%@/%@' was not found.", self.wwwFolderName, self.startPage];
        NSLog(@"%@", loadErr);
        self.loadFromString = YES;
        appURL = nil;
    }

Cordovaがローカル以外のファイルアドレスで機能できるようにするために、過去にこのチェックを無効にしました。

0
Rivera

混合コンテンツエラーなしでリモートのhttpsページからローカルファイルをロードできる最も簡単な作業ソリューション:

Androidの場合: https://developer.Android.com/reference/Android/webkit/WebSettings.html#MIXED_CONTENT_ALWAYS_ALLOW )を使用して混合コンテンツポリシーを無効にします。

IOSの場合:iOSでの混合コンテンツの問題を解決するPRをファイルプラグインに送信しました:Apache/cordova-plugin-file#296修正バージョンは次の場所で入手できます https://github.com/guylando/ cordova-plugin-file リモートサイト https://example.com をWebビューにロードすると、次のURLを使用してローカルファイルにアクセスできます: https:// example.com/cdvfile/bundle/www/cordova.js 代わりにcdvfile://localhost/bundle/www/cordova.jsこれにより、混合コンテンツの問題が解決されます

0
Guy L.

私はそれをphoneGapクイックデバッグのために非常に長い間機能させるように努めましたが、cordova.jsをアプリと一緒に(リモートロケーションではなく)せずにAPIを機能させる方法を見つけることができませんでした。

これが機能しない理由を正確には知りません。あなたが内部の仕組みを知っているなら、私はそれを聞くのを楽しみにしています...

私が試した最後のことは、メインのhtmlに100%x 100%のiframeを置き、ローカルのcordova.jsを同じドキュメントにロードすることでした。その後、APIを使用することができましたが、iOSでいくつかのスケーリングの問題がありました。

これを実装および構築した正確な方法は覚えていませんが、見つかったら編集します。

0
Ali Naci Erdem