Cordova Plugin Continued

Here I demonstrate how to create a Cordova plugin for android that allows the user to select a csv file from their device, which is passed back to Cordova to process as a javascript string.

Cordova Plugin

Introduction

In this example an Intent is created once the cordova application triggers a plugin request, which is defined with the CordovaPlugin Java class. This function is the point of entry to the plugin which has three parameters these are action, arguments and callbackContext. It is possible to execute most of the Android’s SDK through this java class. For example, I have used it to print HTML content to a printer from Cordova using the Android Printer Service, import file contents and use deep linking to open the app remotely and pass parameters through the URL link. Cordova plugins allow you as a developer to access the Android SDK while still using a web based front end for your applications.

Open File Chooser - Java Source code

This is an example of how to create a plugin that opens a file chooser to find and read files on the local device. The source code is straight forward, and I have provided comments explaining each line of the java code.



    /*
    *   Copyright (c) Mr Steven J Baldwin. All rights reserved.
    *   Author: Mr Steven J Baldwin
    *   Date: 27 August 2020 
    *
    *   THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    *   KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
    *   WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
    *   MERCHANTABLITY OR NON-INFRINGEMENT.
    */
    
    package com.example.plugin;
    
    import org.apache.cordova.*;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import org.apache.cordova.CordovaPlugin;
    import org.apache.cordova.CallbackContext;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    
    
    public class MyPlugin extends CordovaPlugin {
    
        private String fileContent;         //  Contains the file contents
        CallbackContext finalCallback;      //  Store callback function for javascript..
    
        @Override
        public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
            
            //  Define Plugin Method name, callable from javascript.
            if (action.equals("importFile")) {
                
                //  Display Open File chooser
                this.openFileDialog(callbackContext);
                //  Store callback function to execute once user has selected a file.
                finalCallback = callbackContext;
                return true;
            }
            return false;
        }
    
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    
            if(requestCode == 101 && resultCode == cordova.getActivity().RESULT_OK) {
                Uri selectedfile = data.getData();
    
                try {
                    // Open Input Stream for the users selected file.
                    InputStream in = cordova.getActivity().getContentResolver().openInputStream(selectedfile);
                    
                    // create a buffer read to read the content of the file.
                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                    // create a string builder to store the contents of the file into a string
                    
                    StringBuilder res = new StringBuilder();
                    
                    // Foreach line append it to the final string builder.
                    for(String line;(line = reader.readLine()) != null;){
                        res.append(line).append('\n');
                    }
                    
                    // Set the final content string from the string builder
                    fileContent = res.toString();
                    
                    // Return the string containing the file contents as a string to Cordova
                    PluginResult result = new PluginResult(PluginResult.Status.OK, fileContent);
    
                    //  Execute plugin callback javascript function
                    finalCallback.success(fileContent);
    
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        private void openFileDialog(CallbackContext callbackContext) {
    
            //  Create and File Chosser Intent which allows users to select a file
            Intent intent = new Intent();
    
            //  Set type of files allowed to be opened.
            intent.setType("text/comma-separated-values");  
            intent.setAction(Intent.ACTION_GET_CONTENT);
    
            // Override Activity Callback, this will execute "onActivityResult" once the user has selected a file
            cordova.setActivityResultCallback(this);
    
            //  Open And show file chooser
            cordova.getActivity().startActivityForResult(Intent.createChooser(intent, "Select a file"), 101);
        }
    }
                                                       
                            
Javascript Source Code

The front end javascript code waits for the user to press a button, then it executes the plugin and method defined. In this case the plugin is "MyPlugin" and the method is "importFile".

                                /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you 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.
    */
    
    // Wait for the deviceready event before using any of Cordova's device APIs.
    // See https://cordova.apache.org/docs/en/latest/cordova/events/events.html#deviceready
    document.addEventListener('deviceready', onDeviceReady, false);
    
    function onDeviceReady() {
        // Cordova is now initialized. Have fun!
    
        console.log('Running cordova-' + cordova.platformId + '@' + cordova.version);
        document.getElementById('deviceready').classList.add('ready');
    
    
        /* Button On click */
        document.getElementById('openFile').addEventListener('click', function(e){
            e.preventDefault();
            //  Execute Open File Plugin
            cordova.exec(function(response){
                //Display Popup showing the contents of the file opened
                alert(response);
            }, function(err){
                console.log(err);
            }, "MyPlugin", "importFile");
        });
    
    }