0

How do I access a file saved by Titanium from within a native module? In my code, I save a picture taken with the camera (Ti.Media) to a file. Then, I'm trying to read that same file from my module. I'm passing the nativePath to the module's method. But, I keep getting file not found errors in my module.

In the camera success callback, I have this code:

// earlier in the code
var tiexif = require('com.me.tiexif');

Ti.Media.showCamera({
    success: function(event) {
        console.log("TIEXIF: showCamera.success()");
        anImageView.image = event.media; // works
        if (Ti.Filesystem.hasStoragePermissions()) {
            console.log("TIEXIF: hasStoragePermissions");
            var file = Titanium.Filesystem.getFile(Ti.Filesystem.externalStorageDirectory, 'testphoto.jpg');
            console.log("TIEXIF: nativePath: " + file.nativePath);
            file.write(event.media);
            someUILabel.text = tiexif.getExifOrientation(file.nativePath);
        } else ...
    }, ...
}) 

I see this in the logs:

[INFO]  TIEXIF: showCamera.success()
[ERROR] File: fail readDirectory() errno=20
[ERROR] File: fail readDirectory() errno=13
[ERROR] File: fail readDirectory() errno=13
[ERROR] File: fail readDirectory() errno=13
[INFO]  TIEXIF: hasStoragePermissions
[INFO]  TIEXIF: nativePath: file:///storage/emulated/0/com.me.exiftest/testphoto.jpg
[WARN]  ExifInterface: Invalid image.
[WARN]  ExifInterface: java.io.FileNotFoundException: file:/storage/emulated/0/com.me.exiftest/testphoto.jpg: open failed: ENOENT (No such file or directory)

I have tried with externalStorageDirectory, applicationDataDirectory, tempDirectory, and applicationCacheDirectory all with the same results.

skypanther
  • 975
  • 8
  • 19

2 Answers2

2

Please remove the file:/ suffix, it is a Titanium specific stuff. Paths in Android begins with /

  • That did it! I do `nativePath.replace('file:', '').replace(/\/\//g, '/')` and pass that to my module and it can access the file just fine. Thanks! – skypanther Dec 20 '16 at 13:51
1

This is how I convert a image path to a file:

private String getPathToApplicationAsset(String assetName) {
    // The url for an application asset can be created by resolving the specified
    // path with the proxy context. This locates a resource relative to the 
    // application resources folder

    String result = resolveUrl(null, assetName);
    return result;
}

// ...
String imageSrc = options.getString("image"); 
// ...
String url = getPathToApplicationAsset(imageSrc);
TiBaseFile file = TiFileFactory.createTitaniumFile(new String[] { url }, false); 

I'm using it to open a file from the resource folder. Didn't try it with an external file yet.

Could you perhaps show your module code where you load the file?

Edit

To use a file for Exif information have a look at this project: https://github.com/freshheads/fh.imagefactory/blob/master/android/src/fh/imagefactory/ImagefactoryModule.java#L66 and especially the marked function. That will convert the path (strip elements)

miga
  • 3,997
  • 13
  • 45
  • I'm trying to use ExifInterface. The constructor accepts a String which the docs say refers to the filename. I was assuming that meant file path but maybe it's just a name relative to the app's data directory. https://developer.android.com/reference/android/media/ExifInterface.html#ExifInterface(java.lang.String) – skypanther Dec 19 '16 at 18:03
  • Ah ok, I've added a link to fh.imagefactory which opens a file and access its exif information (it'll remove the file part) That should work for you, too – miga Dec 19 '16 at 19:38
  • Thanks, that link to the freshheads repo is great. That's better than doing it app side so that the module is easier for a Ti dev to use. – skypanther Dec 20 '16 at 13:53