diff options
author | Jeff Sharkey <jsharkey@android.com> | 2014-11-15 16:38:15 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-11-15 16:38:15 +0000 |
commit | 515761c04150f40b68403d5dc02017325be520c1 (patch) | |
tree | 8f4df22a224d91fe4c7684ba2fa7d83d80e553d9 | |
parent | f611ca4b9580c624b91d006920dd4485dde30250 (diff) | |
parent | c9cd4b66263697ddc227b012d96a90ead8d21d92 (diff) | |
download | HTMLViewer-515761c04150f40b68403d5dc02017325be520c1.tar.gz |
am c9cd4b66: Modernize HTMLViewer, offer to decompress.
* commit 'c9cd4b66263697ddc227b012d96a90ead8d21d92':
Modernize HTMLViewer, offer to decompress.
-rw-r--r-- | AndroidManifest.xml | 17 | ||||
-rw-r--r-- | res/layout/main.xml | 35 | ||||
-rw-r--r-- | src/com/android/htmlviewer/FileContentProvider.java | 94 | ||||
-rw-r--r-- | src/com/android/htmlviewer/HTMLViewerActivity.java | 133 |
4 files changed, 88 insertions, 191 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 315a958..9a2ccd0 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -19,12 +19,14 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.htmlviewer"> - <original-package android:name="com.android.htmlviewer" /> + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + <application android:label="@string/app_label"> - <activity android:name="HTMLViewerActivity" android:label="HTMLViewer" - android:theme="@android:style/Theme.Holo" > + <activity android:name="HTMLViewerActivity" + android:label="@string/app_label" + android:theme="@android:style/Theme.DeviceDefault"> <intent-filter> <category android:name="android.intent.category.DEFAULT" /> <action android:name="android.intent.action.VIEW" /> @@ -36,14 +38,5 @@ <data android:mimeType="application/vnd.wap.xhtml+xml"/> </intent-filter> </activity> - - <provider android:name="FileContentProvider" - android:exported="false" - android:authorities="com.android.htmlfileprovider" - android:syncable="false" android:multiprocess="false" - android:grantUriPermissions="true" /> - </application> - </manifest> - diff --git a/res/layout/main.xml b/res/layout/main.xml new file mode 100644 index 0000000..8a9f48a --- /dev/null +++ b/res/layout/main.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@*android:color/white"> + + <WebView + android:id="@+id/webview" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + <ProgressBar + android:id="@+id/loading" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:indeterminate="true" + style="?android:attr/progressBarStyle" /> + +</FrameLayout> diff --git a/src/com/android/htmlviewer/FileContentProvider.java b/src/com/android/htmlviewer/FileContentProvider.java deleted file mode 100644 index 4cf16a6..0000000 --- a/src/com/android/htmlviewer/FileContentProvider.java +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package com.android.htmlviewer; - -import java.io.FileNotFoundException; -import java.io.File; -import java.lang.UnsupportedOperationException; - -import android.content.ContentProvider; -import android.content.ContentValues; -import android.database.Cursor; -import android.net.Uri; -import android.os.Binder; -import android.os.ParcelFileDescriptor; -import android.os.Process; - -/** - * WebView does not support file: loading. This class wraps a file load - * with a content provider. - * As HTMLViewer does not have internet access nor does it allow - * Javascript to be run, it is safe to load file based HTML content. -*/ -public class FileContentProvider extends ContentProvider { - - public static final String BASE_URI = - "content://com.android.htmlfileprovider"; - - @Override - public String getType(Uri uri) { - // If the mimetype is not appended to the uri, then return an empty string - String mimetype = uri.getQuery(); - return mimetype == null ? "" : mimetype; - } - - @Override - public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { - // android:exported="false" is broken in older releases so we have to - // manually enforce the calling identity. - if (Process.myUid() != Binder.getCallingUid()) { - throw new SecurityException("Permission denied"); - } - if (!"r".equals(mode)) { - throw new FileNotFoundException("Bad mode for " + uri + ": " + mode); - } - String filename = uri.getPath(); - File f = new File(filename); - if (f.isDirectory()) { - return null; - } - return ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY); - } - - @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { - throw new UnsupportedOperationException(); - } - - @Override - public Uri insert(Uri uri, ContentValues values) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean onCreate() { - return true; - } - - @Override - public Cursor query(Uri uri, String[] projection, String selection, - String[] selectionArgs, String sortOrder) { - throw new UnsupportedOperationException(); - } - - @Override - public int update(Uri uri, ContentValues values, String selection, - String[] selectionArgs) { - throw new UnsupportedOperationException(); - } - -} diff --git a/src/com/android/htmlviewer/HTMLViewerActivity.java b/src/com/android/htmlviewer/HTMLViewerActivity.java index d4f4f73..0de772d 100644 --- a/src/com/android/htmlviewer/HTMLViewerActivity.java +++ b/src/com/android/htmlviewer/HTMLViewerActivity.java @@ -17,73 +17,49 @@ package com.android.htmlviewer; import android.app.Activity; +import android.content.ContentResolver; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.util.Log; -import android.view.Window; -import android.webkit.CookieSyncManager; +import android.view.View; import android.webkit.WebChromeClient; +import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; import android.webkit.WebSettings; import android.webkit.WebView; +import android.webkit.WebViewClient; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.util.zip.GZIPInputStream; /** - * Wraps a WebView widget within an Activity. When launched, it uses the - * URI from the intent as the URL to load into the WebView. - * It supports all URLs schemes that a standard WebView supports, as well as - * loading the top level markup using the file scheme. - * The WebView default settings are used with the exception of normal layout - * is set. - * This activity shows a loading progress bar in the window title and sets - * the window title to the title of the content. - * + * Simple activity that shows the requested HTML page. This utility is + * purposefully very limited in what it supports, including no network or + * JavaScript. */ public class HTMLViewerActivity extends Activity { + private static final String TAG = "HTMLViewer"; - /* - * The WebView that is placed in this Activity - */ private WebView mWebView; - - /* - * As the file content is loaded completely into RAM first, set - * a limitation on the file size so we don't use too much RAM. If someone - * wants to load content that is larger than this, then a content - * provider should be used. - */ - static final int MAXFILESIZE = 8096; - - static final String LOGTAG = "HTMLViewerActivity"; + private View mLoading; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // Call createInstance() explicitly. createInstance() is called in - // BrowserFrame by WebView. As it is called in WebCore thread, it can - // happen after onResume() is called. To use getInstance() in onResume, - // createInstance() needs to be called first. - CookieSyncManager.createInstance(this); + setContentView(R.layout.main); - requestWindowFeature(Window.FEATURE_PROGRESS); + mWebView = (WebView) findViewById(R.id.webview); + mLoading = findViewById(R.id.loading); - mWebView = new WebView(this); - setContentView(mWebView); + mWebView.setWebChromeClient(new ChromeClient()); + mWebView.setWebViewClient(new ViewClient()); - // Setup callback support for title and progress bar - mWebView.setWebChromeClient( new WebChrome() ); - - // Configure the webview WebSettings s = mWebView.getSettings(); s.setUseWideViewPort(true); s.setSupportZoom(true); - s.setBuiltInZoomControls(true); s.setSavePassword(false); s.setSaveFormData(false); s.setBlockNetworkLoads(true); @@ -91,46 +67,14 @@ public class HTMLViewerActivity extends Activity { // Javascript is purposely disabled, so that nothing can be // automatically run. s.setJavaScriptEnabled(false); - s.setDefaultTextEncodingName("utf-8"); - // Restore a webview if we are meant to restore - if (savedInstanceState != null) { - mWebView.restoreState(savedInstanceState); - } else { - // Check the intent for the content to view - Intent intent = getIntent(); - if (intent.getData() != null) { - Uri uri = intent.getData(); - String contentUri = "file".equals(uri.getScheme()) - ? FileContentProvider.BASE_URI + uri.getEncodedPath() - : uri.toString(); - mWebView.loadUrl(contentUri); - } + final Intent intent = getIntent(); + if (intent.hasExtra(Intent.EXTRA_TITLE)) { + setTitle(intent.getStringExtra(Intent.EXTRA_TITLE)); } - } - - @Override - protected void onResume() { - super.onResume(); - CookieSyncManager.getInstance().startSync(); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - // the default implementation requires each view to have an id. As the - // browser handles the state itself and it doesn't use id for the views, - // don't call the default implementation. Otherwise it will trigger the - // warning like this, "couldn't save which view has focus because the - // focused view XXX has no id". - mWebView.saveState(outState); - } - - @Override - protected void onStop() { - super.onStop(); - CookieSyncManager.getInstance().stopSync(); + mWebView.loadUrl(String.valueOf(intent.getData())); } @Override @@ -139,21 +83,40 @@ public class HTMLViewerActivity extends Activity { mWebView.destroy(); } - class WebChrome extends WebChromeClient { - + private class ChromeClient extends WebChromeClient { @Override public void onReceivedTitle(WebView view, String title) { - HTMLViewerActivity.this.setTitle(title); + if (!getIntent().hasExtra(Intent.EXTRA_TITLE)) { + HTMLViewerActivity.this.setTitle(title); + } } + } + private class ViewClient extends WebViewClient { @Override - public void onProgressChanged(WebView view, int newProgress) { - getWindow().setFeatureInt( - Window.FEATURE_PROGRESS, newProgress*100); - if (newProgress == 100) { - CookieSyncManager.getInstance().sync(); + public void onPageFinished(WebView view, String url) { + mLoading.setVisibility(View.GONE); + } + + @Override + public WebResourceResponse shouldInterceptRequest(WebView view, + WebResourceRequest request) { + final Uri uri = request.getUrl(); + if (ContentResolver.SCHEME_FILE.equals(uri.getScheme()) + && uri.getPath().endsWith(".gz")) { + Log.d(TAG, "Trying to decompress " + uri + " on the fly"); + try { + final InputStream in = new GZIPInputStream( + getContentResolver().openInputStream(uri)); + final WebResourceResponse resp = new WebResourceResponse( + getIntent().getType(), "utf-8", in); + resp.setStatusCodeAndReasonPhrase(200, "OK"); + return resp; + } catch (IOException e) { + Log.w(TAG, "Failed to decompress; falling back", e); + } } + return null; } } - } |