Android webView和js互動
阿新 • • 發佈:2019-01-02
<?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") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); contentWebView = (WebView) findViewById(R.id.webview); // 啟用javascript contentWebView.getSettings().setJavaScriptEnabled(true); // 隨便找了個帶圖片的網站 contentWebView.loadUrl("http://www.sina.com.cn/"); // 新增js互動介面類,並起別名 imagelistner contentWebView.addJavascriptInterface(new scriptInterface(this), "imagelistner"); contentWebView.setWebViewClient(new MyWebViewClient()); } // 注入js函式監聽 @android.webkit.JavascriptInterface private 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.JavascriptInterface public 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 { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { return super.shouldOverrideUrlLoading(view, url); } @Override public void onPageFinished(WebView view, String url) { view.getSettings().setJavaScriptEnabled(true); super.onPageFinished(view, url); // html載入完成之後,新增監聽圖片的點選js函式 addImageClickListner(); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { view.getSettings().setJavaScriptEnabled(true); super.onPageStarted(view, url, favicon); } @Override public 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;
@Override
protected 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 {
// Statics
static 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 matrix
private Matrix mMatrix = new Matrix();
// Used to filter the bitmaps when hardware acceleration is not enabled
private 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 view
private int mThisWidth = -1, mThisHeight = -1;
// The max zoom for the view, determined programatically
private float mMaxZoom;
// If not null, calls setImageBitmap when onLayout is triggered
private Runnable mOnLayoutRunnable = null;
// Stacked to the internal queue to invalidate the view
private Runnable mRefresh = null;
// Stacked to the internal queue to scroll the view
private Runnable mFling = null;
// The time of the last draw operation
private double mLastDraw = 0;
// Scale and gesture listeners for the view
private ScaleGestureDetector mScaleDetector;
private GestureDetector mGestureDetector;
// Single tap listener
private OnImageTouchedListener mImageTouchedListener;
// Programatic entry point
public ZoomableImageView(Context context) {
super(context);
init( context );
}
// Set the single tap listener
public void setOnImageTouchedListener( OnImageTouchedListener listener ){
this.mImageTouchedListener = listener;
}
// XML entry point
public ZoomableImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init( context );
}
// Setup the view
private void init( Context context) {
mPaint = new Paint();
mPaint.setDither(true);
mPaint.setFilterBitmap(true);
mPaint.setAntiAlias(true);
// Setup the refresh runnable
mRefresh = new Runnable() {
@Override
public void run() {
postInvalidate();
}
};
// Setup the gesture and scale listeners
mScaleDetector = new ScaleGestureDetector( context, new ScaleListener() );
mGestureDetector = new GestureDetector(context, new MyGestureListener());
// Force hardware acceleration
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB )
setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
// Get the bitmap for the view
public Bitmap getImageBitmap(){
return mBitmap;
}
// Free the bitmaps and matrices
public void clear(){
if(mBitmap!=null)
mBitmap = null;
}
// When the layout is calculated, set the
@Override
protected 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 ImageView
public void setImageMatrix(Matrix m){
if (m != null && m.isIdentity()) {
m = null;
}
// don't invalidate unless we're actually changing our matrix
if (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 base
public 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 screen
zoomTo(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 ImageViewTouchBase
protected 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 scale
if(mBitmap!=null)
return getValue(matrix, Matrix.MSCALE_X);
// Otherwise return the default value of 1
else
return 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 picture
public 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 ImageViewTouchBase
protected 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 ImageViewTouchBase
protected 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 runnable
post(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 ImageViewTouchBase
public void zoomTo(float scale) {
float width = getWidth();
float height = getHeight();
zoomTo(scale, width/2F, height/2F);
}
// Unchanged from ImageViewTouchBase
protected void zoomIn() {
zoomIn(sScaleRate);
}
// Unchanged from ImageViewTouchBase
protected void zoomOut() {
zoomOut(sScaleRate);
}
// Unchanged from ImageViewTouchBase
protected 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 ImageViewTouchBase
protected 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 ImageViewTouchBase
protected void postTranslate(float dx, float dy) {
mSuppMatrix.postTranslate(dx, dy);
}
// Fling a view by a distance over time
protected 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 velocity
private 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
@Override
protected void onDraw(Canvas canvas) {
// Check if the bitmap was ever set
if(mBitmap!=null && !mBitmap.isRecycled() ){
// If the current version is above Gingerbread and the layer type is
// hardware accelerated, the paint is no longer needed
if( 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 bitmap
if( (System.currentTimeMillis()-mLastDraw) > sPaintDelay ){
canvas.drawBitmap(mBitmap, mMatrix, mPaint);
mLastDraw = System.currentTimeMillis();
}
// Otherwise draw the bitmap without the paint and resubmit a new request
else{
canvas.drawBitmap(mBitmap, mMatrix, null);
removeCallbacks(mRefresh);
postDelayed(mRefresh, sPaintDelay);
}
}
}
}
// Adjusts the zoom of the view
class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale( ScaleGestureDetector detector )
{
// Check if the detector is in progress in order to proceed
if(detector!=null && detector.isInProgress() ){
try{
// Grab the scale
float targetScale = getScale() * detector.getScaleFactor();
// Correct for the min scale
targetScale = Math.min( maxZoom(), Math.max( targetScale, 1.0f) );
// Zoom and invalidate the view
zoomTo( targetScale, detector.getFocusX(), detector.getFocusY() );
invalidate();
return true;
}catch(IllegalArgumentException e){
e.printStackTrace();
}
}
return false;
}
}
// Handles taps and scrolls of the view
private class MyGestureListener extends
GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if(mImageTouchedListener!=null){
mImageTouchedListener.onImageTouched();
return false;
}
return super.onSingleTapConfirmed(e);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
// Skip if there are multiple points of contact
if ( (e1!=null&&e1.getPointerCount() > 1) || (e2!=null&&e2.getPointerCount() > 1) || (mScaleDetector!=null && mScaleDetector.isInProgress()) )
return false;
// Scroll the bitmap
if ( getScale() > zoomDefault() ) {
removeCallbacks(mFling);
postTranslate(-distanceX, -distanceY);
center(true, true, false);
}
// Default case
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
// If the zoom is over 1x, reset to 1x
if ( getScale() > zoomDefault() ){
zoomTo(zoomDefault());
}
// If the zoom is default, zoom into 2x
else
zoomTo(zoomDefault()*3, e.getX(), e.getY(),200);
// Always true as double tap was performed
return true;
}
@Override
public 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 );
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// If the bitmap was set, check the scale and gesture detectors
if(mBitmap!=null){
// Check the scale detector
mScaleDetector.onTouchEvent( event );
// Check the gesture detector
if(!mScaleDetector.isInProgress())
mGestureDetector.onTouchEvent( event );
}
// Default case
return 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>