Showing posts with label Android. Show all posts
Showing posts with label Android. Show all posts

Friday, June 22, 2012

Sax Parser example in Android

There are 2 ways to parse an xml in android. SAX an DOM. The DOM parser loads the whole document into memory before it can work with it, which can be slow and uses up a lot more memory - the benefit is that you're not writing as much code. So in mobile environment we are not using commonly this method for parsing xml.But in  SAX , it goes through each element and attribute one at a time, and you can pick and choose which one you want added into memory, but you do need to write a lot more code.  So this one is used in android for parsing. Here find an simple example for implementing this.
 
public static Login parse(String xml) throws Exception {
 LoginHandler handler = new LoginHandler();
 Xml.parse(xml ,handler);
 return handler.tempItem;
}

public static class LoginHandler extends DefaultHandler {

  private static final String RESPONSE = "response";
  private static final String STATUS = "result";
  private static final String CSRF = "_csrf";
  private static final String USER_TOKEN = "user_token"; 

  Login tempItem;
  private StringBuilder builder;

  @Override
  public void characters(char[] ch, int start, int length)
    throws SAXException {
   super.characters(ch, start, length);
   builder.append(ch, start, length);
  }

                // taking upto </tag> position.
  @Override
  public void endElement(String uri, String localName, String qName)
    throws SAXException {
   super.endElement(uri, localName, qName);
   if (this.tempItem != null) {
    if (localName.equalsIgnoreCase(STATUS)) {
      tempItem.setStatus(builder.toString().trim());
    }
   }
    builder.setLength(0);
  }

  @Override
  public void error(SAXParseException e) throws SAXException {
   super.error(e);
  }

  @Override
  public void fatalError(SAXParseException e) throws SAXException {
   super.fatalError(e);
  }

  @Override
  public void startDocument() throws SAXException {
   super.startDocument();
   builder = new StringBuilder();
  }
                // taking start position <response _csrf="456465" user_token="4557897">
  @Override
  public void startElement(String uri, String localName, String qName,
    Attributes attributes) throws SAXException {
   builder.setLength(0);
   super.startElement(uri, localName, qName, attributes);
   if (localName.equalsIgnoreCase(RESPONSE)) {
       tempItem = new Login();
                            // taking attributes value    
                            tempItem.setCsrf(attributes.getValue(CSRF));
                            tempItem.setUser_token(attributes.getValue(USER_TOKEN));
   }
  }

 }

public class Login {

 private String csrf = "";
 public String getUser_token() {
  return user_token;
 }

 public void setUser_token(String user_token) {
  this.user_token = user_token;
 }

 private String status = "";
 private String user_token = "";

 public String getCsrf() {
  return csrf;
 }

 public void setCsrf(String csrf) {
  this.csrf = csrf;
 }

 public String getStatus() {
  return status;
 }

 public void setStatus(String status) {
  this.status = status;
 }

}

Monday, March 26, 2012

Implementing Broadcast Receiver in Android

broadcast receiver is a component that responds to system-wide broadcast announcements. Many broadcasts originate from the system—for example, a broadcast announcing that the screen has turned off, the battery is low, or a picture was captured. Applications can also initiate broadcasts—for example, to let other applications know that some data has been downloaded to the device and is available for them to use. Although broadcast receivers don't display a user interface, they may create a status bar notification to alert the user when a broadcast event occurs. More commonly, though, a broadcast receiver is just a "gateway" to other components and is intended to do a very minimal amount of work. For instance, it might initiate a service to perform some work based on the event.

               We can simply implement broadcast receivers in applications .If you don't need to send broadcasts across applications, consider using this class with LocalBroadcastManager instead of the more general facilities described below. This will give you a much more efficient implementation (no cross-process communication needed) and allow you to avoid thinking about any security issues related to other applications being able to receive or send your broadcasts. 


Here a simple example for registering and sending a broadcast.



For receiving a broadcast
@Override
public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 IntentFilter filter = new IntentFilter("LOGOUT_BROADCAST");
     registerReceiver(logoutReceiver, filter);

}

private BroadcastReceiver logoutReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context arg0, Intent arg1) {
                      // to do 
  }
};
@Override
 protected void onDestroy() {
  super.onDestroy();
  unregisterReceiver(logoutReceiver);
 }
For sending a broadcast
Intent intent = new Intent("LOGOUT_BROADCAST",null);
context.sendBroadcast(intent);

Wednesday, March 21, 2012

ImageView zooming in Android

The common way to show a big image was enable the  user to zoom in, zoom out and pan  that image . A simple method is load the image in a web view. it will automatically handle the zooming. Also there are so many other ways to do the same. Please go through the following links.

 1. https://github.com/MikeOrtiz/TouchImageView 

 2. https://github.com/a85/WebComicViewer/blob/master/src/com/rickreation/ui/ZoomableImageView.java 

 3. http://code.google.com/p/android-multitouch-controller/

Wednesday, March 14, 2012

Keyboard raising issue when tabview at bottom of Android

There is an issue when placing a edittext in a tabview at bottom. when we tap on edit box the soft keyboard pops up and it move the whole view to upward (means the bottom tab also). When  we want to show the keyboard over the tabs at bottom itself. To solve this issue you may need to adjust the windowSoftInputMode in your manifest. This controls how the screen shifts when the soft keyboard is shown. This page has more info on the various input modes.   We can solve it as follows.


In AndroidManifest.xml


<activity
             android:name="TabActivity" android:windowSoftInputMode="adjustPan" >  
</activity>

Tuesday, March 6, 2012

Converting an inputStream to String in utf-8

Sometimes we need to check the response of the http request by converting the stream to a string.  A simple method with which  we can do it in UTF-8 format  is  follows.
public static String readStream(InputStream in) throws Exception {

  if(in == null){
     return "";
  }

  int ch;
  ByteArrayOutputStream bos = new ByteArrayOutputStream();
  while ((ch = in.read()) != -1) {
   bos.write(ch);
  }
  in.close();
  return new String(bos.toByteArray(), "UTF-8");

}

Monday, March 5, 2012

Add images to gallery dynamically in Android


To add an image into the  android gallery we can use   MediaScannerConnection  class. The system scans the SD card when it is mounted to find any new image (and other) files.So sometimes we need to restart the phone to get updated. To solve this   we can  programmatically add a file,  using this class.

public void saveImageBitmap(byte[] sourceImageData, Context context) {
  Bitmap scaledBitmap = null;
  try {
   ContentValues image = new ContentValues();
   image.put(Media.DISPLAY_NAME, "sample_" + System.currentTimeMillis());
   image.put(Media.MIME_TYPE, "image/jpeg");
   Uri uri = context.getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, image); 
   Bitmap bitmap = BitmapFactory.decodeByteArray(sourceImageData, 0, sourceImageData.length);
   Bitmap rotateBitmap = null;
   Matrix matrix = new Matrix();
   rotateBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
 
   OutputStream ops = context.getContentResolver().openOutputStream(uri);
   rotateBitmap.compress(Bitmap.CompressFormat.JPEG, 90, ops);
   ops.close();
   Cursor c = context.getContentResolver().query(uri, null, null, null, null);
   c.moveToFirst();
   String imagePath = c.getString(1);
   c.close();
   SingleScanMediaFile mScanner = new SingleScanMediaFile(context, imagePath);
          mScanner.onScanCompleted(imagePath, Uri.fromFile(new File(imagePath)));
  } catch (Exception e) {
   e.printStackTrace();
        }
  
} 


 public static class SingleScanMediaFile implements MediaScannerConnectionClient {
     private MediaScannerConnection mMediaScanner;
     private String uri; 
    SingleScanMediaFile (Context c, String uri) {
         this.uri = uri;
         mMediaScanner = new MediaScannerConnection(c, this);
         mMediaScanner.connect();
    } 
   
   @Override public void onMediaScannerConnected() {
         Log.i("Sample", "MEDIA SCANNER CONNECTED");
         try { 
              mMediaScanner.scanFile(uri, null);
         } catch (Exception e) {
             e.printStackTrace();
             mMediaScanner.disconnect(); 
         }
   }
  @Override public void onScanCompleted(String path, Uri uri) {
        Log.i("sample", "MEDIA SCANING COMPLETED");
        mMediaScanner.disconnect(); 
   } 
 }   

Escaping single quotes when using SQLite in Android

A verycommon problem while using sqlite and content providers are single quotes in arguements of query. Eventhough  we are not bothered about the same, it may lead to some problems  while executing the query. A simple approach to solve this issue is to use  content values and  selectionArgs.   Some examples are given below.


String sql = "select COUNT(*) FROM  table name WHERE parameter=?"; // parameter - column name
 mDB.rawQuery(sql , new String[]{param value} );

ContentValues values = new ContentValues();
values.put("categoryId", category.getCategoryId());
mDB.insert(table name , "NULL", values);


ContentValues values = new ContentValues();
values.put("registeredDate", regDate);
mDB.update(table name, values, "postId=?", new String[]{postId});

Saturday, March 3, 2012

Android : ListView inside a ScrollView

If there is a requirement  to place listview inside a scrollview , we cant implement it directly because of their vertical scroll property . To achieve this , after calling adpater.notifyDataSetChanged() , find the width and height of the listview  and invoke  requestLayout function. By doing this the performance of the list view become poor because we are changing listview as a normal linearlayout. It becomes a normal view group and child.




public static void setListViewHeightBasedOnChildren(ListView listView) {
  ListAdapter listAdapter = listView.getAdapter();
  if (listAdapter == null) {
   // pre-condition
   return;
  }

  int totalHeight = 0;
  int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(),
    MeasureSpec.AT_MOST);
  for (int i = 0; i < listAdapter.getCount(); i++) {
   View listItem = listAdapter.getView(i, null, listView);
   listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
   totalHeight += listItem.getMeasuredHeight();
  }

  ViewGroup.LayoutParams params = listView.getLayoutParams();
  params.height = totalHeight
    + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
  listView.setLayoutParams(params);
  listView.requestLayout();
 }

Friday, March 2, 2012

UTF-8 Encoding of parameters in POST request

We should consider  encoding of  the parameters  which we sent on  http request.. Otherwise when a parameter  such as in japaneese language then request may not be a successful one .In an http post request we can do it as below.

ArrayList<namevaluepair> nameValuePairs = new ArrayList<namevaluepair>();
nameValuePairs.add(new BasicNameValuePair("parameter","parameter value"));
URL url = new URL(" url string ");

AbstractHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url.toURI());
httpPost.addHeader("Date", dateCurrent);
int nResponse = 0;
HttpResponse response = null;
try {
         httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs , "UTF-8"));
         response = httpClient.execute(httpPost);
        nResponse = response.getStatusLine().getStatusCode();
        if (nResponse == HttpURLConnection.HTTP_OK) {
          InputStream instream = response.getEntity().getContent();
                              // Process the stream
        }else if (nResponse == HttpURLConnection.HTTP_UNAUTHORIZED) {
        String res = readStream(response.getEntity().getContent());
        Log.i("Response", res);
                            // Process the error stream.
       }
   }  catch (Exception e) {
 e.printStackTrace();
}
return null;
}

Progress Dialog issue when clicking default search button in Android

When we are using a Non-cancelable progress dialog , There a chance to dismiss when a  when a user click in default search button of Anroid phone.. To prevent this , Override keylistner of the progress dialog and consume that event.
For example :

mDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
  @Override
  public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
   if (keyCode == KeyEvent.KEYCODE_SEARCH && event.getRepeatCount() == 0) {
    return true; // Pretend we processed it
   }
  return false; // Any other keys are still processed as normal
  }
});