For a little game I'm programming I'm trying to supply the user with some voice lines for flavor reasons. I've already recorded several lines, and they're all in the format of languageCode_packageName_name01.mp3.
Since I don't want the same few lines to play all the time, I intend to record several versions, and randomly pick one when retrieving them. For example, retrieving lines for "start" two times could result in playback of de_std_start01 and then de_std_start06.
Since I am quite new to android I'd like to ask for help regarding this implementation. I'm not sure whether I should utilize the raw folder for this task, or the assets folder. If possible, I would like to implement a folder structure like this, which would to my understanding need the use of the assets folder, in order to be able to simply drag & drop new files inside the folder, which will then be taken into account for random selection.:
<root folder>
- de
-- std
--- start
---- start01.mp3
---- start02.mp3
...
When given arguments specifying de, std and start, how would I go about retrieving the different files and randomly pick one of them? Thanks for your help!
If you include them in the raw folder, you should be able to access them as so:
//from your activity
AudioService audioService = new AudioService;
int randomTune = audioService.getRandom();
MediaPlayer mediaPlayer = MediaPlayer.create(context, randomTune);
mediaplayer.start;
//From a seperate service class
Class AudioService {
private int[] audioFiles = {
R.raw.song1, R.raw.song2, R.raw.song3, R.raw.song4, R.raw.song5, R.raw.song6
};
I believe that your folder structure will be somewhat flexible since you are wrapping the actual resource with the R class and referencing that in your code.
public int getRandom(){
// Here i am asking for a random number between 0 and 1, multiplying by 6, rounding
// it down, and explicitly casting to int.
// Result will be random int between 0 and 5. This will be the array index that
// randomly chooses the song.
private int randomIndex;
randomindex = (int) Math.floor(6 * Math.random);
return this.audioFiles[randomIndex];
}
}
Related
In my app there's a large EditText field that contains barcodes separated by "\n". Barcodes can be added to this EditText field either programmatically(in onActivityResult returning from a scanning Activity) or manually.
Random example:
010566510415
40541651654556
561516551588
0043211652
003789453
I need each of these barcodes to be saved locally with their barcode type.
Random example:
012315612323 - Code128 (scanned)
561516551588 - Custom (manually inputted)
0123156124xx - Code128_Custom (scanned, then edited by user!!)
The scanning library I use identifies the barcode types on scan, so I have an ArrayList of objects that saves the scanned barcodes with their respective barcode type.
public class BarcodeObject
{
private int _position = -1;
private String _barcode = "";
private String _barcodeType = "";
}
The problem I'm having is keeping the ArrayList<BarcodeObject> in sync with the editText, when the user manually edits a barcode.
Do you have any ideas as how I should accomplish this?
Edit 1 : Thank you for your answers. One issue is that I don't know what barcode the user is modifying. I managed to solve it by using numbersList.getSelectionStart(); to find out where the cursor is and then look for the nearest "\n" so as to identify the correct barcode(bcs all barcodes are between "\n"). But what happens if the user click selects more than one barcodes and changes them. I just don't know how to keep them in sync.
you can update the array list based of index, example :
private ArrayList<BarcodeObject> barcodes = new ArrayList<Object>();
barcodes.set(#indexposition#, #BarcodeObject#);
and add getter and setter in your BarcodeObject class, for update the object;
Assuming you have an EditText only and you want to save the data after the user stop typing...
You have to extend the class with TextWatcher and override afterTextChanged(),beforeTextChanged(), onTextChanged().
You have to write your desired logic in afterTextChanged() method to achieve functionality needed by you.
That means, in your afterTextChanged(), you can write the following code and it will work well..
bcodes.set(#position#, #Barcode-Object#);
Assuming you have already initilized bcodes...
private ArrayList<BarcodeObject> bcodes = new ArrayList<Object>();
Hope it helps. Cheers!
So guys, this is a big one
I'm currently working on an App which involves a big database creation.
Basicalls what it does is scanning the entire device for any kind of media file and adds it to the database (filtered by certain file extensions).
The way it currently does that is scanning through the device's folders with a recursive function, and every time it finds a file that is actually a file and not a directory AND matches the file extensions I picked it adds the file's path to a previously created ArrayList containing only strings.
This is implemented in an AsyncTask so it's done in the background.
As soon as that task finishes it passes the ArrayList on to another AsyncTask that is responsible for adding those files to the database. Out of simplicity resons I only took the file's path, its name and the title that is stored in its tags for every entry (simple sqlite stuff) and displayed the titles in a ListView in another activity over cursor adapters and so on (which isnt really an issue in my case).
Right now it workes pretty well, doesn't crash or return anything bad (I'm testing on a OnePlus One right now).
BUT I have a really big music library on my phone (around 5400 songs) which is nearly filling my entire storage. And out of some unknown reason to me, the scanning task i mentioned (with the ArrayList) stops at around 3000 files and passes the ArrayList on to the second task, which is obviously not what I'm aming at to have.
My guess is that there might be a big performance issue and using an ArrayList is not the best way to approach this. It might work with a number of files that is under 3000 but higher than that is also necessary...
So what would you guys suggest? Does my approach lack something or do I have to try something completely different?
You don't need scan your folders (and, probably, creating database of media files too), you can just use MediaStore class
The Media provider contains meta data for all available media on both internal and external storage devices.
For example, this piece of code will return all available audio playlists
private List<Playlist> getPlayListsList(){
ContentResolver resolver = getContentResolver();
Uri uri = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;
String[] columns = { _ID, NAME };
Cursor playLists = resolver.query(uri, columns, null, null, null);
List<Playlist> result = new ArrayList<>();
if (playLists == null) {
return result;
}
Cursor cursor;
for (boolean hasItem = playLists.moveToFirst(); hasItem; hasItem = playLists.moveToNext()) {
long id = playLists.getLong(playLists.getColumnIndex(_ID));
String name = playLists.getString(playLists.getColumnIndex(NAME));
cursor = resolver.query(MediaStore.Audio.Playlists.Members.getContentUri("external", id),
new String[]{MediaStore.Audio.Playlists.Members.TITLE, MediaStore.Audio.Playlists.Members.ARTIST,
MediaStore.Audio.Media.DATA, MediaStore.Audio.Playlists.Members.PLAY_ORDER}, null, null, null
);
int songsCount = cursor.getCount();
result.add( new Playlist(
id,
name,
songsCount));
cursor.close();
}
playLists.close();
return result;
}
I am trying a java desktop application(I am a student).
It have to deal with four kinds data during start up:
1)project tree(like eclipse Project tree) view data.
Currently I using XMLEncoder/XMLDecoder to save and reload from XML file.
2)user preferences data. such as font,recently files and so on.
Currently I using java.util.prefs.Preferences.
3)Class data .Some factory class like MenuFactory,util class like DatabaseUtil,FileUtil and so on they have some static data.
Currently I using static initializer in these class to initialize default data.
4)Database-related information,such as connection configuration,frequently used database name and table names.
Currently I using java.util.Properties;
What I want to improve:
1) Is it the right way to save my application data in those four kinds mentioned above ?
2)since there are so many data to load,what should I do during a splash screen.
To load them at start up time or delayed to the time when using them ?
At least,I do not want to deceive user by using the following code(not updating progress bar at a meaningful time):
SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
#Override
protected Void doInBackground() throws Exception {
for (int i = 0; i < 50; i++) {
Thread.sleep(100);// Simulate loading
publish(i*2);// Notify progress
}
return null;
}
3) I think too many static initializer may slowdown the program start up ,any suggestion?
If your app is targeted for high end devices then you can certainly load most of it during the startup/splash screen.
But the issue comes when you have low end devices as well as your target devices. For some of the low end devices loading too much data at startup leaves very less memory for other processing. Some imd leading to even crashing.
Thus it a decision which you have to take wisely and if it some small data then better leave for loading as per required or while that screen is loaded.
I am very new to java and android programming. I was working through the developer page trying to figure out the goings on and the example found at this address: http://developer.android.com/training/basics/fragments/creating.html
produced results that I could not explain. Specifically, the R file generates a couple of variables in the ID subpart that I could not find in any of the resource files. I don't know if I am looking in the wrong place or perhaps it pre generated not from the provided xmls? I am just trying to understand the dynamics of R file generation and interaction with the resource files and am having trouble reconciling that example.
In an android project the R class is automatically updated or generated when every time you build your project. By default the eclipse builds or compiles your code automatically when you save changes or when you hit ctrl + s. So any changes in your resources R is updated. When you specify new ids, layouts, drawables, menus, strings, styles etc. android adds a reference static integer in your R class.
example:
public static final class id {
public static final int image=0x7f070001;
public static final int input=0x7f070000;
public static final int menu_settings=0x7f070002;
}
When you add #+id/myname R will be updated to...
public static final class id {
public static final int image=0x7f070001;
public static final int input=0x7f070000;
public static final int menu_settings=0x7f070002;
public static final int myname=0x<something>;
}
R class is used also to access or as a reference when you want to find, set or get.
setContentView(R.layout.activity_main); //this will set the layout in the activity where R class points out to the integer reference in the R class which somehow used by the system to get the xml layout activity_main
someView.setBackgroundResource(R.drawable.picture) //R points to the integer reference of image which then the system interprets the someView's background is set by the image file picture under drawable resource.
I hope this helps and welcome to android :)
The IDs generated in the R-file cannot be found up, they are generated through algorithms, you have to imagine them like hashcodes, which are unique generated
I recently finished the basics of a game that I'm making and I was going to send it to some friends, but whenever they open the .jar it's just a grey window. When I heard that I assumed it was because of the way I got the images (I used a full path: C:\Users\etc). I did some Googling and found a way to get images that seemed more efficient.
private static Image[] mobImages = new Image[1];
public static void loadImages()
{
mobImages[1] = Handler.loadImage("res/EnemyLv1.png");
}
public static Image getMobImages(int index)
{
return mobImages[index];
}
That's what I would like to use. But I did that and changed the rest of my code to support that. And whenever I run a game I get a few errors. Which all point back to
this:
if(getBounds().intersects(tempEnemy.getBounds()))
and so probably the way I'm getting the images too. How could I fix this? And are there better ways to get Images? I've tried a few but they haven't worked.
EDIT: I finally solved all of the errors! :D The only problem is that none of the images appear. Here's my code again. Any more help? That would be fantastic! Thanks everybody for the support so far!
Hard to say whats going wrong in your code. However I recommend you put your image files into a package in the java project (so they will be part of the JAR file) and access them using Class.getResource()/Class.getResourceAsStream(). That avoids multiple pitfalls and keeps everything together.
A sample how to structure your images into the packages:
myproject
images
ImageLocator.class
MyImage1.jpg
MyImage2.jpg
The ImageLocator class then needs to use relative pathes (just the image name + extension) to access to resources.
public class ImageLocator {
public final static String IMAGE_NAME1 = "MyImage1.jpg";
public static Image getImage(final String name) {
URL url = ImageLocator.class.getResource(name);
Image image = Toolkit.getDefaultToolkit().createImage(url);
// ensure the image is loaded
return new ImageIcon(image).getImage();
}
}
This can be done more elegant, but this should get you started. Defining the image names as constants in the ImageLocator class avoids spreading the concrete path throughout the project (as long as the name is correct in ImageLocator, everything else will be checked by the compiler)
Your code still uses "C:\Users\Kids\Desktop\Java Game\Cosmic Defense\res\EnemyLv2.png" in Enemy.java. Are you sure this exists? If you moved the Cosmic Defense folder, it will not.
(You were talking about changing absolute paths to relative paths, so this may be your problem)
Part of the reason could be that your code is pointing to an index of "1" in an array of size 1, meaning that the only available index is in fact "0".
Try mobImages[0] = Handler.loadImage("res/EnemyLv1.png");