Android webView和js交互

来源:互联网 发布:苹果软件推广 编辑:程序博客网 时间:2024/04/29 20:52
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <WebView        android:id="@+id/webview"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:layout_weight="9" /></LinearLayout>

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <!-- TODO 默认占位图 -->    <wst.webview.ZoomableImageView        android:id="@+id/show_webimage_imageview"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:scaleType="matrix"        android:src="@drawable/ic_launcher" />    <TextView        android:id="@+id/show_webimage_imagepath_textview"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:gravity="center"        android:textColor="#ffff0000" /></LinearLayout>

package wst.webview;import android.annotation.SuppressLint;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.graphics.Bitmap;import android.os.Bundle;import android.webkit.WebView;import android.webkit.WebViewClient;@SuppressLint({ "SetJavaScriptEnabled", "JavascriptInterface" })public class MainActivity extends Activity {private WebView contentWebView = null;@SuppressLint("SetJavaScriptEnabled")@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);contentWebView = (WebView) findViewById(R.id.webview);// 启用javascriptcontentWebView.getSettings().setJavaScriptEnabled(true);// 随便找了个带图片的网站contentWebView.loadUrl("http://www.sina.com.cn/");// 添加js交互接口类,并起别名 imagelistnercontentWebView.addJavascriptInterface(new scriptInterface(this), "imagelistner");contentWebView.setWebViewClient(new MyWebViewClient());}// 注入js函数监听@android.webkit.JavascriptInterfaceprivate void addImageClickListner() {// 这段js函数的功能就是,遍历所有的img几点,并添加onclick函数,在还是执行的时候调用本地接口传递url过去     contentWebView.loadUrl("javascript:(function(){" +"var objs = document.getElementsByTagName(\"img\"); " + "for(var i=0;i<objs.length;i++)  " + "{"+ "    objs[i].onclick=function()  " + "    {  " + "        window.imagelistner.openImage(this.src);  " + "    }  " + "}" + "})()");}// js通信接口 class scriptInterface {private Context context;public scriptInterface(Context context) {this.context = context;}@android.webkit.JavascriptInterfacepublic void openImage(String img) {System.out.println(img);//Intent intent = new Intent();intent.putExtra("image", img);intent.setClass(context, ShowWebImageActivity.class);context.startActivity(intent);System.out.println(img);}}// 监听private class MyWebViewClient extends WebViewClient {@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {return super.shouldOverrideUrlLoading(view, url);}@Overridepublic void onPageFinished(WebView view, String url) {view.getSettings().setJavaScriptEnabled(true);super.onPageFinished(view, url);// html加载完成之后,添加监听图片的点击js函数addImageClickListner();}@Overridepublic void onPageStarted(WebView view, String url, Bitmap favicon) {view.getSettings().setJavaScriptEnabled(true);super.onPageStarted(view, url, favicon);}@Overridepublic void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {super.onReceivedError(view, errorCode, description, failingUrl);}}}

package wst.webview;public interface OnImageTouchedListener {void onImageTouched();}

package wst.webview;import java.io.IOException;import java.io.InputStream;import java.net.MalformedURLException;import java.net.URL;import java.net.URLConnection;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.drawable.Drawable;import android.os.AsyncTask;import android.os.Bundle;import android.widget.TextView;public class ShowWebImageActivity extends Activity {private TextView imageTextView = null;private String imagePath = null;private ZoomableImageView imageView = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.show_webimage);this.imagePath = getIntent().getStringExtra("image");this.imageTextView = (TextView) findViewById(R.id.show_webimage_imagepath_textview);imageTextView.setText(this.imagePath);imageView = (ZoomableImageView) findViewById(R.id.show_webimage_imageview);//try {//imageView.setImageBitmap(((BitmapDrawable) ShowWebImageActivity.loadImageFromUrl(this.imagePath)).getBitmap());//} catch (IOException e) {//e.printStackTrace();//}LoadImageAsyncTask task = new LoadImageAsyncTask();task.setImageView(imageView); task.execute(this.imagePath); // 执行任务,参数与 doInBackground(String... params) 方法参数一致}public static Drawable loadImageFromUrl(String url) throws IOException {URL m = new URL(url);InputStream i = (InputStream) m.getContent();Drawable d = Drawable.createFromStream(i, "src");return d;}                /**     * 异步加载图片     *      */    public class LoadImageAsyncTask extends AsyncTask<String, Integer, Bitmap> {     private ZoomableImageView imageView;     @Override     protected void onPostExecute(Bitmap bitmap) {      if (null != imageView) {       imageView.setImageBitmap(bitmap);      }     }          // 设置图片视图实例     public void setImageView(ZoomableImageView image) {      this.imageView = image;     }     @Override     protected Bitmap doInBackground(String... params) {      Bitmap bitmap = GetBitmapByUrl(params[0]); // 调用前面 ApacheUtility 类的方法      return bitmap;     }    }            /**     * 获取图片流     *      * @param uri 图片地址     * @return     * @throws MalformedURLException     */    public static InputStream GetImageByUrl(String uri) throws MalformedURLException {     URL url = new URL(uri);     URLConnection conn;     InputStream is;     try {      conn = url.openConnection();      conn.connect();      is = conn.getInputStream();      // 或者用如下方法      // is=(InputStream)url.getContent();      return is;     } catch (IOException e) {      e.printStackTrace();     }     return null;    }           /**     * 获取Bitmap     *      * @param uri 图片地址     * @return     */    public static Bitmap GetBitmapByUrl(String uri) {     Bitmap bitmap;       InputStream is;     try {      is =  GetImageByUrl(uri);       bitmap = BitmapFactory.decodeStream(is);      is.close();      return bitmap;     } catch (MalformedURLException e) {      e.printStackTrace();     } catch (IOException e) {      e.printStackTrace();     }     return null;    }           /**     * 获取Drawable     *      * @param uri  图片地址     * @return     */    public static Drawable GetDrawableByUrl(String uri) {     Drawable drawable;       InputStream is;     try {      is =  GetImageByUrl(uri);       drawable= Drawable.createFromStream(is, "src");      is.close();      return drawable;     } catch (MalformedURLException e) {      e.printStackTrace();     } catch (IOException e) {      e.printStackTrace();     }     return null;    }}
package wst.webview;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.Paint;import android.os.Build;import android.os.SystemClock;import android.util.AttributeSet;import android.view.GestureDetector;import android.view.MotionEvent;import android.view.ScaleGestureDetector;import android.view.View;import android.view.animation.Animation;import android.view.animation.TranslateAnimation;@SuppressLint("NewApi")public class ZoomableImageView extends View {// Staticsstatic final float sPanRate = 7;static final float sScaleRate = 1.25F;static final int sPaintDelay = 250;static final int sAnimationDelay = 500;// This is the base transformation which is used to show the image// initially.  The current computation for this shows the image in// it's entirety, letterboxing as needed.  One could chose to// show the image as cropped instead.  //// This matrix is recomputed when we go from the thumbnail image to// the full size image.private Matrix mBaseMatrix = new Matrix();// This is the supplementary transformation which reflects what // the user has done in terms of zooming and panning.//// This matrix remains the same when we go from the thumbnail image// to the full size image.private Matrix mSuppMatrix = new Matrix();// This is the final matrix which is computed as the concatentation// of the base matrix and the supplementary matrix.private Matrix mDisplayMatrix = new Matrix();// A replacement ImageView matrixprivate Matrix mMatrix = new Matrix();// Used to filter the bitmaps when hardware acceleration is not enabledprivate Paint mPaint;// Temporary buffer used for getting the values out of a matrix.private float[] mMatrixValues = new float[9];// The current bitmap being displayed.private Bitmap mBitmap;// Dimensions for the viewprivate int mThisWidth = -1, mThisHeight = -1;// The max zoom for the view, determined programaticallyprivate float mMaxZoom;// If not null, calls setImageBitmap when onLayout is triggeredprivate Runnable mOnLayoutRunnable = null;// Stacked to the internal queue to invalidate the viewprivate Runnable mRefresh = null;// Stacked to the internal queue to scroll the viewprivate Runnable mFling = null;// The time of the last draw operationprivate double mLastDraw = 0;// Scale and gesture listeners for the viewprivate ScaleGestureDetector mScaleDetector;private GestureDetector mGestureDetector;// Single tap listenerprivate OnImageTouchedListener mImageTouchedListener;// Programatic entry pointpublic ZoomableImageView(Context context) {super(context);init( context );}// Set the single tap listenerpublic void setOnImageTouchedListener( OnImageTouchedListener listener ){this.mImageTouchedListener = listener;}// XML entry pointpublic ZoomableImageView(Context context, AttributeSet attrs) {super(context, attrs);init( context );}// Setup the viewprivate void init( Context context) {mPaint = new Paint();mPaint.setDither(true);mPaint.setFilterBitmap(true);mPaint.setAntiAlias(true);// Setup the refresh runnablemRefresh = new Runnable() {@Overridepublic void run() {postInvalidate();}};// Setup the gesture and scale listenersmScaleDetector = new ScaleGestureDetector( context, new ScaleListener() );mGestureDetector = new GestureDetector(context, new MyGestureListener());// Force hardware accelerationif( Build.VERSION.SDK_INT >=  Build.VERSION_CODES.HONEYCOMB )setLayerType(View.LAYER_TYPE_HARDWARE, null);}// Get the bitmap for the viewpublic Bitmap getImageBitmap(){return mBitmap;}// Free the bitmaps and matricespublic void clear(){if(mBitmap!=null)mBitmap = null;}// When the layout is calculated, set the @Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);mThisWidth = right - left;mThisHeight = bottom - top;Runnable r = mOnLayoutRunnable;if (r != null) {mOnLayoutRunnable = null;r.run();}if (mBitmap != null) {setBaseMatrix(mBitmap, mBaseMatrix);setImageMatrix(getImageViewMatrix());}}// Translate a given point through a given matrix.static private void translatePoint(Matrix matrix, float [] xy) {matrix.mapPoints(xy);}// Identical to the setImageMatrix method in ImageViewpublic void setImageMatrix(Matrix m){if (m != null && m.isIdentity()) {m = null;}// don't invalidate unless we're actually changing our matrixif (m == null && !this.mMatrix.isIdentity() || m != null && !this.mMatrix.equals(m)) {this.mMatrix.set(m);invalidate();}}// Sets the bitmap for the image and resets the basepublic void setImageBitmap(final Bitmap bitmap) {final int viewWidth = getWidth();if( Build.VERSION.SDK_INT >=  Build.VERSION_CODES.HONEYCOMB && bitmap!=null && bitmap.getHeight()>1800 )setLayerType(View.LAYER_TYPE_SOFTWARE, null);if (viewWidth <= 0)  {mOnLayoutRunnable = new Runnable() {public void run() {setImageBitmap(bitmap);}};return;}if (bitmap != null) {setBaseMatrix(bitmap, mBaseMatrix);this.mBitmap = bitmap;} else {mBaseMatrix.reset();this.mBitmap = bitmap;}mSuppMatrix.reset();setImageMatrix(getImageViewMatrix());mMaxZoom = maxZoom();// Set the image to fit the screenzoomTo(zoomDefault());}// Unchanged from ImageViewTouchBase// Center as much as possible in one or both axis.  Centering is// defined as follows:  if the image is scaled down below the // view's dimensions then center it (literally).  If the image// is scaled larger than the view and is translated out of view// then translate it back into view (i.e. eliminate black bars).protected void center(boolean vertical, boolean horizontal, boolean animate) {if (mBitmap == null)return;Matrix m = getImageViewMatrix();float [] topLeft  = new float[] { 0, 0 };float [] botRight = new float[] { mBitmap.getWidth(), mBitmap.getHeight() };translatePoint(m, topLeft);translatePoint(m, botRight);float height = botRight[1] - topLeft[1];float width  = botRight[0] - topLeft[0];float deltaX = 0, deltaY = 0;if (vertical) {int viewHeight = getHeight();if (height < viewHeight) {deltaY = (viewHeight - height)/2 - topLeft[1];} else if (topLeft[1] > 0) {deltaY = -topLeft[1];} else if (botRight[1] < viewHeight) {deltaY = getHeight() - botRight[1];}}if (horizontal) {int viewWidth = getWidth();if (width < viewWidth) {deltaX = (viewWidth - width)/2 - topLeft[0];} else if (topLeft[0] > 0) {deltaX = -topLeft[0];} else if (botRight[0] < viewWidth) {deltaX = viewWidth - botRight[0];}}postTranslate(deltaX, deltaY);if (animate) {Animation a = new TranslateAnimation(-deltaX, 0, -deltaY, 0);a.setStartTime(SystemClock.elapsedRealtime());a.setDuration(250);setAnimation(a);}setImageMatrix(getImageViewMatrix());}// Unchanged from ImageViewTouchBaseprotected float getValue(Matrix matrix, int whichValue) {matrix.getValues(mMatrixValues);return mMatrixValues[whichValue];}// Get the scale factor out of the matrix.protected float getScale(Matrix matrix) {// If the bitmap is set return the scaleif(mBitmap!=null)return getValue(matrix, Matrix.MSCALE_X);// Otherwise return the default value of 1elsereturn 1f;}// Returns the current scale of the view public float getScale() {return getScale(mSuppMatrix);}// Setup the base matrix so that the image is centered and scaled properly.private void setBaseMatrix(Bitmap bitmap, Matrix matrix) {float viewWidth = getWidth();float viewHeight = getHeight();matrix.reset();float widthScale = Math.min(viewWidth / (float)bitmap.getWidth(), 1.0f);float heightScale = Math.min(viewHeight / (float)bitmap.getHeight(), 1.0f);float scale;if (widthScale > heightScale) {scale = heightScale;} else {scale = widthScale;}matrix.setScale(scale, scale);matrix.postTranslate((viewWidth  - ((float)bitmap.getWidth()  * scale))/2F, (viewHeight - ((float)bitmap.getHeight() * scale))/2F);}// Combine the base matrix and the supp matrix to make the final matrix.protected Matrix getImageViewMatrix() {mDisplayMatrix.set(mBaseMatrix);mDisplayMatrix.postConcat(mSuppMatrix);return mDisplayMatrix;}// Sets the maximum zoom, which is a scale relative to the base matrix. It is calculated to show// the image at 400% zoom regardless of screen or image orientation. If in the future we decode// the full 3 megapixel image, rather than the current 1024x768, this should be changed down to// 200%.protected float maxZoom() {if (mBitmap == null)return 1F;float fw = (float) mBitmap.getWidth()  / (float)mThisWidth;float fh = (float) mBitmap.getHeight() / (float)mThisHeight;float max = Math.max(fw, fh) * 16;return max;}// Tries to make best use of the space by zooming the picturepublic float zoomDefault() {if (mBitmap == null)return 1F;float fw = (float)mThisWidth/(float)mBitmap.getWidth();float fh = (float)mThisHeight/(float)mBitmap.getHeight();return Math.max(Math.min(fw, fh),1);}// Unchanged from ImageViewTouchBaseprotected void zoomTo(float scale, float centerX, float centerY) {if (scale > mMaxZoom) {scale = mMaxZoom;}float oldScale = getScale();float deltaScale = scale / oldScale;mSuppMatrix.postScale(deltaScale, deltaScale, centerX, centerY);setImageMatrix(getImageViewMatrix());center(true, true, false);}// Unchanged from ImageViewTouchBaseprotected void zoomTo(final float scale, final float centerX, final float centerY, final float durationMs) {final float incrementPerMs = (scale - getScale()) / durationMs;final float oldScale = getScale();final long startTime = System.currentTimeMillis();// Setup the zoom runnablepost(new Runnable() {public void run() {long now = System.currentTimeMillis();float currentMs = Math.min(durationMs, (float)(now - startTime));float target = oldScale + (incrementPerMs * currentMs);zoomTo(target, centerX, centerY);if (currentMs < durationMs) {post(this);}}});}// Unchanged from ImageViewTouchBasepublic void zoomTo(float scale) {float width = getWidth();float height = getHeight();zoomTo(scale, width/2F, height/2F);}// Unchanged from ImageViewTouchBaseprotected void zoomIn() {zoomIn(sScaleRate);}// Unchanged from ImageViewTouchBaseprotected void zoomOut() {zoomOut(sScaleRate);}// Unchanged from ImageViewTouchBaseprotected void zoomIn(float rate) {if (getScale() >= mMaxZoom) {return;     // Don't let the user zoom into the molecular level.}if (mBitmap == null) {return;}float width = getWidth();float height = getHeight();mSuppMatrix.postScale(rate, rate, width/2F, height/2F);setImageMatrix(getImageViewMatrix());}// Unchanged from ImageViewTouchBaseprotected void zoomOut(float rate) {if (mBitmap == null) {return;}float width = getWidth();float height = getHeight();Matrix tmp = new Matrix(mSuppMatrix);tmp.postScale(1F/sScaleRate, 1F/sScaleRate, width/2F, height/2F);if (getScale(tmp) < 1F) {mSuppMatrix.setScale(1F, 1F, width/2F, height/2F);} else {mSuppMatrix.postScale(1F/rate, 1F/rate, width/2F, height/2F);}setImageMatrix(getImageViewMatrix());center(true, true, false);}// Unchanged from ImageViewTouchBaseprotected void postTranslate(float dx, float dy) {mSuppMatrix.postTranslate(dx, dy);}// Fling a view by a distance over timeprotected void scrollBy( float distanceX, float distanceY, final float durationMs ){final float dx = distanceX;final float dy = distanceY;final long startTime = System.currentTimeMillis();mFling = new Runnable() {float old_x= 0;float old_y= 0;public void run(){long now = System.currentTimeMillis();float currentMs = Math.min( durationMs, now - startTime );float x = easeOut( currentMs, 0, dx, durationMs );float y = easeOut( currentMs, 0, dy, durationMs );postTranslate( ( x - old_x ), ( y - old_y ) );center(true, true, false);old_x = x;old_y = y;if ( currentMs < durationMs ) {post( this );}}};post( mFling );}// Gradually slows down a fling velocityprivate float easeOut( float time, float start, float end, float duration){return end * ( ( time = time / duration - 1 ) * time * time + 1 ) + start;}// Custom draw operation to draw the bitmap using mMatrix@Overrideprotected void onDraw(Canvas canvas) {// Check if the bitmap was ever setif(mBitmap!=null && !mBitmap.isRecycled() ){// If the current version is above Gingerbread and the layer type is // hardware accelerated, the paint is no longer neededif( Build.VERSION.SDK_INT >=  Build.VERSION_CODES.HONEYCOMB && getLayerType() == View.LAYER_TYPE_HARDWARE ){canvas.drawBitmap(mBitmap, mMatrix, null);}else{// Check if the time between draws has been met and draw the bitmapif( (System.currentTimeMillis()-mLastDraw) > sPaintDelay ){canvas.drawBitmap(mBitmap, mMatrix, mPaint);mLastDraw = System.currentTimeMillis();}// Otherwise draw the bitmap without the paint and resubmit a new requestelse{canvas.drawBitmap(mBitmap, mMatrix, null);removeCallbacks(mRefresh);postDelayed(mRefresh, sPaintDelay);}}}}// Adjusts the zoom of the viewclass ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {@Overridepublic boolean onScale( ScaleGestureDetector detector ){// Check if the detector is in progress in order to proceedif(detector!=null && detector.isInProgress() ){try{// Grab the scalefloat targetScale = getScale() * detector.getScaleFactor();// Correct for the min scaletargetScale = Math.min( maxZoom(), Math.max( targetScale, 1.0f) );// Zoom and invalidate the viewzoomTo( targetScale, detector.getFocusX(), detector.getFocusY() );invalidate();return true;}catch(IllegalArgumentException e){e.printStackTrace();}}return false;}}// Handles taps and scrolls of the viewprivate class MyGestureListener extendsGestureDetector.SimpleOnGestureListener {@Overridepublic boolean onSingleTapConfirmed(MotionEvent e) {if(mImageTouchedListener!=null){mImageTouchedListener.onImageTouched();return false;}return super.onSingleTapConfirmed(e);}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {// Skip if there are multiple points of contactif ( (e1!=null&&e1.getPointerCount() > 1) || (e2!=null&&e2.getPointerCount() > 1) || (mScaleDetector!=null && mScaleDetector.isInProgress()) ) return false;// Scroll the bitmapif ( getScale() > zoomDefault() ) {removeCallbacks(mFling);postTranslate(-distanceX, -distanceY);center(true, true, false);}// Default casereturn true;}@Overridepublic boolean onDoubleTap(MotionEvent e) {// If the zoom is over 1x, reset to 1xif ( getScale() > zoomDefault() ){zoomTo(zoomDefault());}// If the zoom is default, zoom into 2xelse zoomTo(zoomDefault()*3, e.getX(), e.getY(),200);// Always true as double tap was performedreturn true;}@Overridepublic boolean onFling( MotionEvent e1, MotionEvent e2, float velocityX, float velocityY ){if ( (e1!=null&&e1.getPointerCount() > 1) || (e2!=null&&e2.getPointerCount() > 1) ) return false;if ( mScaleDetector.isInProgress() ) return false;try{float diffX = e2.getX() - e1.getX();float diffY = e2.getY() - e1.getY();if ( Math.abs( velocityX ) > 800 || Math.abs( velocityY ) > 800 ) {scrollBy( diffX / 2, diffY / 2, 300 );invalidate();}}catch(NullPointerException  e){}return super.onFling( e1, e2, velocityX, velocityY );}}@Overridepublic boolean onTouchEvent(MotionEvent event) {// If the bitmap was set, check the scale and gesture detectorsif(mBitmap!=null){// Check the scale detectormScaleDetector.onTouchEvent( event );// Check the gesture detectorif(!mScaleDetector.isInProgress())mGestureDetector.onTouchEvent( event );}// Default casereturn true;}}

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="wst.webview"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="18" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="wst.webview.MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>          <activity            android:name="wst.webview.ShowWebImageActivity"            android:configChanges="orientation"            android:label="@string/app_name"            android:screenOrientation="portrait"            android:theme="@style/Transparent" >        </activity>    </application>    <uses-permission android:name="android.permission.INTERNET" /></manifest>


0 0
原创粉丝点击