[Android] Use a Dialog box using DialogFragment

Say you want to create a dialog box that lets you remove an item from a list, or some other similar activity.

1.  Create a DialogFragment class

public class DeleteItemDialogFragment extends DialogFragment {

    @Override

    public Dialog onCreateDialog(Bundle savedInstanceState) {

        // Use the Builder class for convenient dialog construction

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setMessage(R.string.remove_rent) .setPositiveButton(R.string.remove, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) {

                   // Send the positive button event back to the host activity

                   mListener.onDialogPositiveClick(DeleteItemDialogFragment.this); } }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) {

                   // Send the negative button event back to the host activity

                   mListener.onDialogNegativeClick(DeleteItemDialogFragment.this); } });

        // Create the AlertDialog object and return it

        return builder.create(); }

    /* The activity that creates an instance of this dialog fragment must

 

     * implement this interface in order to receive event callbacks.

 

     * Each method passes the DialogFragment in case the host needs to query it. */

public interface DeleteItemDialogListener { public void onDialogPositiveClick(DialogFragment dialog); public void onDialogNegativeClick(DialogFragment dialog); } DeleteItemDialogListener mListener;

    // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener

 

    @Override

    public void onAttach(Activity activity) { super.onAttach(activity);

        // Verify that the host activity implements the callback interface

        try {

            // Instantiate the DeleteItemDialogListener so we can send events to the host

            mListener = (DeleteItemDialogListener) activity; } catch (ClassCastException e) {

            // The activity doesn’t implement the interface, throw exception

            throw new ClassCastException(activity.toString()

                    + ” must implement DeleteItemDialogListener”);

        } } }

2.   Set up your listener in your activity:

public class ManageRentActivity extends FragmentActivity implements DeleteItemDialogFragment.DeleteItemDialogListener {
}

3.   Use the implemented methods to set up the ‘Confirm’ and ‘Cancel’ methods:

@Override
public void onDialogPositiveClick(DialogFragment dialog) {  
         //removeRentEntry();  }
@Override 
public void onDialogNegativeClick(DialogFragment dialog) { 
         // Cancel and Return to Activity }

3. Call your DialogFragment from your Activity:

DialogFragment removeDialogFragment = new DeleteItemDialogFragment();
removeDialogFragment.show(getSupportFragmentManager(),  "DeleteItemDialogFragment");

Android Interview questions

1.  During Android unit testing, what is the difficulty in using ‘static’ variables?

Static variables are cleared and set to ‘null’ each time a set of data is called.  This is because your app is reset/killed each time

Solution:  Call super.tearDown() before each test.

2.   What is dependency injection in Android?

Dependency injection is a style of object configuration in which an objects fields and collaborators are set by an external entity.

In Android, Dagger & Guice are examples of dependency injectors:

RoboGuice 2 example:

@ContentView(R.layout.main)
    class RoboWay extends RoboActivity { 
        @InjectView(R.id.name)             TextView name; 
        @InjectView(R.id.thumbnail)        ImageView thumbnail; 
        @InjectResource(R.drawable.icon)   Drawable icon; 
        @InjectResource(R.string.app_name) String myName; 
        @Inject                            LocationManager loc; 

        public void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            name.setText( "Hello, " + myName ); 
        } 
    }

3.  Do Android Applications leak memory?

a.   Sometimes an Activity is pointed to by UI controls.  UI controls can be pointed to by static variables.  This can lead to memory leaks.

4.  How is Serializable different from Parcel?

Parcels are designed for high performance IPC transport, used heavily in Binders.  For normal serialization concepts, use Serializable.  Serializable is much heavier and takes more time.  Therefore Parcels are used in embedded devices.

5.   What is a Handler, Thread & Loader?

Handler:  A class that can synchronize a worker thread to the main thread.  In the example of ASyncTask, the onProgressUpdate() and the doPostExecute() method are already synchronized.  They are examples of handlers.  You can create your custom handler methods for your custom thread classes.

Thread:  A line of execution.

Loader:

  • It provides asynchronous loading of data.
  • They are available to every Activity and Fragment.
  •  They monitor the data source and deliver new results when contents change.
  • They automatically reload to their last loader cursor when being recreated after a configuration change.  They don’t need to re-query data

6.  What is a looper, message queue and handler?

Looper – part of any Thread to loop through message queue.  This will be used to check if any incoming message has arrived to this thread. Only one looper exists for a given thread. Only for handler threads this looper will be activated, for other normal threads this will be in passive or inactive mode.

Message Queue - part of any thread, will store incoming messages to this thread. For any thread only one message Q is available. Handler – communication channel between two threads.

Handler is associated with Looper. for a given looper we can n number of handlers to communicate with it from out side world.

Android SQLite database – A tutorial

1.   Create the DatabaseHelper class. This class is responsible for creating the database. The onUpgrade() method will simply delete all existing data and re-create the table. It also defines several constants for the table name and the table columns.

public class DatabaseHelper extends SQLiteOpenHelper {

	  private static final String DATABASE_NAME = "property.db";
	  private static final int DATABASE_VERSION = 1;
	  
	  public static final String TABLE_PROPERTY = "property";
	  public static final String COLUMN_ID = "_id";
	  public static final String COLUMN_NICKNAME = "nickname";
	  public static final String COLUMN_TENANT = "tenant";
	  public static final String COLUMN_ADDRESS = "address";
	  public static final String COLUMN_LOAN = "loan";

	  // Database creation sql statement
	  private static final String DATABASE_CREATE = "create table "
	      + TABLE_PROPERTY + "(" + COLUMN_ID
	      + " integer primary key autoincrement, " 
	      + COLUMN_NICKNAME + " text not null"
	      + COLUMN_TENANT + " text"
	      + COLUMN_ADDRESS + " address not null"
	      + COLUMN_LOAN + " integer);";

	  public DatabaseHelper(Context context) {
	    super(context, DATABASE_NAME, null, DATABASE_VERSION);
	  }

	  @Override
	  public void onCreate(SQLiteDatabase database) {
	    database.execSQL(DATABASE_CREATE);
	  }

	  @Override
	  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
	    Log.w(DatabaseHelper.class.getName(),
	        "Upgrading database from version " + oldVersion + " to "
	            + newVersion + ", which will destroy all old data");
	    db.execSQL("DROP TABLE IF EXISTS " + TABLE_PROPERTY);
	    onCreate(db);
	  }

	} 

Displaying Git commit version in Rails

At times, you’re doing rapid development and you’d like to frequently update the GIT commit version that is in use

1.  Create a ‘config/initializers/git_revision.rb’ file and update the following:

module MyProject
     REVISION=`git log --pretty=format:'%h' -n 1`
end

2.  In your _footer.html.erb or equivalent view file, call the following:

Version: <%= MyProject::REVISION %>

This should display the version as follows:

Version: 774318e

Route ‘Sign In’ to the previous page

Ever noticed after doing an elaborate search, your website asks you to do a ‘Sign in’.  After logging in, it forgets all about your search results and takes you back to your home page.

When using Rails with Devise, you may have noticed that ‘signing in’ takes you to the home page of the controller.

In order to go to the last page that redirects you to the ‘devise sign in ‘ page, make the following changes to your Devise ‘Sessions Controller’

#Take me to the referring page after sign in
def after_sign_in_path_for(resource)
    redirect_to request.referrer
end

This should redirect to the ‘referring’ or the ‘calling’ page.

Polk Audio RTi A7 Review – Speaker Obession

RTi A7 Image

My research for speakers a level above kept revolving around these RTi A7s.   When I looked at them in the shop they were a perfect color and contour match.  I got a sense of accomplishment when I realized that my speaker search had come to an end.  I love stereo listening and these speakers are built around that.  I was originally thoroughly impressed with the A9s’ but realized that they were really tall for my place and also required a lot of power.  The A7s were more of a match and now I realize that its more than that.

Sound reproduction is incredible.  Even the slightest of sounds are made crystal clear from the speakers.   I did not like the addition of  a subwoofer for stereo listening as it interfered with the clarity.   I use a Denon AVR 3310CI to drive these speakers and they have produced excellent results.  I use it for a lot of low volume listening that I’ve found to appreciate.  And when it comes to high volume, they can go as high as you can take.   Adding an amp would definitely benefit, but there’s nothing wrong without one.

HD Audio, Blu ray discs and audio CDs bring out the best in this speaker.  They discriminate a bit if you’re using compressed audio however high the bit rate may be.  The Restorer function in the AVR 3310 seemed to help a little bit with that.   Addition of a sub woofer definitely takes it to a different level, but I had to increase the volume/channel level to match it with the speakers performance.  The A7s go as low as 30Hz but I set the crossover to 100Hz for excellent bass delivery.  Needless to say, without  a subwoofer the bass is very tight and just enough.   Lovely when you’re reading a book and listening to concert hall music.

I still have to bi-amp them with the AVR to see if the results are any different although I’ve read at places that they dont make a big difference.  The binding posts are excellent and the speaker construction is truly extraordinary.  A simple tap and placing a ear on the walls of the speaker reveals excellent resonance built into the cabinet.  Oh yes, the cabinet,  that is a thing of beauty that matched with my wooden flooring.  It is well constructed and no cheap materials in this speaker unit.   Removing the front panel cover reveals a view of professionalism.  Silk dome tweeters,  polymer mid range and 2 woofers give this speaker quite a look when contrasted with a darker shade of silver.   Venting ports are supplied in the front and back.   With a power range of upto 300W you cannot go wrong for home usage.   Watching movies was a true delight when I had all the lights off.  The sound orientation was brilliant when I couldnt exactly realize where it was coming from.

These speakers are no way in my budget but I realized that the value for money is truly a ratio worth passing of without consideration.  And I was glad when I was right this time.   I really appreciate the engineers at Polk who have come out with such a precise speaker.   You guys made it a part of my second life.

Integrating PaperClip Gem to a Rails Model

Include the gem in ‘Gemfile’

gem "paperclip", "~> 3.0"

1.  Add a rails migration to the model

      rails g migration addAvatarColumnToMenu
      invoke  active_record
      create db/migrate/20131113072946_add_avatar_column_to_menu.rb

2.  Edit your migration

 class AddAvatarColumnToMenu < ActiveRecord::Migration
   def self.up
     change_table :menus do |t|
        t.attachment :avatar
     end
   end
   def self.down
      drop_attached_file :menus, :avatar
   end
 end

3.  Add the following to your model

class Menu < ActiveRecord::Base
  has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
end

4.  Run the migration

 rake db:migrate
==  AddAvatarColumnToMenu: migrating ============================
-- change_table(:menus)
-> 0.5326s
==  AddAvatarColumnToMenu: migrated (0.5328s) ===================

5.  You should see the 4 columns added if you run “rails console”

avatar_file_name: string, avatar_content_type: string, avatar_file_size: integer, avatar_updated_at: datetime

6.  Add this to your “new” and “update” views

<%= form_for @menu, :url => menus_path, :html => { :multipart => true } do |form| %>
  <%= form.file_field :avatar %>
<% end %>

7.  Add this to the ‘show’ view

<%= image_tag @menu.avatar.url %>
<%= image_tag @menu.avatar.url(:medium) %>
<%= image_tag @menu.avatar.url(:thumb) %>

8.  Restart the server to get the new table data set.