title: android get radio stream data
body: <p>I am trying to get what song is on with this code:</p>
  
  <pre><code>import java.io.IOException;
  import java.io.InputStream;
  import java.net.URL;
  import java.net.URLConnection;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  
  public class IcyStreamMeta {
  
  protected URL streamUrl;
  private Map&lt;String, String&gt; 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&lt;String, String&gt; 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&lt;String, String&gt; data = getMetadata();
  
      if (!data.containsKey("streamdata"))
          return "";
  
      String streamTitle = data.get("StreamTitle");
      String artist = streamTitle.substring(streamTitle.indexOf("-")+1);
      return artist.trim();
  }
  
  public Map&lt;String, String&gt; 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&lt;String, List&lt;String&gt;&gt; headers = con.getHeaderFields();
      InputStream stream = con.getInputStream();
  
      if (headers.containsKey("Current Song:")) {
          // Headers are sent via HTTP
          metaDataOffset = Integer.parseInt(headers.get("Current Song:").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() &gt; 5 &amp;&amp; (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 &gt; metaDataOffset + 1 &amp;&amp; count &lt; (metaDataOffset + metaDataLength)) {              
              inData = true;
          } else {                
              inData = false;             
          }               
          if (inData) {               
              if (b != 0) {                   
                  metaData.append((char)b);               
              }           
          }               
          if (count &gt; (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&lt;String, String&gt; parseMetadata(String metaString) {
      Map&lt;String, String&gt; metadata = new HashMap();
      String[] metaParts = metaString.split(";");
      Pattern p = Pattern.compile("^([a-zA-Z]+)=\\'([^\\']*)\\'$");
      Matcher m;
      for (int i = 0; i &lt; metaParts.length; i++) {
          m = p.matcher(metaParts[i]);
          if (m.find()) {
              metadata.put((String)m.group(1), (String)m.group(2));
          }
      }
  
      return metadata;
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Url I want to use are from this page: <a href="http://radio.m-1.fm/" rel="nofollow">http://radio.m-1.fm/</a> so for example <a href="http://radio.m-1.fm/M-1PLIUS" rel="nofollow">http://radio.m-1.fm/M-1PLIUS</a> (which is <code>http://84.46.147.81/m1plius/mp3</code>) but I get error <code>java.net.SocketException: Permission denied</code> Any ideas what is wrong?</p>