Подтвердить что ты не робот

Как получить доступ к API телефонных разговоров с удаленной страницы

У меня должна быть следующая ситуация: У меня есть уже существующая удаленная веб-страница, и я хочу разработать приложение, которое использует эту страницу. Все идет нормально. Когда я запускаю приложение, загружается локальный index.html и перенаправляет (window.open target: _self) на внешний веб-сайт. Этот веб-сайт открывается в веб-просмотре phonegap. На внешнем веб-сайте я добавил cordova.js, чтобы получить доступ к родному API-интерфейсу. Но это работает неправильно. Событие deviceReady запускается правильно, но у меня нет доступа к API phonegap, например navigator.camera.

Как я могу это сделать, чтобы получить доступ к API?

Пожалуйста, не комментируйте, что он будет отклонен AppStore и т.д. и т.д.

Благодарим за помощь!

4b9b3361

Ответ 1

Ну, для меня решение было смесью нескольких источников, но большая часть решения была найдена здесь.

Что вам нужно сделать, это следующее:

  • Определите свой config.xml, чтобы указать прямо на удаленный index.html.

    <content src="http://your-remote-location/index.html" />
    
  • В вашей index.html ссылка на локальный ресурс устройства Android будет добавлена ​​с некоторым уникальным префиксом, например **injection**. Например, для cordova.js вы найдете что-то вроде:

    <script type="text/javascript" src="**injection**www/cordova.js"></script>
    
  • Найдите SystemWebViewClient.java в следующем местоположении: your-project-location\platforms\android\CordovaLib\src\org\apache\cordova\engine.

  • Добавьте следующее объявление enum в раздел частных членов класса вверху:

    private enum WebExtension {
        PNG, MP3, MP4, TTF, SVG, JS, ICO, HTML, CSS, EOT, WOFF, JSON;
    }
    
  • Найдите метод 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 необходим для правильного загрузки ресурса браузером приложений.

Надеюсь, что это поможет кому-то.

Ответ 2

Включение cordova.js script в удаленный сайт будет сложным, потому что для каждой платформы есть разные cordova.js. Вы можете изменить сервер так, чтобы он вернул правильный cordova.js на основе пользовательского агента, но это также сложно, потому что он будет включать этот script при просмотре сайта из мобильного браузера, и это нежелательно, потому что ошибки JavaScript может отображаться пользователю. Такая же история при просмотре сайта с настольного компьютера, cordova.js не должна включаться.

Мне кажется, что у вас есть локальная веб-страница (с включенной кордорой script), а оттуда вы переходите на удаленную страницу (которая также включает script). Я не уверен, что эта смена страницы будет работать. Если это сработало, вам, возможно, придется ждать второго события deviceready.

Но вы можете просто установить страницу удаленного сайта как корневую страницу в приложении cordova, не нужно промежуточную страницу "загрузчик". Просто установите его в файле config.xml:

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

Вам нужно убедиться, что вы разрешаете загружать свой сайт в приложение. В этом же файле вы должны добавить:

<access origin="http://your.website.fake" subdomains="true"/> 

Ответ 3

У меня тоже была эта проблема, и изменения в файлах config.xml(теги контента и доступа) не помогли. Я осмотрел приложение, пока он работал по телефону, и я обнаружил, что когда я загрузил удаленный сайт, некоторые файлы отсутствовали.

Сначала откройте файл с именем cordova_plugins.js, который вы можете найти для каждой платформы в папке платформы. Тогда вам также понадобятся некоторые файлы с плагинами. Вы можете найти их, выполнив сборку и извлекая их оттуда. Для android путь следующий: APK/assets/www/plugins. Просто скопируйте содержимое на свой сервер, и вы хорошо пойдете.

ПРИМЕЧАНИЕ: вы также можете найти файлы с плагинами в папке платформы, но они неполны, так как они отсутствуют cordova.define("... в начале. Это приводит к required и модуль undefined, поэтому просто выполните сборку и получите их оттуда.

Ответ 4

Этот плагин решает проблему без необходимости кодировать себе решение для Android.

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

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

Удаленный инъекционный плагин позволяет удаленному сайту взаимодействовать с API-интерфейсом java-скриптов cordova при загрузке в ваше приложение cordova.

  • Внедряет кордову и устанавливает плагин JS в веб-просмотр для любой удаленной страницы, позволяя им одинаковый доступ к объекту cordova и его плагинам в виде упакованного приложения cordova.

  • Поддержка платформ iOS и Android.

Я тестировал его, и он работает нормально. Единственное, что вам нужно запомнить, это то, что вам нужно подождать, пока кордова будет готова, например:

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

Ответ 5

Это ограничение на Cordova/PhoneGap здесь:

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

Я отключил эту проверку в прошлом, чтобы позволить Кордове работать с нелокальными файловыми адресами.

Ответ 6

Я работал над тем, чтобы он работал очень долго для быстрой отладки phoneGap, но не смог найти способ заставить API работать без наличия cordova.js вместе с приложением (а не на удаленном месте).

Я точно не знаю, почему это не работает. Если вы знаете внутреннюю работу, я с нетерпением жду ее...

Последнее, что я пробовал, - поставить 100% на 100% iframe в основной html и загрузить локальный cordova.js в том же документе. Тогда я смог использовать API, но были проблемы с масштабированием в iOS, что еще один вопрос...

Я не помню, как именно я реализовал и структурировал это, но я отредактирую, если найду его.