Trying to make WebView based app launcher/drawer for a kiosk application. Idea is you do not need to know Android to launch apps, just how to build intent links. Been through several iterations and answers and can't quite get this right. Target is Android 10.
Currently the intent test links work fine from Chrome, but fail to launch for the WebView. I believe the issue is with resolving the activity from the package manager?
WebView Window Class
public class Window {
private Context context;
private View mView;
private WindowManager.LayoutParams mParams;
private WindowManager mWindowManager;
private LayoutInflater layoutInflater;
public Window(Context context){
this.context=context;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
}
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mView = layoutInflater.inflate(R.layout.popup_window, null);
mParams.gravity = Gravity.CENTER;
mWindowManager = (WindowManager)context.getSystemService(WINDOW_SERVICE);
//setup webview
WebView myWebView = (WebView) mView.findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
myWebView.setBackgroundColor(Color.argb(1, 255, 255, 255));
webSettings.setJavaScriptEnabled(true);
//create webviewclient
myWebView.setWebViewClient(new WebViewClient() {
#SuppressWarnings("deprecation")
public boolean shouldOverrideUrlLoading(WebView view, String url) {
final Uri uri = Uri.parse(url);
return handleUri(view, uri);
}
#TargetApi(Build.VERSION_CODES.N)
#Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
final Uri uri = request.getUrl();
return handleUri(view, uri);
}
private boolean handleUri(WebView view, Uri uri) {
final String url = String.valueOf(uri);
if (url.startsWith("intent://")) {
try {
Context context = view.getContext();
Intent intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
//intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.addFlags(Intent.FLAG_ACTIVITY_REQUIRE_NON_BROWSER);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (intent != null) {
view.stopLoading();
PackageManager packageManager = context.getPackageManager();
ResolveInfo info = packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
context.startActivity(intent);
if (info != null) {
context.startActivity(intent);
} else {
String fallbackUrl = intent.getStringExtra("browser_fallback_url");
view.loadUrl(fallbackUrl);
}
return true;
}
} catch (URISyntaxException e) {
Log.e(TAG, "Can't resolve intent://", e);
}
}
return false;
}
});
myWebView.loadUrl("file:///android_asset/index.html");
};
public void open() {
try {
if(mView.getWindowToken()==null) {
if(mView.getParent()==null) {
mWindowManager.addView(mView, mParams);
}
}
} catch (Exception e) {
Log.d("Error1",e.toString());
}
}
public void close() {
try {
((WindowManager)context.getSystemService(WINDOW_SERVICE)).removeView(mView);
mView.invalidate();
((ViewGroup)mView.getParent()).removeAllViews();
} catch (Exception e) {
Log.d("Error2",e.toString());
}
}
}
Barebones test HTML file
<!DOCTYPE html> <html>
<body>
<button>
Slack
</button>
<button>
Zoom
</button>
<button>
Zoom Room
</button>
</body> </html>
I am also not keen on checking for the existence of intents:// since Slack for example eschews that and instead wants you to use slack://open. Is there a documented way to emulate opening these kinds of links from a Webview like Chrome does?
Related
I am a beginner in making android applications. I have made a web application in HTML which i want to be able to use in my application that I am making in android studio. I managed to make a simple web view in android studio which makes my web application work fine when i test it on my device. The only problem is that the web view handles all the URLĀ“s inside my web application. The web application consists of tabs that directs me to different pages when i click on them which is what i want. But I have contact-buttons and different links that i want to be "released" from the web view. Lets take the contact button as an example. I have a Galaxy note which I am using to test my apps. When i open my application on my phone i see my Web application and i can navigate around. When i click the contact button, the web view handles the link and gives me a "page could not load" instead of opening the mail application on my phone. I also have buttons with links that I want to be able to open in an external browser on my phone. I hope you understand my problem and I am sorry for my bad english.
This is some of my code for the web view.
Mainactivity.java
public class MainActivity extends ActionBarActivity {
WebView browser;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
browser = (WebView) findViewById(R.id.wvwMain);
browser.getSettings().setJavaScriptEnabled(true);
browser.getSettings().setLoadWithOverviewMode(true);
browser.getSettings().setUseWideViewPort(true);
browser.setWebViewClient(new ourViewClient());
try {
browser.loadUrl("http://WebAppURL");
} catch (Exception e) {
e.printStackTrace();
}
}
OurViewClient.java
public class ourViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
Try this way implement your WebViewClient like
private class VideoWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
try{
System.out.println("url called:::" + url);
if (url.startsWith("tel:")) {
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
startActivity(intent);
} else if (url.startsWith("http:")
|| url.startsWith("https:")) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
} else if (url.startsWith("mailto:")) {
MailTo mt=MailTo.parse(url);
send_email(mt.getTo());
}
else {
return false;
}
}catch(Exception e){
e.printStackTrace();
}
return true;
}
}
and create send mail function like
public void send_email(String email_add) {
System.out.println("Email address::::" + email_add);
final Intent emailIntent = new Intent(
android.content.Intent.ACTION_SEND);
emailIntent.setType("plain/text");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
new String[] { email_add });
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "");
yourActivity.this.startActivity(
Intent.createChooser(emailIntent, "Send mail..."));
}
My Code Working Good, just Remember the code line Sequence and placement.. Copy and paste code in your mainactivity.java file
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mywebView = findViewById(R.id.myview);
WebSettings webSettings = mywebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mywebView.loadUrl("http://yourwebsitename.com");
mywebView.setWebViewClient(new MyCustomWebViewClient());
}
class MyCustomWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (Uri.parse(url).getHost().equals("yourwebsitename.com")) {
//open url contents in webview
return false;
} else {
//here open external links in external browser or app
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
}
}
}
I make webview application. i want open both urls "rtsp://" and "market://" in default video player and play store.
i use this code. but problem is "market://" url open in play store correctly but rtsp link not open in default video player. error says page not found.
public class MainActivity extends Activity {
//private Button button;
private WebView webView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webView1);
startWebView("http://google.com");
this.webView.setWebViewClient(new WebViewClient());
this.webView.setDownloadListener(new DownloadListener()
{
public void onDownloadStart(String paramAnonymousString1, String paramAnonymousString2, String paramAnonymousString3, String paramAnonymousString4, long paramAnonymousLong)
{
Intent localIntent = new Intent("android.intent.action.VIEW", Uri.parse(paramAnonymousString1));
MainActivity.this.startActivity(localIntent);
}
});
this.webView.setWebViewClient(new WebViewClient()
{
public boolean shouldOverrideUrlLoading(WebView paramAnonymousWebView, String paramAnonymousString)
{
if (paramAnonymousString.startsWith("rtsp"))
{
Intent localIntent = new Intent("android.intent.action.VIEW", Uri.parse(paramAnonymousString));
MainActivity.this.startActivity(localIntent);
return true;
}
return super.shouldOverrideUrlLoading(paramAnonymousWebView, paramAnonymousString);
}
});
this.webView.setWebViewClient(new WebViewClient()
{
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (Uri.parse(url).getScheme().equals("market")) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
Activity host = (Activity) view.getContext();
host.startActivity(intent);
return true;
} catch (ActivityNotFoundException e) {
// Google Play app is not installed, you may want to open the app store link
Uri uri = Uri.parse(url);
view.loadUrl("http://play.google.com/store/apps/" + uri.getHost() + "?" + uri.getQuery());
return false;
}
}
return false;
}
});
}
This question already has answers here:
Save webview content for offline browsing?
(2 answers)
Closed 8 years ago.
How to show web page even if internet is not connected? And if internet is connected than website should be loaded on webview
..
I am new for android and i needed an app. i checked over internet and created app.
my dashboard code is :
public class Dashboard extends Activity {
public String BASE_URL = "http://mywebsite.com/";
public String DASHBOARD_URL = BASE_URL;
private JavascriptInterface jsInterface;
#SuppressLint("SetJavaScriptEnabled")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
WebView engine = (WebView) findViewById(R.id.web_engine);
// Progress bar.
// With full screen app, window progress bar (FEATURE_PROGRESS) doesn't seem to show,
// so we use an explicitly created one.
final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressbar);
engine.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress)
{
progressBar.setProgress(progress);
}
});
engine.setWebViewClient(new FixedWebViewClient() {
public void onPageStarted(WebView view, String url, Bitmap favicon)
{
jsInterface.enablePreferencesMenu = false;
jsInterface.modalIsVisible = false;
jsInterface.urlForSharing = null;
progressBar.setVisibility(View.VISIBLE);
}
public void onPageFinished(WebView view, String url)
{
progressBar.setVisibility(View.GONE);
}
});
engine.getSettings().setJavaScriptEnabled(true);
jsInterface = new JavascriptInterface();
try {
ComponentName comp = new ComponentName(this, Dashboard.class);
PackageInfo pinfo = getPackageManager().getPackageInfo(comp.getPackageName(), 0);
jsInterface.versionCode = pinfo.versionCode;
} catch(android.content.pm.PackageManager.NameNotFoundException e) {
}
engine.addJavascriptInterface(jsInterface, "Title");
engine.loadUrl(BASE_URL);
}
private WebView getEngine() {
return (WebView) findViewById(R.id.web_engine);
}
public void onBackPressed() {
WebView engine = getEngine();
String url = engine.getUrl();
if (jsInterface.modalIsVisible) {
engine.loadUrl("javascript: android.hideModal();");
} else if (url != null && (
url.equals(BASE_URL) ||
url.equals(DASHBOARD_URL) ||
!engine.canGoBack())) {
// exit
super.onBackPressed();
} else {
// go back a page, like normal browser
engine.goBack();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem prefs = menu.findItem(R.id.preferences_menuitem);
if (prefs != null) {
prefs.setVisible(jsInterface.enablePreferencesMenu);
}
super.onPrepareOptionsMenu(menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.dashboard_menuitem:
getEngine().loadUrl(DASHBOARD_URL);
return true;
case R.id.refresh_menuitem:
getEngine().reload();
return true;
case R.id.preferences_menuitem:
getEngine().loadUrl("javascript: android.showPreferences()");
return true;
case R.id.contact_menuitem:
AboutBox.Show(Dashboard.this);
return true;
case R.id.share_url_menuitem:
final String url = (jsInterface.urlForSharing != null
? jsInterface.urlForSharing
: getEngine().getUrl());
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_SUBJECT, "Android URL");
i.putExtra(Intent.EXTRA_TEXT, url);
startActivity(Intent.createChooser(i, "Share"));
default:
return super.onOptionsItemSelected(item);
}
}
private class FixedWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith(BASE_URL) || url.startsWith("javascript:")) {
// handle by the WebView
return false;
} else if (url.startsWith("mailto:")) {
MailTo mt = MailTo.parse(url);
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL, new String[]{mt.getTo()});
i.putExtra(Intent.EXTRA_SUBJECT, mt.getSubject());
i.putExtra(Intent.EXTRA_CC, mt.getCc());
i.putExtra(Intent.EXTRA_TEXT, mt.getBody());
view.getContext().startActivity(i);
view.reload();
return true;
} else {
// Use external browser for anything not on this site
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
view.getContext().startActivity(i);
return true;
}
}
}
// The methods of JavascriptInterface are called from javascript.
// The attributes are accessed from the Dashboard class.
// This is deliberately a dumb container class to stop possible
// security issues of javascript controlling Java app.
final class JavascriptInterface {
public boolean enablePreferencesMenu = false;
public boolean modalIsVisible = false;
public int versionCode = 0;
public String urlForSharing = null;
public void setEnablePreferencesMenu() {
enablePreferencesMenu = true;
}
public void setModalIsVisible(boolean visible) {
modalIsVisible = visible;
}
// This is useful for allowing the web site to be able to detect
// old app versions and prompt the user to upgrade.
public int getVersionCode() {
return versionCode;
}
public void setUrlForSharing(String url) {
urlForSharing = url;
}
}
}
Where should i edit to show no network connected message if device is not connected to internet???
First you need to check whether or not internet is connected to your device, you can check internet connection with below method
public static boolean checkNetworkConnection(Context _context){
ConnectivityManager connectivity = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null)
{
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED)
{
return true;
}
}
return false;
}
This method will return either true[If internet is connected] or false[if not connected]
Based on that true or false value you can decide whether to display html page or web page
Now Question is if you want to display webpage from your local folder than you can do it like this
You can load local html file as below
WebView lWebView = (WebView)findViewById(R.id.webView);
File lFile = new File(Environment.getExternalStorageDirectory() + "<FOLDER_PATH_TO_FILE>/<FILE_NAME>");
lWebView.loadUrl("file:///" + lFile.getAbsolutePath());
And if you want to display cahed html page than you need to do some R & D task for that.
Now if internet is connected than you can use below method to display web page on webview
wbb = (WebView) findViewById(R.id.webView_tobe_loaded);
WebSettings wbset=wbb.getSettings();
wbset.setJavaScriptEnabled(true);
wbb.setWebViewClient(new MyWebViewClient());
String url="http://www.google.com";
System.out.println(getdeviceid());
wbb.getSettings().setJavaScriptEnabled(true);
wbb.loadUrl(url);
I hope you understood all the explanation
You can check for internet connection using this:
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();
more info here: http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html
And to show HTML without load it from the internet:
webview.loadData("<b>Connection not availeable</b>", "text/html", null);
more info: http://developer.android.com/reference/android/webkit/WebView.html#loadData(java.lang.String,java.lang.String, java.lang.String)
I have developed a web app that displays a list of pdf documents hosted on a web server. This app is embedded in a webview app for android however when I load the app on my phone, selection of a pdf link does nothing. What am I doing wrong? Thanks
Heres the java code:
package com.hellowebview;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class HellowebviewActivity extends Activity {
/** Called when the activity is first created. */
private WebView mWebView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.loadUrl("http://aipnz.webs.com");
mWebView.setWebViewClient(new HelloWebViewClient());
mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
}
private class HelloWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView webview, String url)
{
webview.loadUrl(url);
return true;
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack())
{
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
If you want to load pdf you can use Google docs to load it.
String googleDocs = "https://docs.google.com/viewer?url=";
String pdf_url = "http://kronox.org/documentacion/Hello.Android.new.pdf";
webView.loadUrl(googleDocs + pdf_url);
NOTE: You need android.permission.INTERNET in Manifest file
Just create an Intent in your shouldOverrideUrlLoading method:
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if ( urlIsPDF(url)){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(url), "application/pdf");
try{
view.getContext().startActivity(intent);
} catch (ActivityNotFoundException e) {
//user does not have a pdf viewer installed
}
} else {
webview.loadUrl(url);
}
return true;
}
And then whenever a user clicks a PDF link in a page within your webview, the file will open in an external PDF app.
webView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.endsWith(".pdf")) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(url), "application/pdf");
try {
view.getContext().startActivity(intent);
} catch (ActivityNotFoundException e) {
//user does not have a pdf viewer installed
}
} else {
webView.loadUrl(url);
}
return true;
}
}
This is the solution I use:
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.endsWith(".pdf")){
String pdfUrl = googleDocs + url;
view.loadUrl(pdfUrl);
} else {
view.loadUrl(url);
}
return true;
}
with
private final String googleDocs = "https://docs.google.com/viewer?url=";
You have to override shouldOverrideUrlLoading method in WebClient. I use this approach with combination of intent and Google Docs as a backup:
/* You might want to move this string definition somewhere else */
final String googleDocs = "https://docs.google.com/viewer?url=";
WebView webView = new WebView(getContext());
//webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
if (url.endsWith(".pdf")) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(url), "application/pdf");
/* Check if there is any application capable to process PDF file. */
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
} else {
/* If not, show PDF in Google Docs instead. */
view.loadUrl(googleDocs + url);
}
} else {
webView.loadUrl(url);
}
return true;
}
});
You might need to change passing the context and accessing startActivity method, but other than that it should run as it is.
Also note that since API 24, there are 2 shouldOverrideUrlLoading methods you can override. As it is stated here from #CommonsWare, it is OK to override deprecated method.
use loadurl another overloaded methods...and write internet permission
Sharing this answer as I tried all the above solutions but did not work for me, this is Kotlin code (not javascript)
myWebView.setWebViewClient(object:WebViewClient() {
override fun shouldOverrideUrlLoading(view:WebView, url:String):Boolean {
if (url.endsWith(".pdf"))
{
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(android.net.Uri.parse(url), "application/pdf")
try
{
view.getContext().startActivity(intent)
}
catch (e:ActivityNotFoundException) {
//user does not have a pdf viewer installed
}
}
else
{
myWebView.loadUrl(url)
}
return true
}
})
How do can you generate a bitmap from HTML in Android?
Can the WebView be used for this or is there a better approach (like maybe using the WebView rendering engine directly)? How?
I would like to implement the following method...
public Bitmap toBitmap(Context context, String html, Rect rect);
...where html is the html to render and rect is the frame of the desired bitmap.
A synchronous method that generates a bitmap from an HTML string using a WebView, and can be used within an AsyncTask:
public Bitmap getBitmap(final WebView w, int containerWidth, int containerHeight, final String baseURL, final String content) {
final CountDownLatch signal = new CountDownLatch(1);
final Bitmap b = Bitmap.createBitmap(containerWidth, containerHeight, Bitmap.Config.ARGB_8888);
final AtomicBoolean ready = new AtomicBoolean(false);
w.post(new Runnable() {
#Override
public void run() {
w.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
ready.set(true);
}
});
w.setPictureListener(new PictureListener() {
#Override
public void onNewPicture(WebView view, Picture picture) {
if (ready.get()) {
final Canvas c = new Canvas(b);
view.draw(c);
w.setPictureListener(null);
signal.countDown();
}
}
});
w.layout(0, 0, rect.width(), rect.height());
w.loadDataWithBaseURL(baseURL, content, "text/html", "UTF-8", null);
}});
try {
signal.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return b;
}
It has some limitations, but it's a start.
You can use the draw method to let it draw in a Bitmap of your choice. I made an example, don't forget internet and external storage rights of your manifest:
public class MainActivity extends Activity {
private WebView mWebView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mWebView = new WebView(this);
setContentView(mWebView);
mWebView.loadUrl("http://tea.ch");
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode != KeyEvent.KEYCODE_BACK) return super.onKeyDown(keyCode, event);
Bitmap bm = Bitmap.createBitmap(200, 300, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
mWebView.draw(c);
OutputStream stream = null;
try {
stream = new FileOutputStream(Environment.getExternalStorageDirectory() +"/teach.png");
bm.compress(CompressFormat.PNG, 80, stream);
if (stream != null) stream.close();
} catch (IOException e) {
} finally {
bm.recycle();
}
return super.onKeyDown(keyCode, event);
}
}
Why not use the WebView method : capturePicture() which returns a Picture and is available since API level 1 ?
It returns a picture of the entire document.
You could then crop the result with your rectangle and save the bitmap from there.
This example shows how to capture webView content last picture (it waits until webview complete rendering picture), it is an example of convert HTML to PNG using Android
Activity Code
public class HtmlViewer extends Activity {
private String HTML;
private Context ctx;
private Picture pic = null;
private int i=0; suppose this is the last pic
private int oldi = 0;
private Timer myTimer; // timer for waiting until last picture loaded
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_html_viewer);
Intent intent = getIntent();
HTML = intent.getStringExtra("HTML");
ctx = this;
WebView wv = (WebView)findViewById(R.id.webView1);
wv.setPictureListener(new PictureListener(){
public void onNewPicture(WebView view, Picture picture) {
Log.w("picture", "loading.." + String.valueOf(view.getProgress()));
pic = picture;
i++;
}
});
wv.loadData(HTML, "text/html; charset=utf-8", null);
wv.setWebViewClient(new WebViewClient()
{
public void onPageFinished(WebView wv, String url)
{
Picture p = wv.capturePicture();
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
if (i > oldi)
oldi = i;
else
if (i != 0)
{
Log.w("picture", "finished");
cancel();
Picture picture = pic;
Log.w("picture", "onNewPicture- Height"+ picture.getHeight());
Log.w("picture", "onNewPicture- Width"+ picture.getWidth());
File sdCard = Environment.getExternalStorageDirectory();
if (picture != null)
{
Log.w("picture", " P OK");
Bitmap image = Bitmap.createBitmap(picture.getWidth(),picture.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(image);
picture.draw(canvas);
Log.w("picture", "C OK");
if (image != null) {
Log.w("picture", "I OK");
ByteArrayOutputStream mByteArrayOS = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.PNG, 90, mByteArrayOS);
try {
File file = new File(sdCard, "AccountView.PNG");
FileOutputStream fos = new FileOutputStream(file);
fos.write(mByteArrayOS.toByteArray());
fos.flush();
fos.close();
Log.w("picture", "F OK " + String.valueOf(mByteArrayOS.size()) + " ? " + String.valueOf(file.length()));
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
Uri screenshotUri = Uri.fromFile(file);
sharingIntent.setType("image/png");
sharingIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.ACCOUNT_VIEW_TITLE)));
((Activity)ctx).finish();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}, 0, 1000);
Log.w("picture", "done");
loadcompleted = true;
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_html_viewer, menu);
return true;
}
}
Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".HtmlViewer" >
<WebView
android:id="#+id/webView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
This is a good library that can be used to convert any HTML content to bitmap.
It supports both URL and HTML String
https://github.com/iZettle/android-html2bitmap