accessing a file from folder within assets - android

I have an application which displays html file from assets folder.Now the issue is if there is only one html, all works fine but in case I have more than 1 html, how do I refer it?
Folder structure when only 1 html is present is like
and I refer to html file as follows:
InputStream input = this.getAssets().open("index.html");
but in case of multiple html's, it should/will be like
So, in this scenario , how do I refer different html's?i.e. how do I refer a file from a folder placed within assets folder?
As I have no idea how to proceed, any help appreciated...

You can access it as a URL like so:
"file:///android_asset/myfile.html"
So in a WebView you can use the method:
loadUrl("file:///android_asset/myfile.html")

You can refer like this
WebView webview;
webview=(WebView)findViewById(R.id.webView1);
webview.getSettings().setJavaScriptEnabled(true);
webview.loadUrl("file:///android_asset/HTML 1/index.html");
webview.addJavascriptInterface(new MyJavaScriptInterface(), "Android");
final class MyJavaScriptInterface
{
public void ProcessJavaScript(final String scriptname, final String args)
{
mHandler.post(new Runnable()
{
public void run()
{
//ToDo Something here...
}
});
}
}

Related

How to show a program in text view..?

I want to show a simple java program in my app
when i put the below code in my textview it simply shows it like a paragraph.
How to show a program in my textview like the format given below
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Help me :-) please
I dont have any idea how you are trying but refer my answer i think you will get some idea
String firststring = "public class Main {";
String secondstring = "public static void main(String[] args) {";
String thirdstring = "System.out.println("Hello, World!");";
textview.setText(Html.fromHtml(firststring + "<br>" + secondstring+"<br>"+thirdstring));//Your textview
I finally got the answer.
Place texts which you want to look like a program in the Syntax highlighter save it as html and put it on assets folder load the url in webview!
That's what I found on matter:
Syntax Highlighter Link

Get type of object when click on webview - Android

I am developing a webview in which i have to define the type of object when i click to this object. For example, when i click to a link, webview understand it is a link and i can get link (returned object); when i click to a image, webview understand it is a image and return image object. I want to get the object type to do some more activities. For example, when i long click to the image, there are some action for me: download, set as background,... when i long click to a link, there are some option like: open in new tab, add to bookmark,... Does anyone know the solution. Thank u very much :)
I think that you cannot have direct visibility to the "downside" html/javasctipt from webview listeners.
(WebView reference here: http://developer.android.com/reference/android/webkit/WebView.html)
However, if you are developing the web application running in the WebView, you can obtain the same result by using JavascriptInterface methods, implementing the javascript methods to "upside" return objects toward android app.
Example interface class:
public class JSUpInterface {
protected Context mContext;
public JSUpInterface(Context c) {
mContext = c;
}
#JavascriptInterface
public void showToast(String message) {
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
}
#JavascriptInterface
public void getLink(String link) {
// shows in a toast the clicked link
Toast.makeText(mContext, link, Toast.LENGTH_SHORT).show();
}
}
WebView attaching:
jsUi = new JSUpInterface(context);
webview.addJavascriptInterface(jsUi, "jsui");
your html:
www.google.com

Javascript Interface, error "Uncaught Error: Error calling method on NPObject"

In my Android application, I am using the WebAppInterface to bridge from Javascript to Java.
My .html file includes some JS that runs "Android.canPlay();" at certain times.
In my app, the function "canPlay()" fires a variable listener.
When the variable listener fires, if conditions are met, some files are renamed (temporary files, that were downloaded with a .tmp additional extension, including the .html file (so it is .html.tmp, with the original .html existing alongside it))
After the renaming happens, the Web View is reloaded (I have tried using both a function and just ".loadUrl()" - both give errors)
When time comes to reload the html file in the webview, I get the error:
E/Web Console﹕ Uncaught Error: Error calling method on NPObject. at
file:////mnt/sdcard/Download/qwerty/playlists/29/2/index.html:206
Line 206 is the "Android.canPlay()" call.
Things to note - If I don't rename the files before reloading the webview and instead, rename then from a background service that runs, I don't have this error (although I do get one about running stuff on the WebViewCoreThread)
Some code:
WebAppInterface
public class WebAppInterface {
final Context mContext;
WebAppInterface(Context c) {
mContext = c;
}
#JavascriptInterface
public void canPlay()
{
mPlaylistReady.changeState(true);
}
}
Variable Listener (gets fired via a listener class) (some bits of code removed e.g. sharedprefences for file locations)
#Override
public void onStateChange(boolean state) {
if (state) { // true
// this finds all the files and removes the .tmp extension
fileRenamer.removeTmp(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS + "/qwerty/playlists/"));
// reloads the webview
WebViewActivity.this.runOnUiThread(new Runnable() {
public void run() {
webView.loadUrl("file:///" + htmlFile.getAbsolutePath());
}
});
}
}
}
FileRenamer class
public class FileRenamer {
public void removeTmp(File directory)
{
File dir = directory;
if(dir.isDirectory()) {
for(File child : dir.listFiles()) {
String name = child.getName();
String ext = name.substring(name.lastIndexOf('.'));
if(ext.equals(".tmp")) {
final int lastPeriodPos = name.lastIndexOf('.');
File renamed = new File(dir, name.substring(0, lastPeriodPos));
child.renameTo(renamed);
}
}
}
}
}
This error is thrown by JavaScript because an exception has occurred during the Java canPlay() implementation.
Try to encapsulate the WebAppInterface.canPlay() method in a try-catch clause and log the exception to find out what could've been happening.
Besides that, I'm trying to discover a way to map exceptions in the JavaScript context, but i'm afraid that is not possible.

Issue with loading local javascript files inside a webview

I had with an issue that has plagued me for days. It turned out that it was an Android glitch and has been submitted, confirmed, and hopefully will be fixed in a future release. Now I have found a solution that works for me, and will provide it below, however the solution is not perfect as it involves editing the phone gap source. Mainly my question is if someone can find a better solution to this issue.
The Bug:
There is a glitch when you attempt to load a page inside of a WebView on Android 3.0+. The glitch is that if that page references any local javascript files, you cannot append query data to the url. Basically
This works:
<script type="text/javascript" src="StaticJS.js"></script>
This does not work:
<script type="text/javascript" src="StaticJS.js?var=val"></script>
Why the hell would anyone want to do this since the file obviously can't do anything with the query vals? Well for me I have a phonegap application that loads a settings file via JSONP, however if a settings file is not specified it defaults to a local file. So yeah, the file can't process the query data but it would be nice to use the same file format and loading structure.
Solution 1 (Non-PhoneGap)
So there is an easy solution to this if the target android platform is 11(Honeycomb) or higher. (As long as you are careful and do not use any method that do not exists in any lower API levels this code will run on <11 apis, but you will still have to set 11 as your target)
Basically you add a WebViewClient to the WebView that utilizes the shouldInterceptRequest method to intercept the loading of local js files with query data attached.
import java.io.IOException;
import java.io.InputStream;
import android.content.res.AssetManager;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class PatchingWebViewClient extends WebViewClient{
AssetManager am;
public PatchingWebViewClient(AssetManager am){
this.am = am;
}
#Override
public WebResourceResponse shouldInterceptRequest (WebView view, String url){
if(url.indexOf("file:///android_asset") == 0 && url.contains("?")){
String filePath = url.substring(22, url.length());
filePath = filePath.substring(0, filePath.indexOf("?"));
try {
InputStream is = am.open(filePath);
WebResourceResponse wr = new WebResourceResponse("text/javascript", "UTF-8", is);
return wr;
} catch (IOException e) {
return null;
}
}else{
return null;
}
}
}
To set the WebViewClient, your code would look something like this:
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
public class CanWeBreakAWebViewActivity extends Activity {
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.setWebViewClient(new PatchingWebViewClient(this.getAssets()));
mWebView.loadUrl("file:///android_asset/index.html");
}
}
Solution 2 (PhoneGap)
Now for Phonegap I don't have a clean solution. My solution is to go and download the Phonegap source and edit the CordovaWebViewClient by adding the following method:
#Override
public WebResourceResponse shouldInterceptRequest (WebView view, String url){
if(url.indexOf("file:///android_asset") == 0 && url.contains("?")){
String filePath = url.substring(22, url.length());
filePath = filePath.substring(0, filePath.indexOf("?"));
try {
InputStream is = ctx.getAssets().open(filePath);
WebResourceResponse wr = new WebResourceResponse("text/javascript", "Cp1252", is);
return wr;
} catch (IOException e) {
return null;
}
}else{
return null;
}
}
Solution 3 (Non-Existent)
This solution would hopefully be some easy to include class or tweak to the main activity so that you can use phone gap but could just use a .jar file of the code, making upgrades easier.
Thanks for this post, you clued me in to the latest solution which is simply to use IceCreamCordovaWebViewClient.
#Override
public void init() {
super.init(webView, new IceCreamCordovaWebViewClient(this, webView), new CordovaChromeClient(this, webView));
}
Query data is appended to javascript files (and other file types like css) to prevent browser caching. The query data is useless to the file but the browser treats it as new because the location is changed (in the eyes of the browser) and it loads a fresh copy.
I'm glad you found an answer to your problem, just thought I'd give my input as to why people use this method.

Load HTML file into WebView

I have a local html page along with several other resources pointed by it (css files and Javascript libraries) that I would like to load into a WebView . How could this be achieved ?
Perhaps not the best way to procede but I'm still experimenting.
The easiest way would probably be to put your web resources into the assets folder then call:
webView.loadUrl("file:///android_asset/filename.html");
For Complete Communication between Java and Webview See This
Update: The assets folder is usually the following folder:
<project>/src/main/assets
This can be changed in the asset folder configuration setting in your <app>.iml file as:
<option name=”ASSETS_FOLDER_RELATIVE_PATH” value=”/src/main/assets” />
See Article Where to place the assets folder in Android Studio
probably this sample could help:
WebView lWebView = (WebView)findViewById(R.id.webView);
File lFile = new File(Environment.getExternalStorageDirectory() + "<FOLDER_PATH_TO_FILE>/<FILE_NAME>");
lWebView.loadUrl("file:///" + lFile.getAbsolutePath());
In this case, using WebView#loadDataWithBaseUrl() is better than WebView#loadUrl()!
webView.loadDataWithBaseURL(url,
data,
"text/html",
"utf-8",
null);
url: url/path String pointing to the directory all your JavaScript files and html links have their origin. If null, it's about:blank.
data: String containing your hmtl file, read with BufferedReader for example
More info: WebView.loadDataWithBaseURL(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
The Accepted Answer is not working for me, This is what works for me
WebSettings webSetting = webView.getSettings();
webSetting.setBuiltInZoomControls(true);
webView1.setWebViewClient(new WebViewClient());
webView.loadUrl("file:///android_asset/index.html");
XML Layout File:
<WebView android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/webView"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".activities.Bani9">
</WebView>
Java Code:
public class Bani9 extends AppCompatActivity {
WebView webView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bani9);
webView = findViewById(R.id.webView);
WebSettings webSetting = webView.getSettings();
webSetting.setBuiltInZoomControls(true);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("file:///android_asset/punjabi/bani9.html");
}
}
Make sure you set file path accurately.
From the official guide https://developer.android.com/develop/ui/views/layout/webapps/load-local-content :
Store the HTML as an asset in app/src/main/assets/
Use WebViewAssetLoader to load the asset. Construct it in your onCreate() as follows:
final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder()
.addPathHandler("/assets/", new WebViewAssetLoader.AssetsPathHandler(this))
.addPathHandler("/res/", new WebViewAssetLoader.ResourcesPathHandler(this))
.build();
Subclass WebViewClient to wrap WebViewAssetLoader:
private static class LocalContentWebViewClient extends WebViewClientCompat {
private final WebViewAssetLoader mAssetLoader;
LocalContentWebViewClient(WebViewAssetLoader assetLoader) {
mAssetLoader = assetLoader;
}
#Override
#RequiresApi(21)
public WebResourceResponse shouldInterceptRequest(WebView view,
WebResourceRequest request) {
return mAssetLoader.shouldInterceptRequest(request.getUrl());
}
#Override
#SuppressWarnings("deprecation") // to support API < 21
public WebResourceResponse shouldInterceptRequest(WebView view,
String url) {
return mAssetLoader.shouldInterceptRequest(Uri.parse(url));
}
}
This basically passes the request URL to WebViewAssetLoader to load web content from an asset.
Use assetLoader from (2) to construct WebViewClient from (3), and set it in your WebView. Your index.html can be loaded by using https and the default domain appassets.androidplatform.net:
mWebView.setWebViewClient(new LocalContentWebViewClient(assetLoader));
mWebView.loadUrl("https://appassets.androidplatform.net/assets/index.html");
Note that loading local files using web-like URLs instead of file:// is desirable as it is compatible with the Same-Origin policy.

Categories

Resources