Archive | Android RSS for this section

Apple TV 3 vs Roku 2 vs Popcorn Hour Streaming Media Servers

Its pretty simple really I’d go Roku 2. For a couple reasons. First the Apple TV 3 hasn’t yet been jailbroken. There are lots of groups claiming a release but none have come through to my knowledge. I suspect it might be some time. To find exploits takes time and often ipad, iphone have higher priority due to saturation in the market. If you’re a non geek type this may not matter to you however it may without you realizing it.

Here is what I mean. One of the things that is a bit frustrating with ATV is the supported codecs. What’s a codec? Well I won’t go into detail but in short its a way for the device to decode or understand the content. Movies, music and the like all have codecs they need to be played. ATV is limited in this area compared to other devices. The other gotcha with ATV is that you need iTunes to sync to it. I’m not a fan of iTunes in fact if that interface went away and it was more seamless I’d be rather pleased with ATV.

Moving on and I want to be clear, there is NOTHING wrong with AppleTV. However if you want any flexibility its not the device for you. A couple other options are the Roku 2 and the Popcorn Hour devices. Both are very good at what they do. I own both. The Popcorn Hour is probably the most universal of them all in that it will play anything. With that said it is not for the faint of heart in that its more of a geek device that you can tinker with, write code for etc.

One of the main reasons I like the Roku 2 is its form factor of course and that it supports Plex right out of the box. Plex folks is a must have moving forward as TV and the Internet continue to merge. For Plex alone I’d choose Roku 2 over AppleTV. In fact it is one of the major contributing factors to why ATV 2’s are so popular right now (they can be jailbroken and you can add Plex where ATV 3 you can’t…yet that is).

Winner: Roku 2 XS

Which Android Tablet Should I Buy

Initial Thoughts

I Tested a few recently and thought I’d share my findings before the article is released. The units tested were the Galaxy Tab 2 10.1, the Asus Transformer Infinity 10.1 and the Toshiba Excite 10.

Let me say going into this I thought hands down the Transformer Infinity would be the clear cut winner with its industry leading high resolution screen. I have to say though I find the Asus product although slick, slim and sexy not as functional as other tablets. What I mean is I experienced some odd scrolling problems, where content was very jerky. It looked great but if I’m constantly fighting that its a deal breaker for me.

Findings

Asus Transformer Infinity

As you might remember the Transformer Prime was a bit of a disaster. Due to the alum. back it caused issues with the GPS in the device. Now if that wasn’t something you’d be using I guess it wasn’t that big of a deal but to shell out $500.00 or more it should work nonetheless. I think Asus was pretty stand up about the issue. They didn’t run and hide by any stretch. Still the same scrolling issue I found with the Prime still exists in the Infinity. I can’t put my stamp on a device that is buggy like that. The screen does look great. Overall it feels rather snappy as well, but the lack of smooth responsiveness really turned me off.

Samsung Galaxy Tab 2

The Samsung overall is a solid device. There are some nice features with the Tab 2. Particularly the IR Blaster which is cool if you want to control your home theater devices. However I’m not sure how practical it really is. I found a remote with buttons is hard to beat. I’ve had touchscreen remotes with elaborate programming since the first Pronto. Have programmed Crestron and others and I still swear buy a high end Universal Remote with actual buttons. Maybe that’s just me. Of the three here I’d have to give the nod to Samsung for the software bundles included. Its a very nice presentation of software. Where the Samsung really falls off for me is they are still using the last gen processor as opposed to stepping up to the Tegra 3 as have others. Really a disservice to the customer in my opinion.

Toshiba Excite 10

First off to be clear this is the Excite 10 NOT the LE version. The Excite is a pretty straight forward device. For example you don’t have the software media share bundling like you have with the Samsung nor the Asus Storage Cloud service, however What it does have are super smooth transitions in the UI. With the Tegra 3 quad core processor it is rather speedy much like the Asus Infinity, but unlike the Infinity the scrolling and screens are quick to transition but in the same breath very smooth. I was happily surprised by its performance. Not flashy. Not as sexy but works well. Come to think of it every thing I’ve owned with the Toshiba name has been about the same. One knock on the Toshiba Excite that I must admit and at least with the audio/video I was testing it has the lowest audio output of the bunch. With that said if I’m watching a film or doing anything other than hearing haptics I’m using headphones.

The Winner Is Toshiba Excite 10

Now before you go saying this guy’s off his rocker understand that I’m a very picky buyer. Small things will get you big red marks with me. Functionality for me is far more important that buzz words and specs that say “I’m really good and I have more x than any other on the market”. What I mean is I want things to do the tasks they were designed to do and do them well. For me the winner here is the Toshiba Excite 10. It’s not the thinest. It doesn’t have the 1080p screen of the Asus Transformer Infinity, doesn’t have the bundling of the Samsung and ease of use but it does have the most responsiveness of the bunch and is rather smooth as I transition between tasks. Please keep in mind I’m a business user. I’m not playing Temple Run (although that was thoroughly tested on each by my 12 yr old, she gave them all +1’s ha ha) or smashing objects with birds. No I’m using it as a tool to check corporate mail, but to scan networks for security wholes, to browse the net to update applications and debug applications I’ve built. The point is if you’re a multimedia guy you might like the Samsung Galaxy Tab 2. If you want to watch great movies in super clear high resolution you may want to try out the Asus Transformer Infinity. If you’re a business user I strongly suggest the Toshiba.

Lastly the Toshiba for a quad core is rather reasonably priced. At just $400 bucks you can afford to use it for now and maybe go for a Nexus 10 once released. If you haven’t heard of the Nexus 10 take a look at the Nexus 7, look at the price tag, roll eyes and prepare to hit submit for the 10 when released I will. Oh and for the record I was able to stream HD .mkv files across my network from my NAS server with zero issues using Vplayer on the Toshiba Excite. It was a beautiful image, was clear and the audio was crisp. There are several video players out there, I’ve found the VPlayer when it comes to playing the .MKV container to be the best. More consistently decodes audio than say Mobo, MXPlayer or others.

Android HttpRequest Class

This is simply a post of a class you can find here. The posted class from the source had some errors (missing escapes). This is just the corrected class.

import java.net.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import org.apache.http.client.HttpClient;
import org.apache.commons.*;
import android.util.Log;
/**
* HTTP Request class
*
* You can use this class and distribute it as long as you give proper credit
* and place and leave this notice intact :). Check my blog for updated
* version(s) of this class (http://moazzam-khan.com)
*
* Usage Examples:
*
* Get Request
* --------------------------------
* HttpData data = HttpRequest.get("http://example.com/index.php?user=hello");
* System.out.println(data.content);
*
* Post Request
* --------------------------------
* HttpData data = HttpRequest.post("http://xyz.com", "var1=val&var2=val2");
* System.out.println(data.content);
* Enumeration<String> keys = dat.cookies.keys(); // cookies
* while (keys.hasMoreElements()) {
*         System.out.println(keys.nextElement() + " = " +
*                 data.cookies.get(keys.nextElement() + "rn");
*    }
* Enumeration<String> keys = dat.headers.keys(); // headers
* while (keys.hasMoreElements()) {
*         System.out.println(keys.nextElement() + " = " +
*                 data.headers.get(keys.nextElement() + "rn");
*    }
*
* Upload a file
* --------------------------------
* ArrayList<File> files = new ArrayList();
* files.add(new File("/etc/someFile"));
* files.add(new File("/home/user/anotherFile"));
*
* Hashtable<String, String> ht = new Hashtable<String, String>();
* ht.put("var1", "val1");
*
* HttpData data = HttpRequest.post("http://xyz.com", ht, files);
* System.out.println(data.content);
*
* @author Moazzam Khan
*/
public class HttpRequest {
 
        /**
        * HttpGet request
        *
        * @param sUrl
        * @return
        */
        public static HttpData get(String sUrl) {
                HttpData ret = new HttpData();
                String str;
                StringBuffer buff = new StringBuffer();
                try {
                        URL url = new URL(sUrl);
                        URLConnection con = url.openConnection();
 
                        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
                        while ((str = in.readLine()) != null) {
                                buff.append(str);
                        }
                        ret.content = buff.toString();
                        //get headers
                        Map<String, List<String>> headers = con.getHeaderFields();
                        Set<Entry<String, List<String>>> hKeys = headers.entrySet();
                        for (Iterator<Entry<String, List<String>>> i = hKeys.iterator(); i.hasNext();) {
                                Entry<String, List<String>> m = i.next();
 
                                Log.w("HEADER_KEY", m.getKey() + "");
                                ret.headers.put(m.getKey(), m.getValue().toString());
                                if (m.getKey().equals("set-cookie"))
                                ret.cookies.put(m.getKey(), m.getValue().toString());
                        }
                } catch (Exception e) {
                        Log.e("HttpRequest", e.toString());
                }
                return ret;
        }
 
 
 
 
        /**
        * HTTP post request
        *
        * @param sUrl
        * @param ht
        * @return
        * @throws Exception
        */
        public static HttpData post(String sUrl, Hashtable<String, String> ht) throws Exception {
                String key;
                StringBuffer data = new StringBuffer();
                Enumeration<String> keys = ht.keys();
                while (keys.hasMoreElements()) {
                        key = keys.nextElement();
                        data.append(URLEncoder.encode(key, "UTF-8"));
                        data.append("=");
                        data.append(URLEncoder.encode(ht.get(key), "UTF-8"));
                        data.append("&amp;");
                }
                return HttpRequest.post(sUrl, data.toString());
        }
        /**
        * HTTP post request
        *
        * @param sUrl
        * @param data
        * @return
        */
        public static HttpData post(String sUrl, String data) {
                StringBuffer ret = new StringBuffer();
                HttpData dat = new HttpData();
                String header;
                try {
                        // Send data
                        URL url = new URL(sUrl);
                        URLConnection conn = url.openConnection();
                        conn.setDoOutput(true);
                        OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
                        wr.write(data);
                        wr.flush();
 
                        // Get the response
 
                        Map<String, List<String>> headers = conn.getHeaderFields();
                        Set<Entry<String, List<String>>> hKeys = headers.entrySet();
                        for (Iterator<Entry<String, List<String>>> i = hKeys.iterator(); i.hasNext();) {
                                Entry<String, List<String>> m = i.next();
 
                                Log.w("HEADER_KEY", m.getKey() + "");
                                dat.headers.put(m.getKey(), m.getValue().toString());
                                if (m.getKey().equals("set-cookie"))
                                dat.cookies.put(m.getKey(), m.getValue().toString());
                        }
                        BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                        String line;
                        while ((line = rd.readLine()) != null) {
                                ret.append(line);
                        }
 
                        wr.close();
                        rd.close();
                } catch (Exception e) {
                        Log.e("ERROR", "ERROR IN CODE:"+e.getMessage());
                }
                dat.content = ret.toString();
                return dat;
        }
        /**
        * Post request (upload files)
        * @param sUrl
        * @param files
        * @return HttpData
        */
        public static HttpData post(String sUrl, ArrayList<File> files)
        {
                Hashtable<String, String> ht = new Hashtable<String, String>();
                return HttpRequest.post(sUrl, ht, files);
        }
        /**
        * Post request (upload files)
        * @param sUrl
        * @param params Form data
        * @param files
        * @return
        */
        public static HttpData post(String sUrl, Hashtable<String, String> params, ArrayList<File> files) {
                HttpData ret = new HttpData();
                try {
                        String boundary = "*****************************************";
                        String newLine = "rn";
                        int bytesAvailable;
                        int bufferSize;
                        int maxBufferSize = 4096;
                        int bytesRead;
 
                        URL url = new URL(sUrl);
                        HttpURLConnection con = (HttpURLConnection) url.openConnection();
                        con.setDoInput(true);
                        con.setDoOutput(true);
                        con.setUseCaches(false);
                        con.setRequestMethod("POST");
                        con.setRequestProperty("Connection", "Keep-Alive");
                        con.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
                        DataOutputStream dos = new DataOutputStream(con.getOutputStream());
 
                        //dos.writeChars(params);
 
                        //upload files
                        for (int i=0; i<files.size(); i++) {
                                Log.i("HREQ", i+"");
                                FileInputStream fis = new FileInputStream(files.get(i));
                                dos.writeBytes("--" + boundary + newLine);
                                dos.writeBytes("Content-Disposition: form-data; "
                                + "name=\"file_"+i+"\";filename=\""
                                + files.get(i).getPath() +"\"" + newLine + newLine);
                                bytesAvailable = fis.available();
                                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                                byte[] buffer = new byte[bufferSize];
                                bytesRead = fis.read(buffer, 0, bufferSize);
                                while (bytesRead > 0) {
                                        dos.write(buffer, 0, bufferSize);
                                        bytesAvailable = fis.available();
                                        bufferSize = Math.min(bytesAvailable, maxBufferSize);
                                        bytesRead = fis.read(buffer, 0, bufferSize);
                                }
                                dos.writeBytes(newLine);
                                dos.writeBytes("--" + boundary + "--" + newLine);
                                fis.close();
                        }
                        // Now write the data
 
                        Enumeration keys = params.keys();
                        String key, val;
                        while (keys.hasMoreElements()) {
                                key = keys.nextElement().toString();
                                val = params.get(key);
                                dos.writeBytes("--" + boundary + newLine);
                                dos.writeBytes("Content-Disposition: form-data;name=\""
                                + key+"\"" + newLine + newLine + val);
                                dos.writeBytes(newLine);
                                dos.writeBytes("--" + boundary + "--" + newLine);
 
                        }
                        dos.flush();
 
                        BufferedReader rd = new BufferedReader(
                        new InputStreamReader(con.getInputStream()));
                        String line;
                        while ((line = rd.readLine()) != null) {
                                ret.content += line + "rn";
                        }
                        //get headers
                        Map<String, List<String>> headers = con.getHeaderFields();
                        Set<Entry<String, List<String>>> hKeys = headers.entrySet();
                        for (Iterator<Entry<String, List<String>>> i = hKeys.iterator(); i.hasNext();) {
                                Entry<String, List<String>> m = i.next();
 
                                Log.w("HEADER_KEY", m.getKey() + "");
                                ret.headers.put(m.getKey(), m.getValue().toString());
                                if (m.getKey().equals("set-cookie"))
                                ret.cookies.put(m.getKey(), m.getValue().toString());
                        }
                        dos.close();
                        rd.close();
                } catch (MalformedURLException me) {
 
                } catch (IOException ie) {
 
                } catch (Exception e) {
                        Log.e("HREQ", "Exception: "+e.toString());
                }
                return ret;
        }
}