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.
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.
Oh thanks very much vknow36 with your code i did lots of progress:
it work fine and i succed to obtain album art by saving it in a file, passing path to extention and see it in a layout !
the only problem still existing is that it works well throug companion but as soon as i built APK it doesn't work any more...
the problem is due to outputStream = new FileOutputStream(file);
even if i delete bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
I have "erreur" in reponse ...
i'm sure it's just a detail, because it works very well with companion !
The problem is that you're saving it to an absolute path on the emulated (external) storage. If the compiled app doesn't have the WRITE_EXTERNAL_STORAGE permission and request it at runtime prior to writing the file, the app will fail. Instead, you could write it to a relative file, which writes it to the app-private data directory, and then return the relative path for use in the Image or arrangement components.
it seems there is no error any more, because my code returns :
"/data/user/0/edu.mit.appinventor.aicompanion3/cache/temp.png" with companion
or "/data/user/0/appinventor.ai_jm_latour.imagesMp3/cache/temp.png" with built
but i don't really know if temp.png exists, because i can't go there and see it with my file explorer, and i can't use it in AI with blocks to display image file:
It should work with the whole absolute path. As an alternative so you can inspect the file, you could use form.getExternalCacheDir(), which will dump the file into /storage/emulated/0/Android/.../cache rather than putting it in the private directory.
Cache dir has a problem: i need to move file to Files dir in order to be able to put it in an image...
which is the instruction to save it directly in files dir in my extension ?