- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
任何人都可以帮助使用此代码来播放嵌入在网站中的 youtube 视频吗?已经尝试了各种各样的事情,包括 list 中的 hardwareAccelerated=true 。
WebView 显示了 youtube 页面和缩略图,但点击它们时没有任何反应。
在某些具有 hardwareAccelerated 的设备上,它会播放声音但不会播放视频。谢谢大家!
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;
import android.webkit.WebView.PictureListener;
import android.widget.Button;
import android.widget.LinearLayout;
public class BT_screen_customURL extends BT_activity_base{
private boolean didCreate = false;
private WebView webView = null;
private String dataURL = "";
private String currentURL = "";
private String originalURL = "";
private AlertDialog confirmLaunchInNativeAppDialogue = null;
private AlertDialog confirmEmailDocumentDialogue = null;
private String showBrowserBarBack = "";
private String showBrowserBarLaunchInNativeApp = "";
private String showBrowserBarEmailDocument = "";
private String showBrowserBarRefresh = "";
//////////////////////////////////////////////////////////////////////////
//activity life-cycle events.
//onCreate
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
this.activityName = "BT_screen_customURL";
BT_debugger.showIt(activityName + ":onCreate");
//reference to base layout..
LinearLayout baseView = (LinearLayout)findViewById(R.id.baseView);
//setup background colors...
BT_viewUtilities.updateBackgroundColorsForScreen(this, this.screenData);
//setup background images..
if(backgroundImageWorkerThread == null){
backgroundImageWorkerThread = new BackgroundImageWorkerThread();
backgroundImageWorkerThread.start();
}
//setup navigation bar...
LinearLayout navBar = BT_viewUtilities.getNavBarForScreen(this, this.screenData);
if(navBar != null){
baseView.addView(navBar);
}
//inflate this screens layout file...
LayoutInflater vi = (LayoutInflater)thisActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View thisScreensView = vi.inflate(R.layout.screen_customurl, null);
//add the view to the base view...
baseView.addView(thisScreensView);
//reference to the webview in the layout file.
webView = (WebView) thisScreensView.findViewById(R.id.webView);
webView.setBackgroundColor(0);
webView.setInitialScale(0);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setSupportZoom(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setPluginsEnabled(true);
webView.setPictureListener(new MyPictureListener());
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url){
//remember the URL...
currentURL = url;
//load the URL in the app's built-in browser if it's in our list of types to load...
if(BT_act_controller.canLoadDocumentInWebView(url)){
//load url in built-in browser...
// showProgress(null, null);
return false;
}else{
//ask user what app to open this in if the method returned NO...
try{
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 + ": Error launching native app for url: " + url);
showAlert(getString(R.string.noNativeAppTitle), getString(R.string.noNativeAppDescription));
}
//do not try to load the URL..
return true;
}
}
@Override
public void onPageFinished(WebView view, String url){
hideProgress();
BT_debugger.showIt(activityName + ":onPageFinished finished Loading: " + url);
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
hideProgress();
showAlert(getString(R.string.errorTitle), getString(R.string.errorLoadingScreen));
BT_debugger.showIt(activityName = ":onReceivedError ERROR loading url: " + failingUrl + " Description: " + description);
}
});
//fill JSON properties...
dataURL = BT_strings.getJsonPropertyValue(this.screenData.getJsonObject(), "dataURL", "");
currentURL = dataURL;
originalURL = dataURL;
//button options for hardware menu 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");
//prevent user interaction?
String preventUserInteraction = BT_strings.getJsonPropertyValue(this.screenData.getJsonObject(), "preventUserInteraction", "0");
if(preventUserInteraction.equalsIgnoreCase("1")){
//can't seem to get Android to "prevent user interaction"...???
}
//hide scroll bars..
String hideVerticalScrollBar = BT_strings.getJsonPropertyValue(this.screenData.getJsonObject(), "hideVerticalScrollBar", "0");
if(hideVerticalScrollBar.equalsIgnoreCase("1")){
webView.setVerticalScrollBarEnabled(false);
}
String hideHorizontalScrollBar = BT_strings.getJsonPropertyValue(this.screenData.getJsonObject(), "hideHorizontalScrollBar", "0");
if(hideHorizontalScrollBar.equalsIgnoreCase("1")){
webView.setHorizontalScrollBarEnabled(false);
}
String preventAllScrolling = BT_strings.getJsonPropertyValue(this.screenData.getJsonObject(), "preventAllScrolling", "0");
if(preventAllScrolling.equalsIgnoreCase("1")){
webView.setVerticalScrollBarEnabled(false);
webView.setHorizontalScrollBarEnabled(false);
}
//figure out what to load...
if(dataURL.length() > 1){
String useUrl = BT_strings.mergeBTVariablesInString(dataURL);
BT_debugger.showIt(activityName + ": loading URL from: " + useUrl);
this.loadUrl(useUrl);
}else{
BT_debugger.showIt(activityName + ": No URL found? Not loading web-view!");
showAlert(getString(R.string.errorTitle), getString(R.string.errorLoadingScreen));
}
//flag as created..
didCreate = true;
/*
* *******************************************************************
Notes: This screen has fully loaded it's layout file at this point.
BT_activity_base loaded act_base.xml
--THEN--
this screen loaded it's own layout file.
JSON properties for this screen from the app's configuration data are
available for use. You can read these properties easily using the BT_strings class.
Example:
String thisScreensNavBarTitleText = BT_strings.getJsonPropertyValue(this.screenData.getJsonObject(), "thisScreensNavBarTitleText", "default value here");
The screens background and title bar were setup using the BT_viewUtilities class:
BT_viewUtilities.updateBackgroundColorsForScreen()
You are free to modify the layout file and extend this screen however you want.
********************************************************************
*/
}//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");
//verify onCreate already ran...
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");
}
//end activity life-cycle events
//////////////////////////////////////////////////////////////////////////
//load URL in webView
public void loadUrl(String theUrl){
BT_debugger.showIt(activityName + ": loadUrl");
try{
webView.loadUrl(theUrl);
}catch(Exception e){
BT_debugger.showIt(activityName + ":loadUrl Exception: " + e.toString());
}
}
/* Hardware Back-Key, uncomment as needed.
Uncomment this to make the hardware back-key act like a browser back button
Warning: If you do this the user will need to go "back" the number of times they
when "forward" to return to the previous screen.
@Override
public boolean onKeyDown(int keyCode, KeyEvent event){
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()){
webView.goBack();
return true;
}
//not the back-key..
return super.onKeyDown(keyCode, event);
}
*/
//back button...
public void handleBackButton(){
BT_debugger.showIt(activityName + ":handleBackButton");
if(webView.canGoBack()){
webView.goBack();
}else{
BT_debugger.showIt(activityName + ":handleBackButton cannot go back?");
}
}
//refresh button...
public void handleRefreshButton(){
BT_debugger.showIt(activityName + ":handleRefreshButton");
if(currentURL.length() > 1){
showProgress(null, null);
webView.loadUrl(currentURL);
}else{
BT_debugger.showIt(activityName + ":handleRefreshButton cannot refresh?");
}
}
//launch in native app button...
public void handleLaunchInNativeAppButton(){
BT_debugger.showIt(activityName + ":handleLaunchInNativeAppButton");
if(currentURL.length() > 1 && originalURL.length() > 1){
confirmLaunchInNativeApp();
}else{
showAlert(getString(R.string.errorTitle), getString(R.string.cannotOpenDocumentInNativeApp));
BT_debugger.showIt(activityName + ":handleLaunchInNativeAppButton NO url?");
}
}
//handle email button
public void handleEmailDocumentButton(){
BT_debugger.showIt(activityName + ":handleLaunchInNativeAppButton");
showAlert(getString(R.string.errorTitle), getString(R.string.cannotEmailDocument));
BT_debugger.showIt(activityName + ":handleEmailDocumentButton NO document to email on URL screens");
}
//confirm launch in native app
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);
//YES
confirmLaunchInNativeAppDialogue.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.yes), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
confirmLaunchInNativeAppDialogue.dismiss();
//tell Android to load the URL in the best available Native App...
try{
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(currentURL));
startActivity(i);
}catch(Exception e){
BT_debugger.showIt(activityName + ": Error launching native app for url: " + currentURL);
showAlert(getString(R.string.noNativeAppTitle), getString(R.string.noNativeAppDescription));
}
} });
//NO
confirmLaunchInNativeAppDialogue.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.no), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
confirmLaunchInNativeAppDialogue.dismiss();
} });
//show the confirmation box...
confirmLaunchInNativeAppDialogue.show();
}
//confirm email document
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);
//YES
confirmEmailDocumentDialogue.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.yes), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
confirmEmailDocumentDialogue.dismiss();
//tell Android launch the native email application...
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);
//chooser will propmpt user if they have more than one email client..
startActivity(Intent.createChooser(emailIntent, getString(R.string.openWithWhatApp)));
} });
//NO
confirmEmailDocumentDialogue.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.no), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
confirmEmailDocumentDialogue.dismiss();
} });
//show the confirmation box...
confirmEmailDocumentDialogue.show();
}
//see webView (above) where onPageFinished is loading too soon...
class MyPictureListener implements PictureListener {
public void onNewPicture(WebView view, Picture arg1) {
//BT_debugger.showIt("here" + ":onNewPicture done");
hideProgress();
}
}
/////////////////////////////////////////////////////
//options menu (hardware menu-button)
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
//set up dialog
final Dialog dialog = new Dialog(this);
//linear layout holds all the options...
LinearLayout optionsView = new LinearLayout(this);
optionsView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
optionsView.setOrientation(LinearLayout.VERTICAL);
optionsView.setGravity(Gravity.CENTER_VERTICAL);
optionsView.setPadding(0, 0, 0, 20);
//options have individual layout params
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;
//holds all the options
ArrayList<Button> options = new ArrayList<Button>();
//cancel...
final Button btnCancel = new Button(this);
btnCancel.setText(getString(R.string.okClose));
btnCancel.setOnClickListener(new OnClickListener(){
public void onClick(View v){
dialog.cancel();
}
});
options.add(btnCancel);
//back...
if(showBrowserBarBack.equalsIgnoreCase("1")){
final Button btn = new Button(this);
btn.setText(getString(R.string.browserBack));
btn.setOnClickListener(new OnClickListener(){
public void onClick(View v){
dialog.cancel();
handleBackButton();
}
});
options.add(btn);
}
//launch in native app...
if(showBrowserBarLaunchInNativeApp.equalsIgnoreCase("1")){
final Button btn = new Button(this);
btn.setText(getString(R.string.browserOpenInNativeApp));
btn.setOnClickListener(new OnClickListener(){
public void onClick(View v){
dialog.cancel();
handleLaunchInNativeAppButton();
}
});
options.add(btn);
}
//email document...
if(showBrowserBarEmailDocument.equalsIgnoreCase("1")){
final Button btn = new Button(this);
btn.setText(getString(R.string.browserEmailDocument));
btn.setOnClickListener(new OnClickListener(){
public void onClick(View v){
dialog.cancel();
handleEmailDocumentButton();
}
});
options.add(btn);
}
//refresh page...
if(showBrowserBarRefresh.equalsIgnoreCase("1")){
final Button btn = new Button(this);
btn.setText(getString(R.string.browserRefresh));
btn.setOnClickListener(new OnClickListener(){
public void onClick(View v){
dialog.cancel();
handleRefreshButton();
}
});
options.add(btn);
}
//refreshAppData (if we are on home screen)
if(this.screenData.isHomeScreen() && inglesupdated_appDelegate.rootApp.getDataURL().length() > 1){
final Button btnRefreshAppData = new Button(this);
btnRefreshAppData.setText(getString(R.string.refreshAppData));
btnRefreshAppData.setOnClickListener(new OnClickListener(){
public void onClick(View v){
dialog.cancel();
refreshAppData();
}
});
options.add(btnRefreshAppData);
}
//add each option to layout, set layoutParams as we go...
for(int x = 0; x < options.size(); x++){
options.get(x).setLayoutParams(btnLayoutParams);
options.get(x).setPadding(5, 5, 5, 5);
optionsView.addView(options.get(x));
}
//set content view..
dialog.setContentView(optionsView);
if(options.size() > 1){
dialog.setTitle(getString(R.string.menuOptions));
}else{
dialog.setTitle(getString(R.string.menuNoOptions));
}
//show
dialog.show();
return true;
}
//end options menu
/////////////////////////////////////////////////////
}
最佳答案
在 3 天尝试使用在 10 个 Google 搜索页面上找到的不同解决方案在 WebView 中播放 Youtube 视频后,一些解决方案有效但不适用于所有设备或操作系统版本,我决定思考自己的方式。
对我来说,直接在 WebView 上播放视频的解决方案即使在最后一个 Android 设备上也会产生许多伪像:Nexus 4因此,我必须找到一种方法来捕捉 Youtube iframe 上的点击,以便像 iOS 一样直接启动 Youtube 应用程序,无需任何开发人员的努力即可完美完成。
public class MyWebViewClient extends WebViewClient {
public Activity mActivity;
public MyWebViewClient(Activity activity) {
super();
mActivity = activity;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Uri uri = Uri.parse(url);
if (uri.getHost().contains("youtube.com")) {
IntentUtils.viewYoutube(mActivity, url);
return true;
}
return false;
}
public static void viewYoutube(Context context, String url) {
IntentUtils.viewWithPackageName(context, url, "com.google.android.youtube");
}
public static void viewWithPackageName(Context context, String url, String packageName) {
try {
Intent viewIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
if (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);
}
}
public static boolean isAppInstalled(Context context, String packageName) {
PackageManager packageManager = context.getPackageManager();
try {
packageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
return true;
} catch (NameNotFoundException e) {
}
return false;
}
@Override
public void onPageFinished(final WebView view, String url) {
String javascript = "javascript:" +
"var iframes = document.getElementsByTagName('iframe');" +
"for (var i = 0, l = iframes.length; i < l; i++) {" +
" var iframe = iframes[i]," +
" a = document.createElement('a');" +
" a.setAttribute('href', iframe.src);" +
" d = document.createElement('div');" +
" d.style.width = iframe.offsetWidth + 'px';" +
" d.style.height = iframe.offsetHeight + 'px';" +
" d.style.top = iframe.offsetTop + 'px';" +
" d.style.left = iframe.offsetLeft + 'px';" +
" d.style.position = 'absolute';" +
" d.style.opacity = '0';" +
" d.style.filter = 'alpha(opacity=0)';" +
" d.style.background = 'black';" +
" a.appendChild(d);" +
" iframe.offsetParent.appendChild(a);" +
"}";
view.loadUrl(javascript);
super.onPageFinished(view, url);
}
}
顺便说一句,我不得不说,我对为开发人员提供可接受的 WebView 所做的一些努力感到有点沮丧。
即使我理解避免仅基于 HTML 的 Android 应用程序的愿望,它始终是在详细信息页面上显示丰富内容的最佳/最快方式。例如,就我而言,我管理着一个基于 RSS 的应用程序,它允许我的客户自行更改内容。
此外,与 Windows Phone 开发相比,我们必须花费时间将 UI 与网络数据和保存的数据相比较,在 Windows Phone 开发中,每个数据都直接链接到 UI 组件。
关于Android webView 播放 YouTube 视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14088623/
我最近在/ drawable中添加了一些.gifs,以便可以将它们与按钮一起使用。这个工作正常(没有错误)。现在,当我重建/运行我的应用程序时,出现以下错误: Error: Gradle: Execu
Android 中有返回内部存储数据路径的方法吗? 我有 2 部 Android 智能手机(Samsung s2 和 s7 edge),我在其中安装了一个应用程序。我想使用位于这条路径中的 sqlit
这个问题在这里已经有了答案: What's the difference between "?android:" and "@android:" in an android layout xml f
我只想知道 android 开发手机、android 普通手机和 android root 手机之间的实际区别。 我们不能从实体店或除 android marketplace 以外的其他地方购买开发手
自Gradle更新以来,我正在努力使这个项目达到标准。这是一个团队项目,它使用的是android-apt插件。我已经进行了必要的语法更改(编译->实现和apt->注释处理器),但是编译器仍在告诉我存在
我是android和kotlin的新手,所以请原谅要解决的一个非常简单的问题! 我已经使用导航体系结构组件创建了一个基本应用程序,使用了底部的导航栏和三个导航选项。每个导航选项都指向一个专用片段,该片
我目前正在使用 Facebook official SDK for Android . 我现在正在使用高级示例应用程序,但我不知道如何让它获取应用程序墙/流/状态而不是登录的用户。 这可能吗?在那种情
我在下载文件时遇到问题, 我可以在模拟器中下载文件,但无法在手机上使用。我已经定义了上网和写入 SD 卡的权限。 我在服务器上有一个 doc 文件,如果用户单击下载。它下载文件。这在模拟器中工作正常但
这个问题在这里已经有了答案: What is the difference between gravity and layout_gravity in Android? (22 个答案) 关闭 9
任何人都可以告诉我什么是 android 缓存和应用程序缓存,因为当我们谈论缓存清理应用程序时,它的作用是,缓存清理概念是清理应用程序缓存还是像内存管理一样主存储、RAM、缓存是不同的并且据我所知,缓
假设应用程序 Foo 和 Eggs 在同一台 Android 设备上。任一应用程序都可以获取设备上所有应用程序的列表。一个应用程序是否有可能知道另一个应用程序是否已经运行以及运行了多长时间? 最佳答案
我有点困惑,我只看到了从 android 到 pc 或者从 android 到 pc 的例子。我需要制作一个从两部手机 (android) 连接的 android 应用程序进行视频聊天。我在想,我知道
用于使用 Android 以编程方式锁定屏幕。我从 Stackoverflow 之前关于此的问题中得到了一些好主意,并且我做得很好,但是当我运行该代码时,没有异常和错误。而且,屏幕没有锁定。请在这段代
文档说: android:layout_alignParentStart If true, makes the start edge of this view match the start edge
我不知道这两个属性和高度之间的区别。 以一个TextView为例,如果我将它的layout_width设置为wrap_content,并将它的width设置为50 dip,会发生什么情况? 最佳答案
这两个属性有什么关系?如果我有 android:noHistory="true",那么有 android:finishOnTaskLaunch="true" 有什么意义吗? 最佳答案 假设您的应用中有
我是新手,正在尝试理解以下 XML 代码: 查看 developer.android.com 上的文档,它说“starStyle”是 R.attr 中的常量, public static final
在下面的代码中,为什么当我设置时单选按钮的外观会发生变化 android:layout_width="fill_parent" 和 android:width="fill_parent" 我说的是
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
假设我有一个函数 fun myFunction(name:String, email:String){},当我调用这个函数时 myFunction('Ali', 'ali@test.com ') 如何
我是一名优秀的程序员,十分优秀!