Уведомления в настоящее время выключены , и вы не будете получать обновления. Чтобы включить их, перейдите в Настройки уведомлений на странице Профиль .
В вашем сообщении мы обнаружили следующую личную информацию:
Эта информация будет видна всем, кто посещает или подписывается на уведомления об этом сообщении. Вы уверены, что хотите продолжить?
Перейдите на страницу юридической помощи, чтобы запросить изменение содержимого по юридическим причинам.
Перейдите на страницу юридической помощи, чтобы запросить изменение содержимого по юридическим причинам.
Android WebView для воспроизведения видео с YouTube
Может ли кто-нибудь помочь с использованием этого кода для воспроизведения видеороликов YouTube, встроенных в веб-сайт? пробовали все виды вещей, включая hardwareAccelerated = true в манифесте.
Веб-просмотр показывает страницу YouTube и миниатюры изображений, но при нажатии на них ничего не происходит.
На некоторых устройствах с аппаратным ускорением воспроизводится звук, но нет видео. спасибо всем !
package com.inglesupdated; import java.util.ArrayList; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android .content.DialogInterface; import android.content.Intent; import android.graphics.Picture; import android.net.Uri; import android.os.Bundle; import android.view.Gravity; import android.view.LayoutInflater; import android. view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.webkit.WebChromeClient; import android.webkit.WebView; import android.webkit.WebViewClient; импорт android.webkit.WebView.PictureListener; импорт android.widget.Button; импорт android.widget. LinearLayout; открытый класс BT_screen_customURL расширяет BT_activity_base {частное логическое didCreate = false; частный WebView webView = null; частная строка dataURL = ""; частная строка currentURL = ""; частная строка originalURL = ""; частный AlertDialog confirmLaunchInNativeAppDialogue = null; частный AlertDialog confirmEmailDocumentDialogue = null; частная строка showBrowserBarBack = ""; частная строка showBrowserBarLaunchInNativeApp = ""; частная строка showBrowserBarEmailDocument = ""; частная строка showBrowserBarRefresh = ""; ////////////////////////////////////////////////////////////////////////////События жизненного цикла активности. //onCreate @Override public void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); this.activityName = "BT_screen_customURL"; BT_debugger.showIt (activityName + ": onCreate"); //ссылка на базовый макет .. LinearLayout baseView = (LinearLayout) findViewById (R.id.baseView); //настраиваем цвета фона ... BT_viewUtilities.updateBackgroundColorsForScreen (this, this.screenData); //настраиваем фоновые изображения .. if (backgroundImageWorkerThread == null) {backgroundImageWorkerThread = new BackgroundImageWorkerThread (); backgroundImageWorkerThread.start (); }//настраиваем панель навигации ... LinearLayout navBar = BT_viewUtilities.getNavBarForScreen (this, this.screenData); если (navBar! = null) {baseView.addView (navBar); }//раздуваем этот файл макета экранов ... LayoutInflater vi = (LayoutInflater) thisActivity.getSystemService (Context.LAYOUT_INFLATER_SERVICE); Просмотр thisScreensView = vi.inflate (R.layout.screen_customurl, null); //добавляем представление к базовому представлению ... baseView.addView (thisScreensView); //ссылка на веб-просмотр в файле макета. webView = (WebView) thisScreensView.findViewById (R.id.webView); webView.setBackgroundColor (0); webView.setInitialScale (0); webView.getSettings (). setJavaScriptEnabled (истина); webView.getSettings (). setSupportZoom (истина); webView.getSettings (). setBuiltInZoomControls (истина); webView.getSettings (). setPluginsEnabled (истина); webView.setPictureListener (новый MyPictureListener ()); webView.setWebChromeClient (новый WebChromeClient ()); webView.setWebViewClient (new WebViewClient () {@Override public boolean shouldOverrideUrlLoading (WebView view, String url) {//запомнить URL ... currentURL = url;//загрузить URL-адрес во встроенный браузер приложения, если он находится в нашем список типов для загрузки ... if (BT_act_controller.canLoadDocumentInWebView (url)) {//загрузить url во встроенном браузере ...//showProgress (null, null); return false;} else {//спросить пользователя, что приложение, чтобы открыть это, если метод вернул НЕТ ... попробуйте {Intent i = new Intent (Intent.ACTION_VIEW, Uri.parse (url)); startActivity (Intent.createChooser (i, getString (R.string.openWithWhatApp)) );} catch (Exception e) {BT_debugger.showIt (activityName + ": Ошибка при запуске собственного приложения для url:" + url); showAlert (getString (R.string.noNativeAppTitle), getString (R.string. noNativeAppDescription)); }//не пытаемся загрузить URL .. return true; }} @Override public void onPageFinished (представление WebView, строковый URL) {hideProgress (); BT_debugger.showIt (activityName + ": onPageFinished завершено Загрузка:" + url); } @Override public void onReceivedError (представление WebView, int errorCode, строковое описание, String failingUrl) {hideProgress (); showAlert (getString (R.string.errorTitle), getString (R.string.errorLoadingScreen)); BT_debugger.showIt (activityName = ": onReceivedError ОШИБКА загрузки URL:" + failingUrl + "Description:" + description); }}); //заполняем свойства JSON ... dataURL = BT_strings.getJsonPropertyValue (this.screenData.getJsonObject (), "dataURL", ""); currentURL = dataURL; originalURL = dataURL; //параметры кнопки для аппаратного меню key ... showBrowserBarBack = BT_strings.getJsonPropertyValue (this.screenData.getJsonObject (), "showBrowserBarBack", "0"); showBrowserBarLaunchInNativeApp = BT_strings.getJsonPropertyValue (this.screenData.getJsonObject (), «showBrowserBarLaunchInNativeApp», «0»); showBrowserBarEmailDocument = BT_strings.getJsonPropertyValue (this.screenData.getJsonObject (), «showBrowserBarEmailDocument», «0»); showBrowserBarRefresh = BT_strings.getJsonPropertyValue (this.screenData.getJsonObject (), «showBrowserBarRefresh», «0»); //предотвратить взаимодействие с пользователем? Строка preventUserInteraction = BT_strings.getJsonPropertyValue (this.screenData.getJsonObject (), «preventUserInteraction», «0»); if (preventUserInteraction.equalsIgnoreCase ("1")) {//не получается заставить Android "предотвратить взаимодействие с пользователем" ... ??? }//скрываем полосы прокрутки .. String hideVerticalScrollBar = BT_strings.getJsonPropertyValue (this.screenData.getJsonObject (), "hideVerticalScrollBar", "0"); если (hideVerticalScrollBar.equalsIgnoreCase ("1")) {webView.setVerticalScrollBarEnabled (ложь); } Строка hideHorizontalScrollBar = BT_strings.getJsonPropertyValue (this.screenData.getJsonObject (), «hideHorizontalScrollBar», «0»); если (hideHorizontalScrollBar.equalsIgnoreCase ("1")) {webView.setHorizontalScrollBarEnabled (ложь); } Строка preventAllScrolling = BT_strings.getJsonPropertyValue (this.screenData.getJsonObject (), «preventAllScrolling», «0»); если (preventAllScrolling.equalsIgnoreCase ("1")) {webView.setVerticalScrollBarEnabled (ложь); webView.setHorizontalScrollBarEnabled (ложь); }//выясняем, что загружать ... if (dataURL.length ()> 1) {String useUrl = BT_strings.mergeBTVariablesInString (dataURL); BT_debugger.showIt (activityName + ": URL загрузки из:" + useUrl); this.loadUrl (useUrl); } else {BT_debugger.showIt (activityName + ": URL не найден? Веб-просмотр не загружается!"); showAlert (getString (R.string.errorTitle), getString (R.string.errorLoadingScreen)); }//помечаем как созданное.. didCreate = true; /* * ********************************************* ******************** Примечания: На этом экране полностью загружен файл макета. BT_activity_base загружен act_base.xml --ЗАТЕМ - этот экран загрузил собственный файл макета. Свойства JSON для этого экрана из данных конфигурации приложения доступны для использования. Вы можете легко прочитать эти свойства, используя класс BT_strings. Пример: String thisScreensNavBarTitleText = BT_strings.getJsonPropertyValue (this.screenData.getJsonObject (), «thisScreensNavBarTitleText», «здесь значение по умолчанию»); Фон экрана и строка заголовка были настроены с использованием класса BT_viewUtilities: BT_viewUtilities.updateBackgroundColorsForScreen () Вы можете изменить файл макета и расширить этот экран, как хотите. ************************************************* ****************** */}//onCreate//onStart @Override protected void onStart () {//BT_debugger.showIt(activityName + ": onStart"); super.onStart (); }//onResume @Override public void onResume () {super.onResume (); //BT_debugger.showIt(activityName + ": onResume"); //проверяем, что onCreate уже запущен ... if (didCreate) {}}//onPause @Override public void onPause () {super.onPause (); //BT_debugger.showIt(activityName + ": onPause"); }//onStop @Override protected void onStop () {super.onStop (); //BT_debugger.showIt(activityName + ": onStop"); }//onDestroy @Override public void onDestroy () {super.onDestroy (); //BT_debugger.showIt(activityName + ": onDestroy"); }//события жизненного цикла конечной активности//////////////////////////////////////////////////////////////////////////загрузить URL в webView public void loadUrl (String theUrl) {BT_debugger.showIt (activityName + ": loadUrl"); попробуйте {webView.loadUrl (theUrl); } catch (исключение e) {BT_debugger.showIt (activityName + ": loadUrl Exception:" + e.toString ()); }}/* Аппаратный обратный ключ, при необходимости раскомментируйте. Раскомментируйте это, чтобы аппаратная клавиша возврата действовала как кнопка возврата в браузере. Предупреждение: если вы сделаете это, пользователю нужно будет вернуться «назад» столько раз, сколько они нажимали «вперед», чтобы вернуться к предыдущему экрану. @Override общедоступное логическое значение onKeyDown (int keyCode, событие KeyEvent) {if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack ()) {webView.goBack (); вернуть истину; }//не обратная клавиша .. return super.onKeyDown (keyCode, event); } *///кнопка возврата ... public void handleBackButton () {BT_debugger.showIt (activityName + ": handleBackButton"); если (webView.canGoBack ()) {webView.goBack (); } else {BT_debugger.showIt (activityName + ": handleBackButton не может вернуться?"); }}//кнопка обновления ... public void handleRefreshButton () {BT_debugger.showIt (activityName + ": handleRefreshButton"); если (currentURL.length ()> 1) {showProgress (ноль, ноль); webView.loadUrl (текущийURL); } else {BT_debugger.showIt (activityName + ": handleRefreshButton не может обновиться?"); }}//запуск в нативной кнопке приложения ... public void handleLaunchInNativeAppButton () {BT_debugger.showIt (activityName + ": handleLaunchInNativeAppButton"); если (currentURL.length ()> 1 && originalURL.length ()> 1) {confirmLaunchInNativeApp (); } else {showAlert (getString (R.string.errorTitle), getString (R.string.cannotOpenDocumentInNativeApp)); BT_debugger.showIt (activityName + ": handleLaunchInNativeAppButton NO url?"); }}//обрабатываем кнопку электронной почты public void handleEmailDocumentButton () {BT_debugger.showIt (activityName + ": handleLaunchInNativeAppButton"); showAlert (getString (R.string.errorTitle), getString (R.string.cannotEmailDocument)); BT_debugger.showIt (activityName + ": handleEmailDocumentButton НЕТ документа для отправки по электронной почте на экранах URL"); }//подтверждаем запуск в родном приложении public void confirmLaunchInNativeApp () {confirmLaunchInNativeAppDialogue = new AlertDialog.Builder (this) .create (); confirmLaunchInNativeAppDialogue.setTitle (getString (R.string.confirm)); confirmLaunchInNativeAppDialogue.setMessage (getString (R.string.confirmLaunchInNativeBrowser)); confirmLaunchInNativeAppDialogue.setIcon (R.drawable.icon); //ДА confirmLaunchInNativeAppDialogue.setButton (DialogInterface.BUTTON_POSITIVE, getString (R.string.yes), new DialogInterface.OnClickListener () {public void onClick (DialogInterface dialog, int which) {confirmLaunchInNissAppDialogue (load);//tellism URL в лучшем доступном нативном приложении ... попробуйте {Intent i = new Intent (Intent.ACTION_VIEW, Uri.parse (currentURL)); startActivity (i);} catch (Exception e) {BT_debugger.showIt (activityName + " : Ошибка при запуске собственного приложения для url: "+ currentURL); showAlert (getString (R.string.noNativeAppTitle), getString (R.string.noNativeAppDescription));}}}); //НЕТ confirmLaunchInNativeAppDialogue.setButton (DialogInterface.BUTTON_NEGATIVE, getString (R.string.no), new DialogInterface.OnClickListener () {public void onClick (DialogInterface dialog, int which) {confirmLaunchInNativeAppDialogue }.dismiss (); //показать окно подтверждения ... confirmLaunchInNativeAppDialogue.show (); }//подтверждаем документ электронной почты public void confirmEmailDocumentDialogue () {confirmEmailDocumentDialogue = new AlertDialog.Builder (this) .create (); confirmEmailDocumentDialogue.setTitle (getString (R.string.confirm)); confirmEmailDocumentDialogue.setMessage (getString (R.string.confirmEmailDocument)); confirmEmailDocumentDialogue.setIcon (R.drawable.icon); //ДА confirmEmailDocumentDialogue.setButton (DialogInterface.BUTTON_POSITIVE, getString (R.string.yes), new DialogInterface.OnClickListener () {public void onClick (DialogInterface dialog, int which) {confirmEmailDocumentDialogue.dismiss (); собственное почтовое приложение ... Intent emailIntent = new Intent (android.content.Intent.ACTION_SEND); emailIntent.setType ("plain/text"); emailIntent.putExtra (android.content.Intent.EXTRA_SUBJECT, getString (R.string. sharingWithYou)); emailIntent.putExtra (android.content.Intent. EXTRA_TEXT, currentURL); //выборщик будет поддерживать пользователя, если у него более одного почтового клиента .. startActivity (Intent.createChooser (emailIntent, getString (R.string.openWithWhatApp))); }}); //НЕТ confirmEmailDocumentDialogue.setButton (DialogInterface.BUTTON_NEGATIVE, getString (R.string.no), new DialogInterface.OnClickListener () {public void onClick (DialogInterface dialog, int which) {confirmEmailDocumentDialogue.dismiss ();}}) //показать окно подтверждения ... confirmEmailDocumentDialogue.show (); }//видим webView (выше), где onPageFinished загружается слишком рано ... класс MyPictureListener реализует PictureListener {public void onNewPicture (представление WebView, Picture arg1) {//BT_debugger.showIt("here "+": onNewPicture done "); hideProgress (); }}///////////////////////////////////////////////////////меню опций (аппаратное меню-кнопка) @Override public boolean onPrepareOptionsMenu (меню меню) {super.onPrepareOptionsMenu (меню); //настраиваем диалог final Dialog dialog = new Dialog (this); //линейный макет содержит все параметры ... LinearLayout optionsView = new LinearLayout (this); optionsView.setLayoutParams (новый LayoutParams (LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); optionsView.setOrientation (LinearLayout.VERTICAL); optionsView.setGravity (Gravity.CENTER_VERTICAL); optionsView.setPadding (0, 0, 0, 20); //параметры имеют индивидуальные параметры макета LinearLayout.LayoutParams btnLayoutParams = new LinearLayout.LayoutParams (400, LayoutParams.WRAP_CONTENT); btnLayoutParams.setMargins (10, 10, 10, 10); btnLayoutParams.leftMargin = 10; btnLayoutParams.rightMargin = 10; btnLayoutParams.topMargin = 0; btnLayoutParams.bottomMargin = 10; //содержит все параметры ArrayList
После 3 дней попытки воспроизвести Youtube видео внутри WebView с использованием различных решений, найденных на 10 страницах поиска Google, некоторые решения работают, но не на всех устройствах или версиях ОС, я решил думать по-своему.
Для меня решение игры видео непосредственно в WebView генерирует множество артефактов даже на последнем устройстве Android: Nexus 4 Итак, мне пришлось найти способ поймать щелчок на iframe Youtube, чтобы запустить приложение Youtube напрямую, как iOS отлично справляется без каких-либо усилий разработчика.
открытый класс MyWebViewClient расширяет WebViewClient {public Activity mActivity; общедоступный MyWebViewClient (активность) {super (); mActivity = активность; } @Override public boolean shouldOverrideUrlLoading (представление WebView, строковый URL) {Uri uri = Uri.parse (url); если (uri.getHost (). contains ("youtube.com")) {IntentUtils.viewYoutube (mActivity, url); вернуть истину; } return false; } общедоступный статический void viewYoutube (контекст контекста, строковый URL-адрес) {IntentUtils.viewWithPackageName (контекст, URL-адрес, «com.google.android.youtube»); } public static void viewWithPackageName (Контекст контекста, String url, String packageName) {попробуйте {Intent viewIntent = new Intent (Intent.ACTION_VIEW, Uri.parse (url)); если (isAppInstalled (context, packageName)) {viewIntent.setPackage (packageName); } context.startActivity (viewIntent); } catch (Exception e) {Intent viewIntent = new Intent (Intent.ACTION_VIEW, Uri.parse (url)); context.startActivity (viewIntent); }} общедоступное статическое логическое значение isAppInstalled (контекстный контекст, строка packageName) {PackageManager packageManager = context.getPackageManager (); попробуйте {packageManager.getPackageInfo (packageName, PackageManager. GET_ACTIVITIES); вернуть истину; } catch (NameNotFoundException e) {} return false; } @Override public void onPageFinished (финальное представление WebView, строковый URL) {String javascript = "javascript:" + "var iframes = document.getElementsByTagName ('iframe');" + "for (var i = 0, l = iframes.length; i
Между прочим, я должен сказать, что я немного расстроен тем немногими усилиями, которые были предприняты, чтобы предоставить разработчикам приемлемый WebView.
Даже если я понимаю желание избегать приложений Android, основанных только на HTML, это всегда лучший/самый быстрый способ отображать богатый контент на странице сведений. Например, в моем случае я управляю приложением на основе RSS, которое позволяет моим клиентам для изменения самого содержимого.
Кроме того, если посмотреть на время, которое мы должны потратить на связывание пользовательского интерфейса с сетевыми данными и сохраненными данными, по сравнению с разработкой Windows Phone, где все данные напрямую связаны с компонентом пользовательского интерфейса .
2
Томас Дж. . решение сработало для меня, однако мне пришлось изменить javascript.
String javascript = "javascript:" + "setTimeout (function () {" + "var iframes = document.getElementsByTagName ('iframe'); "+" f или (var i = 0, l = iframes.length; я
Выполнение javascript немного позже события onPageFinished устранило проблему на устройстве Samsung Tab, которое, казалось, не было готово, если js выполнялся немедленно. Я попробовал событие onload/$ (document) .ready, но по-прежнему не работает. Ожидание 600 мс — не лучший вариант, но я уже потратил достаточно времени, пытаясь заставить это работать.
Убедитесь, что z-index больше, чем у iframe , самый простой подход — установить для zIndex значение Integer.MAX_VALUE