0

I am really new to Android and just developed a WebView App in Android Studio (Java platform) for Android 7 and higher. The WebView is accessing an HTML page which dynamically generates string using JavaScript. I am able to feed the string to the WebView from the HTML page using instructions from this post: Download file generated by javascript in android webview

I would like to save the string in a text file. I tried few solutions but nothing worked. It would be really helpful if anybody could provide me some code to save the string in a .txt file. Also I need instructions on how to implement check/request permission to access storage (which may be required for saving file).

I tried to implement suggestions from "glzlaohuai" below. Below is my MainActivity.java

package com.example.brahma;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.JavascriptInterface;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import androidx.appcompat.app.AppCompatActivity;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class MainActivity extends AppCompatActivity {
private Context mContext;
private Activity mActivity;
private static final int MY_PERMISSION_REQUEST_CODE = 123;
WebView web;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    web = findViewById(R.id.brahma_wv);
    WebSettings webSettings = web.getSettings();
    webSettings.setJavaScriptEnabled(true);
    webSettings.setDomStorageEnabled(true);
    webSettings.setSupportZoom(true);
    webSettings.setAllowFileAccess(true);
    webSettings.supportMultipleWindows();
    webSettings.setSupportZoom(true);
    webSettings.setBuiltInZoomControls(true);
    webSettings.setDisplayZoomControls(false);
    webSettings.setAllowFileAccessFromFileURLs(true);
    webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
    web.setWebViewClient(new Callback());
    web.loadUrl("https://script.google.com/macros/s/myWebAppId/exec");
    web.addJavascriptInterface(new myJavascriptInterface(this), "Android");

}


public class myJavascriptInterface {
    Context mContext;

    myJavascriptInterface(Context c) {
        mContext = c;
    }

    @JavascriptInterface
    public void sendData(String attString) {
        File file = new File(getExternalFilesDir(null), "Testfile.txt");
        try {
            OutputStream fileWriter = new FileOutputStream(file);
            Log.d("ATT", attString);
            fileWriter.write(attString.getBytes());
            fileWriter.close();
        } catch (IOException e) {
            Log.w("ExternalStorage", "Error writing " + file, e);
        }
    }
  }
} 

The code runs and I am getting the desired string in the Log, but no file is being saved or downloaded. Also I don't see any error.

Below is the modified code which is working as intended.

public class myJavascriptInterface {
    Context mContext;

    myJavascriptInterface(Context c) {
        mContext = c;
    }

    @JavascriptInterface
    public void sendData(String attString) {
        Log.d("Txt", attString.toString());

        //save attString as file
        String filename = "TestFile.txt";
        saveTextAsFile(filename, attString);
    }
}

private void saveTextAsFile(String filename, String content) {
    File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), filename);
    try {
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(content.getBytes());
        fos.close();
        Toast.makeText(this, "Saved!", Toast.LENGTH_SHORT).show();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    catch (IOException e) {
        e.printStackTrace();
    }
}
Partha S. Pal
  • 169
  • 1
  • 2
  • 14

1 Answers1

0

You should implement the saveTheGeneratedString(use any other name that you like) method on the Java side, and call this method in your javascript code, refer to this link for details: https://developer.android.com/reference/android/webkit/WebView#addJavascriptInterface(java.lang.Object,%20java.lang.String)

About the permissions to access storage, as your app targets Android 7 and higher, so no additional permissions needed, refer to these below links for details:

https://developer.android.com/reference/android/content/Context#getFilesDir() https://developer.android.com/reference/android/content/Context#getExternalFilesDir(java.lang.String)

glzlaohuai
  • 76
  • 5
  • I added my code for MainActivity.java to my question. Its compiling but file is not being downloaded or saved. – Partha S. Pal Nov 25 '20 at 08:38
  • Which log did you get? `ATT` or `ExternalStorage ` – glzlaohuai Nov 25 '20 at 08:44
  • ATT from Log.d("ATT", attString). There is no log regarding Log.w("ExternalStorage", "Error writing " + file, e); – Partha S. Pal Nov 25 '20 at 09:09
  • I suggest you add some test logs to see if the file exists or not just after you create the file instance. – glzlaohuai Nov 25 '20 at 11:48
  • After some modification (code added above) I am able to save the text file. However instead of sending only the content of the file (in this case: attString) I would like to feed an array [filename, attString] into the function sendData(). How can that be achieved? – Partha S. Pal Nov 25 '20 at 16:19
  • Simply change your function `sendData(attString)` to `sendData(fileName,attString)`, plus also modify your js side code that invoke the `sendData` function. – glzlaohuai Nov 26 '20 at 02:40
  • I think you might check the wrong directory `getExternalFilesDir ` did not return the root path, it's `/data/` – glzlaohuai Nov 26 '20 at 02:46
  • I tried changing sendData(String attString) to sendData(String filename, String attString) and modified my js side to Android.sendData(filename, attSstring). This does not work, the webpage is not loading. The log shows [INFO:CONSOLE(150)] "Uncaught Error: Method not found", source: https:// ... . ..-script.googleusercontent.com/userCodeAppPanel (150). – Partha S. Pal Nov 26 '20 at 08:28
  • How about sending Android.sendData(JSON.stringify([filename, attString])) and parsing it in the WebView? But I dont know how to parse a stringified array in Android Java. – Partha S. Pal Nov 26 '20 at 08:31
  • 1
    Those two methods are both ok. Don't know why you got "Method not found exception", I guess maybe you send the wrong type of arguments from the javascript side to the java side, java is a strongly typed language. About how to parse JSON-formatted string in java, read these links for details: https://developer.android.com/reference/org/json/JSONArray https://developer.android.com/reference/org/json/JSONObject – glzlaohuai Nov 26 '20 at 09:15
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/225152/discussion-between-glzlaohuai-and-partha-s-pal). – glzlaohuai Nov 26 '20 at 09:20