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.
Related
this is my first post here
i'm new, so be good with me!
i'm following travis's tutorials and it goes to saving data and using async task
i really focused but i can't find out whats wrong with my code, so i posted here! :
I added the logcat!
it worked without async and progress bar (both save and load)
latest changes!:
i fixed the progress bar but loadwithasync class is not working, i mean this line:
I think this must return the Srting ld and set that in text view res. but it is not looking this way! why travis from mybringback! didn't wrote the line like Strig s = new loadWith..... ? can u tell me where is the problem! i'm confused and i don't know how to debug properly!!
new loadWithAsyncTask().execute(FILENAME);
public class SaveAndLoadInternal extends Activity implements OnClickListener {
EditText file, data;
TextView res;
FileInputStream fis;
FileOutputStream fos;
String FILE_NAME;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.save_load_internal);
Button load, save;
file = (EditText) findViewById(R.id.etSLIfile);
data = (EditText) findViewById(R.id.etSLIdata);
res = (TextView) findViewById(R.id.tvSLIres);
load = (Button) findViewById(R.id.bSLIload);
save = (Button) findViewById(R.id.bSLIsave);
// set file and close it!
load.setOnClickListener(this);
save.setOnClickListener(this);
}
#Override
public void onClick(View v) {
FILE_NAME = file.getText().toString();
switch (v.getId()) {
case R.id.bSLIload:
//Commented just for doing some tweaks! run
//loading process in another thread to give UI thread rest :D for avoid hanging!
FileInputStream fis = null;
String ld = "LOADING FAILED!";
/* try {
fis = openFileInput(FILE_NAME);
byte[] b = new byte[fis.available()];
while (fis.read(b) != -1) {
ld = new String(b);
}
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
res.setText(ld);
*/
new loadWithAsyncTask ().execute(FILE_NAME);
// execute will run doInBackground method!
break;
case R.id.bSLIsave:
String sd = data.getText().toString();
/*
// one way to save in file is below! must work but it isn't!
File f = new File(FILE_NAME);
try {
fos = new FileOutputStream(FILE_NAME);
fos.write(sd.getBytes());
fos.close();
res.setText("SAVING DONE!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
*/
try {
fos = openFileOutput(FILE_NAME, Context.MODE_PRIVATE);
fos.write(sd.getBytes());
fos.close();
res.setText("SAVING DONE!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
// /*
// first param: what is being passed in (FILE_NAME)
// second param for progress bar (we use integer here)
// third one is what we will return! (the saved text! String ld)
public class loadWithAsyncTask extends AsyncTask<String, Integer, String>{
ProgressDialog pd;
String Ld = "LOADING FAILED!";
FileInputStream fis = null;
// this gonna called first
#Override
protected void onPreExecute(){
// example: setting up variables or something else!
pd = new ProgressDialog(SaveAndLoadInternal.this);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMax(100);
pd.show();
}
#Override
protected String doInBackground(String... params) {
//for progress dialog
for(int i =0 ; i< 20 ; i++){
publishProgress(5);
try {
Thread.sleep(88);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
pd.dismiss();
try {
fis = openFileInput(FILE_NAME);
byte[] b = new byte[fis.available()];
res.setText(String.valueOf(fis.available()));
while (fis.read(b) != -1) {
Ld = new String(b);
}
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
//return the string!
return Ld;
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
// progress of loading in example!
#Override
protected void onProgressUpdate(Integer...progress){
pd.incrementProgressBy(progress[0]);
}
}// */
}
When you look at the error, you'll see that onProgressUpdate() throws a NPE. Looking at the code, there are two possibilities: 1. pd is null or 2. progress is null. Add a breakpoint or some logging there to see what exactly is going on.
protected void onProgressUpdate(Integer...progress){
pd.incrementProgressBy(progress[0]);
}
I am really facing problem from last couple of days but I am not able to find the exact solution please help me.
I want to merge two .mp3 or any audio file and play final single one mp3 file. But when I am combine two file the final file size is ok but when I am trying to play it just play first file, I have tried this with SequenceInputStream or byte array but I am not able to get exact result please help me.
My code is the following:
public class MerginFileHere extends Activity {
public ArrayList<String> audNames;
byte fileContent[];
byte fileContent1[];
FileInputStream ins,ins1;
FileOutputStream fos = null;
String combined_file_stored_path = Environment
.getExternalStorageDirectory().getPath()
+ "/AudioRecorder/final.mp3";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
audNames = new ArrayList<String>();
String file1 = Environment.getExternalStorageDirectory().getPath()
+ "/AudioRecorder/one.mp3";
String file2 = Environment.getExternalStorageDirectory().getPath()
+ "/AudioRecorder/two.mp3";
File file = new File(Environment.getExternalStorageDirectory()
.getPath() + "/AudioRecorder/" + "final.mp3");
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
audNames.add(file1);
audNames.add(file2);
Button btn = (Button) findViewById(R.id.clickme);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
createCombineRecFile();
}
});
}
public void createCombineRecFile() {
// String combined_file_stored_path = // File path in String to store
// recorded audio
try {
fos = new FileOutputStream(combined_file_stored_path, true);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
File f = new File(audNames.get(0));
File f1 = new File(audNames.get(1));
Log.i("Record Message", "File Length=========>>>" + f.length()+"------------->"+f1.length());
fileContent = new byte[(int) f.length()];
ins = new FileInputStream(audNames.get(0));
int r = ins.read(fileContent);// Reads the file content as byte
fileContent1 = new byte[(int) f1.length()];
ins1 = new FileInputStream(audNames.get(1));
int r1 = ins1.read(fileContent1);// Reads the file content as byte
// from the list.
Log.i("Record Message", "Number Of Bytes Readed=====>>>" + r);
//fos.write(fileContent1);// Write the byte into the combine file.
byte[] combined = new byte[fileContent.length + fileContent1.length];
for (int i = 0; i < combined.length; ++i)
{
combined[i] = i < fileContent.length ? fileContent[i] : fileContent1[i - fileContent.length];
}
fos.write(combined);
//fos.write(fileContent1);*
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fos.close();
Log.v("Record Message", "===== Combine File Closed =====");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I already published an app with this function... try my method using SequenceInputStream, in my app I just merge 17 MP3 files in one and play it using the JNI Library MPG123, but I tested the file using MediaPlayer without problems.
This code isn't the best, but it works...
private void mergeSongs(File mergedFile,File...mp3Files){
FileInputStream fisToFinal = null;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mergedFile);
fisToFinal = new FileInputStream(mergedFile);
for(File mp3File:mp3Files){
if(!mp3File.exists())
continue;
FileInputStream fisSong = new FileInputStream(mp3File);
SequenceInputStream sis = new SequenceInputStream(fisToFinal, fisSong);
byte[] buf = new byte[1024];
try {
for (int readNum; (readNum = fisSong.read(buf)) != -1;)
fos.write(buf, 0, readNum);
} finally {
if(fisSong!=null){
fisSong.close();
}
if(sis!=null){
sis.close();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fos!=null){
fos.flush();
fos.close();
}
if(fisToFinal!=null){
fisToFinal.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Mp3 files are some frames.
You can concatenate these files by appending the streams to each other if and only if the bit rate and sample rate of your files are same.
If not, the first file plays because it has truly true encoding but the second file can not decode to an true mp3 file.
Suggestion: convert your files with some specific bit rate and sample rate, then use your function.
Here is how my app works:
After the app received the music it will first save the file into the SD card and then play it.
I tried to play the music with an asynctask called by a class (not an activity but a handler). However, the music can be played for only 1-2 seconds. Here is the code for the call back of AsyncTask:
fos = new FileOutputStream(file);
fos.write(receivedMusicPayload);
fos.flush();
fos.close();
PlayMusicManager pmm = new PlayMusicManager(qrC);
pmm.execute();
and here is the playermanager:
public class PlayMusicManager extends AsyncTask<Void, Void, Void> {
private QRConnection qrC;
public PlayMusicManager(QRConnection qrC) {
this.qrC = qrC;
}
#Override
protected Void doInBackground(Void... params) {
MediaPlayer mediaPlayer = new MediaPlayer();
File dir = Environment.getExternalStorageDirectory();
File file = new File(dir, "music.mid");
if (file.exists()) // check if file exist
{
FileInputStream fis;
try {
fis = new FileInputStream(file);
FileDescriptor fd = fis.getFD();
mediaPlayer.setDataSource( fd);
mediaPlayer.prepare();
mediaPlayer.start();
} 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();
}
} else {
qrC.getQrActivity().showResult("No such file");
}
return null;
}
#Override
protected void onPostExecute(Void parms) {
qrC.getQrActivity().showResult("Music Done.");
}
Thanks for your help!
You need to wait until the file is played.
Because the MediaPlayer mediaPlayer is created as local variable it will be release at the end of
protected Void doInBackground {
You have two options.
1) Make the mediaPlayer variable of class that live long enough
2) OR, put a loop reading mediaPlayer.status. Something like this:
while (mediaPlayer.status==MediaPlayer.Status.PLAYING)
sleep(100);
I have created a file with an asynctask. Afterwards scheduled an executor to write information to said file once every second. Once I touch a button the executor is shut down and the file closed but more often than not nothing is written in the file.
Code:
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
preferences.edit().putBoolean(GlobalConstants.stopPreference,false).commit();
loc_thr = new LocationThread(preferences, getApplicationContext());
loc_thr.run();
startButton.setVisibility(View.INVISIBLE);
startButton.setClickable(false);
stopButton.setVisibility(View.VISIBLE);
stopButton.setClickable(true);
currentDateAndTime = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
fileName = getString(R.string.loc_log_path) + currentDateAndTime + ".txt";
new CreateFileTask(fileName).execute();
loc_file = new File(fileName);
try {
FOS = new FileOutputStream(loc_file.getAbsolutePath());
OSW = new OutputStreamWriter(FOS);
OSW.write(GlobalConstants.fileHeader + '\n');
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
scheduledTaskExecutor = Executors.newScheduledThreadPool(5);
scheduledTaskExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
if(loc_thr.getLocationStatus() & loc_thr.newLocation() & !preferences.getBoolean(GlobalConstants.stopPreference,false)){
SensorBundle SB = new SensorBundle(loc_thr.getCurrentLocation(),loc_thr.getCurrentGPSStatus());
try {
OSW.write(new SimpleDateFormat("yyyy/MM/dd;hh:mm:ss").format(new Date()) + ";");
OSW.write(SB.getLatitude() + ";");
OSW.write(SB.getLongitude() + ";");
OSW.write(SB.getAltitude() + ";");
OSW.write(SB.getAccuracy() + ";");
OSW.write(SB.getProvider() + ";");
OSW.write('\n');
} catch (IOException e) {
e.printStackTrace();
}
} else{
if(preferences.getBoolean(GlobalConstants.stopPreference,false)){
try {
OSW.close();
FOS.close();
scheduledTaskExecutor.shutdown();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}, 0, 1, TimeUnit.SECONDS);
}
});
Whenever the stop button is pressed the SharedPreference queried earlier is set to true.
I think your problem may be here
new CreateFileTask(fileName).execute();
loc_file = new File(fileName);
I assume this task creates the file and you're expecting that when you can new File(fileName) the file is already created. Whether this is true or not is indeterminate. If the AsyncTask CreateFileTask is scheduled to run and completes before the next statement is executed then the file will be there, otherwise it won't be. Are you seeing stack traces in logcat from the IOException or FileNoteFoundExceptions?
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