Wednesday, March 28, 2012

Avoid dialog leak issue in Android?



Dialog leak issue usually occur when the dialog is shown and later the activity destroy without dismissing it. Most common leaks happen while dialog is showing then the configuration or orientation change occur. So, it  causes the leak and sometime it may also cause the App to crash or go into an invalid state. You may notice the leak only by looking at the logcat. This mean that you do not dismiss your dialog correctly before your activity get destroy.
When the orientation change, the activity will be destroyed and re-created again. Before the activity is destroyed due to orientation change, it will save the current state first. So, when the activity is re-created it tries to restore instance state (onRestoreInstanceState()) from the previous activity. Notice that when the activity is re-created, it is a new activity and a new view. The exception may occur, if it try to update the old view (possibly, the dialog that did not dismiss) in the new activity, because the old view will have an invalid Context.
So, if your application have any pop up dialog, make sure that you dismiss it before your application get destroy. Here is what you can do.
1. Dismiss all dialogs completely if exist in onPause() or immediately after it is no longer need.
2. Since most common leaks happen while dialog is showing then the configuration or orientation change occur, another way to avoid dialog leak is NOT to destroy the activity when orientation change. If the activity is not destroyed, then there is no dialog leak and there is no re-creation of new activity, thus no issue neither. This can be achieved by using the attribute android:configChanges=”orientation|keyboardHidden” in the manifest file and using the Override method onConfigurationChanged() inside your activity. By using the attribute android:configChanges you will tell Android that you will handle the configuration change yourself so, don’t destroy the activity. And you can handle the configuration change in the Override method, or you may leave it blank if you prefer not to do anything.

OutOfMemoryError when using bitmap in Android?


The most common issue that you may face while working with bitmap is OutOfMemoryError. This issue occur because the garbage collector (GC) does not free the object associated with the bitmap and clear preference to pixel data fast enough, thus cause the memory allocated for the bitmap to grow until exceeding Virtual Memory limit.

java.lang.OutOfMemoryError: bitmap size exceeds VM budget
In order to avoid this issue, you need to do recycle() for every bitmap as soon as it no long need. Notice that recycle () is used to free the native object associated with this bitmap, and clear the reference to the pixel data. This will not free the pixel data synchronously; it simply allows it to be garbage collected if there are no other references. The bitmap is marked as “dead”, meaning it will throw an exception if getPixels() or setPixels() is called, and will draw nothing. This operation cannot be reversed, so it should only be called if you are sure there are no further uses for the bitmap. This is an advanced call, and normally need not be called, since the normal GC process will free up this memory when there are no more references to this bitmap. See the code below:
public class bitmaptest extends Activity {

     @Override
     public void onCreate(Bundle icicle) {
          super.onCreate(icicle);
          // decode a jpg into bitmap
          Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/myimage.jpg");

          ...

          // indicate that the bitmap is no longer need and GC should
          // free it asap
          bitmap.recycle();
     }
}
 
Bimap is a little tricky, miss-use it may causes an exception. Generally using bitmap is recommended only if you need to get detail data of the image such as image width, height, and pixel data. Otherwise, bitmap should not be used in order to avoid OutOfMemoryError. For an example, if you just want to dispaly an image such as icon, you could you ImageView class instead and it also provides various display options such as scaling and tinting. The following code below shows how to build an ImageView that uses an image from drawable resources and add it to the layout.
public class bitmaptest extends Activity {

     private LinearLayout mLinearLayout;

     @Override
     protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);

          // Create a LinearLayout in which to add the ImageView
          mLinearLayout = new LinearLayout(this);

          // Instantiate an ImageView and define its properties
          ImageView imageView = new ImageView(this);
          imageView.setImageResource(R.drawable.my_image);
          imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
          imageView.setPadding(8, 8, 8, 8);
          imageView.setLayoutParams(new GridView.LayoutParams(200, 200));

          // Add the ImageView to the layout and set the layout as
          // the content view
          mLinearLayout.addView(imageView);
          setContentView(mLinearLayout);
     }
}


Is starting a thread in broadcast receiver a good idea in Android?


Usually, the purpose of using thread is to perform a heavy task in the background without interrupting any UI activity. In addition, the onReceive() is running on UI thread so any long time operation may cause ANR (application not responding). Thus, most developers may think of using a thread in the onReceive() to perform long time operation to avoid the ANR issue. However, using a thread in onReceive() may not be a good idea neither.
As we already know that the broadcast receiver life cycle is very short, and it is destroyed shortly after onReceive() end. Thus, putting a thread in onReceive() will cause it to be in a state that not belong to anything and it may be easily killed which end up cause unexpected behavior. A better way to handle long time operation in onReceive() is to start an Intent Service instead (NOT bind service). See an example below on how to start a service from onReceive().
public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // start an intent service
        context.startService(new Intent(this, MyService.class));
    }
}
public class MyService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // do something here
        return START_STICKY;
    }
}

Tuesday, March 27, 2012

How to convert Date and Time in Millisecond in android?


public long dateConvertor(String date) throws ParseException {
Date currentpastDate = null;
try {
SimpleDateFormat formatter = new SimpleDateFormat("d MMM yyyy h:mm a");
currentpastDate = (Date) formatter.parse(date);


} catch (Exception E) {
E.printStackTrace();
}
return currentpastDate.getTime();
}

Saturday, March 24, 2012

How to write text through Canvas in android?


public class CanvasGreetingActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(new SampleView(this));
 }

 private static class SampleView extends View {
   public SampleView(Context context) {
     super(context);
     setDrawingCacheEnabled(true);
   }

   @Override
   protected void onDraw(Canvas canvas) {
     canvas.drawColor(Color.WHITE);

     String blackText = "black";
     String redText = " red";

     Paint mPaint = new Paint();
     mPaint.setAntiAlias(true);
     mPaint.setTextSize(30);
     mPaint.setTypeface(Typeface.create(Typeface.SERIF,Typeface.ITALIC));

     float canvasWidth = canvas.getWidth();
     float blackTextWidth = mPaint.measureText(blackText);
     float sentenceWidth = mPaint.measureText(blackText + redText);
     float startPositionX = (canvasWidth - sentenceWidth) / 2;

     mPaint.setTextAlign(Paint.Align.LEFT);
     canvas.translate(0, 80);

     mPaint.setColor(Color.BLACK);
     canvas.drawText(blackText, startPositionX, 0, mPaint);
     mPaint.setColor(Color.RED);
     canvas.drawText(redText, startPositionX + blackTextWidth, 0,mPaint);
   }
 }

Friday, March 23, 2012

How to solve Android Window Leak ?


The WindowLeaked exception in the log usually happens when you have some sort of async task that is finishing after the activity that began it is destroyed.
Solution for the above issue, we can dismiss the progress dialog before finish the activity.
Issue :
Activity com.sample.ViewLeakIssueActivity has leaked window com.android.internal.policy.impl.TvWindow$DecorView@6bc30788 that was originally added here
E/WindowManager( 1687): at android.view.ViewRoot.(ViewRoot.java:230)
E/WindowManager( 1687): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
-----

Sample Leak Issue
public class ViewLeakIssueActivity extends Activity {
volatile ProgressDialog pd;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pd = ProgressDialog.show(ViewLeakIssueActivity.this, "", "test...", true);

new Thread() {
public void run() {
try {
sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("@@@@@@@@@@@"+ViewLeakIssueActivity.this+pd.isShowing());

pd.dismiss();
}
}.start();

finish();

}

}

Solution for the above issue, we can dismiss the progress dialog before finish the activity.

@Override
public void finish() {
if(pd.isShowing()){
pd.dismiss();
}
super.finish();
}

How to make the scrollable TextView in android?



public class MainActivity extends Activity {
/** Called when the activity is first created. */

private TextView mTextView;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextView = (TextView) findViewById(R.id.textView1);
mTextView
.setText("this is for testing \nthis is for testing \nthis is for testing \nthis is for testing \nthis is for testing \nthis is for testing \n");

mTextView.setMovementMethod(new ScrollingMovementMethod() {
public void onTakeFocus(TextView widget, Spannable text, int dir) {

}

@Override
public boolean onKeyDown(TextView widget, Spannable buffer,
int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_DOWN:
for (int i = 0, scrollAmount = getScrollAmount(widget); i < scrollAmount; i++) {
down(widget, buffer);
}
return true;
case KeyEvent.KEYCODE_DPAD_UP:
for (int i = 0, scrollAmount = getScrollAmount(widget); i < scrollAmount; i++) {
up(widget, buffer);
}
return true;
default:
return super.onKeyDown(widget, buffer, keyCode, event);
}
}
private int getScrollAmount(TextView widget) {
final int visibleLineCount = (int) ((1f * widget.getHeight()) / widget
.getLineHeight());
int scrollAmount = visibleLineCount - 1;
if (scrollAmount < 1) {
scrollAmount = 1;
}
return scrollAmount;
}
});
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_DOWN:

return true;
case KeyEvent.KEYCODE_DPAD_UP:
mTextView.dispatchKeyEvent(event);
return true;
default:
return super.onKeyDown(keyCode, event);
}
}
}


How to detect Gesture based action in Android?


I have list of images in a listview with url. When the user wants view the full image then user click the image on the list view
it will take to me the anonther activity and open in a imageview. and as a user wants to tee the next nexe or previous image with come back to listview page

Solution : I have created the HashMap Contains the list of images and pass the selected images name as bundle string. In a detail view created the async task the fetch image from the internet
implement the gestureListener. In this article we discussing about that

Related : gesture move action, gesture based action, example geatures

1. Create a Activity implements OnClickListener
public class MySample1Activity extends Activity implements OnClickListener {
........
}
2. Initialize below required object for gestureListener
ViewConfiguration vc;

static int SWIPE_MAX_OFF_PATH = 250;
static int SWIPE_MIN_DISTANCE = 100;
static int SWIPE_THRESHOLD_VELOCITY = 100;

private GestureDetector gestureDetector;
View.OnTouchListener gestureListener;

3. Set Densitybased velocity
vc = ViewConfiguration.get(this);
SWIPE_MIN_DISTANCE = vc.getScaledTouchSlop();
SWIPE_THRESHOLD_VELOCITY = vc.getScaledMinimumFlingVelocity();

4. Create a Custom GestureListener class which extends SimpleOnGestureListener
class MyGestureDetector extends SimpleOnGestureListener {

}

5. Override the onFling() and implement the geature move action
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
try {
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
return false;
// right to left swipe
if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
Toast.makeText(MySample1Activity.this, "Left Swipe",
Toast.LENGTH_SHORT).show();
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
Toast.makeText(MySample1Activity.this, "Right Swipe",
Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
// nothing
}
return false;
}

Full SourceCode
public class MySample1Activity extends Activity implements OnClickListener {
/** Called when the activity is first created. */
TextView tView;

ViewConfiguration vc;

static int SWIPE_MAX_OFF_PATH = 250;
static int SWIPE_MIN_DISTANCE = 100;
static int SWIPE_THRESHOLD_VELOCITY = 100;

private GestureDetector gestureDetector;
View.OnTouchListener gestureListener;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tView = (TextView) findViewById(R.id.textview1);
vc = ViewConfiguration.get(this);
SWIPE_MIN_DISTANCE = vc.getScaledTouchSlop();
SWIPE_THRESHOLD_VELOCITY = vc.getScaledMinimumFlingVelocity();

gestureDetector = new GestureDetector(new MyGestureDetector());
gestureListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
return true;
}
return false;
}
};
tView.setOnClickListener(this);
tView.setOnTouchListener(gestureListener);
}

class MyGestureDetector extends SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
try {
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
return false;
// right to left swipe
if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
Toast.makeText(MySample1Activity.this, "Left Swipe",
Toast.LENGTH_SHORT).show();
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
Toast.makeText(MySample1Activity.this, "Right Swipe",
Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
// nothing
}
return false;
}
}

@Override
public void onClick(View v) {
// TODO Auto-generated method stub

}

}


How to Hide showed Toast Messages in Android?

In my App, there is a list, when a user clicks on an button, a toast message is being displayed, 10 items - 10 toast messages, so if the user clicks 10 times, then presses the button... he/she has to wait for some seconds, until he's able to read the menu option text.

I have found the below solution to hide the shows toast message.

public class SampleToastActivity extends Activity {
Toast myToast;
static int i=0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button b1 = (Button) findViewById(R.id.button2);
b1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
i++;
if(myToast!=null){
      myToast.cancel();
      myToast.setText("Count"+i);
      }else{
          myToast = Toast.makeText(SampleToastActivity.this, "Sample"+i, 10);
         }
      myToast.show();
   }
    });
  }
}

Combining 2 Images in Android using Canvas ?


Below are the methods to canvert the two bitmap in to one..........


 private BitmapDrawable createUserMarker(Bitmap bmp1, Bitmap bmp2) {
Bitmap bitmapStar = bmp1;
Bitmap bmOverlay = Bitmap.createBitmap(bmp2.getWidth(), bmp2.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bmOverlay);
canvas.drawARGB(0x00, 0, 0, 0);
canvas.drawBitmap(bmp2, 0, 0, null);
canvas.drawBitmap(bitmapStar, 2, 2, null);
BitmapDrawable dr = new BitmapDrawable(bmOverlay);
dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
return (dr);
    }


OR


 public Bitmap combineImages(Bitmap c, Bitmap s) { 
// can add a 3rd parameter 'String loc' if you want to save the new
// image - left some code to do that at the bottom 
   Bitmap cs = null; 
 
   int width, height = 0; 
    
   if(c.getWidth() > s.getWidth()) { 
     width = c.getWidth(); 
     height = c.getHeight() + s.getHeight(); 
   } else { 
     width = s.getWidth(); 
     height = c.getHeight() + s.getHeight(); 
   } 
 
   cs = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
 
   Canvas comboImage = new Canvas(cs); 
 
   comboImage.drawBitmap(c, 0f, 0f, null); 
   comboImage.drawBitmap(s, 0f, c.getHeight(), null); 
 
   // this is an extra bit I added, just incase you want to save the new image somewhere and then return the location 
   /*String tmpImg = String.valueOf(System.currentTimeMillis()) + ".png"; 
 
   OutputStream os = null; 
   try { 
     os = new FileOutputStream(loc + tmpImg); 
     cs.compress(CompressFormat.PNG, 100, os); 
   } catch(IOException e) { 
     Log.e("combineImages", "problem combining images", e); 
   }*/ 
 
   return cs; 
 } 




Thursday, March 22, 2012

How to use Non-Blocking Web-Request in android?


This code fetches content from the web without blocking the UI (runs in the background in a Thread). Once finished, it posts a Handler that is picked up by the UI as soon as possible.

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import org.apache.http.util.ByteArrayBuffer;

public class Iconic extends Activity {
private String html = "";
private Handler mHandler;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mHandler = new Handler();
checkUpdate.start();
}

private Thread checkUpdate = new Thread() {
public void run() {
try {
 URL updateURL = new URL("http://iconic.4feets.com/update");
 URLConnection conn = updateURL.openConnection();
 InputStream is = conn.getInputStream();
 BufferedInputStream bis = new BufferedInputStream(is);
 ByteArrayBuffer baf = new ByteArrayBuffer(50);

 int current = 0;
 while((current = bis.read()) != -1){
 baf.append((byte)current);
 }

/* Convert the Bytes read to a String. */
html = new String(baf.toByteArray());
mHandler.post(showUpdate);
    } catch (Exception e) {
   }
  }
};

private Runnable showUpdate = new Runnable(){
public void run(){
Toast.makeText(Iconic.this, "HTML Code: " + html, Toast.LENGTH_SHORT).show();
}
};
}

Wednesday, March 21, 2012

Reference Integrity Example in Android Sqlite?


Declaring Referential Integrity (Foreign Key) Constraints
Foreign key constraints are used to check referential integrity between tables in a database. Consider for example the following two tables:

create table Residence (
name VARCHAR PRIMARY KEY,
capacity INT
);

create table Student (
id INT PRIMARY KEY,
firstName VARCHAR,
lastName VARCHAR,
residence VARCHAR
);

We can enforce the constraint that a Student's residence actually exists by making Student.residence a foreign key that refers to Residence.name. SQLite lets you specify this relationship in several different ways:

create table Residence (
name VARCHAR PRIMARY KEY,
capacity INT
);

create table Student (
id INT PRIMARY KEY,
firstName VARCHAR,
lastName VARCHAR,
residence VARCHAR,
FOREIGN KEY(residence) REFERENCES Residence(name)
);

or

create table Residence (
name VARCHAR PRIMARY KEY,
capacity INT
);

create table Student (
id INT PRIMARY KEY,
firstName VARCHAR,
lastName VARCHAR,
residence VARCHAR REFERENCES Residence(name)
);

or

create table Residence (
name VARCHAR PRIMARY KEY,
capacity INT
);

create table Student (
id INT PRIMARY KEY,
firstName VARCHAR,
lastName VARCHAR,
residence VARCHAR REFERENCES     Residence -- Implicitly references the primary key of the Residence table.
);

All three forms are valid syntax for specifying the same constraint. More details can be found in the documentation for SQLite Foreign Key Support .
Constraint Enforcement
There are a number of important things about how referential integrity and foreign keys are handled in SQLite:
  • The attribute(s) referenced by a foreign key constraint (i.e. Residence.name in the example above) must be declared unique or as a primary key within their table, but this requirement is checked at run-time, not when constraints are declared. For example, if Residence.name had not been declared as the primary key (or as unique), the FOREIGN KEY declarations above would still be permitteed, but inserting into the Student table would always yield an error.
  • Foreign key constraints are not checked by default. If you want SQLite to check any foreign key constraints specified on your tables, you must enable them with the command:
    PRAGMA foreign_keys = ON;
    once per database session (i.e. once per invocation of /usr/class/cs145/bin/sqlite). Even if you have previously enabled foreign key constraint checking while using a particular database, new sessions with that database will not check foreign key constraints unless you issue this PRAGMA command. If you do not issue this command, foreign key constraints are permitted to become violated, and it will happen in complete silence.
  • Bulk-Loading into a SQLite database while checking referential integrity is very, very slow -- we don't recommend it. It is faster to bulk-load your data with referential integrity checking turned off, then run SQL queries over your tables to verify that the constraints hold, then turn constraint-checking on.
  • Referential integrity checking can be "deferred". This means that the constraint is not checked until the current transaction ends, or if there is no active transaction, when the current statement ends. This can be useful when adding tuples to multiple tables -- so that you don't need to worry about the order of inserts, or in the case of referential integrity between two tables in both directions.
    A foreign key constraint can be made deferrable with the keywords 
    DEFERRABLE INITIALLY DEFERRED:

    create table Residence (
    name VARCHAR PRIMARY KEY,
    capacity INT
    );

    create table Student (
    id INT PRIMARY KEY,
    firstName VARCHAR,
    lastName VARCHAR,
    residence VARCHAR REFERENCES Residence DEFERRABLE INITIALLY DEFERRED
    );

    By doing so, we can write:

    BEGIN;
    insert into Student values (123, 'Ben', 'Savage', 'Gavilan');
    insert into Residence values ('Gavilan', 50);
    COMMIT;

    and no error will be raised after the insertion into Student.

  • Special action can be taken when the referenced tuple is updated or deleted. Let's say our Residence and Student tables contain the tuples inserted above:
    select * from Student;

    id      firstName      lastName     residence
    ------ --------- --------- ---------
    123        Ben             Savage       Gavilan

    select * from Residence;
    name     capacity
    -------      --------
    Gavilan      50

    By default, updating or removing the tuple in Residence is not permitted, since it would leave the tuple in Student "dangling" and the database in an inconsistent state. SQLite supports ON UPDATE and ONDELETE actions that will keep the database in a consistent state:
  • RESTRICT: This is the default behavior -- it prohibits a change to the Residence tuple, as long as there are Student tuples that depend on it.
  • CASCADE: Changes to the Residence tuple will be propagated to all Student tuples that depend on it.
  • SET NULL: A change to the Residence tuple will set the referencing value in Student.residence to null.
    ON UPDATE and ON DELETE actions can be specified along with a foreign key constraint declaration, as in these examples:
  • residence VARCHAR REFERENCES Residence ON UPDATE RESTRICT
  • residence VARCHAR REFERENCES Residence ON DELETE CASCADE
  • residence VARCHAR REFERENCES Residence ON UPDATE SET NULL ON DELETE RESTRICT
Again, more details on referential integrity in SQLite can be found in the SQLite Foreign Key Support documentation.