Showing posts with label SDK. Show all posts
Showing posts with label SDK. Show all posts

Sunday, 1 October 2017

HB Blog 145: Autofill Framework In Andriod O.

Earlier, mobiles were just used for calling and messaging purposes but, now a days mobile technology has been developed such a way that it can do all human based daily tasks. Banking and similar offices were having lot of problems with forms and paper works which has been digitized now thanks to mobile technologies.
We are moving from single screen to multi-screens applications. But, still applications such as banking, etc. have forms which are tired-sum to fill for users.
Android Oreo has new feature called 'Autofill Framework' that can help in solving these problems. Users can save time filling out forms by using autofill in their devices. Android makes filling forms, such as account and credit card forms, easier with the introduction of the Autofill Framework. The Autofill Framework manages the communication between the app and an autofill service.

The Autofill Framework improves the user experience by providing the following benefits:
  •     Less time spent in filling fields Autofill saves users from re-typing information.
  •     Minimize user input errors Typing is prone to errors, especially in mobile devices. Removing the necessity of typing information also removes the errors that come with it.
Before apps can work with the Autofill Framework, an autofill service must be enabled in the system settings. Users can enable or disable autofill as well as change the autofill service in Settings > System > Languages & input > Advanced > Input assistance > Autofill service. An autofill service can require the user to authenticate before the autofill data can be used to complete fields in your app.

Optimizing your app for autofill:-
Apps that use standard views work with the Autofill Framework out of the box. However, you can take some steps to optimize how your app works with the framework.
Ensuring data is available -
In some special cases, you need to take additional steps to make sure that the data is available to the Autofill Framework to save. In this case, the data in the original layout is not available to the framework. To make the data available to the framework, you should call commit() on the AutofillManager object before replacing the original layout.
Providing hints for autofill - Typically, there is just one way to autofill a view, but there could be multiple ways if the view accepts more than one type of information. For example, a view used to identify the user might accept either a username or an email address. These hints can be set using either the android:autofillHints attribute or the setAutofillHints() method.
Mark fields as important for autofill - You can tell the system whether the individual fields in your app should be included in a view structure for autofill purposes. You can use the setImportantForAutofill() method, passing the mode, to determine if the view is important for autofill.

Associate website and mobile app data:-
You can associate your Android app with your website to let other services know that user data, such as login credentials, can be shared between these environments. Autofill services can take advantage of this association if they provide services on a browser and on Android. For example, if users choose the same autofill service in both environments, they can sign-in to a website using a browser, and the login credentials are available to autofill when the same users try to sign-in to the associated app on Android.

Friday, 1 September 2017

HB Blog 143: Implementing Video Call using Sinch Android SDK.

Introduction

The Sinch SDK is a product that makes adding voice calling and/or instant messaging to mobile apps easy. It handles all the complexity of signalling and audio management while providing you the freedom to create a stunning user interface.
Refer the below link for complete sample code:-

Download Sample Code

First time setup

Below is a step-by-step guide on setting up the Sinch SDK for the first time.

Register an Application
1.    Register a Sinch Developer account at http://www.sinch.com/signup.
2.    Setup a new Application using the Dashboard where you can then obtain an Application Key and an Application Secret.

Download
The Sinch SDK can be downloaded at www.sinch.com/download/. It contains: the library aar, this user guide, reference documentation, and sample apps for calling and instant messaging.

Add the Sinch library
The Sinch SDK library is distributed in AAR format. To use it in your project choose File -> New -> New Module -> Import .JAR/.AAR Package option

Permissions
A minimum set of permissions are needed for the app to use the Sinch SDK. These are specified in the AndroidManifest.xml file. If the calling functionality will be used, all five permissions listed here are needed. However, if the calling functionality isn’t used, the last three (RECORD_AUDIO, MODIFY_AUDIO_SETTINGS and READ_PHONE_STATE) can be omitted.
1
2
3
4
5
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Note: By default, the Sinch SDK hangs up any Sinch call if the regular phone app has an active call. This functionality requires the permission READ_PHONE_STATE. However, if this default functionality isn’t wanted, turn it off by calling sinchClient.getCallClient().setRespectNativeCalls(false); and the permission READ_PHONE_STATE is not needed.

Sinch client

The SinchClient is the Sinch SDK entry point. It is used to configure the user’s and device’s capabilities, as well as to provide access to feature classes such as the CallClient, MessageClient and AudioController.

Create a SinchClient
1
2
3
4
5
6
7
8
// Instantiate a SinchClient using the SinchClientBuilder.
android.content.Context context = this.getApplicationContext();
SinchClient sinchClient = Sinch.getSinchClientBuilder().context(context)
.applicationKey("<application key>")
.applicationSecret("<application secret>")
.environmentHost("sandbox.sinch.com")
.userId("<user id>")
.build();
The Application Key and Application Secret are obtained from the Sinch Developer Dashboard. The User ID should uniquely identify the user on the particular device.
Note: All listener callbacks emitted from the Sinch SDK are invoked on the same thread that the call to SinchClientBuilder.build is made on. If the invoking thread is not the main-thread, it needs to have an associated Looper.

Start the Sinch client
Before starting the client, add a client listener
1
2
3
4
5
6
7
8
sinchClient.addSinchClientListener(new SinchClientListener() {
public void onClientStarted(SinchClient client) { }
public void onClientStopped(SinchClient client) { }
public void onClientFailed(SinchClient client, SinchError error) { }
public void onRegistrationCredentialsRequired(SinchClient client, ClientRegistration registrationCallback) { }
public void onLogMessage(int level, String area, String message) { }
});
sinchClient.start();
Terminate the Sinch client
When the app is done using the SinchClient, it should be stopped. If the client is currently listening for incoming events, it needs to stop listening as well. After terminate is called, any object retrieved directly from the client object (that is, CallClient, MessageClient, and AudioController) is considered invalid.
Terminating the client:
1.    sinchClient.stopListeningOnActiveConnection();
2.    sinchClient.terminate();

Setting up a video call
Just like audio calls, video calls are placed through the CallClient and events are received using the CallClientListener. The call client is owned by the SinchClient and accessed using sinchClient.getCallClient(). Calling is not enabled by default. 

Showing the video streams
Once you have created a VideoCallListener and added it to a call, the onVideoTrackAdded() method will be called.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
@Override
public void onVideoTrackAdded(Call call) {
// Get a reference to your SinchClient, in the samples this is done through the service interface:
VideoController vc = getSinchServiceInterface().getVideoController();
View myPreview = vc.getLocalView();
View remoteView = vc.getRemoteView();
// Add the views to your view hierarchy
}

After the call has ended, dont forget to remove the views from your view hierarchy again.
@Override
public void onCallEnded(Call call) {
// Remove Sinch video views from your view hierarchy
}
Pausing video stream
To pause the local video stream, use the pauseVideo() method on the call.
1.        // User pause the video stream
2.        call.pauseVideo();

Resuming video stream
To resume the local video stream, use the resumeVideo() method on the call.
1.       // User resumes the video stream
2.       call.resumeVideo();

Pausing video stream delegates
Once you have created a VideoCallListener and added it to a call, the onVideoTrackPaused() method will be called when the remote user pause the video stream.
1.       @Override
2.       public void onVideoTrackPaused(Call call) {
3.            // Implement what to be done when remote user pause video stream.
4.       }

Resuming video stream delegates
Once you have created a VideoCallListener and added it to a call, the onVideoTrackResumed() method will be called when the remote user resumes the video stream..
1.       @Override
2.       public void onVideoTrackResumed(Call call) {
3.            // Implement what to be done when remote user resumes video stream.
4.       }

Video content fitting and aspect ratio
How the remote video stream is fitted into a view can be controller by the setResizeBehaviour() method with possible arguments VideoScalingType.ASPECT_FIT, VideoScalingType.ASPECT_FILL and VideoScalingType.ASPECT_BALANCED. The local preview will always use VideoScalingType.ASPECT_FIT.

Switching capturing device
The capturing device can be switched using videoController.setCaptureDevicePosition(int facing) with possible values Camera.CameraInfo.CAMERA_FACING_FRONT and Camera.CameraInfo.CAMERA_FACING_BACK. Use videoController.toggleCaptureDevicePosition() to alternate the two.

Accessing video frames of the remote streams
The Sinch SDK can provide access to raw video frames via a callback function. This callback can be used to achieve rich functionality such as applying filters, adding stickers to the video frames, or saving the video frame as an image.
Your video frame handler needs to implement VideoFrameListener interface by implementing the onFrame() callback. Note that it is important to explicitly release the video frame by calling release().
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Example:
import com.sinch.android.rtc.video.VideoFrame;
import com.sinch.android.rtc.video.VideoFrameListener;
public class YourVideoFrameHandler implements VideoFrameListener {
public synchronized void onFrame(String callId, VideoFrame videoFrame) {
// Process videoFrame
videoFrame.release(); // Release videoFrame}}

Use setVideoFrameListener() to register your video frame handler as the callback to receive video frames.

Example:
YourVideoFrameHandler videoFrameHandler = new YourVideoFrameHandler();
VideoController vc = getSinchServiceInterface().getVideoController();
vc.setVideoFrameListener(videoFrameHandler);

Tuesday, 1 November 2016

HB Blog 122: Android Tools For Analyzing RAM Usage.

Random-access memory (RAM) is a valuable resource in any software development environment, but it's even more valuable on a mobile operating system where physical memory is often constrained. Although both the Android Runtime (ART) and Dalvik virtual machine perform routine garbage collection, this does not mean you can ignore when and where your app allocates and releases memory. You still need to avoid introducing memory leaks, usually caused by holding onto object references in static member variables, and release any Reference objects at the appropriate time as defined by lifecycle callbacks.
Tools for analyzing RAM usage :-
Before you can fix the memory usage problems in your app, you first need to find them. Android Studio and the Android SDK include several tools for analyzing memory usage in your app,

  1. The Device Monitor has a Dalvik Debug Monitor Server (DDMS) tool that allows you to inspect memory allocation within your app process. You can use this information to understand how your app uses memory overall. For example, you can force a garbage collection event and then view the types of objects that remain in memory. You can use this information to identify operations or actions within your app that allocate or leave excessive amounts of objects in memory. 
  2. The Memory Monitor in Android Studio shows you how your app allocates memory over the course of a single session. The tool shows a graph of available and allocated Java memory over time, including garbage collection events. You can also initiate garbage collection events and take a snapshot of the Java heap while your app runs. The output from the Memory Monitor tool can help you identify points when your app experiences excessive garbage collection events, leading to app slowness.
  3. Garbage collection events also show up in the Traceview viewer. Traceview allows you to view trace log files as both a timeline and as a profile of what happened within a method. You can use this tool to determine what code was executing when a garbage collection event occurred. 
  4. The Allocation Tracker tool in Android Studio gives you a detailed look at how your app allocates memory. The Allocation Tracker records an app's memory allocations and lists all allocated objects within the profiling snapshot. You can use this tool to track down parts of your code that allocate too many objects.

Sunday, 1 May 2016

HB Blog 109: Content Assist - The Developer's Friend.

Android Studio and similar other IDE's provide various features to developers which make a comfort environment for them. Hence, it is called as Integrated Development Environment (IDE). More technical, an integrated development environment is a software application that provides comprehensive facilities to computer programmers for software development. One of the most helpful feature is the content assist.

Content/Code assist helps the developer to write code faster and more efficiently. This is achieved by simplifying the task of coding to allow it to focus on the business task being coded. Based on the context of the code, content assist provides the developer with a list of accessible keywords according to a programming language specification, variable, methods, data types.
Autocomplete: - Autocomplete, or word completion, is a feature in which an IDE predicts the rest of a word a user is typing.

For example, in an XML context, when the developer types an opening tag "<" he is offered a list of tags via autocomplete, contextualized following the DTD or XML schema of the document. As the developer types more letters, the offered choices are filtered to only retain the relevant completions. When the developer finally completes the tag, the editor automatically generates the closing tag.

Another example, a developer can just type in the first letter if lowercase and the uppercase letters from a type/variable name then press Ctrl+space to be offered all the choices that match the entered letters that are valid for the current context (class name, interface name, variable or field names).

Code snippet/templates: - Code snippets allow the developer to add a complex coding structure by typing a minimal amount of text. Code snippets can only be used in a valid context (statements snippets are only offered when you can insert statements).

Specifically, in Android Studio ctrl+space (content assist) does 50% work of the developer's work.
Android studio has few more interesting features as well which makes development pretty simple.

Refer below link to meet Android studio,
https://developer.android.com/studio/intro/index.html

Sunday, 25 October 2015

HB Blog 100: How To Draw Graphic Elements On MapView Using ArcGIS Android SDK???

In this post, I will brief little about ArcGIS. ArcGIS is a geographic information system (GIS) for working with maps and geographic information. It is used for: creating and using maps; compiling geographic data; analyzing mapped information; sharing and discovering geographic information; using maps and geographic information in a range of applications; and managing geographic information in a database.

Refer below link for Android setup and documentation for ArcGIS Android SDK.
https://developers.arcgis.com/android/

There are many customization that can be done in maps using ArcGIS, I would like to show how to plot point, polylines, polygone, etc. Basically, ArcGIS is made with different layers such as featured layer, graphic layer, etc.  While drawing or plotting grahpical elements or callout on map we use graphic layer. MapView has two layers (that is, a TiledMapServiceLayer and GraphicsLayer). The TiledMapServiceLayer points to a map service on one of Esri's servers, while the GraphicsLayer holds graphic elements that a user draws on the screen. When the sample application starts, a MapView, TiledMapServiceLayer, and GraphicsLayer are instantiated. A TouchListener is added to a MapView and other Android user interface (UI) elements (AlertDialog, Buttons) are also instantiated.
When a user selects a geometry type from the AlertDialog, the AlertDialog's onClick() handler method assigns the appropriate symbology to the GraphicLayer's renderer. The MapView's TouchListener class has handlers to listen to SingleTap, OnDragPointerMove, and OnDragPointerUp events. These collect geometry based on the user's actions on the screen and assign this geometry to a graphic object, which is then added to the GraphicsLayer. This application also retains its state when the device is flipped or the user switches to another application.


Refer the below link for complete sample code:-
Download Sample Code
Download Apk File
Download Support Library
Have a look on few code snippets,

AndroidManifest.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
<?xml version="1.0" encoding="utf-8"?>
<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.esri.arcgis.android.samples.helloworld"
  android:versionCode="1"
  android:versionName="1.0">

  <uses-sdk
    android:minSdkVersion="10"
    android:targetSdkVersion="19" />

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

  <uses-feature
    android:glEsVersion="0x00020000"
    android:required="true" />

  <application
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:allowBackup="true" >


      <activity
          android:name=".DrawGraphicElements"
          android:configChanges="orientation"
          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>

DrawGraphicElements.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
package com.esri.arcgis.android.samples.helloworld;

/**
 * Created by harshalbenake on 01/07/15.
 */
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.esri.android.map.GraphicsLayer;
import com.esri.android.map.MapOnTouchListener;
import com.esri.android.map.MapView;
import com.esri.android.map.ags.ArcGISTiledMapServiceLayer;
import com.esri.android.map.event.OnStatusChangedListener;
import com.esri.core.geometry.MultiPath;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.Polygon;
import com.esri.core.geometry.Polyline;
import com.esri.core.map.Graphic;
import com.esri.core.symbol.SimpleFillSymbol;
import com.esri.core.symbol.SimpleLineSymbol;
import com.esri.core.symbol.SimpleMarkerSymbol;
import com.esri.core.symbol.SimpleMarkerSymbol.STYLE;

public class DrawGraphicElements extends Activity {

    /*
     * ArcGIS Android elements
     */
    MapView mapView = null;
    ArcGISTiledMapServiceLayer tiledMapServiceLayer = null;
    GraphicsLayer graphicsLayer = null;
    MyTouchListener myListener = null;

    /*
     * Android UI elements
     */
    Button geometryButton;
    Button clearButton;
    TextView label;

    /*
     * Other elements that hold app state
     */
    String mapURL = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyBasemap/MapServer";

    final String[] geometryTypes = new String[] { "Point", "Polyline",
            "Polygon" };

    int selectedGeometryIndex = -1;

    @SuppressWarnings("serial")
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//      setContentView(mapView);
        setContentView(R.layout.main_draw);
        /*
         * Initialize ArcGIS Android MapView, tiledMapServiceLayer, and Graphics
         * Layer
         */
//      mapView = new MapView(this);
        mapView = (MapView)findViewById(R.id.map);
        myListener = new MyTouchListener(DrawGraphicElements.this, mapView);
        mapView.setOnTouchListener(myListener);

        /*
         * Initialize Android Geometry Button
         */
        geometryButton = (Button) findViewById(R.id.geometrybutton);
        geometryButton.setEnabled(false);
        geometryButton.setOnClickListener(new View.OnClickListener() {
            /*
             * This displays an AlertDilaog as defined in onCreateDialog()
             * method. Invocation of show() causes onCreateDialog() to be called
             * internally.
             */
            public void onClick(View v) {
                showDialog(0);
            }
        });

        label = (TextView) findViewById(R.id.label);

        clearButton = (Button) findViewById(R.id.clearbutton);
        clearButton.setEnabled(false);
        clearButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                graphicsLayer.removeAll();


                clearButton.setEnabled(false);
            }
        });

        /*
         * Initialize MapView, TiledMapServiceLayer and GraphicsLayer. This
         * block will be executed when app is started the first time.
         */
//      mapView.setExtent(new Envelope(-85.61828847183895, 38.19242311866144, -85.53589100936443, 38.31361605305102),0);

        tiledMapServiceLayer = new ArcGISTiledMapServiceLayer(mapURL);
        graphicsLayer = new GraphicsLayer();

        /*
         * Use TiledMapServiceLayer's OnStatusChangedListener to listen to
         * events such as change of status. This event allows developers to
         * check if layer is indeed initialized and ready for use, and take
         * appropriate action. In this case, we are modifying state of other UI
         * elements if and when the layer is loaded.
         */
        tiledMapServiceLayer
                .setOnStatusChangedListener(new OnStatusChangedListener() {
                    /*
                     * This callback method will be invokes when status of layer
                     * changes
                     */
                    public void onStatusChanged(Object arg0, STATUS status) {
                        /*
                         * Check if layer's new status = INITIALIZED. If it is,
                         * initialize UI elements
                         */
                        if (status
                                .equals(OnStatusChangedListener.STATUS.INITIALIZED)) {
                            geometryButton.setEnabled(true);
                        }
                    }
                });

        /**
         * Add TiledMapServiceLayer and GraphicsLayer to map
         */
        mapView.addLayer(tiledMapServiceLayer);
        mapView.addLayer(graphicsLayer);
    }

    /*
     * MapView's touch listener
     */
    class MyTouchListener extends MapOnTouchListener {
        // ArrayList<Point> polylinePoints = new ArrayList<Point>();

        MultiPath poly;
        String type = "";
        Point startPoint = null;

        public MyTouchListener(Context context, MapView view) {
            super(context, view);
        }

        public void setType(String geometryType) {
            this.type = geometryType;
        }

        public String getType() {
            return this.type;
        }

        /*
         * Invoked when user single taps on the map view. This event handler
         * draws a point at user-tapped location, only after "Draw Point" is
         * selected from Spinner.
         *
         * @see
         * com.esri.android.map.MapOnTouchListener#onSingleTap(android.view.
         * MotionEvent)
         */
        public boolean onSingleTap(MotionEvent e) {
            if (type.length() > 1 && type.equalsIgnoreCase("POINT")) {
                graphicsLayer.removeAll();
                Graphic graphic = new Graphic(mapView.toMapPoint(new Point(e.getX(), e
                        .getY())),new SimpleMarkerSymbol(Color.RED,25,STYLE.CIRCLE));
                //graphic.setGeometry();
                graphicsLayer.addGraphic(graphic);

                clearButton.setEnabled(true);
                return true;
            }
            return false;

        }

        /*
         * Invoked when user drags finger across screen. Polygon or Polyline is
         * drawn only when right selected is made from Spinner
         *
         * @see
         * com.esri.android.map.MapOnTouchListener#onDragPointerMove(android
         * .view.MotionEvent, android.view.MotionEvent)
         */
        public boolean onDragPointerMove(MotionEvent from, MotionEvent to) {
            if (type.length() > 1
                    && (type.equalsIgnoreCase("POLYLINE") || type
                    .equalsIgnoreCase("POLYGON"))) {

                Point mapPt = mapView.toMapPoint(to.getX(), to.getY());

                /*
                 * if StartPoint is null, create a polyline and start a path.
                 */
                if (startPoint == null) {
                    graphicsLayer.removeAll();
                    poly = type.equalsIgnoreCase("POLYLINE") ? new Polyline()
                            : new Polygon();
                    startPoint = mapView.toMapPoint(from.getX(), from.getY());
                    poly.startPath((float) startPoint.getX(),
                            (float) startPoint.getY());

                    /*
                     * Create a Graphic and add polyline geometry
                     */
                    Graphic graphic = new Graphic(startPoint,new SimpleLineSymbol(Color.RED,5));

                    /*
                     * add the updated graphic to graphics layer
                     */
                    graphicsLayer.addGraphic(graphic);
                }

                poly.lineTo((float) mapPt.getX(), (float) mapPt.getY());

                return true;
            }
            return super.onDragPointerMove(from, to);

        }

        @Override
        public boolean onDragPointerUp(MotionEvent from, MotionEvent to) {
            if (type.length() > 1
                    && (type.equalsIgnoreCase("POLYLINE") || type
                    .equalsIgnoreCase("POLYGON"))) {

                /*
                 * When user releases finger, add the last point to polyline.
                 */
                if (type.equalsIgnoreCase("POLYGON")) {
                    poly.lineTo((float) startPoint.getX(),
                            (float) startPoint.getY());
                    graphicsLayer.removeAll();
                    graphicsLayer.addGraphic(new Graphic(poly,new SimpleFillSymbol(Color.RED)));

                }
                graphicsLayer.addGraphic(new Graphic(poly,new SimpleLineSymbol(Color.BLUE,5)));
                startPoint = null;
                clearButton.setEnabled(true);
                return true;
            }
            return super.onDragPointerUp(from, to);
        }
    }

    /*
     * Returns an AlertDialog that includes names of all layers in the map
     * service
     */
    protected Dialog onCreateDialog(int id) {
        return new AlertDialog.Builder(DrawGraphicElements.this)
                .setTitle("Select Geometry")
                .setItems(geometryTypes, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        graphicsLayer.removeAll();

                        // ignore first element
                        Toast toast = Toast.makeText(getApplicationContext(),
                                "", Toast.LENGTH_LONG);
                        toast.setGravity(Gravity.BOTTOM, 0, 0);

                        // Get item selected by user.
                        String geomType = geometryTypes[which];
                        label.setText(geomType + " selected.");
                        selectedGeometryIndex = which;

                        // process user selection
                        if (geomType.equalsIgnoreCase("Polygon")) {
                            myListener.setType("POLYGON");
                            toast.setText("Drag finger across screen to draw a Polygon. \nRelease finger to stop drawing.");
                        } else if (geomType.equalsIgnoreCase("Polyline")) {
                            myListener.setType("POLYLINE");
                            toast.setText("Drag finger across screen to draw a Polyline. \nRelease finger to stop drawing.");
                        } else if (geomType.equalsIgnoreCase("Point")) {
                            myListener.setType("POINT");
                            toast.setText("Tap on screen once to draw a Point.");
                        }

                        toast.show();
                    }
                }).create();
    }


    @Override
    protected void onPause() {
        super.onPause();
        mapView.pause();
    }
    @Override   protected void onResume() {
        super.onResume();
        mapView.unpause();
    }

}

main_draw.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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">

  <!-- MapView layout, including basemap layer, initial center point, and zoom level -->
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Button"
        android:id="@+id/geometrybutton"
        android:layout_gravity="center_horizontal" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Button"
        android:id="@+id/clearbutton"
        android:layout_gravity="center_horizontal" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:id="@+id/label"
        android:layout_gravity="center_horizontal" />

    <com.esri.android.map.MapView
    android:id="@+id/map"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    mapoptions.MapType="Topo" />

</LinearLayout>

Sunday, 18 October 2015

HB Blog 98: Go Programming Language - Google's Open Source Project.

Go, also commonly referred to as golang, is a programming language, an open source project developed at Google. It is expressive, concise, clean, and efficient. Its concurrency mechanisms make it easy to write programs that get the most out of multicore and networked machines, while its novel type system enables flexible and modular program construction. Go compiles quickly to machine code yet has the convenience of garbage collection and the power of run-time reflection. It's a fast, statically typed, compiled language that feels like a dynamically typed, interpreted language.
Go was born out of frustration with existing languages and environments for systems programming. Programming had become too difficult and the choice of languages was partly to blame. One had to choose either efficient compilation, efficient execution, or ease of programming; all three were not available in the same mainstream language. Programmers who could were choosing ease over safety and efficiency by moving to dynamically typed languages such as Python and JavaScript rather than C++ or, to a lesser extent, Java.

Go is an attempt to combine the ease of programming of an interpreted, dynamically typed language with the efficiency and safety of a statically typed, compiled language. It also aims to be modern, with support for networked and multicore computing. Finally, it is intended to be fast: it should take at most a few seconds to build a large executable on a single computer. To meet these goals required addressing a number of linguistic issues: an expressive but lightweight type system; concurrency and garbage collection; rigid dependency specification; and so on. These cannot be addressed well by libraries or tools; a new language was called for.

It is a statically-typed language with syntax loosely derived from that of C, adding garbage collection, type safety, some dynamic-typing capabilities, additional built-in types such as variable-length arrays and key-value maps, and a large standard library. Although it borrows ideas from existing languages, it has unusual properties that make effective Go programs different in character from programs written in its relatives. A straightforward translation of a C++ or Java program into Go is unlikely to produce a satisfactory result—Java programs are written in Java, not Go. On the other hand, thinking about the problem from a Go perspective could produce a successful but quite different program. In other words, to write Go well, it's important to understand its properties and idioms. It's also important to know the established conventions for programming in Go, such as naming, formatting, program construction, and so on, so that programs you write will be easy for other Go programmers to understand.
Refer below link to download the Go distribution:-
https://golang.org/dl/

Project structure:-
 Go code must be kept inside a workspace. A workspace is a directory hierarchy with three directories at its root:
    src contains Go source files organized into packages (one package per directory),
    pkg contains package objects, and
    bin contains executable commands.

The go tool builds source packages and installs the resulting binaries to the pkg and bin directories.
The src subdirectory typically contains multiple version control repositories (such as for Git or Mercurial) that track the development of one or more source packages.

To give an idea of how a workspace looks in practice, here's an example:

bin/
    hello                          # command executable
    outyet                         # command executable
pkg/
    linux_amd64/
        github.com/golang/example/
            stringutil.a           # package object
src/
    github.com/golang/example/
        .git/                      # Git repository metadata
    hello/
        hello.go               # command source
    outyet/
        main.go                # command source
        main_test.go           # test source
    stringutil/
        reverse.go             # package source
        reverse_test.go        # test source


This workspace contains one repository (example) comprising two commands (hello and outyet) and one library (stringutil).
A typical workspace would contain many source repositories containing many packages and commands.
Commands and libraries are built from different kinds of source packages.

Check that Go is installed correctly by building a simple program, as follows.
Create a file named hello.go and put the following program in it:
package main
import "fmt"
func main() {
    fmt.Printf("hello, world\n")
}

Then run it with the go tool:
$ go run hello.go
hello, world

If you see the "hello, world" message then your Go installation is working.

An interactive introduction to Go in three sections. The first section covers basic syntax and data structures; the second discusses methods and interfaces; and the third introduces Go's concurrency primitives. Each section concludes with a few exercises so you can practice what you've learned.
Refer below link to download the Go distribution:-
https://tour.golang.org/