Receiving Info of a ShoutCast stream on Android - android

I am currently making an app to go with my online radio site, I am coding it with Android 2.2 (API 8) and I have got the Shoutcast Stream working with two buttons.
Here is the code on my main class:
public class GrooveOfMusicRadioActivity extends Activity {
/** Called when the activity is first created. */
MediaPlayer mediaPlayer;
Button start, stop;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
start = (Button) findViewById(R.id.button1);
stop = (Button) findViewById(R.id.button2);
start.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
mediaPlayer.start();
}
});
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
mediaPlayer.pause();
}
});
String url = "http://67.212.165.106:8161"; // your URL here
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
try {
mediaPlayer.setDataSource(url);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
So I was wondering so how do I receive the stream title,song,artist etc.. and make it appear
The main XML is in a relative layout
Thanks, I am a total noob when it comes to programming.
Thanks mark :)

I just had to get meta data myself, I basically did the same stuff from: Pulling Track Info From an Audio Stream Using PHP. A lot of data is in the headers so you can use those, but all I wanted was the Stream Title, so thats what I got.
Activity mainAct = this;
public void getNowPlaying(View v) {
Log.w("getNowPlaying", "fired");
new Thread(new Runnable() {
public void run() {
String title = null, djName = null;
try {
URL updateURL = new URL(YOUR_STREAM_URL_HERE);
URLConnection conn = updateURL.openConnection();
conn.setRequestProperty("Icy-MetaData", "1");
int interval = Integer.valueOf(conn.getHeaderField("icy-metaint")); // You can get more headers if you wish. There is other useful data.
InputStream is = conn.getInputStream();
int skipped = 0;
while (skipped < interval) {
skipped += is.skip(interval - skipped);
}
int metadataLength = is.read() * 16;
int bytesRead = 0;
int offset = 0;
byte[] bytes = new byte[metadataLength];
while (bytesRead < metadataLength && bytesRead != -1) {
bytesRead = is.read(bytes, offset, metadataLength);
offset = bytesRead;
}
String metaData = new String(bytes).trim();
title = metaData.substring(metaData.indexOf("StreamTitle='") + 13, metaData.indexOf(" / ", metaData.indexOf("StreamTitle='"))).trim();
djName = metaData.substring(metaData.indexOf(" / ", metaData.indexOf("StreamTitle='")) + 3, metaData.indexOf("';", metaData.indexOf("StreamTitle='"))).trim();
Log.w("metadata", metaData);
is.close();
} catch (MalformedURLException e) { e.printStackTrace();
} catch (IOException e) { e.printStackTrace(); }
final String titleFin = title;
final String djNameFin = djName;
mainAct.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(mainAct, titleFin + "\n" + djNameFin, Toast.LENGTH_SHORT).show();
}
});
}
}).start();
}

What you're using to play the stream has no knowledge of (and doesn't care about) the metadata. You're going to have to deal with that separately.
See these posts for something you can easily adapt to Android:
Pulling Track Info From an Audio Stream Using PHP
http://www.smackfu.com/stuff/programming/shoutcast.html

Related

Android App Async Failing to load internal data

I'm currently learning about IO and Async but am having issues. I'm following a guide, and according to the guide this is supposed to work. I have created an activity with a simple EditText, TextView, and 2 Buttons(save and load). I am trying to have the save button take the text in the EditText and save to internal storage, and the load button take whatever is saved and set the TextView as that. Everything works flawlessly when I put all the code to run in the UI thread, but if I change the code to have the UI thread call the Async class for the loading, nothing seems to happen.
**Packages and imports have been removed to save space.
public class InternalData extends Activity implements OnClickListener {
EditText etSharedData;
TextView tvDataResults;
FileOutputStream fos;
String FILENAME = "InternalString";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.sharedpreferences);
setupVariables();
}
private void setupVariables() {
Button bSave = (Button) findViewById(R.id.bSave);
Button bLoad = (Button) findViewById(R.id.bLoad);
etSharedData = (EditText) findViewById(R.id.etSharedPrefs);
tvDataResults = (TextView) findViewById(R.id.tvLoadSharedPrefs);
bSave.setOnClickListener(this);
bLoad.setOnClickListener(this);
try {
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.bSave:
String sData = etSharedData.getText().toString();
try {
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(sData.getBytes());
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case R.id.bLoad:
String sCollected = null;
FileInputStream fis = null;
try {
fis = openFileInput(FILENAME);
byte[] dataArray = new byte[fis.available()];
while(fis.read(dataArray) != -1){
sCollected = new String(dataArray);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
try {
fis.close();
tvDataResults.setText(sCollected);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
break;
}
}
The previous code makes everything work, but the UI lags a bit when trying to load large strings. When I try to have an LoadSomeStuff(Async) class do the loading, it does absolutely nothing when I hit Load on my phone. Within the LoadSomeStuff class it has the doInBackground method open the file and read the data into a string then return that string, and the onPostExecute method set the TextView's text to the returned String. Here's the code:
The onClick method for load button has:
new LoadSomeStuff().execute(FILENAME);
LoadSomeStuff Class *Note: This class is declared within the InternalData class.
public class LoadSomeStuff extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
String sCollected = null;
FileInputStream fis = null;
try {
fis = openFileInput(FILENAME);
byte[] dataArray = new byte[fis.available()];
while(fis.read(dataArray) != -1){
sCollected = new String(dataArray);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
try {
fis.close();
return sCollected;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
protected void onPostExecute(String result){
tvDataResults.setText(result);
}
}
}
Any help is greatly appreciated, thanks!
It actually looks like I had an extra method or two(like onPreExecute) with no code in them and when I deleted them it starting working.

Android record stream can't stop

I want to record streaming radio
now this is my code
press.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
String filename = Environment.getExternalStorageDirectory().getAbsolutePath();
filename += "/music.mp3";
outputSource= new File(filename);
bytesRead = -1;
URL url;
try {
url = new URL("** URL **");
inputStream = url.openStream();
Log.d(LOG_TAG, "url.openStream()");
fileOutputStream = new FileOutputStream(outputSource);
Log.d(LOG_TAG, "FileOutputStream: " + outputSource);
while ((c = inputStream.read()) != -1) {
fileOutputStream.write(c);
bytesRead++;
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
when i click the button it run continuously and can't be stopped, when i click the stop button it said to me that the program is not responding i have to wait or exit
so how i can start the record when i click record button and stop it when i click stop button ?
You do network operations on UI thread. This is not only wrong, this will throw NetworkOnMainThreadException
Use AsyncTask or create new Thread, which will be terminated on cancel.

Button text and string from text file (from asset) should be the same, but not in Android

I would like to make a quiz program. The questions are in a text file in asset folder. The answers are also in the asset folder called the number of the question (for example: the first question answers are in the text file called 1). I would like to give the questions and answers randomly (answers to a button). Until this everything is all right (maybe not the shortest solution, but works well). Then the user can answer the question clicking the correct button. And here is the problem. I get the text of the button and the first row of the answer file (always the first row is the right answer in the answer text file). It should be the same, and then I sign, this is the correct answer. But it's not the same, and I don't know why. A put text to the button from the answer file and get the first row from the answer file, so it should be the same. I print it out to log cat, and look like they are the same. I don't know what could be went wrong.
Can anybody help me out.
This is where I set the text of the button (randomly) and compare the first rows and the text of the button:
BufferedReader br2 = new BufferedReader(is2, 8192);
for(int k2=0; k2<3; k2++){
try {
kerdes2[k2] = br2.readLine();
final ArrayList <Integer> kerdesno2 = new ArrayList<Integer>();
for(int j=0;j<3;j++) kerdesno2.add(j);
Collections.shuffle(kerdesno2);
System.out.println(kerdesno2);
answ.setText(kerdes2[kerdesno2.get(0)]);
answ2.setText(kerdes2[kerdesno2.get(1)]);
answ3.setText(kerdes2[kerdesno2.get(2)]);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
answ.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
InputStreamReader is3 = null;
try {
is3 = new InputStreamReader(am.open(i3), "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedReader br3 = new BufferedReader(is3, 8192);
try {
String helyes = br3.readLine();
System.out.println(helyes);
String gomb = answ.getText().toString();
System.out.println(gomb);
for(int f=0; f<helyes.length(); f++)
{
char c = helyes.charAt(f);
char d = gomb.charAt(f);
if(c != d){
System.out.println(c);
System.out.println(((String) gomb).indexOf(c));
}
}
if(gomb == helyes)
{
x++;
TextView eredmeny = (TextView)findViewById(R.id.eredmeny);
eredmeny.setText("Eredményed: " + Math.round(x*100/i2) + "%");
}
else
{
TextView eredmeny = (TextView)findViewById(R.id.eredmeny);
eredmeny.setText(gomb + " = " + helyes);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
answ2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
InputStreamReader is3 = null;
try {
is3 = new InputStreamReader(am.open(i3), "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedReader br3 = new BufferedReader(is3, 8192);
try {
String helyes = br3.readLine();
System.out.println(helyes);
String gomb = answ2.getText().toString();
System.out.println(gomb);
if(gomb == helyes)
{
x++;
TextView eredmeny = (TextView)findViewById(R.id.eredmeny);
eredmeny.setText("Eredményed: " + Math.round(x*100/i2) + "%");
}
else
{
TextView eredmeny = (TextView)findViewById(R.id.eredmeny);
eredmeny.setText(gomb + " = " + helyes);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
answ3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
InputStreamReader is3 = null;
try {
is3 = new InputStreamReader(am.open(i3), "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedReader br3 = new BufferedReader(is3, 8192);
try {
String gomb = answ3.getText().toString();
String helyes = br3.readLine();
System.out.println(gomb);
System.out.println(helyes);
if(gomb == helyes){
x++;
TextView eredmeny = (TextView)findViewById(R.id.eredmeny);
eredmeny.setText("Eredményed: " + Math.round(x*100/i2) + "%");
}
else
{
TextView eredmeny = (TextView)findViewById(R.id.eredmeny);
eredmeny.setText(gomb + " = " + helyes);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
As You can see I try to iterate over the two strings to realize where the problem is, but I couldn't manage to find...
String is an object. When comparing objects, use .equals(), not ==.
Your code:
if(gomb == helyes)
Should be:
if(gomb.equals(helyes))
By using == you're comparing memory, not the actual String objects. Sometimes you'll get the expected result, but other times you won't. .equals() will always test the Strings themselves.
I can see you are comparing by
if(gomb == helyes){
while it should be
if(gomb.equals(helyes)){

File reading not working for android

I am an android newbie and wrote this code for file handling but for some reason i am always getting back null values from the file. I also tried using readline() but got the same result. Would appreciate any help.
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
String file = "test123";
try
{
OutputStream out = v.getContext().openFileOutput(file, MODE_PRIVATE);
InputStream in = v.getContext().openFileInput(file);
WriteFile(out);
String str = ReadFile(in);
Toast.makeText(v.getContext(), str, Toast.LENGTH_LONG);
} catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
public static void WriteFile(OutputStream out)
{
OutputStreamWriter tmp = new OutputStreamWriter(out);
try
{
for (int i = 0 ; i < 10; i++)
{
tmp.write(i);
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String ReadFile(InputStream in)
{
InputStreamReader tmp = null;
String str = "";
tmp = new InputStreamReader(in);
BufferedReader reader=new BufferedReader(tmp);
try
{
for (int i = 0; i < 10; i++)
{
str += " " + reader.readLine();
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return str;
}
}
String file = "test123";
So, the path of your file should be {root}/test123
Try defining a path were you can access to see if it has written something. (usually : /mnt/storage/your_file)
Then, you'll be able to determine if the Write/Read process works or not
Note : Take a look at FileOutputStream, it already implements lots of useful methods

Android pause and resume downloading file to sdcard

I am making an application in which I need to download a file from server and save it to sd card of android device.
Apart of this there is a feature for the user to pause and resume the file.
The problem I am facing is that I am able to download file to sdcard but when try to pause and resume it, it gets starts from the beginning.......
Here is the source ......
public class DownloadWithProgressActivity extends Activity {
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private Button startBtn, pauseButton, resumeButton;
private ProgressBar bar;
URLConnection conexion;
OutputStream output;
static int count = 0;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startBtn = (Button) findViewById(R.id.startBtn);
pauseButton = (Button) findViewById(R.id.button1);
resumeButton = (Button) findViewById(R.id.button2);
bar = (ProgressBar) findViewById(R.id.progressBar1);
bar.setVisibility(ProgressBar.INVISIBLE);
bar.setId(0);
startBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
startDownload();
}
});
pauseButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
try {
output.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
resumeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// not getting what to write here
}
});
}
private void startDownload() {
String url = "http://farm1.static.flickr.com/114/298125983_0e4bf66782_b.jpg";
new DownloadFileAsync().execute(url);
}
class DownloadFileAsync extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
bar.setVisibility(ProgressBar.VISIBLE);
}
#Override
protected String doInBackground(String... aurl) {
int downloaded = 0;
File file = new File("/sdcard/some_photo_from_gdansk_poland.jpg");
URL url = null;
try {
url = new URL(aurl[0]);
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
conexion = url.openConnection();
if (file.exists()) {
downloaded = (int) file.length();
conexion.setRequestProperty("Range", "bytes="+(file.length())+"-");
}
else {
conexion.setRequestProperty("Range", "bytes=" + downloaded
+ "-");
}
} catch (Exception exception1) {
}
conexion.setDoInput(true);
conexion.setDoOutput(true);
System.out.println(tryGetFileSize(url));
conexion.setRequestProperty("Range", "bytes=" + count + "-");
try {
conexion.connect();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
InputStream input = null;
try {
input = new BufferedInputStream(url.openStream());
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
output = new FileOutputStream(file);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
byte data[] = new byte[1024];
long total = 0;
try {
while ((count = input.read(data)) != -1) {
total += count;
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
output.write(data, 0, count);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
output.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
output.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
input.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC", progress[0]);
bar.setProgress(Integer.parseInt(progress[0]));
System.out.println(Integer.parseInt(progress[0]));
}
protected void onPostExecute(String unused) {
}
int tryGetFileSize(URL url) {
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("HEAD");
conn.getInputStream();
return conn.getContentLength();
} catch (IOException e) {
return -1;
} finally {
conn.disconnect();
}
}
}
}
Please help.......
Thanks
Nikhil
connection.setRequestProperty("Range", "bytes=" + ***downloaded*** + "-");
Make "downloaded" as global variable, because download start from this position.
when you press on restart button, check value of this downloaded variable,must not zero all time.
This line return a wrong file size, I used the same code to open a Zip file on the net :
int lenghtOfFile = conexion.getContentLength();
How can I pause download other than by closing the output?
pauseButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
try {
output.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
resumeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// not getting what to write here
}
});

Categories

Resources