0

Hello people of Stackverflow!

I'm developing a small Android app which purpose is to read an .xlsx file and display its data in a certain form (bar/doughnut charts). As I don't have the time to learn everything I need in Java and Android I'm using Cordova & Ionic framework to do it. I'm pretty new to these (also pretty new to AngularJS) but I'm used to code in JavaScript, and already coded with NodeJS.

So far I've managed to create a simple view which reads and display dummy data I created and stored directly in my Javascript/Angular code, using the Highcharts library. But now I want to use real data I got, but get stuck on two major problems:

  • first of all, the file that will be used by my Ionic app is not a file stored directly on the Android device file system, but received by the user on its mail box. I don't understand how to configure intent-filter so my app is detected as capable to open such files (so that the user can choose it when trying to open an .xlsx file from his mail box)
  • secondly, when the user select my app to open an xlsx file, how do I manage to retrieve the file in my JS code? Note that I already found the library I'll use to extract information from my .xlsx file in a JSON format, and already have ideas on how to treat those data afterwards.

I'll keep this topic updated if you need more info.

TheFrenchieCake
  • 123
  • 1
  • 12

2 Answers2

1
  1. Use Intent filter with your MainActivity (cordova just have 1 activity btw)
<activity android:name="com.example.app.MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="file" />
        <data android:mimeType="*/*" />
        <data android:pathPattern=".*\\.xlsx" />
        <data android:host="*" />
    </intent-filter> 
</activity>

And in your mainactivity, add the handler in your onCreate:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    // Get the intent that started this activity
    Intent intent = getIntent();

    if (intent != null){
       Uri data = intent.getData(); //get the uri of your xlsx
    }
    .
    . // your cordova code
    .
    .
}
  1. I think you need a database to store your data. But if you can make your own CordovaPlugin for that problem, then you got the faster way to transfer your data from native to your webview. And if you choose to use a database, then this plugin may help you
Randyka Yudhistira
  • 3,612
  • 1
  • 26
  • 41
0

I've managed to answer my own questions, partly thanks to Randyka Yudhistira for the first one.

First of all, in order that your app is detected as capable of opening XLSX files, you have to edit its AndroidManifest.xml. In a Ionic app, this file is located at: YOUR_APP/platforms/android/AndroidManifest.xml. Add the following intent-filter inside of the <activity> section (thanks again for this, Randyka Yudhistira):

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="file" />
    <data android:mimeType="*/*" />
    <data android:pathPattern=".*\\.xlsx" />
    <data android:host="*" />
</intent-filter>

Secondly, to open and read the XLSX file and extract the data from it, you'll need the ngCordova plugin, that you can install easily with Bower, and the WebIntent Android plugin for Cordova and ngCorodva plugin named File:

bower install ngCordova
cordova plugin add https://github.com/Initsogar/cordova-webintent.git
cordova plugin add org.apache.cordova.file

Reference ngCordova in your HTML file (before the reference to the cordova lib):

<script src="lib/ngCordova/dist/ng-cordova.js"></script>
<script src="cordova.js"></script>

And inject it as an Angular dependency in your angular module:

var yourApp = angular.module("yourApp", ['ionic', 'ngCordova']);

If you need to "feed" your app with a given file, like in my app, you need to retrieve the URL of the file. To do so, in your Ionic controller, add the services $cordovaFile and $ionicPlatform, and use the webintent plugin as follow to get the URI to your file:

yourApp.controller('yourAppController', function($scope, $ionicPlatform, $cordovaFile) {
  $ionicPlatform.ready(function() {
    if (window.plugins && window.plugins.webintent) { // checks if plugins are enabled and loaded
      window.plugins.webintent.getUri(function (url) {
        if(url) {
          // use your file URL here
        }
      }
    }
  });
}

To open the file and read its data, you'll need to separate the path to your file from the name of the file:

var path = url.slice(0, url.lastIndexOf('/') + 1);
var filename = url.substring(url.lastIndexOf('/') + 1);

Finally, you can read the data from your file with the cordova File plugin, in four different ways (as Text, as DataURL, BinaryString, ArrayBuffer), with the function cordovaFile.readAs<theWayYouWant>(path, file) (you get a Promise); here for example I needed the data as a binary string:

$cordovaFile.readAsBinaryString(path, filename)
  .then(function(result) { // success
    ...
  }, function() { // failure
    alert('failed to open file');
});

Hope this answer will help people who struggled like me to open and read data from a file in a Ionic App :-)

TheFrenchieCake
  • 123
  • 1
  • 12