How to access files in the working_directory from an Android extension?

A

AMAAAAAR

Guest
I'm trying to make an extension that allows the player to share a screenshot of their game.

I've made the extension able to send images, and I've made the game take a screenshot with screen_save, but I'm not sure how to pass the path of the image to the extension, as simply giving it the working_directory is not enough. Does anyone know how I could possibly make this work?

I'm using GM 1.4 if it matters.
 
Last edited by a moderator:

FrostyCat

Member
Check out this discussion from a month ago about copying out files from the sandbox (skip to post #13). The strategy that worked in the end was converting the screenshot into Base64 string form and then passing that into the extension instead of the original file.
 
A

AMAAAAAR

Guest
Thank you, I have attempted to imlement the code linked. I have tweaked the code a little to allow the passing of a screenshot rather than a sound file, but I'm getting an error: "315: Couldn't find file". Here's my code:

GML code:
Code:
        fname = "screenshot.png";
        screen_save(fname);
     
        if(file_exists(fname)){
            file = file_bin_open(fname,0);
            size = file_bin_size(file);
            gameTransfer = buffer_create(1024, buffer_grow, 1);
            for(var i=0;i<size;i++;){
                buffer_write(gameTransfer, buffer_u8, file_bin_read_byte(file));
            }
            file_bin_close(file);
            var dataString = buffer_base64_encode(gameTransfer, 0, buffer_get_size(gameTransfer));
            share_image(dataString, fname);
        } else {
          show_debug_message("file open failed");
        }

Java code:
Code:
    public void share_image(String dataString, String fname) {
     
        byte[] data = Base64.decode(dataString, 0);
     
        try{
            File outFile = new File(Environment.getExternalStorageDirectory() + fname);
            FileOutputStream fos = new FileOutputStream(outFile, false);
            fos.write(data);
            fos.close();
        } catch (Exception e){
            Log.i("yoyo", "315: Couldn't find file");
        }
     
    }
Do you know what I'm doing wrong?
 

Tsa05

Member
Why create a grow buffer on the line one line after precisely computing the needed size of the buffer?
gameTransfer = buffer_create(size, buffer_fast, 1);

Aside from that, it looks as though you're now in need of Java assistance, not GameMaker assistance.
Offhand, it would be wise to set up a try-catch block that catches more than just everything. You could catch, for example, FileNotFoundException and SecurityException in order to see whether your Java code is falling apart when it creates the output stream. And what is Base64.decode? Is that a library you've imported? If so...what exceptions can you try there?
Did you mean to use https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html instead?
 
A

AMAAAAAR

Guest
Why create a grow buffer on the line one line after precisely computing the needed size of the buffer?
gameTransfer = buffer_create(size, buffer_fast, 1);

Aside from that, it looks as though you're now in need of Java assistance, not GameMaker assistance.
Offhand, it would be wise to set up a try-catch block that catches more than just everything. You could catch, for example, FileNotFoundException and SecurityException in order to see whether your Java code is falling apart when it creates the output stream. And what is Base64.decode? Is that a library you've imported? If so...what exceptions can you try there?
Did you mean to use https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html instead?

I'm simply trying to follow this solution, while also trying to adapt it to a screenshot rather than sound file: https://forum.yoyogames.com/index.p...-file-using-buffer-problem.38131/#post-236087.
 

Tsa05

Member
Pretty sure that the poster in that thread didn't provide all of his Java code, since he had that working properly and needed gml help. The op provided only the part of his java code where he tried to handle GMS data.

Are you importing a base64 library?
https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html

Side question--what are you really trying to do?
It looks like you're taking a screenshot to a file, opening the file in GameMaker, sending the file's contents to a Java extension, and writing it down again. Is there any reason in particular for this? GameMaker has a file_copy function, there's marketplace extensions for going outside the sandbox, get_save_filename lets you go out of the sandbox natively, and you can post file data using network functions or even open files in a browser. With the code provided, the data seems to be going nowhere.
 

FrostyCat

Member
It looks like you're taking a screenshot to a file, opening the file in GameMaker, sending the file's contents to a Java extension, and writing it down again. Is there any reason in particular for this? GameMaker has a file_copy function, there's marketplace extensions for going outside the sandbox, get_save_filename lets you go out of the sandbox natively, and you can post file data using network functions or even open files in a browser. With the code provided, the data seems to be going nowhere.
There are extensions for reaching things outside the sandbox, but there is no formal documentation on where or how extensions can get at files within the emulated sandbox environment, nor is there a formally sanctioned way to smuggle out things from inside the sandbox.

That's the point of this topic and the one I cited, and it's a blind spot in the Android implementation of the GMS extension mechanism.
 
Top