Showing posts with label Android Wear. Show all posts
Showing posts with label Android Wear. Show all posts

Wednesday, 5 August 2015

Maps in Android Wear

We can show maps in Android wear we display user current location recived from the phone.
Currently we can update user current location from phone only. So this maps on android wear will be helpful for user to see the locations near by when riding.


What is DismissOverlayView? Need to know this first.

In Android wear we Dismiss a screen or view by swiping from left to right. But When we are dealing with Maps in android wear then gestures are overiden by the map gestures so we are not able to perform the normal left to right swipe dismiss action in android wear in maps.

So in order to overcome there is DismissOverlayView which lets you dismiss the map screen view by just long press on the map screen and you will get a alert to quit with cross icon which allows you to dismiss the current screen in view.



And how can we show maps in android wear programmactically is shown below.


Project Structure will be as shown





1. MainActivity.java

public class MainActivity extends FragmentActivity implements OnMapReadyCallback,

        GoogleMap.OnMapLongClickListener,GoogleMap.OnMarkerDragListener {



    private GoogleApiClient mGoogleApiClient;

    private static final LatLng CHANDIGARH = new LatLng(30.7500, 76.7800);

    ArrayList<LatLng> points;

    float distance;

    private DismissOverlayView mDismissOverlay;

    private GoogleMap mMap;



    public void onCreate(Bundle savedState) {

        super.onCreate(savedState);

        setContentView(R.layout.activity_main);

        final FrameLayout topFrameLayout = (FrameLayout) findViewById(R.id.root_container);

        final FrameLayout mapFrameLayout = (FrameLayout) findViewById(R.id.map_container);

        topFrameLayout.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {

            @Override

            public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {

                insets = topFrameLayout.onApplyWindowInsets(insets);

                FrameLayout.LayoutParams params =

                        (FrameLayout.LayoutParams) mapFrameLayout.getLayoutParams();

                params.setMargins(

                        insets.getSystemWindowInsetLeft(),

                        insets.getSystemWindowInsetTop(),

                        insets.getSystemWindowInsetRight(),

                        insets.getSystemWindowInsetBottom());

                mapFrameLayout.setLayoutParams(params);



                return insets;

            }

        });



        mDismissOverlay = (DismissOverlayView) findViewById(R.id.dismiss_overlay);

        mDismissOverlay.setIntroText(R.string.intro_text);

        mDismissOverlay.showIntroIfNecessary();

        SupportMapFragment mapFragment =

                (SupportMapFragment) getSupportFragmentManager()

                        .findFragmentById(R.id.map);

        mapFragment.getMapAsync(this);

    }



    @Override

    public void onMapReady(GoogleMap googleMap) {

        mMap = googleMap;

        mMap.setOnMapLongClickListener(this);

        MarkerOptions marker = new MarkerOptions()

                .position(CHANDIGARH)

                .title("Wear Maps")

                .snippet("" + CHANDIGARH)

                .icon(BitmapDescriptorFactory

                        .defaultMarker(BitmapDescriptorFactory.HUE_GREEN));

        mMap.addMarker(marker);

        mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {

            @Override

            public void onInfoWindowClick(Marker marker) {



            }

        });

        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(CHANDIGARH, 14));



    }



    @Override

    public void onMapLongClick(LatLng latLng) {

        mDismissOverlay.show();

    }



    @Override

    public void onMarkerDragEnd(Marker arg0) {

        LatLng dragPosition = arg0.getPosition();

        double dragLat = dragPosition.latitude;

        double dragLong = dragPosition.longitude;

        Log.i("info", "on drag end :" + dragLat + " dragLong :" + dragLong);

        PolylineOptions polylineOptions = new PolylineOptions();

        polylineOptions.color(Color.RED);

        polylineOptions.width(3);

        points.add(dragPosition);

        polylineOptions.addAll(points);

        mMap.addPolyline(polylineOptions);

        Toast.makeText(getApplicationContext(), "Distance ="+distance, Toast.LENGTH_LONG).show();

    }



    @Override

    public void onMarkerDragStart(Marker arg0) {

    }



    @Override

    public void onMarkerDrag(Marker marker) {

    }

}





2. activity_main.xml

<FrameLayout

    xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:map="http://schemas.android.com/apk/res-auto"

    android:id="@+id/root_container"

    android:layout_height="match_parent"

    android:layout_width="match_parent">





    <FrameLayout

        android:id="@+id/map_container"

        android:layout_width="match_parent"

        android:layout_height="match_parent">



        <fragment

            android:id="@+id/map"

            android:layout_width="match_parent"

            android:layout_height="match_parent"

            android:name="com.google.android.gms.maps.SupportMapFragment"/>



    </FrameLayout>



    <android.support.wearable.view.DismissOverlayView

        android:id="@+id/dismiss_overlay"

        android:layout_height="match_parent"

        android:layout_width="match_parent"/>



</FrameLayout>





3.AndroidManifest.xml

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

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.watchmaps.androidsmartwatchmaps" >



    <!-- Permissions and features required for the Android Maps API v2 -->

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

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

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

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

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

    <uses-feature

        android:glEsVersion="0x00020000"

        android:required="true"/>



    <application

        android:allowBackup="true"

        android:icon="@mipmap/ic_launcher"

        android:label="@string/app_name"

        android:theme="@android:style/Theme.DeviceDefault" >

        <!-- API key for the Android Maps API v2. The value is defined as a string resource. -->

        <meta-data android:name="com.google.android.geo.API_KEY"

            android:value="@string/google_maps_key"/>

        <!-- Meta data required for Google Play Services -->

        <meta-data

            android:name="com.google.android.gms.version"

            android:value="@integer/google_play_services_version" />

        <activity

            android:name=".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>

    </application>



</manifest>





4. build.gradle

apply plugin: 'com.android.application'



android {

    compileSdkVersion 22

    buildToolsVersion "22.0.1"



    defaultConfig {

        applicationId "com.watchmaps.androidsmartwatchmaps"

        minSdkVersion 20

        targetSdkVersion 22

        versionCode 1

        versionName "1.0"

    }

    buildTypes {

        release {

            minifyEnabled false

            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

        }

    }

}



dependencies {

    compile fileTree(dir: 'libs', include: ['*.jar'])

    compile 'com.google.android.support:wearable:1.2.0'

    compile 'com.google.android.gms:play-services-wearable:7.5.0'

    compile 'com.google.android.gms:play-services-maps:7.5.0'

}



Happy coding
Cheers!!!


References : https://developers.google.com/maps/documentation/android/wear?hl=en

Wednesday, 27 May 2015

Designing Layouts for Wearables Android


So while designing layouts for wearable we need to keep both above types in mind so that our layout design looks perfectly fine on both round and square screens.

Android wearable fall's into two categories :

1. Round Shape
2. Square Shape

Now, question is how should we achieve this.Well i encountered some issues on round screen.My screen layout included text and image.So whenever text was large it was cutting in round edges from left side.

So after sometime,i camed to know about BoxInsetLayout which comes under android.support.wearable.view.BoxInsetLayout included in Wearable UI Library .
This helps us define a single layout that works both in round and square screens for wearbles.

Round Shape View


 Square Shape View


Now how to Make use of this lets have a look :




<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:padding="20dp">

    <android.support.v4.view.ViewPager
        android:id="@+id/myviewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</android.support.wearable.view.BoxInsetLayout>


1. android:padding="20dp" : Now this gives the padding to the BoxInsetLayout from all directions which creates a kind of rectangle for us and we've to work inside it.And this paddingapplies only to square screen of wearable as window insets on round devices are larger than 15 dp.

Note :BoxInsetLayout act as a parent and we have to create our layout inside this parent(like we do inside linear layout etc).

 2. android:padding="5dp" for our child view in this case view pager is our child : This padding applies on both round and square screens.
 
    For Square screen : this makes 20+5 = 25 dp padding
    For Round  screen :this makes 5    = 5 dp padding
 
 3. app:layout_box="all" :This line ensures that the ViewPager element and its children are boxed inside the area defined by the window insets on round screens. This line has no effect on square screens.



References : https://developer.android.com/training/wearables/ui/layouts.html#add-library


happy coding!!
Cheers !!

Monday, 25 May 2015

Android Wear Host Disconnected even after running connecting commands

A issue normally that we faced when we try to connect android wear(smartwatch) via android wear companion app

Host   : Disconnected.
Target : Connected.

This normally happens if you've connected with an emulator previously, Then it will cause an issue with the connection.

To solve this just follow below steps :

1. open android wear companion app
2. Go to settings
3. click on Emulator.
4. click on FORGET WATCH

That did the trick for me :-)

Posting by keeping in mind that you guys already know how to connect any wearable by running commands :-)

Cheers!!

Wednesday, 1 April 2015

Creating App for Wearables



# Use Android Studio.(Recommended)
  •  Create Android Project
  •  Select Phone & Wear project
  •  Follow the steps for project creation wizard.
  • Design your layouts for both mobile and wearable in respective projects.

Now Problems that come when working with wearable

Firstly you need to install Android Wear Companion app on your device in order to make the device and wearable communicate.Which you can download from : https://play.google.com/store/apps/details?id=com.google.android.wearable.app

How to test the wearable app :

Now you need not to have a wearable device (Smartwatch) to test your app. You can test your app on the emulator.Create a wearble emulator using AVD.

Now open the android wearable app in the device and make sure your device is connected to system.After this you will see the welcome screen then select connect with emulator option from the action bar.After selecting the option simultaneously run this command inside i.e command prompt in windows or terminal in Mac in order to make device and emulator connected with each other.

adb -d forward tcp:5601 tcp:5601

Now after this you will see device and wearable emulator are connected with each other.Now whenever you install the Signed apk on device it will sync wearable apk for same onto emulator.

And if your app is not syncing to wearable device or emulator then make sure below points are corrected in your project :

Most of us face a common problem i.e apk file is not automatically installed on wearable when installed on Phone.Frankly i was troubled alot with this one.
But i got it right after few mistakes So do perfrom these steps in order to make app automatically installed as done installing on phone.

Step 1 : 

All the permissions defined in the wear app manifest file should be present in the mobile app manifest file.And you need not to put all phone permissions in wearable manifest.

Step 2 : 

Secondly  In build.gradle file of your phone app Confirm this

dependencies {
    wearApp project(':wear') // You should mention the exact name of the wear app folder here
}


Step 3 : 

Package name : In manifest file for both mobile and wear app should be same.
Application ID : (build.gradle file) of mobile and wear app should be same.


Now if you want to test app on wearable device then follow these instructions :
Firstly enable developer options in your wearable device as we do in device.
then enable debuggin over bluetooth in wearable under developer option.


Now On the handheld, open the Android Wear companion app then Tap the menu on the top right and select Settings.
Enable Debugging over Bluetooth. You can see the status :
Host: disconnected // this will be connected when we run the command to connect both device and wearable
Target: connected

To Connect the handheld to your machine over USB and run:

adb forward tcp:4444 localabstract:/adb-hub
adb connect localhost:4444

Then under settings in companion app you will see following status :
Host: connected
Target: connected

You can also check the connected devices in command prompt in Command prompt by using following command :

adb devices

Finally when you are done with the development of the app then you can generate a signed apk which will be installed on phone and automatically installed on wearable device.
Make sure that build generated is Signed then only it will be installed on wearable.

To generate signed apk Android studio provide us the simple wizard to do it. Well there are other ways available to generate the signed apk but prefer this.
Click on Build, Then select the Generate Signed apk option and go through the wizrad And you will get the signed apk.


Sometimes your app may take time to get Synced to wearable after installation on device so be Patience.And you can always sync manually app to wearable by using sync apps to watch option in android companion app under settings section.


Happy coding!!!
Cheers!!!