Streaming media from Samba share to Android

Like many, I have a server/NAS that contains all my media (movies, music, photos, documents etc.), which is accessible via a Samba share to PCs in my house via LAN/wifi. XMBC works great to view all the media on-demand on the TV, however I was looking for a way to stream the media to an Android tablet (Samsung Galaxy Tab 10.1). And I found a REALLY simple, free solution:

  1. Install ES File Explorer (free) from the Android Market.
  2. Install RockPlayer Lite (free) from the Android Market.
  3. Open ES File Explorer and change view to LAN, then hit ‘New’ then ‘Server’ (from menu).
  4. Enter your server/NAS IP address, then a forward slash, then your share name, and any credentials if necessary.
  5. Hit OK, now you should be able to browse all the files on your Samba share with ease.

Now, when you tap on a movie file (avi/mpg/wmv etc.), you will get a prompt to choose which video player to use. Select RockPlayer Lite, and your movie will start playing within a few seconds. I’ve tested this for a variety of movie file types and sizes and RockPlayer Lite works really well, including skipping forwards and backwards through movies. For HD movies, expect to wait a little longer for the movie to buffer before it begins to play (e.g. > 10 seconds), once it gets going it seems pretty stable (no buffering). I’ve also tested this approach on an Android smartphone (LG P500 Optimus One, as well as the Samsung Galaxy S, both running Android 2.2) and it works just the same on the phone as the tablet). Awesome! And of course, you can also use this approach to play music and view photos from your server anywhere in range of your wifi signal 🙂

Can iPad do that!? :p

Using TuneLink with Meridian on Android

I tried some of those cheap FM-transmitters to allow me to play music from my Android in my non-bluetooth enabled car stereo, and no suprises, you get what you pay for. The major problem was the fact that when you get into your car, you have to find your phone, connect it and hit play etc. TuneLink Auto automatically connects to your phone via bluetooth, wherever it is in the car, and then the TuneLink app on the phone starts the music player once connected. So there’s nothing for you to do, but just turn on your ignition and go. It works pretty well, but I had a problem where I didn’t want to use the standard music player on my phone anymore, instead I wanted to use Meridian due to its capability to browse folders (not all my music has ID3 tags that are accurate). In order to make TuneLink activate Meridian to play, it sends the Android headset command (AVRPC), and you have to enable a setting in Meridian to register for receipt of this command. Steps:

  1. Open Meridian
  2. Press Menu, then Preferences
  3. Go to Music and check the Headset Buttons option.

Now TuneLink will trigger Meridian to play automatically.

Instantiating a custom view in Android

Creating a custom view/control in Android is fairly simple – here are the steps I used:

  1. Create a new class which extends from the ‘View’ abstract base class. E.g.
    public class MyCustomControl extends View
  2. Provide constructor overloads for ALL of the following prototypes, where initView() is a method in which you perform initialization of things such as Paint objects:
    public MyCustomControl(Context context)
    	{
    		super(context);
    		initView();
    	}
    	
    	public MyCustomControl(Context context, AttributeSet attrs)
    	{
    		super(context, attrs);
    		initView();
    	}
    
    	public MyCustomControl(Context context, AttributeSet attrs, int defStyle)
    	{
    		super(context, attrs, defStyle);
    		initView();
    	}
    
  3. Override onMeasure() in order to scale your control to the parent drawing area, such as shown in this good example.
  4. Do your canvas drawing operations in onDraw on the supplied Canvas object.
  5. Instantiate your custom view in a layout xml file (e.g. main.xml), for example:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
    	<com.android.samples.MyCustomControl
    		android:id="@+id/myCustomControl"
        	android:layout_width="fill_parent" 
        	android:layout_height="fill_parent" 
        />
    </LinearLayout>

I found that if I didn’t add the 2nd and 3rd constructors, I got an exception when calling setContentView(R.layout.main) from onCreate() of the main Activity. You can instead construct an instance of the view manually in onCreate() of the main Activity, and then call setContentView(yourCustomViewInstance) if you don’t want to use XML layout.

Upgrading your Android SD card

Short version:

To move data between SD cards in your Android phone, just copy it to a computer (with the phone plugged in – via enabling USB mass storage mode from the phone), power down the phone, insert new SD card, boot up, and copy data from computer back to new SD card in the phone. Easy.

Detailed version:

My Android (LG Optimus One) came with a 2Gb micro SD card, which did the job for about 6 months. Now I use my phone for listening to music in the car and elsewhere, and the apps I installed started to consume space as well, so I needed upgrade the SD card to something bigger. The biggest the most phones support right now is 32Gb, so I bought a Lexar 32 Gb micro SD card (class 10) for $AU100 (retail). I was a little concerned about the exact procedure to move the data from the 2Gb to the 32Gb card, but it turns out it was really simple (assuming you have not partitioned your SD card):

1. Connect phone to PC via USB (with old SD card install still inserted), and copy everything off the SD card into a folder on your HDD. I got a few errors trying to copy some ThinkFree Office files, probably due to the path length being too long, so I just skipped those files (they didn’t look too important anyway).

2. Power off phone, insert new SD card, boot up phone.

3. Connect phone to PC via USB, copy everything from the folder in step 1 to phone’s SD card, and disconnect USB.

That’s it.

Pairing SPP bluetooth devices with Android phones

Update: I have turned the below class into an app which I’ve made available in the Google Play Store called Bluetooth Class Zero. It is a simple application which just enables pairing with bluetooth class zero devices without having to root & patch your phone.

————————————–

I bought a Bluetooth Bee from Seeed Studios, which is an SPP (Serial Port Profile) bluetooth device, with the intention of writing an app for Android that communicates with a remote data logger. Unfortunately, it turns out that there’s a bug in the BroadComm bluetooth stack that is used by most Android phone manufacturers (LG, HTC, Samsung are affected, but not the Google Nexus phones) that prevents discovery to this and all other bluetooth devices that report their Class of Device (CoD) code as 0x00. This is the case for many SPP bluetooth devices, and SPP is probably the most common bluetooth profile (at least it’s the most basic – just straight serial comms) so this bug is pretty nasty.

Basically, if you perform a scan for devices, your SPP device will not show up, and in the logs you will see:

ERROR/DTUN_HCID4(663): Device [00:18:E4:0C:6E:CA] class is 0x00 – skip it.

The code for the Broadcom bluetooth stack is open source, so the bug is plain for all to see here. The bug has been reported on StackOverflow and elsewhere.

Until Broadcom and/or all users of their bluetooth stack fix this issue (by simply removing the IF block that skips devices whose CoD is 0x00), the only way to connect to your SPP device from Android is to read the log files, looking for the above error, extract the device address, and manually initiate a connection in code. After this, your SPP device will appear along with all your other bluetooth devices in the bluetooth settings page on your phone, and you can successfully communicate using the bluetooth API provided by Google.

I have written a re-usable class that implements this workaround, which you can download from here.

How to use (from your Activity class):

(new BluetoothClassZeroDiscoveryTask(
    this, 
    new BluetoothDiscoveryCallback())).execute();

Where BluetoothDiscoveryCallback is a class defined e.g. in your Activity. The call method will be called after the discovery task completes, and is passed the complete list of paired bluetooth devices, including those that are undiscoverable due to the above bug.

private class BluetoothDiscoveryCallback
    implements Action<ArrayList<BluetoothDevice>>
{
	public void call(ArrayList<BluetoothDevice> devices)
	{
		// Now you have the list of ALL available devices, 
		// including those that report class 0x00.
	}
}

// Java equivalent of the built-in Action from C#.
public interface Action<T>
{
	void call(T target);
}

You’ll also need to add READ_LOGS permission to your manifest file:

<uses-permission android:name="android.permission.READ_LOGS" />

Feel free to suggest improvements to the code, I’m new to Android and haven’t done Java in ages 🙂

P.S. Hassle your phone manufacturer to fix this bug so this workaround is not needed!

App Screenshots:

After pressing “Start Discovery”, if any bluetooth class zero devices were found (but ignored), you will get the standard pairing dialog:

After entering the correct PIN code, your device will be listed alongside others in your bluetooth settings:

The app requires Android 2.1+. It’s been tested on the following phones:

Manufacturer Model Android Version Affected Results
LG Optimus One 2.2 Yes Works
HTC Desire HD 2.2 Yes Works, but unfortunately may interfere with networking / bluetooth operation.
Samsung Galaxy S (I9000) 2.2 Yes Fails
Samsung Galaxy Player 50 2.1 Yes Works

The app is free to use, if you find it useful, feel free to make small donation 🙂