Monday, 2 September 2013

Showing current location in Google Maps using API V2 with SupportMapFragment

In this article, we will create an Android application which will display current location in Google Maps using Google Maps Android API V2.


Since the Google Map is displayed using SupportMapFragment, this application can run in Android API Level 8 or above.
In order to use MapFragment for Google Maps, we need Android device with API level 12 or above.

This application is developed in Eclipse 4.2.1 with ADT plugin ( 21.0.0 ) and Android SDK ( 21.0.0 ). This application is tested in a real Android Phone with Android ( 2.3.6 ).
An alternative method for this application is available at Showing current location using OnMyLocationChangeListener in Google Map Android API V2

1. Download and configure Google Play Services Library in Eclipse

Google Map for Android is now integrated with Google Play Services. So we need to set up Google Play Service Library for developing Google Map application in Android.
Please follow the given below link to setup Google Play Service library in Eclipse.

2. Create a new Android Application Project namely “LocationInGoogleMapV2″

3. Configure Android Application Project

4. Design Application Launcher Icon

5. Create a blank activity

6. Enter Main Activity Details

7. Link to Google Play Service Library

8. Get the API key for Google Maps Android API v2 
We need to get an API key from Google to use Google Maps in Android application. Please follow the given below link to get the API key for Google Maps Android API v2.

9. Add Android Support library to this project
By default, Android support library (android-support-v4.jar ) is added to this project by Eclipse IDE to the directory libs. If it is not added, we can do it manually by doing the following steps :
  • Open Project Explorer by Clicking “Window -> Show View -> Project Explorer”
  • Right click this project
  • Then from popup window, Click “Android Tools -> Add Support Library “
10. Update the file res/values/strings.xml
1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">CurrentLocation</string>
    <string name="hello_world">Hello world!</string>
    <string name="menu_settings">Settings</string>
</resources>

11. Update the file AndroidManfiest.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?xml version="1.0" encoding="utf-8"?>
    package="in.wptrafficanalyzer.locationingooglemapv2"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />
    <permission
        android:name="in.wptrafficanalyzer.locationingooglemapv2.permission.MAPS_RECEIVE"
        android:protectionLevel="signature"/>
    <uses-permission android:name="in.wptrafficanalyzer.locationingooglemapv2.permission.MAPS_RECEIVE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true"/>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="in.wptrafficanalyzer.locationingooglemapv2.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
             android:value="YOUR_API_KEY"/>
    </application>
</manifest>
Note : In the above code, replace “YOUR_API_KEY” with the api key, you generated in step 8.

12. Update the layout file to display Google Map using SupportMapFragment
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<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=".MainActivity" >
    <TextView
        android:id="@+id/tv_location"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/tv_location"
        class="com.google.android.gms.maps.SupportMapFragment" />
</RelativeLayout>

13. Update the file src/in/wptrafficanalyzer/locationingooglemapv2/MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package in.wptrafficanalyzer.locationingooglemapv2;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.widget.TextView;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
public class MainActivity extends FragmentActivity implements LocationListener {
    GoogleMap googleMap;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Getting Google Play availability status
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());
        // Showing status
        if(status!=ConnectionResult.SUCCESS){ // Google Play Services are not available
            int requestCode = 10;
            Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
            dialog.show();
        }else { // Google Play Services are available
            // Getting reference to the SupportMapFragment of activity_main.xml
            SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
            // Getting GoogleMap object from the fragment
            googleMap = fm.getMap();
            // Enabling MyLocation Layer of Google Map
            googleMap.setMyLocationEnabled(true);
            // Getting LocationManager object from System Service LOCATION_SERVICE
            LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
            // Creating a criteria object to retrieve provider
            Criteria criteria = new Criteria();
            // Getting the name of the best provider
            String provider = locationManager.getBestProvider(criteria, true);
            // Getting Current Location
            Location location = locationManager.getLastKnownLocation(provider);
            if(location!=null){
                onLocationChanged(location);
            }
            locationManager.requestLocationUpdates(provider, 20000, 0, this);
        }
    }
    @Override
    public void onLocationChanged(Location location) {
        TextView tvLocation = (TextView) findViewById(R.id.tv_location);
        // Getting latitude of the current location
        double latitude = location.getLatitude();
        // Getting longitude of the current location
        double longitude = location.getLongitude();
        // Creating a LatLng object for the current location
        LatLng latLng = new LatLng(latitude, longitude);
        // Showing the current location in Google Map
        googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        // Zoom in the Google Map
        googleMap.animateCamera(CameraUpdateFactory.zoomTo(15));
        // Setting latitude and longitude in the TextView tv_location
        tvLocation.setText("Latitude:" +  latitude  + ", Longitude:"+ longitude );
    }
    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

14. Enable GPS in the device from Settings

15. Running the application
Showing current location in Google Map Android API V2
Figure 7 : Showing current location in Google Map Android API V2

16. Download Source Code

17. Tryout
We can tryout this application from Google Play Store at https://play.google.com/store/apps/developer?id=Back+To+Hell

Monday, 19 August 2013

NullPointerException in adnroid

Solution :- 

http://developer.android.com/reference/java/lang/NullPointerException.html

Why NullPointerException occures in Android ?

Many Android developer faced NullPointerException more than one times in a day.


When you try to use Any nullable object then NPE is getting.Any object that not initialize or not give  correct refrences .Also View have not give correct refrences from xml.Sometimes make mistakes due to set wrong content to view.And also when you give any refrence of view from xml  layout see you setContentView().Before setContenview you cant get any refrence from xml.


Suppose i declare ListView and setAdapter.
ListView listview;
listview.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,mStrings));

Now your listview is null and you try to setAdapter so nullPointerException is occur.

so you have to give refrence from the xml or create object of listview.

ListView listview=(ListView)findViewById(R.id.list);

or

ListView listview = new ListView(this);

In Most case NPE is occured Android Custom Dialog(Alert Dialog),Custom Adapter ListView.see red color text ,thats wrong.


Custom Dilaog/AlertDialog.


Dialog dialog = new Dialog(MyActivityName.this);
dialog.setContentView(R.layout.dialog_layout);


EditText editText =(EditText)dialog.findViewById(R.id.editext1);
TextView textView =(TextView)dialog.findViewById(R.id.textview1);
ImageView imgView =( ImageView)dialog.findViewById(R.id.imageview1);


editText.setText("edittext"); textView.setText("textview");
imgView.setImageResources(R.drawable.icon);


dialog.show();


Custom Adapter ListView


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        ViewHolder holder;
        if (view == null) {
            LayoutInflater inflater = (LayoutInflater) activity
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.row, null);
            holder = new ViewHolder();
            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }
   
        holder.title = (TextView) view.findViewById(R.id.txttitle);
        holder.description = (TextView) view.findViewById(R.id.txtdesc);

    
     holder.title.setText("title"+ position);
     holder.description.setText("description"+ position);


    return view
} public class ViewHolder {
        public TextView title,description;
    }



How To Solve NullPointerException::
When you get NPE ,First Check your Logcat Error.And find your app package and activity/class name.Then see in parentheses there are your activity/Class name and line no of code that have nullable View/Object.


Here i have NPE in GameActivity.java and Line no. is 11.

java.lang.RuntimeException: Unable to instantiate activity ComponentInfo
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1573)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3691)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
    at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.NullPointerException
    at android.app.Activity.findViewById(Activity.java:1653)
    at com.zafar.game.GameActivity.<init>(GameActivity.java:11)
    at java.lang.Class.newInstanceImpl(Native Method)
    at java.lang.Class.newInstance(Class.java:1409)
    at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1565)
    ... 11 more


Android Export aborted because fatal error were founds

*Export Aborted
Export aborted because fatal Lin error were founds. These are listed in the
problems view. Either fix these before running Export Again, or turn off "Run
full error check when exporting app" in the Android > Lint Error Cheking preference page.*
To solve issue:
Project -> properties, 
find Android Lint Preferences, in top to right click configure workspace settings... -> unclick "Run full error check when exporting app", apply done.
Window>Preferences>Android>Lint Error Checking

uncheck Run full error check when exporting app

Thursday, 25 July 2013

Cover Flow Animation in Android

Hello, Friend today i am going to post Cover flow animation sample code.



CoverFlow.java
import android.content.Context;
import android.graphics.Camera;
import android.graphics.Color;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Transformation;
import android.widget.Gallery;
import android.widget.ImageView;

@SuppressWarnings("deprecation")
public class CoverFlow extends Gallery 
{
/**
 * Graphics Camera used for transforming the matrix of ImageViews
 */
private Camera mCamera = new Camera();

/**
 * The maximum angle the Child ImageView will be rotated by
 */
private int mMaxRotationAngle = 60;

/**
 * The maximum zoom on the centre Child
 */
private int mMaxZoom = -120;

/**
 * The Centre of the Coverflow
 */
private int mCoveflowCenter;

public CoverFlow(Context context) {
super(context);
this.setStaticTransformationsEnabled(true);
this.setBackgroundColor(Color.BLACK);
}

public CoverFlow(Context context, AttributeSet attrs) {
super(context, attrs);
this.setStaticTransformationsEnabled(true);
this.setBackgroundColor(Color.BLACK);
}

public CoverFlow(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setStaticTransformationsEnabled(true);
this.setBackgroundColor(Color.BLACK);
}

/**
 * Get the max rotational angle of the image
 * 
 * @return the mMaxRotationAngle
 */
public int getMaxRotationAngle() {
return mMaxRotationAngle;
}

/**
 * Set the max rotational angle of each image
 * 
 * @param maxRotationAngle
 *            the mMaxRotationAngle to set
 */
public void setMaxRotationAngle(int maxRotationAngle) {
mMaxRotationAngle = maxRotationAngle;
}

/**
 * Get the Max zoom of the centre image
 * 
 * @return the mMaxZoom
 */
public int getMaxZoom() {
return mMaxZoom;
}

/**
 * Set the max zoom of the centre image
 * 
 * @param maxZoom
 *            the mMaxZoom to set
 */
public void setMaxZoom(int maxZoom) {
mMaxZoom = maxZoom;
}

/**
 * Get the Centre of the Coverflow
 * 
 * @return The centre of this Coverflow.
 */
private int getCenterOfCoverflow() {
return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
+ getPaddingLeft();
}

/**
 * Get the Centre of the View
 * 
 * @return The centre of the given view.
 */
private static int getCenterOfView(View view) {
return view.getLeft() + view.getWidth() / 2;
}

/**
 * {@inheritDoc}
 * 
 * @see #setStaticTransformationsEnabled(boolean)
 */
protected boolean getChildStaticTransformation(View child, Transformation t) {

final int childCenter = getCenterOfView(child);
final int childWidth = child.getWidth();
int rotationAngle = 0;

t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);

if (childCenter == mCoveflowCenter) {
transformImageBitmap((ImageView) child, t, 0);
} else {
rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
if (Math.abs(rotationAngle) > mMaxRotationAngle) {
rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle
: mMaxRotationAngle;
}
transformImageBitmap((ImageView) child, t, rotationAngle);
}

return true;
}

/**
 * This is called during layout when the size of this view has changed. If
 * you were just added to the view hierarchy, you're called with the old
 * values of 0.
 * 
 * @param w
 *            Current width of this view.
 * @param h
 *            Current height of this view.
 * @param oldw
 *            Old width of this view.
 * @param oldh
 *            Old height of this view.
 */
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCoveflowCenter = getCenterOfCoverflow();
super.onSizeChanged(w, h, oldw, oldh);
}

/**
 * Transform the Image Bitmap by the Angle passed
 * 
 * @param imageView
 *            ImageView the ImageView whose bitmap we want to rotate
 * @param t
 *            transformation
 * @param rotationAngle
 *            the Angle by which to rotate the Bitmap
 */
private void transformImageBitmap(ImageView child, Transformation t,
int rotationAngle) 
{
mCamera.save();
final Matrix imageMatrix = t.getMatrix();
;
final int imageHeight = child.getLayoutParams().height;
;
final int imageWidth = child.getLayoutParams().width;
final int rotation = Math.abs(rotationAngle);

mCamera.translate(0.0f, 0.0f, 100.0f);

// As the angle of the view gets less, zoom in
if (rotation < mMaxRotationAngle) 
{
float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
mCamera.translate(0.0f, 0.0f, zoomAmount);
}

mCamera.rotateY(rotationAngle);
mCamera.getMatrix(imageMatrix);
imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
mCamera.restore();
}
}

CoverFlowDemo.java
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

public class CoverFlowDemo extends Activity 
{

@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle savedInstanceState) 
{
super.onCreate(savedInstanceState);

CoverFlow coverFlow;
coverFlow = new CoverFlow(this);

coverFlow.setAdapter(new ImageAdapter(this));

ImageAdapter coverImageAdapter = new ImageAdapter(this);

coverFlow.setAdapter(coverImageAdapter);

coverFlow.setSpacing(-25);
coverFlow.setSelection(4, true);
coverFlow.setAnimationDuration(1000);

coverFlow.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView arg0, View arg1, int position,
long arg3) {
Toast.makeText(CoverFlowDemo.this, "" + position,
Toast.LENGTH_LONG).show();
}
});

setContentView(coverFlow);
}

public class ImageAdapter extends BaseAdapter 
{
int mGalleryItemBackground;
private Context mContext;

private Integer[] mImageIds = { R.drawable.android,
R.drawable.img1, R.drawable.img2,
R.drawable.img3, R.drawable.img4,
R.drawable.img1, R.drawable.img2,
R.drawable.img3, R.drawable.img4
};

private ImageView[] mImages;

public ImageAdapter(Context c) {
mContext = c;
mImages = new ImageView[mImageIds.length];
}

@SuppressWarnings("deprecation")
public boolean createReflectedImages() 
{
// The gap we want between the reflection and the original image
final int reflectionGap = 4;

int index = 0;
for (int imageId : mImageIds)
{
Bitmap originalImage = BitmapFactory.decodeResource(
getResources(), imageId);
int width = originalImage.getWidth();
int height = originalImage.getHeight();

// This will not scale but will flip on the Y axis
Matrix matrix = new Matrix();
matrix.preScale(1, -1);

// Create a Bitmap with the flip matrix applied to it.
// We only want the bottom half of the image
Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
height / 2, width, height / 2, matrix, false);

// Create a new bitmap with same width but taller to fit
// reflection
Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
(height + height / 2), Config.ARGB_8888);

// Create a new Canvas with the bitmap that's big enough for
// the image plus gap plus reflection
Canvas canvas = new Canvas(bitmapWithReflection);
// Draw in the original image
canvas.drawBitmap(originalImage, 0, 0, null);
// Draw in the gap
Paint deafaultPaint = new Paint();
canvas.drawRect(0, height, width, height + reflectionGap,
deafaultPaint);
// Draw in the reflection
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap,
null);

// Create a shader that is a linear gradient that covers the
// reflection
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0,
originalImage.getHeight(), 0,
bitmapWithReflection.getHeight() + reflectionGap,
0x70ffffff, 0x00ffffff, TileMode.CLAMP);
// Set the paint to use this shader (linear gradient)
paint.setShader(shader);
// Set the Transfer mode to be porter duff and destination in
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
// Draw a rectangle using the paint with our linear gradient
canvas.drawRect(0, height, width,
bitmapWithReflection.getHeight() + reflectionGap, paint);

ImageView imageView = new ImageView(mContext);
imageView.setImageBitmap(bitmapWithReflection);
android.widget.Gallery.LayoutParams imgLayout = new CoverFlow.LayoutParams(
320, 480);
imageView.setLayoutParams(imgLayout);
imageView.setPadding(30, 100, 20, 20);
mImages[index++] = imageView;

}
return true;
}

public int getCount() 
{
return mImageIds.length;
}

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

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

@SuppressWarnings("deprecation")
public View getView(int position, View convertView, ViewGroup parent) 
{

// Use this code if you want to load from resources
ImageView i = new ImageView(mContext);
i.setImageResource(mImageIds[position]);
i.setLayoutParams(new CoverFlow.LayoutParams(380, 450));
i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);

// Make sure we set anti-aliasing otherwise we get jaggies
BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();
drawable.setAntiAlias(true);
return i;

// return mImages[position];
}

/**
 * Returns the size (0.0f to 1.0f) of the views depending on the
 * 'offset' to the center.
 */
public float getScale(boolean focused, int offset) {
/* Formula: 1 / (2 ^ offset) */
return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));
}

}
}