↑↓ 选择 · ↵ 打开 · 共索引 379 篇

    兼容android2.1以上flash视频播放的完美解决方案

    ARCHIVE 这篇写于 2013 年,距今 13 年多了。里面的版本、链接和做法可能都已经过时,看的时候留个心眼。

    通过androi官方文档,android是在2.1以后的版本开始支持flash视频播放的。 参见官方说明。

    既然官方都不支持了,那我们再研究flash播放器就显得毫无必要,所以我们的解决方案主要是靠android提供的WebView,可浏览网页的内置组件来播放flash。

    adobe官方关于OBJECT tag syntax说明 上面有详细的说明,我这里就不详细解释了,如果有不明白的,欢迎联系。

    了解清楚解决方案中的核心用法之后继续下一步就水到渠成了。

    主要分为以下几个步骤:

    1. 创建android项目
    2. 创建一个用于播放flash的activity
    package com.ftxgame.ftxplatform.activity;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.List;
    
    import android.annotation.SuppressLint;
    import android.app.Activity;
    import android.app.ActivityManager;
    import android.app.AlertDialog;
    import android.app.ProgressDialog;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.content.pm.PackageInfo;
    import android.content.pm.PackageManager;
    import android.os.Bundle;
    import android.os.Handler;
    import android.util.DisplayMetrics;
    import android.util.Log;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    import android.webkit.WebChromeClient;
    import android.webkit.WebSettings;
    import android.webkit.WebSettings.PluginState;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    import android.widget.FrameLayout;
    
    import com.ftxgame.ftxplatform.R;
    import com.umeng.analytics.MobclickAgent;
    
    @SuppressLint("NewApi")
    public class FTXVideoActivity extends Activity {
    	
    	private FrameLayout mFullscreenLayout;
    	private FrameLayout mContentLayout;
    	
    	private String mUrl;
    	private View mCustomView = null;
    	private WebView mWebView;
    	private Intent intent;
    	private boolean hasAdobePlayer = false;// ADOBE FLASH PLAYER插件安装状态
    	private Context mContext;
    	private ProgressDialog mProgressDialog;
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		// 隐藏标题栏
    		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    		// 隐藏状态栏
    		this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
    				WindowManager.LayoutParams.FLAG_FULLSCREEN);
    
    		initView();
    		initWebView();
    		
    		DisplayMetrics dm = this.getResources().getDisplayMetrics();
    		int widthScreen = dm.widthPixels/2;
    		int heightScreen = dm.heightPixels/2;
    
    		if (onCheck() == true) {
    			StringBuilder html = new StringBuilder(1000);
    			html.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />")
    			.append("<style type='text/css'>")
    			.append("html,body{margin:0px;padding:0px;}")
    			.append("*{margin:0px;padding:0px;}</style>")
    			.append("</head><body>")
    			
    			.append("<object width=\""+widthScreen+"\" height=\""+heightScreen+"\" type=\"application/x-shockwave-flash\" name=\"qzshareFlash\" id=\"qzshareFlash\" data=\""+mUrl+"\" class=\"video_play\">")
    			.append("<param name=\"movie\" value=\""+mUrl+"\">")
    			.append("<param value=\"always\" name=\"allowScriptAccess\">")
    			.append("<param value=\"all\" name=\"allowNetworking\">")
    			.append("<param value=\"true\" name=\"allowFullScreen\">")
    			.append("<param value=\"opaque\" name=\"wmode\">")
    			.append("</object></body></html>");
    			showProgress();
    			mWebView.loadData(html.toString(), "text/html", "UTF-8");
    		} else {
    			new AlertDialog.Builder(this)
    					.setIcon(R.drawable.ic_launcher)
    					.setTitle("温馨提醒:")
    					.setMessage("Flash Player未安装或版本过低,请下载安装新版本后重试~")
    					.setPositiveButton("重试",
    							new DialogInterface.OnClickListener() {
    
    								@Override
    								public void onClick(DialogInterface dialog,
    										int which) {
    									intent.setClass(FTXVideoActivity.this,
    											FTXVideoActivity.class);
    									startActivity(intent);
    								}
    							})
    					.setNegativeButton("退出",
    							new DialogInterface.OnClickListener() {
    
    								@Override
    								public void onClick(DialogInterface dialog,
    										int which) {
    									ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    									am.restartPackage(getPackageName());
    									intent.setClass(FTXVideoActivity.this,
    											FTXVideoActivity.class);
    									Intent i = new Intent(Intent.ACTION_MAIN);
    									i.addCategory(Intent.CATEGORY_HOME);
    									intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    									startActivity(intent);
    									startActivity(i);
    								}
    							}).show();
    		}
    	}
    	
    	private void initView() {
    		setContentView(R.layout.videoview);
    		mContext = FTXVideoActivity.this;
    		mFullscreenLayout = (FrameLayout) findViewById(R.id.fullscreen_custom_content);
    		mContentLayout = (FrameLayout) findViewById(R.id.main_content);
    		mWebView = (WebView) findViewById(R.id.video_view);
    
    		if (getPhoneAndroidSDK() >= 14) {// 4.0需打开硬件加速
    			getWindow().setFlags(0x1000000, 0x1000000);
    		}
    		
    		intent = getIntent();
    		mUrl = intent.getStringExtra("videoUrl");
    	}
    	
    	/**
    	 * WebView相关设置
    	 */
    	private void initWebView() {
    		WebSettings settings = mWebView.getSettings();
    		settings.setJavaScriptEnabled(true);
    		settings.setJavaScriptCanOpenWindowsAutomatically(true);
    		settings.setPluginState(PluginState.ON);
    		settings.setPluginsEnabled(true);
    		settings.setAllowFileAccess(true);
    		settings.setLoadWithOverviewMode(true);
    
    		mWebView.setWebChromeClient(new MyWebChromeClient());
    		mWebView.setWebViewClient(new MyWebViewClient());
    	}
    
    	public static int getPhoneAndroidSDK() {
    		int version = 0;
    		try {
    			version = Integer.valueOf(android.os.Build.VERSION.SDK);
    		} catch (NumberFormatException e) {
    			e.printStackTrace();
    		}
    		return version;
    	}
    
    	/**
    	 * 判断是否安装ADOBE FLASH PLAYER插件
    	 * 
    	 * @return
    	 */
    	public boolean onCheck() {
    		// 判断是否安装ADOBE FLASH PLAYER插件
    		PackageManager pm = getPackageManager();
    		List<PackageInfo> lsPackageInfo = pm.getInstalledPackages(0);
    
    		for (PackageInfo pi : lsPackageInfo) {
    			if (pi.packageName.contains("com.adobe.flashplayer")) {
    				hasAdobePlayer = true;
    				break;
    			}
    		}
    		// 如果插件安装一切正常
    		if (hasAdobePlayer == true) {
    			return true;
    		} else {
    			return false;
    		}
    	}
    	
    	private void showProgress() {
    		if(mProgressDialog == null){
    			mProgressDialog = ProgressDialog.show(mContext, null, mContext.getString(R.string.loading));
    		}else if(!mProgressDialog.isShowing()){
    			mProgressDialog.show();
    		}
    	}
    	
    	private void hideProgress() {
    			if (mProgressDialog != null && mProgressDialog.isShowing()) {
    				mProgressDialog.dismiss();
    			}
    	}
    
    	private void callHiddenWebViewMethod(String name) {
    		if (mWebView != null) {
    			try {
    				Method method = WebView.class.getMethod(name);
    				method.invoke(mWebView);
    			} catch (NoSuchMethodException e) {
    				Log.i("No such method: " + name, e.toString());
    			} catch (IllegalAccessException e) {
    				Log.i("Illegal Access: " + name, e.toString());
    			} catch (InvocationTargetException e) {
    				Log.d("Invocation Target Exception: " + name, e.toString());
    			}
    		}
    	}
    	
    	class MyWebChromeClient extends WebChromeClient {
    		
    		private CustomViewCallback mCustomViewCallback;
    		private int mOriginalOrientation = 1;
    		
    		@Override
    		public void onShowCustomView(View view, CustomViewCallback callback) {
    			Log.i("FTXVideoActivity", "onShowCustomView");
    			onShowCustomView(view, mOriginalOrientation, callback);
    			super.onShowCustomView(view, callback);
    		}
    	
    		public void onShowCustomView(View view, int requestedOrientation,
    				WebChromeClient.CustomViewCallback callback) {
    			if (mCustomView != null) {
    				callback.onCustomViewHidden();
    				return;
    			}
    			Log.i("FTXVideoActivity", mOriginalOrientation+"");
    			if (getPhoneAndroidSDK() >= 14) {
    				mFullscreenLayout.addView(view);
    				mCustomView = view;
    				mCustomViewCallback = callback;
    				mOriginalOrientation = getRequestedOrientation();
    				mContentLayout.setVisibility(View.INVISIBLE);
    				mFullscreenLayout.setVisibility(View.VISIBLE);
    				mFullscreenLayout.bringToFront();
    	
    				setRequestedOrientation(mOriginalOrientation);
    			}
    			Log.i("FTXVideoActivity", mOriginalOrientation+"");
    		}
    	
    		public void onHideCustomView() {
    			Log.i("FTXVideoActivity", "onHideCustomView");
    			mContentLayout.setVisibility(View.VISIBLE);
    			if (mCustomView == null) {
    				return;
    			}
    			mCustomView.setVisibility(View.GONE);
    			mFullscreenLayout.removeView(mCustomView);
    			mCustomView = null;
    			mFullscreenLayout.setVisibility(View.GONE);
    			try {
    				mCustomViewCallback.onCustomViewHidden();
    			} catch (Exception e) {
    				Log.e("FTXVideoActivity", e.getMessage());
    			}
    			// Show the content view.
    			setRequestedOrientation(mOriginalOrientation);
    		}
    		
    		@Override
    		public void onProgressChanged(WebView view, int newProgress) {
    			super.onProgressChanged(view, newProgress);
    			if(100 == newProgress) {				
    				hideProgress();
    			}
    		}
    	
    	}
    	
    	class MyWebViewClient extends WebViewClient {
    	
    		@Override
    		public boolean shouldOverrideUrlLoading(WebView view, String url) {
    			view.loadUrl(url);
    			Log.i("FTXVideoActivity", "shouldOverrideUrlLoading");
    			return super.shouldOverrideUrlLoading(view, url);
    		}
    		
    		@Override
    		public void onPageFinished(WebView view, String url) {
    			super.onPageFinished(view, url);
    			hideProgress();
    			Log.i("FTXVideoActivity", "onPageFinished");
    		}
    	}
    }
    
    1. 创建layout.xml
    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    
        <FrameLayout  
           android:id="@+id/fullscreen_custom_content"  
           android:layout_width="match_parent"  
           android:layout_height="match_parent"  
           android:visibility="gone" />
        
        <FrameLayout
           android:id="@+id/main_content"  
           android:layout_width="match_parent"  
           android:layout_height="match_parent">  
    	    <WebView
    	        android:id="@+id/video_view"
    	        android:layout_width="fill_parent"
    	        android:layout_height="fill_parent" />
        </FrameLayout>
    </FrameLayout>
    

    一个兼容android2.1以上系统的flash播放解决方案就完成了。

    后面经过我的全面兼容性测试,可能会有以下问题:

    1. android系统自身已经安装adobe flash player 11或之前版本,在android4.1之前的老系统上可能是正常的,但是在新系统上会存在问题,或许还包括4.0系统,因为资源问题,我就无法测试到位,希望有朋友能给我测试的反馈。
    2. android4.0以上系统全屏支持不够好,android2.3.5基本上可以说是完美播放。
    3. android2.2系统是不支持flash11.1的,所以我们在提示播放的时候要安装对应的版本。