As far as I know the Android emulator does not provide simulation of hardware sensors. I spent plenty of time searching for options to throw hardware sensor events to the emulator in Eclipse and the Android developers site. I came accross in the Android developer's guide where it describes means to send events to the emulator, but the explanation was so brief I had no idea what to do. Also, I'm not sure if that was the part which describes what I want to acheive. In other words, it isn't so clear in any of the reference I haved looked about how you can simulate the hardware sensors in the emulator. For this reason, if you are developing an Android application which operates based on the orientation(or acceleration) of the device, you might be having trouble debugging your app.

So be it... I was so sure there must be some way to do it. After googling a while, I was led to openintents' google code project page. There I was able to find a sub-project called "Sensor Simulator". It was exactly the thing I was looking for, and it served its purpose right. I was able to simulate hardware sensor and send events to the Android emulator using it. The wiki page in the goole code project site seems to be outdated and you must make modifications to the resulting code of the instructions listed there in order to get it work. So I thought I should share the information about how I managed to make it work along with my understanding of how the thing works since the document on the wiki page delivers partly false instructions.


The distributed zip file of Sensor Simulator contains the hardware sensor simulator server, client, and an external jar library file. The hardware sensor simulator server is where you can change the orientation of the device in a GUI environment and generates the sensory input values. The client is an Android package that must be installed in the emulator(the Android device) which will read generated sensory input from the hardware sensor simulator server. The external jar library file consists of classes that provide an abstract layer to the SensorManager for reading sensory input values generated from the sensor simulator client which was read from the server.

To reduce confusion for future readers, I might as well aknowledge the version I downloaded and worked on for the people who might refer to this post later on when there is an updated version available and this post becomes invalid. But it's already been a while since the last update was done to the distributed zip file which was in July 2009. Everything is working quite well, and I see no reason for future updates in the near future unless there is a major change in the Android class architecture that relates to hardware sensors. Anyway, The version I worked with is 1.0.0-beta1 on Android SDK 2.0.


The Sensor Simulator wiki page can be found here.
And the distribution file I downloaded can be found here.

The following instructions are based on the project's wiki page, modified and added instructions and their description is based on my personal experience.

1. Installing the client in the Android emulator
Install SensorSimulatorSettings.apk in the bin directory to the Android emulator. I'm pretty sure there is a way to install Android packages from the DDMS perspective in Eclipse, but I personally prefer using the adb tool from the command prompt. 
adb install SensorSimulatorSettings.apk
You might have to add options to adb if you have multiple devices connected or emulators running. 

2. Execute the server and configure the cilent to make a connection
Execute sensorsimulator.jar in the bin directory which is the executable jar file of the server. The following is a screenshot of the server application. (The appearance of the server app may look weird as the layout is all messed up as the textboxes appear smaller than they are supposed to. You can correct this by resizing the window)

<An instance of the Sensor Simulator Server Application>

 
Scroll up the coresponding textbox which is marked with a red rectangle in the above picture in the server application. As you scroll up, you may see the possible IPs that the client can use to identify and connect to the server. Do not quit the server application.



Now start the Sensor Simulator client which you installed in your Android emulator by installing the sensorsimulatorsettings.apk to your emulator. The client Android app will look like the screenshot on the right.

Enter one of the possible IPs that was shown in the server application in the IP address field. If you did not make any modifications to the port number from the server application, you can use the default value 8010 which is the default value for the port number being used for the server application.






Then go to the Testing tab so you will see something like the screenshot on the left. Press the connect button and select the sensors you will like to retreive infromation from. The order of pressing the connect button and selecting the sensors does not seem to matter. Since the purpose of this post is demonstrating how to simulate hardware sensors, I will be enabling the orientation sensor only.

Now play around with the server. You can change the orientation of the device by clicking and dragging the mobile device looking like figure or by using slide bars. See if the values change in the client where it is marked with a red rectangle in the left picture.



If you can see the values change in the Android emulator by playing around with the server application, it means that the Android emulator is successfully retrieving the simulated hardware sensory input values.


3. Modifying the code to use simulated hardware sensory input
A portion of your application will have something similar to the following code if you were developing an Android application that reads hardware sensor values. The highlighted part is subject to change later on. This code is not tested on an actual device, so I will not guarantee it will work. But I have checked it is buildable. Also, keep in mind that this code contains a lot of deprecated API which I did not bother to make changes. I was referring to an outdated book published in the days of Android SDK 1.5 to make this quick example.

Here are the changes you must make to use the sensory values from the Sensor Simulator to simulate hardware sensors.

  1. The type of mSensorManager must be changed to SensorManagerSimulator. Create a SensorManagerSimulator instance by using the static method SensorManagerSimulator.getSystemServices(Context, String).
  2. Connect SensorManager to the simulator by calling static method SensorManagerSimulator.connectSimulator() before registering SensorListener.
The resulting code may look like the following. The lines highlighted in pink are the newly added lines and the yellow highlighted lines are lines that are modified.

There isn't much to modify after all. Here is how the instructions here are different from the project wiki page.
 The instruction where it says to retrieve the content resolver and create an Intent instance to start an Activity with it is left out because it seems to be unnecessary code. It explains as if it is a very important step, but it causes syntax errors and I have no idea how to interpret in order to make proper modifications. And it still works without those lines. 
 The step where unregistering the SensorListener before registering a new SensorListener from the wiki page is also left out here because I see no reason to do that in my simple example. Maybe that step might be required for some special cases, but I don't think that should happen too often.
 The way how the SensorManagerSimulator instance is created different. SensorManagerSimulator constructor is now private and the instance can be only created via the static method getSystemService().


4. The result

<You can see the simulated hardware sensory input value displayed in the TextView>


if your application stops unexpectedly, review the logs from logcat. See if you find anything similar to the following phrase from your log,

"Permission denied (maybe missing INTERNET permission)."

If this is the case, add the following line right before </manifest> at the end of AndroidManifest.xml.

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









Posted by Dansoonie