I'm recently starting with codenameone and I'm working on a music player app. I want to get the musics from a folder. I found out in the documentation a code about "Audio Capture & Recording".
But what I'm looking for is to just play audios from a specific folder.How can I adjust this code? I'm also not finding where these audios are being saved to.
Here's the code+ a footage of the Recording code.
Button button = new Button("musiques!");
Form hi = new Form("musiques", new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE));
hi.addComponent(BorderLayout.CENTER, LayeredLayout.encloseIn(BoxLayout.encloseY(button)));
button.addActionListener((e) -> {
InputStream streamFromResource = CN.getResourceAsStream("/filename.mp3");
try {
MediaManager.createMedia(streamFromResource, "audio/mp3");
} catch (IOException ex) {
System.out.print("non");
}
});
The audio is in fs.getAppHomePath() + "recordings/". Bundling the audios into the jar will increase your jar size and final app size which will exceed the free quota so we don't normally recommend that.
If you still choose to go with that route you can store the files in the root of the src folder and access them using CN.getResourceAsStream("/filename.mp3").
Then you can just use:
Media m = MediaManager.createMedia(streamFromResource, "audio/mp3");
Alternatively you can store the files on the web and use an HTTPS URL instead of a file URL to play them.
You can't dynamically list the files since there's no listing option for HTTP or for the contents of the jar.
Related
I'm trying to copy a file that is located in the External storage directory into a directory that is in my SD Card. However, when I check to see if the file has successfully been copied, the file is not even created in the SD Card.
Am I missing something? Here is the code I have:
String sourcePath = Environment.getExternalStorageDirectory().getPath() + newFileName;
File source = new File(Environment.getExternalStorageDirectory().getPath(), newFileName);
String destinationPath = "/storage/external_SD";
File destination = new File(destinationPath, newFileName);
try {
if(!destination.exists()){
destination.mkdir();
}
FileUtils.copyFile(source, destination);
} catch (IOException e) {
e.printStackTrace();
}
The copyFile method is from an Apache library. Here is the link for it: https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/FileUtils.html
However, when I check to see if the file has successfully been copied, the file is not even created in the sd Card.
You do not have arbitrary filesystem-level access to removable storage on Android 4.4+.
Is there a work around for this?
That depends on what your objective is.
If you insist that you must be able to write to that specific path on arbitrary user devices... then, no, there is no supported workaround. After all, there is no /storage/external_SD on the vast majority of Android devices. Where and how device manufacturers choose to mount removable media is up to them and is an implementation detail that will vary.
If you relax that restriction, but insist that you must be able to write a file to the root directory of removable storage on arbitrary user devices... then, no, there is no supported workaround today. The N Developer Preview has a "Scoped Directory Access" feature that should allow this, but it will be several years before you can assume that an arbitrary user device will be running that version of Android or higher. Also, you do not get actual filesystem access, but rather a Uri (see the Storage Access Framework option, below).
Now, if you are more flexible about the precise location, you have other options:
You can use getExternalFilesDirs(), getExternalCacheDirs(), and getExternalMediaDirs(), all methods on Context. Note the plural form. If those return 2+ entries, the second and subsequent ones are locations on removable storage that you can read from and write to, no permissions required. However, you do not get to choose the exact path. And if the device has 2+ removable storage volumes, I'm not quite certain how you would help the user tell them apart.
You can use the Storage Access Framework and let the user choose where to put the file. The user is welcome to choose removable storage... or not. You get a Uri back, which you can use with ContentResolver and openOutputStream() to write your content. You can also take persistable Uri permissions so you can work with that file again in the future, assuming the user doesn't move or delete it behind your back.
If you want to copy to external storage then you need
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
The destinationPath you mentioned may not be accessible as it may belong to the private system folders or some other application folders. You can however use public folders like Pictures,Music, Videos,Downloads,etc. or create sub folders inside them -
String sourcePath = Environment.getExternalStorageDirectory().getPath() + newFileName;
File source = new File(Environment.getExternalStorageDirectory().getPath(), newFileName);
File destinationPath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS, "/external_SD");
try {
if(!destinationPath.exists()){
destinationPath.mkdir();
}
File destination = new File(destinationPath, newFileName);
FileUtils.copyFile(source, destination);
} catch (IOException e) {
e.printStackTrace();
}
Before It gets brought up about my question already being asked, I would like to state that I have tried around 5 other options and possible solutions with no result.
Here is a snippet of my code. This is just a snippet. Upon testing the results of my code currently, a file is being saved in the main directory, /ScoutingApp. However, I would like to files to save in a folder /ScoutingApp/ on the MicroSD card so I can eject data more quickly.
if (Environment.MEDIA_MOUNTED.equals(state)) {
File root = Environment.getExternalStorageDirectory();
File Dir = new File(root.getAbsolutePath() + "/ScoutingApp");
if (!Dir.exists()) {
Dir.mkdir();
} else {
filename = UUID.randomUUID().toString() + ".sql";
File file = new File(Dir, filename);
If the Android that your Fire OS is based on is Android 4.4+, you can try getExternalFilesDirs() on any Context (such as an Activity). Note the plural form — if this method returns 2+ items, the second and subsequent ones are on removable storage. Those locations will be specific for your app, and you can read from and write to those locations without permissions.
Note, though, that Fire OS is not completely compliant with the Play ecosystem's compatibility requirements, and so YMMV.
I am trying to program a classroom assistant (I work as a teacher) using Java who will give spoken instructions to students/ask them questions etc. I have managed to connect successfully to the cerevoice cloud to create an ogg file
e.g. "https://cerevoice.s3.amazonaws.com/Heather220501c8c2e94d4650f64f7d951bf76b08b0eb.ogg"
however when I try to play this ogg file from java I get an error that it could not be found or that it is an unsupported audio resource depending on the ogg player I use (i have tried EasyOGG and TinySound so far) - both the ogg players work successfully locally but I cannot get them to play a file directly from the website.
Examples how I have tried to reference it:
URL url = new URL("https://cerevoice.s3.amazonaws.com/Heather220501c8c2e94d4650f64f7d951bf76b08b0eb.ogg");
Music song = TinySound.loadMusic(url);
song.play(true);
OggClip ogg = new OggClip("https://cerevoice.s3.amazonaws.com/Heather220501c8c2e94d4650f64f7d951bf76b08b0eb.ogg");
ogg.loop();
Apologies for my ignorance I'd really appreciate any help anyone can give with playing this file! =)
Many thanks,
Darren
Edited to show using a literal String value to help clarity
Edit very ugly hack 1 solution: //opens a browser window plays file then closes window
String url = "https://cerevoice.s3.amazonaws.com/Heather220501c8c2e94d4650f64f7d951bf76b08b0eb.ogg"; //hard coded here for simplicity but URL dynamically retrieved from webservice
java.awt.Desktop.getDesktop().browse(java.net.URI.create(url));
Thread.sleep(3000);
Runtime.getRuntime().exec("taskkill /F /IM chrome.exe");
Edit slightly less ugly hack 2 solution:
//creation of a temporary file to allow playing from java without creating a browser window
try{
Files.deleteIfExists(Paths.get("C:/cere/temp.ogg"));
try (InputStream in = URI.create(url.value).toURL().openStream()) {
Files.copy(in, Paths.get("C:/cere/temp.ogg"));
}catch(IOException e) {
}
I have made a music player and I want to save images for album art. Where should I put all the images: in the Asset folder or somewhere else? The images are in large quantity and I want the images available in the app after publishing it.
I also try to get images through URL with this method
private Bitmap downloadBitmap(final String url) {
final MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
metaRetriever.setDataSource(url, new HashMap<String, String>());
try {
final byte[] art = metaRetriever.getEmbeddedPicture();
return BitmapFactory.decodeByteArray(art, 0, art.length);
} catch (Exception e) {
Log.d("ALBUM ERROR", "Couldn't create album art: " + e.getMessage());
return null;
}finally {
metaRetriever.release();
}
}
But the image loading is very slow. This is why I try to save image in the app asset folder, so images are always there if app is publish.
You should read through the Offical Documentation on the storage options available, how to access them and which to use.
The assets folder is used to hold files you ship with your app, not files you dynamically create later. Also since you mentioned there will be many images you should be mindful not to waste space on "internal storage" as some (older) devices have very limited internal space available.
I'd suggest you use the "external storage" as you say there are going to be quite a lot of images. I can't see album art files needing to be private either so a public location like this is just fine although you might opt to use private storage to hide the images from the media scanner and all those images showing up in the user's gallery.
Calling it "external" doesn't necessarily mean it is external, such as a removable SD card. Some devices emulate this storage on internal memory. But you should handle the case where is is actually an external hardware location and the user has removed or unmounted the media.
If you any experience with server side programming I would recommend you to host a simple server yourself in a cheap host such as DigitalOcean or you can try another easier solution for rest api such as Parse.
I personally really like Digital Ocean because its only $5 a month with 20 GB Storage. The only downside is that you have to be familiar of using the Command Line to host your server :)
I am writing out a file to the external storage on android. The file shows up in my device when I browse to location using the ap ES file explorer.
But when I plug my device in to windows, the file does not show up.
Furthermore if I write an empty file named "test.wav" to Ringtones folder, no test.wav will show up in my ringtones settings.
But, if I create an empty file in windows named "test.wav", and drag and drop into my Ringtones folder, it will then properly show up in my ringtones browser in settings.
Code I am using is a follows.
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_RINGTONES), "testfile.wav");
file.setReadable(true);
try {
FileOutputStream fileOut = new FileOutputStream(file);
stream = new DataOutputStream(fileOut);
stream.flush();
stream.close();
//this code successfully creates a file
// but file is not viewable by all means
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Android uses tables to keep track of images, videos, sounds and so on these tables called " content providers " for example it uses MediaStore.Images.Media.DATA for images Note that these tables are used for the view this illustrates why you can only see it using ES. When you add new file manually, you need to add an entry for this file in the corresponding table or refresh your music library in case of sound file was added, but when you add file using windows the device's driver updates its tables automatically. Try refreshing your music application or even restarting your phone if this solves the problem updating your content provider is the solution.
I could be wrong but I think that it is /extsd showing when you plug your device into Windows, whereas external storage is actually /sdcard. so your file is in /sdcard, not in /extsd, that's why you don't see it. At least whenever I plugged Android tab into Windows, I could only browse its removable SD, i.e. /extsd but I couldn't see /sdcard