Search This Blog

Friday, 26 April 2013

Implementing Search functionality inside Android ListView.

Listing in android contains many features that make ListView a powerful tool. Android developer are very much aware from recycling of View inside BaseAdapter. This tutorial address the issue(or say requirement) of searching inside a ListView.
Concept roam around performing search operation on Array and redraw the ListView.
Let Do this step wise



Step 1) Create one simple User interface to handle requirement search

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >


    <RelativeLayout
        android:id="@+id/top"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_margin="5dp"
        android:background="@drawable/search_input1" >

        <Button
            android:id="@+id/btnSearch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="2dp"
            android:background="@drawable/cancel_search" />

        <Button
            android:id="@+id/btnLeft"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:layout_marginLeft="2dp"
            android:background="@drawable/icon_search" />

        <EditText
            android:id="@+id/edSearch"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_centerVertical="true"
            android:layout_toLeftOf="@id/btnSearch"
            android:layout_toRightOf="@id/btnLeft"
            android:background="@null"
            android:hint="Search"
            android:imeOptions="actionSearch"
            android:singleLine="true" />
    </RelativeLayout>

    <ListView
        android:id="@+id/mListView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/top"
        android:layout_marginBottom="5dp"
        android:layout_marginTop="5dp"
        android:cacheColorHint="@android:color/transparent"
        android:divider="@android:color/white"
        android:dividerHeight="2dp" >
    </ListView>

</RelativeLayout>

Step 2) Create One BaseAdapter to bind Data inside a ListView

package com.testsearching;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MySimpleSearchAdapter extends BaseAdapter {

    private ArrayList<String> mData = new ArrayList<String>();
    private LayoutInflater mInflater;

    public MySimpleSearchAdapter(Activity activity) {
        mInflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public void addItem(String item) {
        mData.add(item);
        notifyDataSetChanged();
    }

    public int getCount() {
        return mData.size();
    }

    public String getItem(int position) {
        return mData.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.item_one, null);
            holder.textView = (TextView) convertView.findViewById(R.id.text);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        String str = mData.get(position);
        holder.textView.setText(str);
        return convertView;
    }

    public class ViewHolder {
        public TextView textView;
    }

}


Step 3) Now write the Search Logic inside your activity

package com.testsearching;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;

public class SearchFunctionality extends Activity implements OnClickListener,
        OnEditorActionListener, OnItemClickListener {
    ListView mListView;
    MySimpleSearchAdapter mAdapter;
    Button btnSearch, btnLeft;
    EditText mtxt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        mListView = (ListView) findViewById(R.id.mListView);
        mAdapter = new MySimpleSearchAdapter(this);
        btnSearch = (Button) findViewById(R.id.btnSearch);
        btnLeft = (Button) findViewById(R.id.btnLeft);
        mtxt = (EditText) findViewById(R.id.edSearch);
        mtxt.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before,
                    int count) {

            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                if (0 != mtxt.getText().length()) {
                    String spnId = mtxt.getText().toString();
                    setSearchResult(spnId);
                } else {
                    setData();
                }
            }
        });
        btnLeft.setOnClickListener(this);
        btnSearch.setOnClickListener(this);
        setData();
    }

    ArrayList<String> mAllData;

    String[] str = { "Hit me Hard", "GIJ, Rise Of Cobra", "Troy",
            "A walk To remember", "DDLJ", "Tom Peter Nmae", "David Miller",
            "Kings Eleven Punjab", "Kolkata Knight Rider", "Rest of Piece" };

    public void setData() {
        mAllData = new ArrayList<String>();
        mAdapter = new MySimpleSearchAdapter(this);
        for (int i = 0; i < str.length; i++) {
            mAdapter.addItem(str[i]);
            mAllData.add(str[i]);
        }
        mListView.setOnItemClickListener(this);
        mListView.setAdapter(mAdapter);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btnSearch:
            mtxt.setText("");
            setData();
            break;
        case R.id.btnLeft:

            break;
        }
    }

    public void setSearchResult(String str) {
        mAdapter = new MySimpleSearchAdapter(this);
        for (String temp : mAllData) {
            if (temp.toLowerCase().contains(str.toLowerCase())) {
                mAdapter.addItem(temp);
            }
        }
        mListView.setAdapter(mAdapter);
    }

    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        return false;
    }

    @Override
    public void onBackPressed() {
        setResult(Activity.RESULT_CANCELED);
        finish();
    }

    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position,
            long arg3) {
        String str = mAdapter.getItem(position);
        Toast.makeText(this, str, Toast.LENGTH_LONG).show();
    }
}

See Above code output in form of ScreenShot






Download Source Of Application

Wednesday, 24 April 2013

Android Reverse Geo Coding : Getting Human Readable address from latitude and longitude in android

We can show any address on map using latitude and longitude. But showing number rather than any useful information make no sense for any user. Reverse Geo Coding is process to convert latitude and longitude into one readable address in the form of String

     public String getAddress(Activity acLocal) {
 String address="";
       Geocoder geocoder;
        List<Address> addresses = null;
        geocoder = new Geocoder(_acLocal, Locale.getDefault());
        try {
            addresses = geocoder.getFromLocation(lat, longi, 1);

            String address = addresses.get(0).getAddressLine(0);
            String city = addresses.get(0).getAddressLine(1);
            String country = addresses.get(0).getCountryName();
            address = Html.fromHtml(
                    address + "<br>" + city + "<br>" + country).toString();
        } catch (Exception e) {
            e.printStackTrace();
            address = Html.fromHtml("<br>&nbsp;Unable to get any address.")
                    .toString();
        }
       return address;
} 

It will give you available address for respective latitude and longitude. Throws an exception if not able to convert into address

Saturday, 20 April 2013

Removing status bar notification from android application

Status bar notification used to show some important alert from in or outside the application in android. See Creating Simple notification is simple. This tutorial address the issue of removing notification from status bar while you are inside the application. Its easy to remove when you get involve with notification (like touch) but we will learn today how can we remove them without touch or involving with them Main concept run around notification id. You can remove any notification from anywhere if you notification id. So we need one data base to store id of notification while we generate this and later on remove notification


Steps 

Step 1) Required a simple user Interface with one button to generate notification and one to remove it. Create remove.xml 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".NotificationRemove" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="14dp"
        android:text="Send Notification" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button1"
        android:layout_below="@+id/button1"
        android:layout_marginTop="79dp"
        android:text="Clear Notification" />

</RelativeLayout>

Notification
                                           
Step 2) Create a simple data base class DataBase.java to store the notification id

package com.notificationremoval;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DataBase extends SQLiteOpenHelper {

    public static final String tName = "tName";
    public static final String mNotiID = "mNotiID";

    public DataBase(Context context) {
        super(context, "temp.db", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String mNotifi = "create table noti(noti_id integer not null);";
        db.execSQL(mNotifi);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

}


Step 3) Now create one Activity that Handle removal of notification


package com.notificationremoval;

import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;

public class NotificationRemove extends Activity implements OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.remove);
        findViewById(R.id.button1).setOnClickListener(this);
        findViewById(R.id.button2).setOnClickListener(this);
    }

    private void createAndGenerateNotifcation() {
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                this).setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle("Notification TItile").setContentText("Body");
        mBuilder.setAutoCancel(true);
        Intent resultIntent = new Intent();
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        stackBuilder.addNextIntent(resultIntent);
        int noti_id = (int) System.currentTimeMillis();
        insertNotifi(noti_id);
        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
                PendingIntent.FLAG_UPDATE_CURRENT);
        mBuilder.setContentIntent(resultPendingIntent);
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(noti_id, mBuilder.build());
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.button1:
            createAndGenerateNotifcation();
            break;
        case R.id.button2:
            RemoveAllNotification();
            break;
        }
    }

    public void RemoveAllNotification() {
        DataBase mBase = new DataBase(this);
        Cursor cur = mBase.getWritableDatabase().query("noti", null, null,
                null, null, null, null, null);
        cur.moveToFirst();
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        do {
            int id = cur.getInt(0);
            mNotificationManager.cancel(id);
        } while (cur.moveToNext());
        try {
            cur.close();
        } catch (Exception e) {
        }
    }

    public void insertNotifi(int id) {
        DataBase mBase = new DataBase(this);
        ContentValues cVales = new ContentValues();
        cVales.put("noti_id", id);
        SQLiteDatabase db = mBase.getWritableDatabase();
        long i = db.insert("noti", null, cVales);
        Log.i("Insert", String.valueOf(i));
        try {
            db.close();
        } catch (Exception e) {
        }
    }

}


Enjoy and keep commenting

Wednesday, 17 April 2013

Simple notification example in android with custom sound file

Creating a simple  notification in  android   consists of few steps. NotificationCompat.Builder allow you set notification title, body and icon. then you can go forward to make it custom. See the below function. Call this where ever you want to use notification and set your custom values 

    private void createAndGenerateNotifcation() {
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                this).setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle("Notification TItile").setContentText("Body");
        mBuilder.setAutoCancel(true);
        try {
            Uri uri = Uri.parse("android.resource://" + getPackageName() + "/"
                    + R.raw.yourfile);
            mBuilder.setSound(uri);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // Intent resultIntent = new Intent(this, Notification.class);
        Intent resultIntent = new Intent();
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        stackBuilder.addParentStack(Notification.class);
        stackBuilder.addNextIntent(resultIntent);
        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
                PendingIntent.FLAG_UPDATE_CURRENT);
        mBuilder.setContentIntent(resultPendingIntent);
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify((int) System.currentTimeMillis(),
                mBuilder.build());
    }

Structure of Notification in Android

  1. Content title
  2. Large icon
  3. Content text
  4. Content info
  5. Small icon
  6. Time   that the notification was issued. You can set an explicit value with setWhen(); if you don't it defaults to the time that the system received the notification.

Lets have a look on description 

Setting Notification custom sound - Keep your file inside raw folder of res and give URI to notification like this

        try {
            Uri uri = Uri.parse("android.resource://" + getPackageName() + "/"
                    + R.raw.yourfile);
            mBuilder.setSound(uri);
        } catch (Exception e) {
            e.printStackTrace();
        }

You can set auto cancel to remove when user tap on this       

    mBuilder.setAutoCancel(true); 

Starting your own activity while tap on notification - set your activity
name inside intent

Intent resultIntent = new Intent(this, Youractivty.class); 

Reference URL

Saturday, 6 April 2013

Update Pinch to zoom example and tutorial for android ImageView with zoom limit

I wrote on the same topic Pinch to zoom in android ImageView while i just started blogging. And that still is my one of the popular article, despite that it has many complication and limitation with it. So i am working to improve it. After reading most comment, I feel some problems while implementing pinch to zoom with android ImageView using previous post
  • How to implement that pinch to zoom in their project? 
  • Determining Zoom limit in pinch to zoom ImageView! 
  • Does not work properly as i told in post !! 

So now i come up with a solution in which every drawback avoided and pinch to zoom image in android seems quite simple and work perfect
Follows thes easy steps

1) Create a new project and Download this library , add this Jar to libs folder of your project 

2) Create one layout with one ImageView (Which need to be zoom)

3) Create one Activity and change to following code. This will handle all attributes required for pinch to zoom ImageView


import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

import com.imagezoom.ImageAttacher;
import com.imagezoom.ImageAttacher.OnMatrixChangedListener;
import com.imagezoom.ImageAttacher.OnPhotoTapListener;

public class SampleZoom extends Activity {
    ImageView mImaView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pinch_sample);
        mImaView = (ImageView) findViewById(R.id.simple);

        Bitmap bimtBitmap = BitmapFactory.decodeResource(getResources(),
                R.drawable.a);
        mImaView.setImageBitmap(bimtBitmap);

        /**
         * Use Simple ImageView
         */
        usingSimpleImage(mImaView);

    }

    public void usingSimpleImage(ImageView imageView) {
        ImageAttacher mAttacher = new ImageAttacher(imageView);
        ImageAttacher.MAX_ZOOM = 2.0f; // Double the current Size
        ImageAttacher.MIN_ZOOM = 0.5f; // Half the current Size
        MatrixChangeListener mMaListener = new MatrixChangeListener();
        mAttacher.setOnMatrixChangeListener(mMaListener);
        PhotoTapListener mPhotoTap = new PhotoTapListener();
        mAttacher.setOnPhotoTapListener(mPhotoTap);
    }

    private class PhotoTapListener implements OnPhotoTapListener {

        @Override
        public void onPhotoTap(View view, float x, float y) {
        }
    }

    private class MatrixChangeListener implements OnMatrixChangedListener {

        @Override
        public void onMatrixChanged(RectF rect) {

        }
    }
}

Implementing Zoom Limit. 


See inside function usingSimpleImage(), below two line decide zoom limit ImageAttacher.MAX_ZOOM = 2.0f;  // Double the current Size ImageAttacher.MIN_ZOOM = 0.5f; // Half the current Size

Note : Work perfect for the image with fit width (either in Landscape or portrait)
Android News and source code