I want to build an android app. Basically, I have a Web site where I have a lot of music into categories and from there you can listen to it or download. I want to use my app to have a mobile view of my site, and I know how to do it with android studio, there are just some things I need to change. Anyway, I want the app background/style to be different, and I want everytime I add a new category to my site, to be added to my app to. At first, I was wanting to make a button for every category, but I realised it won t work.
Anyway, in the app, the first thing that you ll see are the categories, then if you click on one of them, you will se a list of ringtone, and if you click on a ringtone, you will have 4 options : set as ringtone, set as notification, set as alarm. I know what s the code for this things, what I do not understand is where to place it, because I want my app to use the music from my site, not to have a music as an asset and then set it (that s the way I know how to do it). I know is redundant, but I am a teenager:)). I know how to build an app that can set a ringtone, I do not know how to do it for hundreds of ringtones that I do not have as an asset.
Some ideas please ? Maybe a video oor something to read
For playing a ringtone for preview purposes you have two options:
You can either stream it via the MediaPlayer class.
which is done like this:
String url = "http://your-path";
MediaPlayer mPlayer = new MediaPlayer();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setDataSource(url);
mPlayer.prepare();
mPlayer.start();
but keep in mind that prepare() method might take a while and it blocks UI thread. you need to use prepareAsync() and set a listener for it when prepared.
mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
mPlayer.start();
}
});
but if you'd also like to download it before playing it you can use this library AQuery. If you are new to android it can really help you to easily make http calls and downloads asynchronously. It is initiated and used as follows:
AQuery aq = new AQuery(context);
File ringtoneFileToDownload = new File("http://path/to/your/online/ringtone");
aq.download(url, ringtoneFileToDownload, new AjaxCallback<File>(){
#Override
public void callback(String url, File file, AjaxStatus status) {
//method is called when the download is finished
//and the file parameter is the file downloaded
//which you can play as above with the MediaPlayer class
}
});
you can use the above method to download it to the device and keep them local.
As the last thing don't forget to add the required permissions in the manifest file:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Related
I have a working Alert Receiver etc., and it starts my 'Alarm Screen Activity'.
I want this activity to play an MP3 file from resources as an alarm tone.
Found lots of questions and answers but no working solution :-(
I have my file in: ... MyFirstApp\app\src\main\res\raw folder
The below code is on the onCreate method of my activity:
Uri uri_a = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
Uri uri_b = Uri.parse("android.resource://com.myapps.myfirstapp/res/raw/" + R.raw.def_alarm_tone);
ringTone = RingtoneManager.getRingtone(getApplicationContext(), uri_b);
ringTone.play();
If I use uri_a on line 3 - it works and plays the default alarm ringtone.
If I use uri_b - I get no sound - Errors in logs show java.io.FileNotFoundException.
So, any suggestions on what I'm doing wrong - or alternatives / better solutions???
Also, some suggestions on managing apps alarms/reminders would be nice.
What are the pros/cons of using MediaPlayer for alarms as an alternative?
Why don't you try something like this?
MediaPlayer BG;
....
BG = MediaPlayer.create(getBaseContext(), R.raw.def_alarm_tone);
BG.setLooping(false);
BG.setVolume(100, 100);
...
//whenever you want to use it
BG.start();
Make sure the file is in the App res/raw directory.
Turns out I was having trouble using URI's because my application ID didn't match my package name in Gradle Script (Module: app) ... as I changed my application name recently.
Fixed that, and now it works as expected.
My app has a photo gallery that displays a constant list of images. I need to add one video to that list (just one, provided by me). This video is inside an expansion file. I would like to let the user decide the video player he wants to use to play the video. So I went for the intent approach:
public void playVideo(View view){
Intent videoint = new Intent(Intent.ACTION_VIEW);
Uri uri = CustomAPEZProvider.buildUri("test.3gp");
Log.d("TEST", uri.toString());
videoint.setDataAndType(uri, "video/*");
startActivity(videoint);
}
My CustomAPEZProvider is the following:
public class CustomAPEZProvider extends APEZProvider {
private static final String AUTHORITY = "com.myapp.package.provider";
#Override
public String getAuthority() {
return AUTHORITY;
}
public static Uri buildUri(String path) {
StringBuilder contentPath = new StringBuilder("content://");
contentPath.append(AUTHORITY);
contentPath.append(File.separator);
contentPath.append(path);
return Uri.parse(contentPath.toString());
}
}
Also, I added this to my manifest:
<provider android:name="com.myapp.package.CustomAPEZProvider"
android:authorities="com.myapp.package.provider" >
android:exported="true"
android:multiprocess="true">
<meta-data
android:name="mainVersion"
android:value="4"/>
</provider>
The provider has this meta-data because the expansion file version differs from the apps version code.
I understand that the file is being found, but the video players are not able to play it. They are launching the can't play this video window (and no errors). I tested it on many devices and with different kinds of videos. The 3gp video I'm using to test can be played just fine from the phone's native gallery.
Line 3 on the playVideo method is printing this
content://com.myapp.package.provider/test.3gp
This is correct, right?
The expansion file has no folders, files are just thrown at root.
Also, I actually need to play this test.3gp video from the patch expansion file. Will there be any difference in that case? I'm eliminating this obstacle for now. I know I should add it to the provider's meta-data.
Some extra information: the expansion file has several audio files that I'm being able to play using a MediaPlayer without any issues. Of course, this is different because in that case I'm doing it by getting an AssetFileDescriptor to the file inside the obb expansion file, whereas with the video I need an Uri, which changes everything.
I read lots of questions with similar problems, but they were not helpful. Does anyone had the same problem?
Workarounds are also welcome. For example, I could accept to use a VideoView if needed.
UPDATE
I've just realised that the video player is not working, even if the file is a resource (inside drawable, raw, or whatever). I did manage to play the video with the code below:
public void playVideo(View view){
Uri uri = CustomAPEZProvider.buildUri("test.3gp");
getWindow().setFormat(PixelFormat.TRANSLUCENT);
VideoView videoHolder = new VideoView(this);
videoHolder.setMediaController(new MediaController(this));
videoHolder.setVideoURI(uri);
setContentView(videoHolder);
videoHolder.start();
}
But this is not exactly what I want, I'd really like to allow the user to choose the video player of his preference. Mainly because I want to free myself from the responsibility to code a nice-to-look-at video player.
I don't think the problem lies anywhere in your code. Or, if it does, it's not your biggest problem.
I think your biggest problem is using a 3GP file. That format is not supported by all devices. You're better off with an MP4. And even then, make sure that it's encoded with a CODEC that all Android devices understand.
I had the same problem (video played without problem with native gallery, but not through intent). How the problem is solved is to add the following line to manifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
and give the permission to the installed app.
According to this post, the song's artist, album, track can be retrieved from a BroadcastReceiver, but the song's information which are current playing in Spotify or Pandora cannot be retrieved.(Maybe because these apps don't send broadcast while playing songs).
My question is, how to get current playing song's information on system level, no matter whether the app is broadcasting.
Listening for com.android.music.* broadcasts is the official way to do this on Android.
Many apps like lyrics displayers rely on it to get info on the current track.
Sadly, if the app is not broadcasting the solution is either to have a look at their Dev documentation in case they provide another way to do this or directly ask them to implement it.
For Spotify, it looks like right now they use a 'com.spotify.music.metadatachanged' broadcast (and a settings in the app). You will have to track down separate cases like this one, nothing forces Android devs to implement the standard broadcast.
In android 4.4+, you can use the RemoteController class to get track information from the current playing song. This works with every app that implements a RemoteControlClient. It also works with video- and streamservices like chromecast.
http://forum.xda-developers.com/showthread.php?p=48702254#post48702254
This is a very handy guide if you want to use this RemoteController.
And the developers page:
https://developer.android.com/reference/android/media/RemoteController.html
definitely u know the path of the song where is running
Uri myUri1 = Uri.parse(path);
now u can call this method having the path then we can get all information either in the activity or from the service by binding
private void getTrackInfo(Uri audioFileUri) {
MediaMetadataRetriever metaRetriever= new MediaMetadataRetriever();
metaRetriever.setDataSource(getRealPathFromURI(audioFileUri));
String artist = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
String title = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
}
private String getRealPathFromURI(Uri uri) {
File myFile = new File(uri.getPath().toString());
String s = myFile.getAbsolutePath();
return s;
}
I am working with streaming video and I want to change from one source to another dinamically.
First I set the video uri to the VideoView
view.setVideoURI(myUri);
And I know that I am capable of changing it afterwards by doing (this is in onPrepare method but it could go somewhere else where I have access to the MediaPlayer).
#Override
public void onPrepared(MediaPlayer mp)
{
Uri newUri = getOtherUri();
mp.reset();
mp.setDataSource(getApplicationContext(), newUri);
mp.prepare();
mp.start();
}
The thing is, I want to change the source without reseting the mediaPlayer (I do not want to disturb the user).
I tried to create a new VideoView with the new Uri and then change one object for the other, and likewise with the media player. However, none of that seems to work.
Is it possible to replace a video while it is playing in Android?
Any comments would be appreciated.
There is no option to reset the video without using mediaplayer.stopPlayback() or mediaplayer.reset. The reason is that; the previous object of the mediaplayer has to be released before you can play other video .
I want to change the source without reseting the mediaPlayer (I do not want to disturb the user).
Well, this cannot be achieved as the mediaplayer has to be reset. So there will be lag while changing videos. And to satisfy you, you can see these behavior in any videoplayer app like youtube or mxplayer.
So the only thing you can do is to show progressbar while loading or changing video.
Hope it helps. Cheeers.:)
I'm using a book called Android Wireless Application Development 2nd edition 2009 (L.Darcey & S.Conder, published by Addison Wesley) as my literature for a course I'm currently doing in Android app development. In the third chapter of this book you use the MediaPlayer class to initiate a media player object to stream mp3 files to your app using to this method below.
public void playMusicFromWeb() {
try {
Uri file = Uri.parse("http://downloads.bbc.co.uk/podcasts/6music/adamandjoe/adamandjoe_20111231-1430a.mp3");
mp = MediaPlayer.create(this, file);
mp.start();
}
catch (Exception e) {
Log.e(DEBUG_TAG, "Player failed", e);
}
}
Happy days, this all works just fine in API 8 (which is what the book uses). However trying to use this method in a higher API, especially 15 which is (on writing) the latest API available I get a NullPointerException thrown. Debugging makes me none the wiser as the file variable seems to hold the string value fine, but it won't translate into a functional mp3 stream. I have tried various different approaches using prepare(); prepareAsync(); setDataSource(); reset(); etc., however nothing seems to work. You'd think that my teachers would be able to help me out, but they apparently don't know what to do either.
I now assume that this way of streaming must be obsolete in higher API's than 8. I would be very grateful if someone could shine a light on how to stream an mp3 file in API 15.
I think you have to do more than that. Here is an example for doing what you want:
The Header's content-type of the URL could be bad.
You could try this syntax:
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(URL_OF_FILE);
mp.prepare();
mp.start();
See if the NullPointerException remains.
You could also view a more recent tutorial on this particular subject.
It was as simple as adding this line:
<uses-permission android:name="android.permission.INTERNET" />
to the manifest file!