Compile error with byte[]

Hello

I try to build extension to get Music files tags.

this works well

Blockquote
@SimpleFunction(description = "return file's genre")
public String genre(String song){
File file=new File(song);
metaRetriever = new MediaMetadataRetriever();
if (file.exists()) {
metaRetriever.setDataSource(song);
try {
song=metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE);
if (song == ""|| song == null) { song = ""; }
} catch (Exception e) {
song=" Exception";
}
}else {
song="file not found";
}
return song;
}

but this in the sams class causes compil error: "[javac] warning: [options] bootstrap class path not set in conjunction with -source 1.7"

Blockquote
@SimpleFunction(description = "return file's album art")
public byte album_art(String song){
File file=new File(song);
byte art = new byte[0];
metaRetriever = new MediaMetadataRetriever();
if (file.exists()) {
metaRetriever.setDataSource(song);
try {
art = metaRetriever.getEmbeddedPicture();
Bitmap songImage = BitmapFactory
.decodeByteArray(art, 0, art.length);
} catch (Exception e) {
}
}else {
song="file not found";
}
return art;
}

is somebody have an idea ?

1 Like

Yes.
You can't return byte array from a method.
Either change it to Object or List.

ok, but how will be possible to put it in an image in AI ?

Either compress Bitmap and return a path or take image component and set picture in your method.

how con i do this ?
sorry but i newbie in Java and it is my first extension !

For this search on Google.

And for this look at AI source.

I find this to save a bipmap image in file:

	// sauve une image bipmap dans un fichier
  private File saveBitmap(Bitmap bitmap, String path) {
    File file = null;
    if (bitmap != null) {
        file = new File(path);
        try {
            FileOutputStream outputStream = null;
            try {
                //outputStream = new FileOutputStream(path); //here is set your file path where you want to save or also here you can set file object directly
                //bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); // bitmap is your Bitmap instance, if you want to compress it you can compress reduce percentage
                // PNG is a lossless format, the compression factor (100) is ignored
            } catch (Exception e) {
                //e.printStackTrace();
            } finally {
                try {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return file;
}

and it doesn't compile so i tried :

// sauve une image bipmap dans un fichier
private File saveBitmap(Bitmap bitmap, String path) {
File file = null;
if (bitmap != null) {
file = new File(path);
FileOutputStream outputStream ;
}
return file;
}

but the only line:

FileOutputStream outputStream =null;

generate a GIT compil error...
so how can i save my bipmapImage in a file ?

Take a look at this:

You can't return file object either.
Just compress bitmap and return its path.

Yes vknw360, it is not a problem to compress bitmap.
the problem is to create the ".bmp" file corresponding. to do that, all codes I have found do it with "FileOutputStream outputStream" . It works well with Android studio,
but is not accepted by AI compilator and give me an error !

Ken, your link use "FileOutputStream outputStream" too so i have the same problem: error when i compil it

But why are you compressing Bitmap to bmp file.
You should compress it to png or jpeg file.
Remember you have to return path (String) not a stream or file.

I tried to modify path here

String defineDir(String path){
if(path.substring(0,2)=="//"){
return "file:///storage/emulated/0/AppInventor/assets/"+path.substring(3,path.length());
}else{
if(path.substring(0,1)=="/"){
return "file:///mnt/sdcard"+path;
}else {
if (path.substring(0, 7) == "file:///" {
return path;
}
else return path;
}
}
}

but it can't compare substring with "/" or "//" I don't know why !

copy from one of my extensions, hope it helps

public InputStream openFile(String filename) throws IOException {
	InputStream inputStream = null;
	if (filename.startsWith("//")) {
		filename = filename.substring(2);
		if (isReplForm) {
			inputStream = new FileInputStream("/mnt/sdcard/AppInventor/assets/" + filename);
		} else {
			final AssetManager am = activity.getAssets();
			inputStream = am.open(filename);
		}
	} else if (filename.toLowerCase().startsWith("/sdcard/")) {
		filename = "/mnt/sdcard/" + filename.substring(8);
		inputStream = new FileInputStream(filename);
	} else {
		inputStream = new FileInputStream(filename);
	}
	return inputStream;
}

Thanks very much Kevinkun.
I just have some trouble when i copy your code:

  • What is "isReplForm" variable ?
    -it ask me for "activity" variable !

but i use .startWith until subString as in your code and it works well.

so, i update my first post

ReplForm - means that it's being run in the Companion

if (form instanceof ReplForm) { // Note: form is defined in our superclass
isReplForm = true;
}

Hi, you can return the image (byte[]) as an Object and pass it to my Extension :https://ullisroboterseite.de/android-AI2-utils-en.html#img. The extension displays it on an AI2 Image Block. So you don't have to store it and worry about wasting memory. You will find my e-mail address on my page if there are further questions.

Ulli

Thanks Ulli,
It seems to be a good way, but how do i return my image as an object ?

i code in Mp3Tags:

@SimpleFunction(description = "return file's album art")
public Object album_art(String song){
File file=new File(song);
AlbumArt art;
art = new AlbumArt() ;
art.album_art(song);
return art;
}

and a new class AlbumArt

package jml.AlbumArt;
import java.io.File;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaMetadataRetriever;
public class AlbumArt {
MediaMetadataRetriever metaRetriever;
byte image =null;
public void AlbumArt(){
}
public void album_art(String song){
File file=new File(song);
byte art = new byte[0];
metaRetriever = new MediaMetadataRetriever();
if (file.exists()) {
metaRetriever.setDataSource(song);
try {
art = metaRetriever.getEmbeddedPicture();
Bitmap songImage = BitmapFactory
.decodeByteArray(art, 0, art.length);
} catch (Exception e) {
}
}else {
song="file not found";
}
image=art;
}
}

I save both Mp3Tags.java and AlbumArt.java in scr/jml/
but i have compil error :

[javac] C:\Users\Jml\appinventor-sources\appinventor\components\src\jml\Mp3Tags.java:156: error: cannot find symbol
[javac] AlbumArt art;
[javac] ^
[javac] symbol: class AlbumArt
[javac] location: class Mp3Tags
[javac] C:\Users\Jml\appinventor-sources\appinventor\components\src\jml\Mp3Tags.java:157: error: cannot find symbol
[javac] art = new AlbumArt() ;
[javac] ^
[javac] symbol: class AlbumArt
[javac] location: class Mp3Tags
[javac] Note: Some input files use or override a deprecated API.
[javac] Note: Recompile with -Xlint:deprecation for details.
[javac] Note: Some input files use unchecked or unsafe operations.
[javac] Note: Recompile with -Xlint:unchecked for details.
[javac] 2 errors

You can return Object, which will just be treated as an opaque thing by the blocks language. The user won't be able to do anything to manipulate it, but it can be passed to other methods. In this case though, you probably want to write the album art data to a file somewhere and return the path so that it can be assigned to a Button's Image property or the Image's Picture property.

I tried this ewpatton, but i didn't succed to write the album art in a file: all exemples i have seen to do that use "FileOutputStream" but as soon as i use it in my code, AI compiler return an error...so i don't know how save my bitmap in a file !

What was the error? Did you forget to import FileOutputStream? You may want to look at code such as Canvas's SaveAs function, which writes the Canvas image to a file. It's definitely feasible to write to a file from an extension.