Amazon Gift Cards

Sunday, May 31, 2009

How to use XmlPullParser in Android

A post from androidguys.com stated that using XmlPullParser instead of DOM might be better in power saving. As i non java guy, i first didn't know what this one is. So today i tried to examine how to use it. And here is what i come up with. Please comment if the stuff i did is wrong or could be further optimized.

Note: XmlUtils is by default not included in the SDK, you can grab the class here. If there is an error, just remove the error.

public static void getAllXML(String url) throws 
XmlPullParserException, IOException, URISyntaxException{ 
  XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
  factory.setNamespaceAware(true);
  XmlPullParser parser = factory.newPullParser(); 
  parser.setInput(new InputStreamReader(getUrlData(url)));  
  XmlUtils.beginDocument(parser,"results");
  int eventType = parser.getEventType();
  do{
    XmlUtils.nextElement(parser);
    parser.next();
    eventType = parser.getEventType();
    if(eventType == XmlPullParser.TEXT){
      Log.d("test",parser.getText());
    }
  } while (eventType != XmlPullParser.END_DOCUMENT) ;       
}
public InputStream getUrlData(String url) 
throws URISyntaxException, ClientProtocolException, IOException {
  DefaultHttpClient client = new DefaultHttpClient();
  HttpGet method = new HttpGet(new URI(url));
  HttpResponse res = client.execute(method);
  return  res.getEntity().getContent();
}



Explanation
The getAllXml function would call getUrlData that would return an InputStream and pass it to the XmlPullParser
XmlPullParser parser = factory.newPullParser();
parser.setInput(new InputStreamReader(getUrlData(url)));


Then we would loop through the whole xml. This part is a bit complicated to explain so i apologize in advance if you would understand the following sentences.
On the loop we first we have to find out, base on the parser, which eventType the current element is at. The common event type that you would use are START_DOCUMENT, END_DOCUMENT, START_TAG, END_TAG, TEXT. Since we use the XMLUtils, which have a function that would help us get the nextElement without worrying about the closetags, text or comments in between the current tag and the next tag. After we get the next element tag, we parse the next one and see if its a TEXT (This might have some errors on your xml), if its a TEXT then we do our magic here. If you have an attribute, you may use getAttribute before the parse.next() on the current tag.

References
TelephonyProvider.java
XmlSnapshot.java (See this to understand the eventType stuff)
WebClient.java

Update History
   Jan 17, 2012 - Visual Update

Tuesday, May 26, 2009

Permissions Journey: ACCESS_NETWORK_STATE

ACCESS_NETWORK_STATE as what the description on the permissions page stated, it allows your application to access information about your network. To use this permissions.

Manifest.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" ></uses-permission>

Main.java
ConnectivityManager conMan = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = conMan.getActiveNetworkInfo();
Log.d("Connected state",networkInfo.getState().toString());
if(networkInfo.isConnected()){
  Log.d("Connected",networkInfo.toString());
}

Explanation
First we need to get the system service that answers queries about the state of network connectivity.
ConnectivityManager conMan = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);

Then we get our active network
NetworkInfo networkInfo = conMan.getActiveNetworkInfo();

We then check the current state of the network
Log.d("Connected state",networkInfo.getState().toString());

We check if this network is connected or not
if(networkInfo.isConnected()){ ...... }

If our network is connected then most likely we would do our magic on that block, but for now let us trace the network
Log.d("Connected",networkInfo.toString());

References
ConnectivityManager
NetworkInfo
http://www.google.com/codesearch/p?hl=en#MkYB9wOx8C4/trunk/DroidGuide/Client/src/br/ufmg/ubicomp/droidguide/utils/AndroidUtils.java&q=networkinfo%20android

Update History
   Jan 17, 2012 - Visual Update

Permissions Journey: ACCESS_WIFI_STATE

ACCESS_WIFI_STATE allows applications to access information about Wi-Fi networks, pretty much explained it all.

Manifest file
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" ></uses-permission>

Main.java
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
Log.d("wifiInfo",wifiInfo.toString());

Explanation
First we need to get our Wifi service, WifiManager class is pretty much the class you need for wifi connectivity.
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);

Get the infomration of the current wifi connection information with getConnectionInfo
WifiInfo wifiInfo = wifiManager.getConnectionInfo();

For now we trace our connection
Log.d("wifiInfo",wifiInfo.toString())

I got this result since i didnt turn on my wifi, you could turn your wifi on via settings and try to trace it again.
SSID: , BSSID: , MAC: 00:18:41:c8:62:98, Supplicant state: UNINITIALIZED, RSSI: -200, Link speed: 54, Net ID: -1

References
WifiManager
WifiInfo
http://www.google.com/codesearch/p?hl=en#8ckgoBxhL4o/trunk/src/android/tether/TetherApplication.java&q=WiFi%20android

Update History
   Jan 17, 2012 - Visual Update

Sunday, May 24, 2009

Permissions Journey: VIBRATE

Lets jump to Vibrate Permissions on Android. By default everything you need to know could be found at the Vibrator Class. To give an example of using vibrate:

Manifest file
<uses-permission android:name="android.permission.VIBRATE" ></uses-permission>

Archos 5 32 GB Internet Tablet with Android

Main.xml Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
>
  <Button  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:id="@+id/simpleBtn"
    android:text="Simple Vibrate"
  />
  <Button
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/patternBtn"
    android:text="Pattern Vibrate"
  />
  <Button  
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/cancelBtn"
    android:text="Cancel Vibrate"
  />
</LinearLayout>


Main.java
private Button simpleBtn;
private Button patternBtn;
private Button cancelBtn;
private Vibrator vibrator; 
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  simpleBtn = (Button)findViewById(R.id.simpleBtn);
  simpleBtn.setOnClickListener(this);
  patternBtn = (Button)findViewById(R.id.patternBtn);
  patternBtn.setOnClickListener(this);
  cancelBtn = (Button)findViewById(R.id.cancelBtn);
  cancelBtn.setOnClickListener(this);
  vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
}
public void onClick(View v) {
  if(v==simpleBtn){
    vibrator.vibrate(500);
  }else if(v == patternBtn){
    long[] pattern = {0L,100L,250L,1000L,250L,500L};
    vibrator.vibrate(pattern,2);
  }else{
    vibrator.cancel();
  }
}


Explanation
We create 3 buttons simpleBtn, patternBtn and cancelBtn and bind the onclick listener to the class.

First we get our vibrator service
vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);

Then on our simpleBtn, we use the vibrate function and vibrate the phone for 500ms
vibrator.vibrate(500);

On our patternBtn, we use an array (long), where the array reads as 0L(off), 100L (on), 250L (off) and so on. Then after completing the first pattern we repeat the series from the 3rd value (250L(off),2 on our function, 0 based index)
long[] pattern = {0L,100L,250L,1000L,250L,500L};
vibrator.vibrate(pattern,2);


On our cancelBtn, we simple cancel the vibration we created
vibrator.cancel();

Reference
Vibrator Class
http://www.google.com/codesearch/p?hl=en#tk1mgwvuros/trunk/src/au/id/weston/scott/Sketchaetch/Sketchaetch.java&q=VIBRATOR_SERVICE&l=287

Update History
   Jan 17, 2012 - Visual Update

Changing the Screen Brightness Programatically in Cupcake

Previously we had blogged about on how to change the screen brightness in android pre cupcake and on cupcake, the android team had added an official way to change the brightness without the hacks. Here is how to use it:

WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = 100 / 100.0f;
getWindow().setAttributes(lp);



References:
http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#screenBrightness
http://groups.google.com/group/android-developers/browse_thread/thread/6de1cb84596a1c9b

Update History
   Jan 17, 2012 - Visual Update

Friday, May 22, 2009

Permissions Journey: ACCESS_FINE_LOCATION

Our second journey takes a peek to ACCESS_FINE_LOCATION permission, where you can use GPS to locate directions. The implementation is basically the same with ACCESS_COARSE_LOCATION except on this article we would further expand the code to use the function requestLocationUpdates.

First up you need to enable your GPS
Settings -> Security and Location -> Enable GPS satellites

Then you need to add ACCESS_FINE_LOCATION to your manifest file
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>

Main.java
private SampleLocationListener mLocationListener;
private LocationManager m_location_manager;
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  mLocationListener = new SampleLocationListener();
  m_location_manager = (LocationManager) getSystemService(LOCATION_SERVICE);
  Boolean gpsEnabled  = m_location_manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
  Log.d("onCreateonCreate",String.valueOf(gpsEnabled));
  m_location_manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, mLocationListener);
}
@Override
protected void onDestroy() {
  // TODO Auto-generated method stub
  super.onDestroy();
  m_location_manager.removeUpdates(mLocationListener);
}
private class SampleLocationListener implements LocationListener {
    public void onLocationChanged(Location location) {
      // TODO Auto-generated method stub
      if(location != null){
        Log.d("SampleLocationListener",location.toString());
      }else{
        Log.d("SampleLocationListener","No location");
      }
    }
  public void onProviderDisabled(String provider) {
    // TODO Auto-generated method stub
    Log.d("SampleLocationListener onProviderDisabled",provider);
  }
  public void onProviderEnabled(String provider) {
    // TODO Auto-generated method stub
    Log.d("SampleLocationListener onProviderEnabled",provider);
  }
  public void onStatusChanged(String provider, int status, Bundle extras) {
    // TODO Auto-generated method stub
    Log.d("SampleLocationListener onStatusChanged",provider);
    }
}


Samsung Moment M900 Android Phone (Sprint)

Explanation
First of you need you to create a listener class that would extends LocationListener.
private class SampleLocationListener implements LocationListener { ..... }

Then create an instance of your created LocationListener
mLocationListener = new SampleLocationListener();

Then get the location service that would create a location manager for your GPS later on
m_location_manager = (LocationManager) getSystemService(LOCATION_SERVICE);

You could then check if the GPS is enable or not
Boolean gpsEnabled = m_location_manager.isProviderEnabled(LocationManager.GPS_PROVIDER);

Then you could continue to create a listener to the GPS service, (every 1 sec, on 1 distance change)
m_location_manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, mLocationListener);

Then on your SampleLocationListener class where the magic happens, here you could know if the network had change from GPS to Network, vise versa or other types of network, if the location has been changed, etc.

** Just one piece of advice, remember to shut off or remove the listener when the users close the app
m_location_manager.removeUpdates(mLocationListener);

Rerefences
http://www.google.com/codesearch/p?hl=en#OOgMjZrCM0A/trunk/OpenStreetMapViewer/src/org/andnav/osm/OpenStreetMapActivity.java&q=requestLocationUpdates
http://www.google.com/codesearch/p?hl=en#2OJgWTG3g9s/trunk/VoteReport/src/com/votereport/android/LocationFinderActivity.java&q=requestLocationUpdates
http://www.google.com/codesearch/p?hl=en#wYGukkcNuKc/trunk/Android20090319/Tutorial/AndroidPedometer/src/chikamune/minoru/pedometer/PedometerActivity.java&q=requestLocationUpdates

Update History
   Jan 17, 2012 - Visual Update

Friday, May 15, 2009

Permissions Journey: ACCESS_COARSE_LOCATION

While having problems on ACCESS_CHECKIN_PROPERTIES permission, i decided to journey to ACCESS_COARSE_LOCATION first. Some of you might ask what's the difference between ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION. ACCESS_COARSE_LOCATION is network based location access meaning the location is by your network, it could work with buildings or underground trains as long as you have access to your network while ACCESS_FINE_LOCATION is using gps thus your phone needs to be united with the sky (Correct me if im wrong here).

Now to our code (Tested this on the phone not on emulator).
Add In Manifest.xml
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
In Main.java
LocationManager m_location_manager = (LocationManager) getSystemService(LOCATION_SERVICE);
Location lm = m_location_manager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Log.d("log",lm.toString());


Explanation
The first line get our system service and the second line would get the last know location based on the network provider.

* Please take note that this assumes that it has a last known location, in order to know have location please see the function requestLocationUpdates.

References:
Google Groups
LocationManager in developer.andriod.com
http://www.google.com/codesearch/p?hl=en#Dgfu4syu6ZY/trunk/src/info/yasskin/droidmuni/DroidMuni.java&q=ACCESS_COARSE_LOCATION
http://www.google.com/codesearch/p?hl=en#uX1GffpyOZk/location/java/android/location/LocationManager.java&q=file:%28/|^%29android/location/LocationManager\.java$

Update History
   Jan 17, 2012 - Visual Update