Вставить внешний файл JS в Android WebView и вызвать его - PullRequest
3 голосов
/ 15 марта 2011

Я пытаюсь внедрить мой внешний файл JS (содержащийся в каталогах ресурсов) в WebView и впоследствии вызвать его.

Это код, который я использую для инъекций:

webView.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        webView.loadUrl("javascript: (function() { "
            + "var script=document.createElement('script');"
            + "script.type='text/javascript';script.src='file://android_asset/js_demo.js';"
            + "document.getElementsByTagName('head').item(0).appendChild(script);"
            + "})()");
        webView.loadUrl("javascript: jsDemo()");
    }
});

Когда я печатаю все содержимое моего веб-представления, я вижу, что тег script с src = 'file: //android_asset/js_demo.js' действительно вставлен, но вызов функции jsDemo ничего не делает.

ПРИМЕЧАНИЕ: функция jsDemo содержится в js_demo.js и не делает ничего умного, просто меняет цвет некоторого диапазона. Он работает нормально, так как я проверил его в браузере.

Я убежден, что ошибся, указав путь к файлу js, но я не уверен, как его изменить, чтобы он работал. Любая помощь будет оценена.

Ответы [ 4 ]

2 голосов
/ 01 сентября 2013

Вот как я это сделал.Я использовал протокол Content: // и настроил contentprovider для обработки возврата файлового дескриптора в систему

Вот мой fileContentProvider:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.io.IOUtils;


import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.util.Log;

public class FileContentProvider extends ContentProvider {
    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) {

        Log.d("FileContentProvider","fetching: " + uri);

        ParcelFileDescriptor parcel = null;

        String fileNameRequested = uri.getLastPathSegment();
        String[] name=fileNameRequested.split("\\.");
        String prefix=name[0];
        String suffix=name[1];
       // String path = getContext().getFilesDir().getAbsolutePath() + "/" + uri.getPath();
        //String path=file:///android_asset/"+Consts.FILE_JAVASCRIPT+"

/*check if this is a javascript file*/

        if(suffix.equalsIgnoreCase("js")){
        InputStream is = null;
        try {
            is = getContext().getAssets().open("www/"+Consts.FILE_JAVASCRIPT);
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }


        File file = stream2file(is,prefix,suffix);
        try {
            parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
        } catch (FileNotFoundException e) {
            Log.e("FileContentProvider", "uri " + uri.toString(), e);
        }
        }
        return parcel;
    }

    /*converts an inputstream to a temp file*/

    public File stream2file (InputStream in,String prefix,String suffix) {
        File tempFile = null;
        try {
            tempFile = File.createTempFile(prefix, suffix);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        tempFile.deleteOnExit();

            FileOutputStream out = null;
            try {
                out = new FileOutputStream(tempFile);
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 

            try {
                IOUtils.copy(in, out);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        return tempFile;
    }


    @Override
    public boolean onCreate() {
        return true;
    }

    @Override
    public int delete(Uri uri, String s, String[] as) {
        throw new UnsupportedOperationException("Not supported by this provider");
    }

    @Override
    public String getType(Uri uri) {
        throw new UnsupportedOperationException("Not supported by this provider");
    }

    @Override
    public Uri insert(Uri uri, ContentValues contentvalues) {
        throw new UnsupportedOperationException("Not supported by this provider");
    }

    @Override
    public Cursor query(Uri uri, String[] as, String s, String[] as1, String s1) {
        throw new UnsupportedOperationException("Not supported by this provider");
    }

    @Override
    public int update(Uri uri, ContentValues contentvalues, String s, String[] as) {
        throw new UnsupportedOperationException("Not supported by this provider");
    }
}

в манифесте, который я определил провайдером:

<provider android:name="com.example.mypackage.FileContentProvider"
          android:authorities="com.example.fileprovider"
        />

Вот javascript, который я вставляю в веб-просмотр:

webView.loadUrl("javascript:(function() { "

           + "var script=document.createElement('script'); "
           + " script.setAttribute('type','text/javascript'); "
           + " script.setAttribute('src', 'content://com.example.fileprovider/myjavascriptfile.js'); "
      /*      + " script.onload = function(){ "
           + "     test(); "
           + " }; "
      */     + "document.body.appendChild(script); "
           + "})();");

, а вот myjavascriptfile.js (как пример):

   function changeBackground(color) {
   document.body.style.backgroundColor = color;

}

2 голосов
/ 15 марта 2011

Почему бы просто не прочитать файл и выполнить его напрямую через loadUrl("javascript:...)?

1 голос
/ 13 марта 2014

Спасибо за отзывы, ребята.Я перепробовал большинство предложений, и вот как я смог внедрить файл .js для каждой загрузки веб-страницы.

  1. Считать локальный файл js в строку.
  2. Добавить эту строкуна script.text после создания элемента документа с типом text/javascript
  3. Вызов javascript: (function() { <programmatically formatted string dynamically creating webpage script element >})()" внутри переопределенного веб-просмотра onPageFinished.

Проверена работа на Android 4.0.3–4.0.4 Сэндвич с мороженым (уровень API 15)

0 голосов
/ 05 марта 2014

Вам нужно три слэша после "file:"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...