Wednesday 4 December 2013

Android Play video from SD Card | Populating a listview with videos from sdcard in android

Hello Friends,
            This is an android simple example which list all videos file store in 
device sd card and Play it in Video view .
Android provides a view control android.widget.VideoView that encapsulates
creating and initializing the MediaPlayer.










1. VideoStoredInSDCard.java

package com.example.videoplayer;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class VideoStoredInSDCard extends Activity {
 private Cursor videocursor;
 private int video_column_index;
 ListView videolist;
 int count;
 String[] thumbColumns = { MediaStore.Video.Thumbnails.DATA,
   MediaStore.Video.Thumbnails.VIDEO_ID };

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  init_phone_video_grid();
 }

 @SuppressWarnings("deprecation")
 private void init_phone_video_grid() {
  System.gc();
  String[] proj = { MediaStore.Video.Media._ID,
    MediaStore.Video.Media.DATA,
    MediaStore.Video.Media.DISPLAY_NAME,
    MediaStore.Video.Media.SIZE };
  videocursor = managedQuery(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
    proj, null, null, null);
  count = videocursor.getCount();
  videolist = (ListView) findViewById(R.id.PhoneVideoList);
  videolist.setAdapter(new VideoAdapter(getApplicationContext()));
  videolist.setOnItemClickListener(videogridlistener);
 }

 private OnItemClickListener videogridlistener = new OnItemClickListener() {
  public void onItemClick(AdapterView parent, View v, int position,
    long id) {
   System.gc();
   video_column_index = videocursor
     .getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
   videocursor.moveToPosition(position);
   String filename = videocursor.getString(video_column_index);
   Intent intent = new Intent(VideoStoredInSDCard.this,
     ViewVideo.class);
   intent.putExtra("videofilename", filename);
   startActivity(intent);
  }
 };

 public class VideoAdapter extends BaseAdapter {
  private Context vContext;

  public VideoAdapter(Context c) {
   vContext = c;
  }

  public int getCount() {
   return count;
  }

  public Object getItem(int position) {
   return position;
  }

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

  public View getView(int position, View convertView, ViewGroup parent) {
   System.gc();
   ViewHolder holder;
   String id = null;
   convertView = null;
   if (convertView == null) {
    convertView = LayoutInflater.from(vContext).inflate(
      R.layout.listitem, parent, false);
    holder = new ViewHolder();
    holder.txtTitle = (TextView) convertView
      .findViewById(R.id.txtTitle);
    holder.txtSize = (TextView) convertView
      .findViewById(R.id.txtSize);
    holder.thumbImage = (ImageView) convertView
      .findViewById(R.id.imgIcon);

    video_column_index = videocursor
      .getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME);
    videocursor.moveToPosition(position);
    id = videocursor.getString(video_column_index);
    video_column_index = videocursor
      .getColumnIndexOrThrow(MediaStore.Video.Media.SIZE);
    videocursor.moveToPosition(position);
    // id += " Size(KB):" +
    // videocursor.getString(video_column_index);
    holder.txtTitle.setText(id);
    holder.txtSize.setText(" Size(KB):"
      + videocursor.getString(video_column_index));

    String[] proj = { MediaStore.Video.Media._ID,
      MediaStore.Video.Media.DISPLAY_NAME,
      MediaStore.Video.Media.DATA };
    @SuppressWarnings("deprecation")
    Cursor cursor = managedQuery(
      MediaStore.Video.Media.EXTERNAL_CONTENT_URI, proj,
      MediaStore.Video.Media.DISPLAY_NAME + "=?",
      new String[] { id }, null);
    cursor.moveToFirst();
    long ids = cursor.getLong(cursor
      .getColumnIndex(MediaStore.Video.Media._ID));

    ContentResolver crThumb = getContentResolver();
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 1;
    Bitmap curThumb = MediaStore.Video.Thumbnails.getThumbnail(
      crThumb, ids, MediaStore.Video.Thumbnails.MICRO_KIND,
      options);
    holder.thumbImage.setImageBitmap(curThumb);
    curThumb = null;

   } /*
    * else holder = (ViewHolder) convertView.getTag();
    */
   return convertView;
  }
 }

 static class ViewHolder {

  TextView txtTitle;
  TextView txtSize;
  ImageView thumbImage;
 }
}


2. ViewVideo.java

package com.example.videoplayer;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.MediaController;
import android.widget.VideoView;

public class ViewVideo extends Activity {
      private String filename;
      VideoView vv;
      @Override
      public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            System.gc();
            Intent i = getIntent();
            Bundle extras = i.getExtras();
            filename = extras.getString("videofilename");
            // vv = new VideoView(getApplicationContext());
            setContentView(R.layout.activity_view);
            vv = (VideoView) findViewById(R.id.videoView);
            vv.setVideoPath(filename);
            vv.setMediaController(new MediaController(this));
            vv.requestFocus();
            vv.start();
      }
}


3. AndroidManifest.xml


<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.videoplayer"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.videoplayer.VideoStoredInSDCard"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

              <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
        </activity>
        <activity android:name=".ViewVideo" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>






Enjoy Coding :)

Download Source code Code

Monday 18 November 2013

Android Lazy Image loader Class Error | Image Loader not loading the image

Hello Friends,


One of my friend using Image Loader class to load an image from an url and displaying it
in a list view. She told me that the Image Loader is loading the image on an emulator, when
she run the app on a real device it's not loading any image.(Just showing the default image).

This problem occurs only when we didn't pass the permission in AndroidManifest.xml file.
When I saw her code I found following permission is missing..

 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


After adding this , the problem is resolved and the the app is working fine on
both emulator as well as on real device.

This issued is faced by most of the android developer , So always remember add
all permission while using lazy Image loader class.

Enjoy.... :)
Happy Coding....

Thursday 14 November 2013

Invalid android_key parameter - Facebook login | Android Facebook hash key error

Hello Droid Friends,
Today , I stuck in Facebook login Issue. I am doing facebook login in my android
application but I am getting following error:


Invalid android_key parameter. The key 26gUhN_wYCwwxenlSneyTeCY
does not match any allowed key. Configure your app key hashes at 
http://developers.facebook.com/apps/22061641443615

I followed following steps:
1. downloaded openssl from here and set it in your system environment path.
     
2. Uses following command to generate hashkey on my pc.
      keytool -exportcert -alias androiddebugkey -keystore "C:\Users\Acer\.android\debug.keystore"
                                 | openssl sha1 -binary | openssl base64
 

3. Then I created a new Facebook app  and also added the generated hashkey.

4. I got the Facebook App Id Which I am now using in my and application.


After following all above steps , still I am facing the error "Invalid android_key
parameter" . Then I go to the facebook developer site and find few new things which
comes in Facebook SDK 3.5. And Its helps me in fixing the above "Invalid android_key
parameter" Issue. There Are Two way:

Step-1. When you get this error, check the logcat it returns you a different hashkey,
so you just need to replace the previous hashkey with this one. If you did not getting
any hashkey in logcat error then step-2 helps you.

Step-2: I think this is the best way of generating hashkey bcoz it removes the dependency
of debugkeystore.No need to copy and paste the same debugkeystore on each developer
machine.Here we generate hashkey on the basis of android application package name.
Just used following code for generating the hashkey.

try  {

      PackageInfo info = getPackageManager().
           getPackageInfo(this.getPackageName(), PackageManager.GET_SIGNATURES);

      for (Signature signature : info.signatures) {

          MessageDigest md = MessageDigest.getInstance("SHA");
          md.update(signature.toByteArray());
          Log.d("====Hash Key===",Base64.encodeToString(md.digest(), 
                   Base64.DEFA  ULT));

      }

  } catch (NameNotFoundException e) {

      e.printStackTrace();

  } catch (NoSuchAlgorithmException ex) {

      ex.printStackTrace();

  }




And use this generated hashkey.This will fixed your "Invalid android_key parameter" issue.

Enjoy :)
Happy Coding... :)


Sunday 10 November 2013

Android Home key press behavior | Activity stack confused when launching app

Hello Droid Guys
I found an strange issue with the behavior of Home key press in android.Please
check below link if you want more details about this issue.


Actually, I think this is an android bug. If an app is installed via market, market 
update, or download from browser and the user launches the app directly from the
installer (ie: when the installer completes it offers the user the options to launch(open)
and done and when use select open the app now) it is launched in such a way that 
the OS gets confused.

If, after the app is launched, the user presses the HOME key to return to the home 
screen and then tries to return to the app by selecting it from the list of applications 
(or by putting a shortcut on the home screen and then selecting the shortcut), the OS
launches the root activity of the app AGAIN, bringing the existing task to the foreground
and placing ANOTHER instance of the root activity on top of the existing activity stack.

This behavior is extremely difficult to debug and has certainly caused countless hours 
of head-scratching by developers.

Note: I too found the same issue when I install an app from my mail and directly launch
the app.Go to Activity "A" then goes to Activity "B" and then I pressed "Home button".
Then ,When I open the same app pressing the app launcher on home screen,Instead of 
taking me directly to Activity "B" where I left it last time , It loads the app from the start.



It takes lots of my time to fixed this issue but finally I did that. I found the
way to resolve this problme :) .
I Added following code in the onCreate() method of my launcher activity and then Its
works fine for me.


protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);

if (!isTaskRoot()) {
           Intent intent = getIntent();
           String action = intent.getAction();
           if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && action != null &&                           action.equals(Intent.ACTION_MAIN)) {
               finish();
               return;
           }
    }
}

Hope, my above code will save some one time.
Enjoy Coding :)

Saturday 9 November 2013

Android ListView Background Color Changes on Scrolling

Hello Friends,
This is very common issue I saw in android with Listview. In one of my app I am using a
listview for displaying the list of Items.I set the background of Listview as blue. Below is 
the Listview code which I am using.

 <ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:background="#0000FF"/>


But, some times when I scroll the Listview the background color will be automatically change
to black or white. Then, I found a solution I added below line in my Listview(in xml file).

android:cacheColorHint="#00000000"
        OR
android:cacheColorHint="@android:color/transparent"


And Finally my Listview code contains following code.....

<ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:cacheColorHint="#00000000"
        android:choiceMode="singleChoice"
        android:background="#2A323D"/>

OR at java code,use below line of code

listview.setCacheColorHint(Color.TRANSPARENT);


After adding the above one line in my xml or java file , the Listview background color 
change on scrolling issue will be gone.

Hope , the above code helps some one.
Enjoy coding......




Sunday 21 July 2013

android listview adapter getview() called multiple times

Hello Droid Guys,
Today , I found a strange issue in android custom listView adapter. I found that
the adapter getview() method called multiple times.

adapter getview() called multiple times

On my listview I am showing following Item:
1. User facebook image
2. His|Her Name
3. Some description

As, I told you that getview() method calls multiple time, due to this behavior the Image on
list item some times remain unchanged or same profile picture will be attach on different
user , in listview.
First of all I think that this was an issue of lazy image loader library But I was wronged.
After spent few times on google for searching this issue , I found this link

http://stackoverflow.com/questions/2618272/custom-listview-adapter-getview-method-being-called-multiple-times-and-in-no-co

Then After I checked my xml file and I found I am using height = wrap_content in listview.

<ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="3dp"
        android:layout_marginRight="3dp"
        android:padding="5dp"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp"
         android:layout_below="@+id/facebook_friend_list_header" >
    </ListView>

And when I changed this to fill_parent

        android:layout_height="fill_parent"

then all problem is resolved and now the getview() method will be called only once.
Also the user profile picture issue will be resolved.

Android Guys , still I was not cleared about the above tricks. Please let me know why
getview() method called multiple times when I am using
android:layout_height="wrap_content" . If some one know the reason then
please let me know.

Thanks in advance.
Enjoy Coding :)

Friday 12 July 2013

ActionBarSherlock with custom View | Changing sherlock action bar menu item background

Hello Friends,
Today , I am going to share my another android tutorial which is based on the
Sherlock Action Bar. ABS(Action Bar Sherlock) is an support library which helps
to use action bar design pattern over all android devices.

Initially , Action bar is supportable over android version 3.0. But if you want to
provide the interactive user interface on lower version of device too, then
ABS comes in a role.

 
sherlock action barandroid action bar
       

1. MainActivity.java

package com.example.actionbar;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.Toast;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.SubMenu;

public class MainActivity extends SherlockActivity {

 private SubMenu mGoItem;

 private static final int GO_ITEM_ID = 1;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  ActionBar ab = getSupportActionBar();
  ab.setBackgroundDrawable(getApplicationContext().getResources()
    .getDrawable(R.drawable.bg_titlebar_tile));
  ab.setLogo(getResources().getDrawable(R.drawable.logo));
  ab.setDisplayShowTitleEnabled(false);
 }

 @SuppressLint("InlinedApi")
 @Override
 public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) {

  mGoItem = menu.addSubMenu(0, GO_ITEM_ID, 0, null);
  mGoItem.setIcon(R.drawable.setting_icon);
  // SubMenu sub = menu.addSubMenu("Theme");
  mGoItem.add(0, R.style.Theme_Sherlock, 0, "View Profile");
  mGoItem.add(0, R.style.Theme_Sherlock_Light, 0, "Account Privacy");
  mGoItem.add(0, R.style.Theme_Sherlock_Light_DarkActionBar, 0,
    "Logout");
  mGoItem.getItem().setShowAsAction(
    MenuItem.SHOW_AS_ACTION_ALWAYS
      | MenuItem.SHOW_AS_ACTION_WITH_TEXT);

  return true;
 }

 @SuppressLint("InlinedApi")
 @Override
 public boolean onOptionsItemSelected(
   com.actionbarsherlock.view.MenuItem item) {

  switch (item.getItemId()) {
  case GO_ITEM_ID:
   Toast.makeText(MainActivity.this,
     "You have Pressed 'Setting' Menu Button", Toast.LENGTH_LONG)
     .show();
   return true;
  }

  return false;
 }

}

2.activity_main.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"
    android:background="@android:color/white"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textColor="@android:color/black"
        android:textStyle="bold"
        android:text="@string/hello_action_bar" />

</RelativeLayout>


Download the complete source code: Here

 

Copyright @ 2013 Android Developers Blog.