I am making the radio app.I have using the android media for playing radio working fine.
Can possible to know song title?
I have play same url in vlc player on desktop it show me the song title.
If there is anyway then please help me.
I also want to implement in 2.1
Thank you.
You'd use the MetaDataRetriever class for this. If you want the song title you'd use the METADATA_KEY_TITLE key. So for instance, you could write some code like this:
MetadataRetriever myRetriever = new MetadataRetriever();
myRetriever.setDataSource(/*specify you data source here*/);
String songName = myRetriever.extractMetadata(MetadataRetriever.METADATA_KEY_TITLE);
If you're developing for less than API level 10, you're going to have to use something else to get the metadata. The MyID3 library will probably do the trick in this case.
I have the solution for 2.2
protected URL streamUrl;
private Map<String, String> metadata;
private boolean isError;
public IcyStreamMeta(URL streamUrl) {
setStreamUrl(streamUrl);
isError = false;
}
/**
* Get artist using stream's title
*
* #return String
* #throws IOException
*/
public String getArtist() throws IOException {
Map<String, String> data = getMetadata();
if (!data.containsKey("StreamTitle"))
return "";
String streamTitle = data.get("StreamTitle");
String title = streamTitle.substring(0, streamTitle.indexOf("-"));
return title.trim();
}
/**
* Get title using stream's title
*
* #return String
* #throws IOException
*/
public String getTitle() throws IOException {
Map<String, String> data = getMetadata();
if (!data.containsKey("StreamTitle"))
return "";
String streamTitle = data.get("StreamTitle");
String artist = streamTitle.substring(streamTitle.indexOf("-")+1);
return artist.trim();
}
public Map<String, String> getMetadata() throws IOException {
if (metadata == null) {
refreshMeta();
}
return metadata;
}
public void refreshMeta() throws IOException {
retreiveMetadata();
}
private void retreiveMetadata() throws IOException {
URLConnection con = streamUrl.openConnection();
con.setRequestProperty("Icy-MetaData", "1");
con.setRequestProperty("Connection", "close");
con.setRequestProperty("Accept", null);
con.connect();
int metaDataOffset = 0;
Map<String, List<String>> headers = con.getHeaderFields();
InputStream stream = con.getInputStream();
if (headers.containsKey("icy-metaint")) {
// Headers are sent via HTTP
metaDataOffset = Integer.parseInt(headers.get("icy-metaint").get(0));
} else {
// Headers are sent within a stream
StringBuilder strHeaders = new StringBuilder();
char c;
while ((c = (char)stream.read()) != -1) {
strHeaders.append(c);
if (strHeaders.length() > 5 && (strHeaders.substring((strHeaders.length() - 4), strHeaders.length()).equals("\r\n\r\n"))) {
// end of headers
break;
}
}
// Match headers to get metadata offset within a stream
Pattern p = Pattern.compile("\\r\\n(icy-metaint):\\s*(.*)\\r\\n");
Matcher m = p.matcher(strHeaders.toString());
if (m.find()) {
metaDataOffset = Integer.parseInt(m.group(2));
}
}
// In case no data was sent
if (metaDataOffset == 0) {
isError = true;
return;
}
// Read metadata
int b;
int count = 0;
int metaDataLength = 4080; // 4080 is the max length
boolean inData = false;
StringBuilder metaData = new StringBuilder();
// Stream position should be either at the beginning or right after headers
while ((b = stream.read()) != -1) {
count++;
// Length of the metadata
if (count == metaDataOffset + 1) {
metaDataLength = b * 16;
}
if (count > metaDataOffset + 1 && count < (metaDataOffset + metaDataLength)) {
inData = true;
} else {
inData = false;
}
if (inData) {
if (b != 0) {
metaData.append((char)b);
}
}
if (count > (metaDataOffset + metaDataLength)) {
break;
}
}
// Set the data
metadata = IcyStreamMeta.parseMetadata(metaData.toString());
// Close
stream.close();
}
public boolean isError() {
return isError;
}
public URL getStreamUrl() {
return streamUrl;
}
public void setStreamUrl(URL streamUrl) {
this.metadata = null;
this.streamUrl = streamUrl;
this.isError = false;
}
public static Map<String, String> parseMetadata(String metaString) {
Map<String, String> metadata = new HashMap();
String[] metaParts = metaString.split(";");
Pattern p = Pattern.compile("^([a-zA-Z]+)=\\'([^\\']*)\\'$");
Matcher m;
for (int i = 0; i < metaParts.length; i++) {
m = p.matcher(metaParts[i]);
if (m.find()) {
metadata.put((String)m.group(1), (String)m.group(2));
}
}
return metadata;
}
Using the thread
public void startThread(){
timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
URL url;
Message msg = handler.obtainMessage();
try {
url = new URL(URL);
IcyStreamMeta icy = new IcyStreamMeta(url);
Log.d("SONG",icy.getTitle());
msg.obj = icy.getTitle();
Log.d("ARTITSi",icy.getArtist());
handler.sendMessage(msg);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 0, 10000);
}
Related
I have a problem while parsing from JSON to Listview in Android. This is an example of data from JSON:
{
"status": {
"statusCode": 200,
"success": true,
"message": "Success"
},
"demandes": [{
"id": "1",
"dateCreation": "21/01/2014",
"tagDemand": "xxxxxxxxxxxx",
"descDemande": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"imageUrl": "https://picsum.photos/3800/50/?image=1"
},
{
"id": "2",
"dateCreation": "15/01/2017",
"tagDemand": "yyyyyyyyyyyyyyyyyyyy",
"descDemande": "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
"imageUrl": "https://picsum.photos/3500/5200/?image=221"
}
]
}
This is the main activity:
public class MyRequests extends AppCompatActivity {
private String jsonURL = "https://26ae7d0d-62b2-4cc4-8ff7-009bee255089.mock.pstmn.io/demands";
private final int jsoncode = 1;
private ListView listView;
ArrayList<DemandeModel> demandeModelArrayList;
private DemandeAdapter demandeAdapter;
String response = "";
private static ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_requests);
listView = findViewById(R.id.lv);
fetchJSON();
}
#SuppressLint("StaticFieldLeak")
private void fetchJSON() {
showSimpleProgressDialog(this, "Chargement...", "Récupération des données", false);
new AsyncTask<Void, Void, String>() {
protected String doInBackground(Void[] params) {
// String response="";
HashMap<String, String> map = new HashMap<>();
try {
HttpRequest req = new HttpRequest(jsonURL);
response = req.prepare(HttpRequest.Method.POST).withData(map).sendAndReadString();
} catch (Exception e) {
response = e.getMessage();
}
return response;
}
protected void onPostExecute(String result) {
//do something with response
Log.d("newwwss", result);
onTaskCompleted(result, jsoncode);
}
}.execute();
}
public void onTaskCompleted(String response, int serviceCode) {
Log.d("responsejson", response.toString());
switch (serviceCode) {
case jsoncode:
if (isSuccess(response)) {
removeSimpleProgressDialog(); //will remove progress dialog
demandeModelArrayList = getInfo(response);
demandeAdapter = new DemandeAdapter(this, demandeModelArrayList);
listView.setAdapter(demandeAdapter);
} else {
Toast.makeText(MyRequests.this, getErrorCode(response), Toast.LENGTH_SHORT).show();
}
}
}
public ArrayList<DemandeModel> getInfo(String response) {
ArrayList<DemandeModel> demandeModelArrayList = new ArrayList<>();
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getJSONObject("status").optString("success").equals("true")) {
JSONArray dataArray = jsonObject.getJSONArray("demandes");
for (int i = 0; i < dataArray.length(); i++) {
DemandeModel playersModel = new DemandeModel();
JSONObject dataobj = dataArray.getJSONObject(i);
playersModel.setId(dataobj.getString("id"));
playersModel.setDate(dataobj.getString("dateCreation"));
playersModel.setNom(dataobj.getString("tagDemand"));
playersModel.setDescription(dataobj.getString("descDemande"));
playersModel.setImgURL(dataobj.getString("imageUrl"));
demandeModelArrayList.add(playersModel);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return demandeModelArrayList;
}
public boolean isSuccess(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getJSONObject("status").optString("success").equals("true")) {
return true;
} else {
return false;
}
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
public String getErrorCode(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
return jsonObject.getJSONObject("status").optString("message");
} catch (JSONException e) {
e.printStackTrace();
}
return "No data";
}
public static void removeSimpleProgressDialog() {
try {
if (mProgressDialog != null) {
if (mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
} catch (IllegalArgumentException ie) {
ie.printStackTrace();
} catch (RuntimeException re) {
re.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void showSimpleProgressDialog(Context context, String title,
String msg, boolean isCancelable) {
try {
if (mProgressDialog == null) {
mProgressDialog = ProgressDialog.show(context, title, msg);
mProgressDialog.setCancelable(isCancelable);
}
if (!mProgressDialog.isShowing()) {
mProgressDialog.show();
}
} catch (IllegalArgumentException ie) {
ie.printStackTrace();
} catch (RuntimeException re) {
re.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
so, I had like a response "no data" so I think that there is a problem here " if (isSuccess(response)) "
This is my Adapter:
public class DemandeAdapter extends BaseAdapter {
private Context context;
private ArrayList<DemandeModel> demandeModelArrayList;
public DemandeAdapter(Context context, ArrayList<DemandeModel> demandeModelArrayList) {
this.context = context;
this.demandeModelArrayList = demandeModelArrayList;
}
#Override
public int getViewTypeCount() {
return getCount();
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public int getCount() {
return demandeModelArrayList.size();
}
#Override
public Object getItem(int position) {
return demandeModelArrayList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.demande, null, true);
holder.iv = (ImageView) convertView.findViewById(R.id.iv);
holder.id = (TextView) convertView.findViewById(R.id.id);
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.desc = (TextView) convertView.findViewById(R.id.desc);
holder.date = (TextView) convertView.findViewById(R.id.date);
convertView.setTag(holder);
}else {
// the getTag returns the viewHolder object set as a tag to the view
holder = (ViewHolder)convertView.getTag();
}
Picasso.get().load(demandeModelArrayList.get(position).getImgURL()).into(holder.iv);
holder.id.setText("ID : "+demandeModelArrayList.get(position).getId());
holder.date.setText("Date : "+demandeModelArrayList.get(position).getDate());
holder.name.setText("Name : "+demandeModelArrayList.get(position).getNom());
holder.desc.setText("Description : "+demandeModelArrayList.get(position).getDescription());
return convertView;
}
private class ViewHolder {
protected TextView id,name,desc,date;
protected ImageView iv;
}
}
and this is my Model:
public class DemandeModel {
private String id;
private String nom;
private String description;
private String date;
private String imgURL;
public DemandeModel() {
}
public DemandeModel(String id, String nom, String description, String date, String imgURL) {
this.id = id;
this.nom = nom;
this.description = description;
this.date = date;
this.imgURL = imgURL;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getImgURL() {
return imgURL;
}
public void setImgURL(String imgURL) {
this.imgURL = imgURL;
}
}
And this is the HttpRequest :
public class HttpRequest {
public static enum Method {
POST, PUT, DELETE, GET;
}
private URL url;
private HttpURLConnection con;
private OutputStream os;
//After instantiation, when opening connection - IOException can occur
public HttpRequest(URL url) throws IOException {
this.url = url;
con = (HttpURLConnection) this.url.openConnection();
}
//Can be instantiated with String representation of url, force caller to check for IOException which can be thrown
public HttpRequest(String url) throws IOException {
this(new URL(url));
Log.d("parameters", url);
}
/**
* Sending connection and opening an output stream to server by pre-defined instance variable url
*
* #param //isPost boolean - indicates whether this request should be sent in POST method
* #throws IOException - should be checked by caller
*/
private void prepareAll(Method method) throws IOException {
con.setDoInput(true);
con.setRequestMethod(method.name());
if (method == Method.POST || method == Method.PUT) {
con.setDoOutput(true);
os = con.getOutputStream();
}
}
//prepare request in GET method
//#return HttpRequest this instance -> for chaining method #see line 22
public HttpRequest prepare() throws IOException {
prepareAll(Method.GET);
return this;
}
/**
* Prepares HttpRequest method with for given method, possible values: HttpRequest.Method.POST,
* HttpRequest.Method.PUT, HttpRequest.Method.GET & HttpRequest.Method.DELETE
*
* #param method HttpRequest.Method - nested enum HttpRequest.Method constant
* #return HttpRequest this instance -> for chaining method #see line 22
* #throws IOException - should be checked by caller
*/
public HttpRequest prepare(Method method) throws IOException {
prepareAll(method);
return this;
}
/**
* Adding request headers (standard format "Key":"Value")
*
* #param headers String variadic params in standard format "Key":"Value"
* #return HttpRequest this instance -> for chaining method #see line 22
*/
public HttpRequest withHeaders(String... headers) {
for (int i = 0, last = headers.length; i < last; i++) {
String[] h = headers[i].split("[:]");
con.setRequestProperty(h[0], h[1]);
}
return this;
}
/**
* Writes query to open stream to server
*
* #param query String params in format of key1=v1&key2=v2 to open stream to server
* #return HttpRequest this instance -> for chaining method #see line 22
* #throws IOException - should be checked by caller
*/
public HttpRequest withData(String query) throws IOException {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(query);
writer.close();
return this;
}
/**
* Builds query on format of key1=v1&key2=v2 from given hashMap structure
* for map: {name=Bubu, age=29} -> builds "name=Bubu&age=29"
* for map: {Iam=Groot} -> builds "Iam=Groot"
*
* #param params HashMap consists of key-> value pairs to build query from
* #return HttpRequest this instance -> for chaining method #see line 22
* #throws IOException - should be checked by caller
*/
public HttpRequest withData(HashMap<String, String> params) throws IOException {
StringBuilder result = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
result.append((result.length() > 0 ? "&" : "") + entry.getKey() + "=" + entry.getValue());//appends: key=value (for first param) OR &key=value(second and more)
Log.d("parameters", entry.getKey() + " ===> " + entry.getValue());
}
withData(result.toString());
return this;
}
//When caller only need to send, and don't need String response from server
public int send() throws IOException {
return con.getResponseCode(); //return HTTP status code to indicate whether it successfully sent
}
/**
* Sending request to the server and pass to caller String as it received in response from server
*
* #return String printed from server's response
* #throws IOException - should be checked by caller
*/
public String sendAndReadString() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuilder response = new StringBuilder();
for (String line; (line = br.readLine()) != null; ) response.append(line + "\n");
Log.d("ressss", response.toString());
return response.toString();
}
/**
* Sending request to the server and pass to caller its raw contents in bytes as it received from server.
*
* #return byte[] from server's response
* #throws IOException - should be checked by caller
*/
public byte[] sendAndReadBytes() throws IOException {
byte[] buffer = new byte[8192];
InputStream is = con.getInputStream();
ByteArrayOutputStream output = new ByteArrayOutputStream();
for (int bytesRead; (bytesRead = is.read(buffer)) >= 0; ) output.write(buffer, 0, bytesRead);
return output.toByteArray();
}
//JSONObject representation of String response from server
public JSONObject sendAndReadJSON() throws JSONException, IOException {
return new JSONObject(sendAndReadString());
}
}
if someone could hepl to solve this problem it will be with a pleasure
I have updated the parsing method. Check below
public ArrayList<DemandeModel> getInfo(String response) {
ArrayList<DemandeModel> demandeModelArrayList = new ArrayList<>();
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getJSONObject("status").optString("success").equals("true")) {
JSONArray dataArray = jsonObject.getJSONArray("demandes");
for (int i = 0; i < dataArray.length(); i++) {
DemandeModel playersModel = new DemandeModel();
JSONObject dataobj = dataArray.getJSONObject(i);
playersModel.setId(dataobj.getString("id"));
playersModel.setDate(dataobj.getString("dateCreation"));
playersModel.setNom(dataobj.getString("tagDemand"));
playersModel.setDescription(dataobj.getString("descDemande"));
playersModel.setImgURL(dataobj.getString("imageUrl"));
demandeModelArrayList.add(playersModel);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return demandeModelArrayList;
}
EDIT below method is updated a bit
public boolean isSuccess(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getJSONObject("status").optString("success").equals("true")) {
return true;
} else {
return false;
}
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
EDIT 2
change below line
response = req.prepare(HttpRequest.Method.POST).withData(map).sendAndReadString();
to
response = req.prepare().sendAndReadString();
It looks like you are reading wrong data:
jsonObject.getString("status").equals("true")
There is no "status" in your json respose example. There is "success".
I want to get an Number from a String.
My Code for this Class is:
The XML is download correct, it founds my Value String but i get not the number from the String.
public class XMLProcessor extends AsyncTask<String, Void, String> {
private String rssURL;
private PostParserDelegate delegate;
private ArrayList<Post> posts;
String euro;
private StringBuilder buffer;
TextView mxntoeur;
TextView eurtomxn;
public XMLProcessor(String rssURL, PostParserDelegate delegate) {
this.rssURL = rssURL;
this.delegate = delegate;
posts = new ArrayList<Post>();
}
#Override
protected String doInBackground(String... strings) {
buffer = new StringBuilder();
try {
URL url = new URL(rssURL);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
// HTTP Status "OK" -> HTTPCODE 200
int httpResponse = httpURLConnection.getResponseCode();
if ( httpResponse != 200) {
throw new Exception("Fehlercode: " + httpResponse);
}
InputStream input = httpURLConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(input);
int charactersRead;
char[] tmpChars = new char[400];
while (true) {
charactersRead = reader.read(tmpChars);
if (charactersRead <= 0) {
break;
}
buffer.append(String.copyValueOf(tmpChars, 0, charactersRead));
}
return buffer.toString();
} catch (Exception e) {
Log.e("XMLProcessor", e.getMessage());
Log.e("XMLProcessor", e.getStackTrace().toString());
}
return String.valueOf(0);
}
#Override
protected void onPostExecute(String aDouble) {
super.onPostExecute(aDouble);
parse();
}
protected void parse()
{
String rawXML = buffer.toString();
Post aPost = null;
boolean isProcessingItem = false;
String innerValue ="";
try {
XmlPullParserFactory pullParserFactory = XmlPullParserFactory.newInstance();
XmlPullParser parser = pullParserFactory.newPullParser();
parser.setInput(new StringReader(rawXML));
int event = parser.getEventType();
while (event !=XmlPullParser.END_DOCUMENT)
{
String tag = parser.getName();
switch ( event) {
case XmlPullParser.START_TAG:
if (tag == "item" ) {
Log.d("XMLProcessor", "Neuer Post!");
isProcessingItem = true;
aPost = new Post();
}
break;
case XmlPullParser.TEXT:
innerValue = parser.getText();
break;
case XmlPullParser.END_TAG:
if (isProcessingItem){
if (tag == "item") {
posts.add(aPost);
isProcessingItem = false;
}
} else if ( tag == "description") {
aPost.setPesoInEuro(innerValue);
euro = new String(innerValue.substring(13,21));
//euro = innerValue.substring(13,21);
eurtomxn.setText(euro);
}
break;
}
event = parser.next();
}
delegate.xmlFeedParsed(posts);
} catch (Exception e) {
Log.e("XMLProcess", e.getStackTrace().toString());
}
}
}
In innerValue i get the Correct Sting what i need
/n 1.00 EUR = 21.90612 MXN<br/>\n 1.00 MXN = 0.04565 EUR<br/>\n
Converter--\n
<a href="http://eur.de.fxexchangerate.com/mxn-exchange-rates-history.html">Historische
</a>
\n.
But my problem is, that i need this Number 21.90612. I have try it with substring(13,21), but it was no working.
Have you a idea, how i can fix my problem?
Thank you
It's not very clear what exactly is the Problem, it would be useful if you show the Exception!
Have you checked if the String innerValue has a valid lenght?
if(innerValue.lenght() >= 21){euro = innerValue.substring(13,21);} else {/* Do something here!*/}
}
I am usind TMDb API to build a project app. Every api call gives me back 20 movies, so normally the app shows only 20 movie posters on startup. I added this code to fetch another 20 movies, using the &page= query, when the user scrolls down the grid View.
gridView.setOnScrollListener(onScrollListener());
private AbsListView.OnScrollListener onScrollListener() {
return new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
int threshold = 1;
int count = gridView.getCount();
if (scrollState == SCROLL_STATE_IDLE) {
if (gridView.getLastVisiblePosition() >= count - threshold && pageCount < 2) {
Log.v(LOG_TAG, "loading more data");
// Execute LoadMoreDataTask AsyncTask
updateMovies(sortBy, true);
}
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
}
};
}
But this solution works really bad. If i scroll down it executes updateMovies(sortBy, true); for 2-3 times at once, jumping pages and making it impossible to read.
Also, the data shown on screen is completely replaced after every page refresh, for example if I am seeing the data on page=1 and I scroll down then i see only the data from page 2 or 3 but the original data is gone.
here is my AsyncTask
public class FetchMoviesTask extends AsyncTask<String, Void, List<Movie>> {
private final String LOG_TAG = FetchMoviesTask.class.getSimpleName();
private final static String API_KEY = "480a9e79c0937c9f4e4a129fd0463f96";
#Override
protected List<Movie> doInBackground(String... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String jsonStr = null;
try {
final String BASE_URL = "http://api.themoviedb.org/3/movie";
final String API_KEY_PARAM = "api_key";
final String PAGE_PARAM = "page";
URL url;
if (params[1].equals("true")){
// if a bool is true
// then I intend to load an additional page
// (needed otherwise going back from detailAct loads a new increasing page
currentPage += 1;
pageCount++;
}else{
currentPage = 1;
}
if (params[0].equals(POPULARITY_DESC)){
Uri builtUri = Uri.parse(BASE_URL).buildUpon()
.appendPath("popular")
.appendQueryParameter(API_KEY_PARAM, API_KEY) // my own API key
.appendQueryParameter(PAGE_PARAM , Integer.toString(currentPage))
.build();
url = new URL(builtUri.toString());
}else if(params[0].equals(RATING_DESC)) {
Uri builtUri = Uri.parse(BASE_URL).buildUpon()
.appendPath("top_rated")
.appendQueryParameter(API_KEY_PARAM, API_KEY)// my own API key
.appendQueryParameter(PAGE_PARAM , Integer.toString(currentPage))
.build();
url = new URL(builtUri.toString());
}else {
Log.v(LOG_TAG, "Something went wrong with URI building :(");
url = new URL("ERROR URL");
}
Log.v(LOG_TAG, "URL BUILT: " + url);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
return null;
}
jsonStr = buffer.toString(); // finally parsed JSON string
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "Error closing stream", e);
}
}
}
try {
return getMoviesDataFromJson(jsonStr);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
// This will only happen if there was an error getting or parsing the forecast.
return null;
}
private List<Movie> getMoviesDataFromJson(String jsonStr) throws JSONException {
JSONObject movieJson = new JSONObject(jsonStr);
JSONArray movieArray = movieJson.getJSONArray("results");
List<Movie> results = new ArrayList<>();
for(int i = 0; i < movieArray.length(); i++) {
JSONObject movie = movieArray.getJSONObject(i);
Movie movieModel = new Movie(movie); // basically Movie has already the fields to fill (image,
// description, rating, etc) and this adds those values from the JSONObject
results.add(movieModel); // it does this one object at the time, for the lenght of the array
}
return results;
}
#Override
protected void onPostExecute(List<Movie> mv) {
if (mv != null) {
if (movieGridAdapter != null) {
movieGridAdapter.clear();
for (Movie movie : mv) {
movieGridAdapter.add(movie);
}
}
movies = new ArrayList<>();
movies.addAll(mv);
}
}
}
I have been trying to get the json response from my company's json webservice. Here is the code:
public final static String GOINOUT_HOST_NAME = "http://ec2-54-254-123-244.ap-southeast-1.compute.amazonaws.com";
public final static String GOINOUT_API_VERSION = "/api/v1";
public final static String GOINOUT_FACEBOOK_AUTHENTICATE = GOINOUT_HOST_NAME + GOINOUT_API_VERSION + "/facebook_authenticate";
public static JSONObject loginGoinoutWithFacebook(String accessToken) {
JSONObject goinoutUserJsonObject = null;
try {
Hashtable params = new Hashtable();
params.put("access_token", accessToken);
String paramsString = StringUtil.toURLParameters(params);
Hashtable properties = new Hashtable();
String response = HttpUtils.sendGoinoutJsonRequest(GOINOUT_FACEBOOK_AUTHENTICATE + "?" + paramsString, paramsString, HttpUtils.TIMEOUT, properties, HttpConnection.POST);
Dialog.alert("res: " + response);
JSONObject goinoutJsonObject = new JSONObject(response);
goinoutUserJsonObject = new JSONObject(goinoutJsonObject.getString("user"));
} catch (IOException e) {
Dialog.alert("e1: " + e.getMessage());
e.printStackTrace();
} catch (JSONException e1) {
Dialog.alert("e2: " + e1.getMessage());
e1.printStackTrace();
}
return goinoutUserJsonObject;
}
And this following chunk of code is the goinout json request:
public static String sendGoinoutJsonRequest(String url,String data,long timeout, Hashtable properties, String method) throws IOException {
HttpConnectionFactory factory = new HttpConnectionFactory(Util.getTransportPriority());
while(true) {
HttpConnectionIOSession httpConnectionIOSession = null;
try {
HttpConnection httpConnection = factory.getHttpConnection(url);
if(httpConnection == null) throw new IOException();
try {
httpConnection.setRequestMethod(method);
httpConnection.setRequestProperty("If-Modified-Since","29 Oct 1999 19:43:31 GMT");
httpConnection.setRequestProperty("User-Agent","Profile/MIDP-2.0 Configuration/CLDC-1.0");
httpConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
httpConnection.setRequestProperty("Accept","application/json");
httpConnection.setRequestProperty("Content-Length",data.getBytes().length + "");
httpConnection.setRequestProperty("Content-Language","en-US");
httpConnection.setRequestProperty("x-rim-transcode-content","none");
Enumeration keys = properties.keys();
while(keys.hasMoreElements()) {
String key = (String) keys.nextElement();
String value = (String) properties.get(key);
httpConnection.setRequestProperty(key, value);
}
OutputStream outputStream = httpConnection.openOutputStream();
InputStream inputStream = null;
if(timeout != -1) {
httpConnectionIOSession = new HttpConnectionIOSession(httpConnection,inputStream,outputStream,timeout);
}
outputStream.write(data.getBytes());
outputStream.close();
int responseCode = httpConnection.getResponseCode();
if(responseCode != HttpConnection.HTTP_OK) {
if(responseCode == HttpConnection.HTTP_BAD_REQUEST) {
continue;
}
if(timeout != -1 && HttpUtils.TIMEOUT + 2000 <= TIMEOUT_MIN) {
HttpUtils.TIMEOUT += 2000;
}
throw new IOException("HTTP " + responseCode + " error code.");
}
inputStream = httpConnection.openInputStream();
final ByteBuffer byteBuffer = new ByteBuffer(inputStream);
final String response = byteBuffer.getString();
close(httpConnection,inputStream,outputStream);
if(timeout != -1 && HttpUtils.TIMEOUT - 1000 >= TIMEOUT_MIN) {
HttpUtils.TIMEOUT -= 1000;
}
if(httpConnectionIOSession != null) httpConnectionIOSession.interrupt();
return response;
} catch(IOException ioException) {
if(timeout != -1 && HttpUtils.TIMEOUT + 2000 <= TIMEOUT_MIN) {
HttpUtils.TIMEOUT += 2000;
}
throw ioException;
}
} catch(IOException ioException) {
if(timeout != -1 && HttpUtils.TIMEOUT + 2000 <= TIMEOUT_MIN) {
HttpUtils.TIMEOUT += 2000;
}
throw ioException;
} finally {
if(httpConnectionIOSession != null) httpConnectionIOSession.interrupt();
}
}
}
Look at the properties that I set. If I use this following of properties:
httpConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
httpConnection.setRequestProperty("Accept","application/json");
what happens is that I could retrieve the JSON data from my BB simulator, and from my real device using wifi connection. BUT, when I use REAL DEVICE using Mobile Service Provider, I will always get IOException: stream closed.
If I use this following code:
httpConnection.setRequestProperty("Content-Type","application/json");
httpConnection.setRequestProperty("Accept","application/json");
I always get HTTP Error Code 500 in simulator. And if I use this property in the real device using mobile service provider, the code is keep running because of while(true) there. I wonder if you guys could help me out.
As a matter of fact, This chunk of code is proven work in obtaining json data from Facebook API and Tumblr API. I always use this code and has no problem. I wonder if it could be something wrong with the server side, or I should add another property??? Thank you so much.
Nate request for HttpConnectionFactory:
package com.hammyliem.abateify.ui.network;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Vector;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import net.rim.device.api.io.http.HttpHeaders;
import net.rim.device.api.io.http.HttpProtocolConstants;
import net.rim.device.api.servicebook.ServiceBook;
import net.rim.device.api.servicebook.ServiceRecord;
import net.rim.device.api.system.Branding;
import net.rim.device.api.system.CoverageInfo;
import net.rim.device.api.system.DeviceInfo;
import net.rim.device.api.system.WLANInfo;
public class HttpConnectionFactory {
public static final int TRANSPORT_WIFI = 1;
public static final int TRANSPORT_BES = 2;
public static final int TRANSPORT_BIS = 4;
public static final int TRANSPORT_DIRECT_TCP = 8;
public static final int TRANSPORT_WAP2 = 16;
public static final int TRANSPORT_SIM = 32;
public static final int TRANSPORTS_ANY = TRANSPORT_WIFI | TRANSPORT_BES | TRANSPORT_BIS | TRANSPORT_DIRECT_TCP | TRANSPORT_WAP2 | TRANSPORT_SIM;
public static final int TRANSPORTS_AVOID_CARRIER = TRANSPORT_WIFI | TRANSPORT_BES | TRANSPORT_BIS | TRANSPORT_SIM;
public static final int TRANSPORTS_CARRIER_ONLY = TRANSPORT_DIRECT_TCP | TRANSPORT_WAP2 | TRANSPORT_SIM;
public static final int DEFAULT_TRANSPORT_ORDER[] = { TRANSPORT_WIFI, TRANSPORT_SIM, TRANSPORT_BIS, TRANSPORT_BES, TRANSPORT_WAP2, TRANSPORT_DIRECT_TCP };
private static final int TRANSPORT_COUNT = DEFAULT_TRANSPORT_ORDER.length;
// private static ServiceRecord srMDS[], srBIS[], srWAP2[], srWiFi[];
private static ServiceRecord srWAP2[];
private static boolean serviceRecordsLoaded = false;
private int transports[];
private int lastTransport = -1;
public HttpConnectionFactory() {
this(0);
}
public HttpConnectionFactory(int allowedTransports) {
this(transportMaskToArray(allowedTransports));
}
public HttpConnectionFactory(int transportPriority[]) {
if (!serviceRecordsLoaded) {
loadServiceBooks(false);
}
transports = transportPriority;
}
public static String getUserAgent() {
StringBuffer sb = new StringBuffer();
sb.append("BlackBerry");
sb.append(DeviceInfo.getDeviceName());
sb.append("/");
sb.append(DeviceInfo.getSoftwareVersion());
sb.append(" Profile/");
sb.append(System.getProperty("microedition.profiles"));
sb.append(" Configuration/");
sb.append(System.getProperty("microedition.configuration"));
sb.append(" VendorID/");
sb.append(Branding.getVendorId());
return sb.toString();
}
public static String getProfile() {
StringBuffer sb = new StringBuffer();
sb.append("http://www.blackberry.net/go/mobile/profiles/uaprof/");
sb.append(DeviceInfo.getDeviceName());
sb.append("/");
sb.append(DeviceInfo.getSoftwareVersion().substring(0, 3)); //RDF file format is 4.5.0.rdf (does not include build version)
sb.append(".rdf");
return sb.toString();
}
public HttpConnection getHttpConnection(String pURL) {
return getHttpConnection(pURL, null, null);
}
public HttpConnection getHttpConnection(String pURL, HttpHeaders headers) {
return getHttpConnection(pURL, headers, null);
}
public HttpConnection getHttpConnection(String pURL, byte[] data) {
return getHttpConnection(pURL, null, data);
}
public HttpConnection getHttpConnection(String pURL, HttpHeaders headers, byte[] data) {
int curIndex = 0;
HttpConnection con = null;
while ((con = tryHttpConnection(pURL, curIndex, headers, data)) == null) {
try {
curIndex = nextTransport(curIndex);
} catch (HttpConnectionFactoryException e) {
e.printStackTrace();
break;
} finally {
}
}
if (con != null) {
setLastTransport(transports[curIndex]);
}
return con;
}
private int nextTransport(int curIndex) throws HttpConnectionFactoryException {
if ((curIndex >= 0) && (curIndex < transports.length - 1)) {
return curIndex + 1;
} else {
throw new HttpConnectionFactoryException("No more transport available.");
}
}
private HttpConnection tryHttpConnection(String pURL, int tIndex, HttpHeaders headers, byte[] data) {
HttpConnection con = null;
OutputStream os = null;
switch (transports[tIndex]) {
case TRANSPORT_SIM:
try {
con = getSimConnection(pURL, false);
} catch (IOException e) {
} finally {
break;
}
case TRANSPORT_WIFI:
try {
con = getWifiConnection(pURL);
} catch (IOException e) {
} finally {
break;
}
case TRANSPORT_BES:
try {
con = getBesConnection(pURL);
} catch (IOException e) {
} finally {
break;
}
case TRANSPORT_BIS:
try {
con = getBisConnection(pURL);
} catch (IOException e) {
} finally {
break;
}
case TRANSPORT_DIRECT_TCP:
try {
con = getTcpConnection(pURL);
} catch (IOException e) {
} finally {
break;
}
case TRANSPORT_WAP2:
try {
con = getWap2Connection(pURL);
} catch (IOException e) {
} finally {
break;
}
}
if (con != null) {
try {
//add headers to connection
if (headers != null) {
int size = headers.size();
for (int i = 0; i < size;) {
String header = headers.getPropertyKey(i);
String value = headers.getPropertyValue(i++);
if (value != null) {
con.setRequestProperty(header, value);
}
}
}
// post data
if (data != null) {
con.setRequestMethod(HttpConnection.POST);
con.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_TYPE, HttpProtocolConstants.CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED);
con.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_LENGTH, String.valueOf(data.length));
os = con.openOutputStream();
os.write(data);
} else {
con.setRequestMethod(HttpConnection.GET);
}
} catch (IOException e) {
e.printStackTrace();
}
}
return con;
}
public int getLastTransport() {
return lastTransport;
}
public String getLastTransportName() {
return getTransportName(getLastTransport());
}
private void setLastTransport(int pLastTransport) {
lastTransport = pLastTransport;
}
private HttpConnection getSimConnection(String pURL, boolean mdsSimulatorRunning) throws IOException {
if (DeviceInfo.isSimulator()) {
if (mdsSimulatorRunning) {
return getConnection(pURL, ";deviceside=false", null);
} else {
return getConnection(pURL, ";deviceside=true", null);
}
}
return null;
}
private HttpConnection getBisConnection(String pURL) throws IOException {
if (CoverageInfo.isCoverageSufficient(4 /* CoverageInfo.COVERAGE_BIS_B */)) {
return getConnection(pURL, ";deviceside=false;ConnectionType=mds-public", null);
}
return null;
}
private HttpConnection getBesConnection(String pURL) throws IOException {
if (CoverageInfo.isCoverageSufficient(2 /* CoverageInfo.COVERAGE_MDS */)) {
return getConnection(pURL, ";deviceside=false", null);
}
return null;
}
private HttpConnection getWifiConnection(String pURL) throws IOException {
if (WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED) {
return getConnection(pURL, ";interface=wifi", null);
}
return null;
}
private HttpConnection getWap2Connection(String pURL) throws IOException {
if (CoverageInfo.isCoverageSufficient(1 /* CoverageInfo.COVERAGE_DIRECT */) && (srWAP2 != null) && (srWAP2.length != 0)) {
return getConnection(pURL, ";deviceside=true;ConnectionUID=", srWAP2[0].getUid());
}
return null;
}
private HttpConnection getTcpConnection(String pURL) throws IOException {
if (CoverageInfo.isCoverageSufficient(1 /* CoverageInfo.COVERAGE_DIRECT */)) {
return getConnection(pURL, ";deviceside=true", null);
}
return null;
}
private HttpConnection getConnection(String pURL, String transportExtras1, String transportExtras2) throws IOException {
StringBuffer fullUrl = new StringBuffer();
fullUrl.append(pURL);
if (transportExtras1 != null) {
fullUrl.append(transportExtras1);
}
if (transportExtras2 != null) {
fullUrl.append(transportExtras2);
}
return (HttpConnection) Connector.open(fullUrl.toString());
}
public static void reloadServiceBooks() {
loadServiceBooks(true);
}
private static synchronized void loadServiceBooks(boolean reload) {
if (serviceRecordsLoaded && !reload) {
return;
}
ServiceBook sb = ServiceBook.getSB();
ServiceRecord[] records = sb.getRecords();
Vector mdsVec = new Vector();
Vector bisVec = new Vector();
Vector wap2Vec = new Vector();
Vector wifiVec = new Vector();
if (!serviceRecordsLoaded) {
for (int i = 0; i < records.length; i++) {
ServiceRecord myRecord = records[i];
String cid, uid;
if (myRecord.isValid() && !myRecord.isDisabled()) {
cid = myRecord.getCid().toLowerCase();
uid = myRecord.getUid().toLowerCase();
if ((cid.indexOf("wptcp") != -1) && (uid.indexOf("wap2") != -1) && (uid.indexOf("wifi") == -1) && (uid.indexOf("mms") == -1)) {
wap2Vec.addElement(myRecord);
}
}
}
srWAP2 = new ServiceRecord[wap2Vec.size()];
wap2Vec.copyInto(srWAP2);
wap2Vec.removeAllElements();
wap2Vec = null;
serviceRecordsLoaded = true;
}
}
public static int[] transportMaskToArray(int mask) {
if (mask == 0) {
mask = TRANSPORTS_ANY;
}
int numTransports = 0;
for (int i = 0; i < TRANSPORT_COUNT; i++) {
if ((DEFAULT_TRANSPORT_ORDER[i] & mask) != 0) {
numTransports++;
}
}
int transports[] = new int[numTransports];
int index = 0;
for (int i = 0; i < TRANSPORT_COUNT; i++) {
if ((DEFAULT_TRANSPORT_ORDER[i] & mask) != 0) {
transports[index++] = DEFAULT_TRANSPORT_ORDER[i];
}
}
return transports;
}
private static String getTransportName(int transport) {
String tName;
switch (transport) {
case TRANSPORT_WIFI:
tName = "WIFI";
break;
case TRANSPORT_BES:
tName = "BES";
break;
case TRANSPORT_BIS:
tName = "BIS";
break;
case TRANSPORT_DIRECT_TCP:
tName = "TCP";
break;
case TRANSPORT_WAP2:
tName = "WAP2";
break;
case TRANSPORT_SIM:
tName = "SIM";
break;
default:
tName = "UNKNOWN";
break;
}
return tName;
}
}
First of all, I'm a little unclear why this question is tagged android. Perhaps it's too late, and I'm missing something. Anyway, I'm answering this as a BlackBerry question.
First of all, if you're encoding a set of parameters with normal URL encoding for your request, and expecting JSON in the response, then your original code:
httpConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
httpConnection.setRequestProperty("Accept","application/json");
is correct. Don't set Content-Type to application/json if your request's content is URL-encoded parameters.
Second, I'm not 100% sure, but I believe you are performing this network request on the UI thread. Even though I can't see the code that calls loginGoinoutWithFacebook(), I believe you're doing it on the UI thread, because that method contains a call to Dialog.alert(), which is a UI method.
Don't make network calls on the UI thread!
Probably what's happening (assuming you set the content type to application/x-www-form-urlencoded) is that over Wi-Fi, the network request completes really quickly, and the UI isn't blocked too long. It appears to work.
However, when you're on the Mobile Carrier Network, everything is slower. You block the UI thread for too long, and that causes problems. I can't remember exactly what the symptoms of making network calls on the UI thread are (because I never do it), but I would bet that this is your problem.
Use a background Thread / Runnable to perform your network calls:
Thread worker = new Thread(new Runnable() {
// this method is run on a background thread:
public void run() {
final JSONObject response = loginGoinoutWithFacebook(token);
// to update the UI with the response, we must use the UI thread:
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
// this just shows an alert, but you can insert your
// own code to update the UI properly with the response
// contents
Dialog.alert(response.toString());
}
});
}
});
worker.start();
I suspect there are two different problems here in addition to the possibility that you are running your code on the Event Thread as pointed out by Nate.
I am not sure that your are running on the Event Thread because your application will be terminated with a Application Not Responding exception if you were. But as Nate points out, you will get an Exception if you try to execute a Dialog off the Event Thread. So I would expect an Exception either way....
To summarise the reported problems, it seems that you get one of the following:
a) an IOException on the connection when running using the Wireless data service on device (as opposed to WiFi)
b) an HTTP code 500 when sending the data with a specific header. This means a Server has returned your request telling you that it has not understood it. So you are sending something incorrectly.
First I suggest you investigate the IOException - basically print out the detail of the exception that you get (toString() will do it). This will give you more detail on the problem. There are a number of choices, I'm guessing it will be a time out, but would like to know before I attempt to suggest a solution.
Can I refer to back to your previous Thread : blackberry-get-error-code-411 Please read my response again.
There were two points in there that are critical to all communications, not just the 411 error:
The encoding used for the data transmitted
The connection method used.
The encoding is perhaps key here for the 500 return code. When you tell the server you are sending JSON data it probably expects that the data will be UTF-8 encoded. However the data you send does not appear to be. If you are using just the standard Latin-1 characters then this will not be a problem. If your JSON data contains characters not included in that character set, then the data will not be encoded correctly and this may be why your Server does not understand it.
So for safety, when sending JSON data, I suggest you UTF-8 encode it (and remember that the number of bytes generated is NOT necessarily the same as the number of characters in the String).
Further with respect to the 500 error code (in fact any error code), I recommend that you dump out the headers on the response you receive back. They will probably identify the Server that actually returned the request. It may not be your Server - when processing over a mobile network as there are other gateways involved that can reject requests.
In summary, to investigate this problem (or any other network problem) I suggest you:
Print out the detail from any Exceptions you get
Make sure you know what connection method is used for the failing
request
If you do not get a good return code, dump out the headers so you
find out which Server actually gave you the return code
Make sure you correctly encode (character encode to bytes) the
data you are sending (and correct decode bytes you are received if
you convert these back to characters).
One final thing. Since the Server is giving you a 500 - I suggest you log the post data before you send it, on a failure, you can check that it is properly formatted.
I am developing a player that plays a url of the form
shoucast http://292.3.23.23:8000 is, as I can restore the
metadata? artist name mediaplayer use the title etc.
play no problem, but I can not retrieve metadata
anyone know how I can do it and display it in a text
titulo.settext (title);
check this out http://developer.android.com/reference/android/media/MediaMetadataRetriever.html but it is on API LEVEL 10
Thank you.
I have done using the thread,not the great solution but it works
public class IcyStreamMeta {
protected URL streamUrl;
private Map<String, String> metadata;
private boolean isError;
public IcyStreamMeta(URL streamUrl) {
setStreamUrl(streamUrl);
isError = false;
}
/**
* Get artist using stream's title
*
* #return String
* #throws IOException
*/
public String getArtist() throws IOException {
Map<String, String> data = getMetadata();
if (!data.containsKey("StreamTitle"))
return "";
String streamTitle = data.get("StreamTitle");
String title = streamTitle.substring(0, streamTitle.indexOf("-"));
return title.trim();
}
/**
* Get title using stream's title
*
* #return String
* #throws IOException
*/
public String getTitle() throws IOException {
Map<String, String> data = getMetadata();
if (!data.containsKey("StreamTitle"))
return "";
String streamTitle = data.get("StreamTitle");
String artist = streamTitle.substring(streamTitle.indexOf("-")+1);
return artist.trim();
}
public Map<String, String> getMetadata() throws IOException {
if (metadata == null) {
refreshMeta();
}
return metadata;
}
public void refreshMeta() throws IOException {
retreiveMetadata();
}
private void retreiveMetadata() throws IOException {
URLConnection con = streamUrl.openConnection();
con.setRequestProperty("Icy-MetaData", "1");
con.setRequestProperty("Connection", "close");
con.setRequestProperty("Accept", null);
con.connect();
int metaDataOffset = 0;
Map<String, List<String>> headers = con.getHeaderFields();
InputStream stream = con.getInputStream();
if (headers.containsKey("icy-metaint")) {
// Headers are sent via HTTP
metaDataOffset = Integer.parseInt(headers.get("icy-metaint").get(0));
} else {
// Headers are sent within a stream
StringBuilder strHeaders = new StringBuilder();
char c;
while ((c = (char)stream.read()) != -1) {
strHeaders.append(c);
if (strHeaders.length() > 5 && (strHeaders.substring((strHeaders.length() - 4), strHeaders.length()).equals("\r\n\r\n"))) {
// end of headers
break;
}
}
// Match headers to get metadata offset within a stream
Pattern p = Pattern.compile("\\r\\n(icy-metaint):\\s*(.*)\\r\\n");
Matcher m = p.matcher(strHeaders.toString());
if (m.find()) {
metaDataOffset = Integer.parseInt(m.group(2));
}
}
// In case no data was sent
if (metaDataOffset == 0) {
isError = true;
return;
}
// Read metadata
int b;
int count = 0;
int metaDataLength = 4080; // 4080 is the max length
boolean inData = false;
StringBuilder metaData = new StringBuilder();
// Stream position should be either at the beginning or right after headers
while ((b = stream.read()) != -1) {
count++;
// Length of the metadata
if (count == metaDataOffset + 1) {
metaDataLength = b * 16;
}
if (count > metaDataOffset + 1 && count < (metaDataOffset + metaDataLength)) {
inData = true;
} else {
inData = false;
}
if (inData) {
if (b != 0) {
metaData.append((char)b);
}
}
if (count > (metaDataOffset + metaDataLength)) {
break;
}
}
// Set the data
metadata = IcyStreamMeta.parseMetadata(metaData.toString());
// Close
stream.close();
}
public boolean isError() {
return isError;
}
public URL getStreamUrl() {
return streamUrl;
}
public void setStreamUrl(URL streamUrl) {
this.metadata = null;
this.streamUrl = streamUrl;
this.isError = false;
}
public static Map<String, String> parseMetadata(String metaString) {
Map<String, String> metadata = new HashMap();
String[] metaParts = metaString.split(";");
Pattern p = Pattern.compile("^([a-zA-Z]+)=\\'([^\\']*)\\'$");
Matcher m;
for (int i = 0; i < metaParts.length; i++) {
m = p.matcher(metaParts[i]);
if (m.find()) {
metadata.put((String)m.group(1), (String)m.group(2));
}
}
return metadata;
}
}
make thread call each 10 sec
public void startThread(){
timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
URL url;
Message msg = handler.obtainMessage();
try {
url = new URL(URL);
IcyStreamMeta icy = new IcyStreamMeta(url);
Log.d("SONG",icy.getTitle());
msg.obj = icy.getTitle();
Log.d("ARTITSi",icy.getArtist());
handler.sendMessage(msg);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 0, 10000);
}