Unique Email – Kotlin -Code Challenge

Problem

Every valid email consists of a local name and a domain name, separated by the '@' sign. Besides lowercase letters, the email may contain one or more '.' or '+'.

  • For example, in "alice@leetcode.com""alice" is the local name, and "leetcode.com" is the domain name.

If you add periods '.' between some characters in the local name part of an email address, mail sent there will be forwarded to the same address without dots in the local name. Note that this rule does not apply to domain names.

  • For example, "alice.z@leetcode.com" and "alicez@leetcode.com" forward to the same email address.

If you add a plus '+' in the local name, everything after the first plus sign will be ignored. This allows certain emails to be filtered. Note that this rule does not apply to domain names.

  • For example, "m.y+name@email.com" will be forwarded to "my@email.com".

It is possible to use both of these rules at the same time.

Given an array of strings where we send one email to each email[i], return the number of different addresses that actually receive mails.

Example 1:

Input: emails = ["test.email+alex@leetcode.com","test.e.mail+bob.cathy@leetcode.com","testemail+david@lee.tcode.com"]
Output: 2
Explanation: "testemail@leetcode.com" and "testemail@lee.tcode.com" actually receive mails.

Example 2:

Input: emails = ["a@leetcode.com","b@leetcode.com","c@leetcode.com"]
Output: 3

Simple Kotlin Solution

fun main(args:Array<String>){

        var result = numUniqueEmails(arrayOf("test.email+alex@leetcode.com","test.email.leet+alex@code.com"))
        printResult("Unique Email Count ", result.toString())
}

fun numUniqueEmails(emails: Array<String>): Int {
    var list=ArrayList<String>()

    for (email in emails){
        var localname=email.split("@")[0].split("+")[0].replace(".","")
        var domain=email.split("@")[1]
        if(!list.contains("$localname@$domain")){
            list.add("$localname@$domain")
        }
    }
    return list.size
}

Remove Duplicate – Kotlin Solution

Problem

Given the head of a sorted linked list, delete all duplicates such that each element appears only once. Return the linked list sorted as well.

Example 1:

Input: head = [1,1,2]
Output: [1,2]

Example 2:

Input: head = [1,1,2,3,3]
Output: [1,2,3]


Solution- Kotlin

fun main(args:Array<String>){
    var node1=ListNode(1)
    var node2=ListNode(1)
    var node3=ListNode(2)
//    var node4=ListNode(3)
//    var node5=ListNode(3)
//    node4.next=node5
//    node3.next=node4
    node2.next=node3
    node1.next=node2
    var result = deleteDuplicates(node1)
}



// * Example:
var li = ListNode(5)
var v = li.`val`
//  Definition for singly-linked list.
class ListNode(var `val`: Int) {
    var next: ListNode? = null
}


fun deleteDuplicates(head: ListNode?): ListNode? {

    if (head?.`val`==null) return head

    var result=ListNode(head.`val`)
    var dummy:ListNode=result
    var headNode=head

    while (headNode!=null){
        if(dummy.`val`!=headNode.`val` ){
            dummy.next= ListNode(headNode.`val`)
            dummy=dummy.next!!
        }
        headNode=headNode.next


    }
    return result
}

Square root of x -Sqrt(x) – Kotlin

Problem

Given a non-negative integer x, compute and return the square root of x.

Since the return type is an integer, the decimal digits are truncated, and only the integer part of the result is returned.

Note: You are not allowed to use any built-in exponent function or operator, such as pow(x, 0.5) or x ** 0.5.

Example 1:

Input: x = 4
Output: 2

Example 2:

Input: x = 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since the decimal part is truncated, 2 is returned.

Solution- Kotlin

fun main(args:Array<String>){

        var result = mySqrt(2000000000)
        printResult("Square Root of 2000000000", result.toString())
}


//Using Binary Search
fun mySqrt(x: Int): Int {
    var ans=0
    if(x!=0){
        var start:Long=0
        var end:Long=x.toLong()
        while (start<=end){
            var mid:Long=(start+end)/2

            if(mid*mid<x){
                start=mid+1
                ans=mid.toInt()

            }else if(mid*mid>x){
                end=mid-1
            }else{
                ans=mid.toInt()
                break

            }
        }
    }
    return ans
}

Valid Parentheses – Code Challenge- Kotlin

Problem

Given a sorted array of distinct integers and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

Given a string s containing just the characters ‘(‘, ‘)’, ‘{‘, ‘}’, ‘[‘ and ‘]’, determine if the input string is valid.

An input string is valid if:

Open brackets must be closed by the same type of brackets.
Open brackets must be closed in the correct order.

Example

Example 1:
Input: s = "()"
Output: true

Example 2:
Input: s = "()[]{}"
Output: true

Example 3:
Input: s = "(]"
Output: false

Example 4:
Input: s = "([)]"
Output: false

Example 5:
Input: s = "{[]}"
Output: true

Solution- Kotlin

fun main(args:Array<String>){

    var result= isValid("{[]}")
    printResult("Remove Element ",result.toString())
}

fun isValid(s: String): Boolean {

    var stack=Stack<String>()
    s.forEach {
        when(it.toString()){
            "{"->stack.push("}")

            "("->stack.push(")")
            "["->stack.push("]")
            else-> {
                if(stack.isEmpty()||stack.pop()!=it.toString()){
                    return false
                }
            }
        }

    }

    return stack.isEmpty()
}

Search Insert Position -Binary Search Kotlin

Problem

Given a sorted array of distinct integers and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

You must write an algorithm with O(log n) runtime complexity.

Example

Example 1:
Input: nums = [1,3,5,6], target = 5
Output: 2

Example 2:
Input: nums = [1,3,5,6], target = 2
Output: 1

Example 3:
Input: nums = [1,3,5,6], target = 7
Output: 4

Example 4:
Input: nums = [1,3,5,6], target = 0
Output: 0

Example 5:
Input: nums = [1], target = 0
Output: 0

Solution- Kotlin

fun main(args:Array<String>){

    var result= searchInsert(intArrayOf(1,3,5,6),5)
        printResult("searchInsert",result.toString())
}

//Binary Search
fun searchInsert(nums: IntArray, target: Int): Int {
    var start=0
    var end=nums.size-1

    while (start<=end){
        var mid=(start+end)/2
        if (nums[mid]>target){
            end=mid-1
        }else if(nums[mid]<target){
            start=mid+1
        }else{
            return mid
        }
    }
    return start
}

Shared Preferences With Kotlin

In this tutorial we are going to learn how to use SharedPreferences In our Android Application to Store data in the form of value-key pairs with a simple Kotlin class.

Here w are going to learn how to create a simple custom SharedPreferences.kt class that can be used to every Android application if needed.

Overview

In many cases, we have to use SharedPreferences in our Application such as to store login status, save user-specific data and save application settings.

SharedPreferences is Application specific, so data stored in SharedPreferences can be lost in the following situations

  • By Uninstalling the Application
  • By Clearing application data (Using device settings)

Storing Data with SharedPreferences

Let’s start with the custom SharedPreference.kt class. Create a Kotlin class And Initialise SharedPreferences as shown below.

package com.kotlincodes.sharedpreferenceswithkotlin

import android.content.Context
import android.content.SharedPreferences

/**
 * Created by Kolincodes on 10/05/2018.
 */

class SharedPreference(val context: Context) {
    private val PREFS_NAME = "kotlincodes"
    val sharedPref: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)

}

PREF_NAME is the name of preference file.

Storing Data

To store String, Int and Boolean data we have three methods with the same name and different parameters (Method overloading). Add these methods to your  SharedPreference.kt class.

To Store String data

 
 fun save(KEY_NAME: String, value: Int) {
        val editor: SharedPreferences.Editor = sharedPref.edit()

        editor.putInt(KEY_NAME, value)

        editor.commit()
    }
    

To Store Int data

  
  fun save(KEY_NAME: String, value: Int) {
        val editor: SharedPreferences.Editor = sharedPref.edit()

        editor.putInt(KEY_NAME, value)

        editor.commit()
    }
    

To Store Boolean data

 
 fun save(KEY_NAME: String, status: Boolean) {

        val editor: SharedPreferences.Editor = sharedPref.edit()

        editor.putBoolean(KEY_NAME, status!!)

        editor.commit()
    }

Retrieve Data

To Retrieve the data stored in SharedPreferences use the following methods.

To Retrieve String

 
 fun getValueString(KEY_NAME: String): String? {

        return sharedPref.getString(KEY_NAME, null)
    }

To Retrieve Int

fun getValueInt(KEY_NAME: String): Int {

        return sharedPref.getInt(KEY_NAME, 0)
    }
    

To Retrieve Boolien

 
 fun getValueString(KEY_NAME: String): String? {

        return sharedPref.getString(KEY_NAME, null)
    }
    

Remove and Clear

To clear the entire SharedPreferences use the below code

 
 fun clearSharedPreference() {

        val editor: SharedPreferences.Editor = sharedPref.edit()

        //sharedPref = PreferenceManager.getDefaultSharedPreferences(context);

        editor.clear()
        editor.commit()
    }
    

To remove a specific data

 
 fun removeValue(KEY_NAME: String) {

        val editor: SharedPreferences.Editor = sharedPref.edit()

        editor.remove(KEY_NAME)
        editor.commit()
    }
    

Now we are almost done with all the methods inside our SharedPreference.kt class.
Please find the Complete code for  SharedPreference.kt file below.

SharedPreference.kt

package com.kotlincodes.sharedpreferenceswithkotlin

import android.content.Context
import android.content.SharedPreferences

/**
 * Created by Kolincodes on 10/05/2018.
 */

class SharedPreference(val context: Context) {
    private val PREFS_NAME = "kotlincodes"
    val sharedPref: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)

    fun save(KEY_NAME: String, text: String) {

        val editor: SharedPreferences.Editor = sharedPref.edit()

        editor.putString(KEY_NAME, text)

        editor!!.commit()
    }

    fun save(KEY_NAME: String, value: Int) {
        val editor: SharedPreferences.Editor = sharedPref.edit()

        editor.putInt(KEY_NAME, value)

        editor.commit()
    }

    fun save(KEY_NAME: String, status: Boolean) {

        val editor: SharedPreferences.Editor = sharedPref.edit()

        editor.putBoolean(KEY_NAME, status!!)

        editor.commit()
    }

    fun getValueString(KEY_NAME: String): String? {

        return sharedPref.getString(KEY_NAME, null)


    }

    fun getValueInt(KEY_NAME: String): Int {

        return sharedPref.getInt(KEY_NAME, 0)
    }

    fun getValueBoolien(KEY_NAME: String, defaultValue: Boolean): Boolean {

        return sharedPref.getBoolean(KEY_NAME, defaultValue)

    }

    fun clearSharedPreference() {

        val editor: SharedPreferences.Editor = sharedPref.edit()

        //sharedPref = PreferenceManager.getDefaultSharedPreferences(context);

        editor.clear()
        editor.commit()
    }

    fun removeValue(KEY_NAME: String) {

        val editor: SharedPreferences.Editor = sharedPref.edit()

        editor.remove(KEY_NAME)
        editor.commit()
    }
}

Implement in our Application

N we are going to implement our SharedPreference.kt class in a Simple Android Application.

The Image below Shows the Final output of the project

Setup Layout

The Layout for our MainActivity.kt class is shown below.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_margin="12dp"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/edt_name"
        android:layout_margin="6dp"
        android:hint="Name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"

        />
    <EditText
        android:id="@+id/edt_email"
        android:layout_margin="6dp"
        android:hint="Email"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"

        />
    <LinearLayout
        android:layout_marginTop="12dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/btn_save"
            android:layout_weight="1"
            android:text="Save"
            android:layout_width="0dp"
            android:layout_height="wrap_content" />
        <Button
            android:id="@+id/btn_retriev"
            android:layout_weight="1"
            android:text="Retrieve"
            android:layout_width="0dp"
            android:layout_height="wrap_content" />
        <Button
            android:id="@+id/btn_clear"
            android:layout_weight="1"
            android:text="Clear"
            android:layout_width="0dp"
            android:layout_height="wrap_content" />

    </LinearLayout>
</LinearLayout>

Setup MainActivity

Our Application have only one page with two EditText and Three Button.

First we Initialize our SharedPreferece.kt class in our MainActivity by

val sharedPreference:SharedPreference=SharedPreference(this)

On Save button click We stores EditText values into SharedPreferences.

On Retrieve Button click we Retrieve the saved data from SharedPreferences and set this data as the EditText hint.

On Clear button click we clear all the data from shared preferences.

Our MainActivity.kt class is given below.

package com.kotlincodes.sharedpreferenceswithkotlin

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast

class MainActivity : AppCompatActivity() {

    lateinit var edtName:EditText
    lateinit var edtEmail:EditText
    lateinit var btnSave:Button
    lateinit var btnRetrive:Button
    lateinit var btnClear:Button
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val sharedPreference:SharedPreference=SharedPreference(this)

        edtName=findViewById(R.id.edt_name)
        edtEmail=findViewById(R.id.edt_email)
        btnClear=findViewById(R.id.btn_clear)
        btnSave=findViewById(R.id.btn_save)
        btnRetrive=findViewById(R.id.btn_retriev)

        btnSave.setOnClickListener {

            val name=edtName.editableText.toString()
            val email=edtEmail.editableText.toString()
            sharedPreference.save("name",name)
            sharedPreference.save("email",email)
            Toast.makeText(this@MainActivity,"Data Stored",Toast.LENGTH_SHORT).show()
            //to save an Int
//            sharedPreference.save("intval",1)

            //to save boolien
//            sharedPreference.save("bool",true)
            
        }
        btnRetrive.setOnClickListener {
            if (sharedPreference.getValueString("name")!=null) {
                edtName.hint = sharedPreference.getValueString("name")!!
                Toast.makeText(this@MainActivity,"Data Retrieved",Toast.LENGTH_SHORT).show()
            }else{
                edtName.hint="NO value found"
            }
            if (sharedPreference.getValueString("email")!=null) {
                edtEmail.hint = sharedPreference.getValueString("email")!!
            }else{
                edtEmail.hint="No value found"
            }


        }

        btnClear.setOnClickListener {
            sharedPreference.clearSharedPreference()
            Toast.makeText(this@MainActivity,"Data Cleared",Toast.LENGTH_SHORT).show()
        }
    }
}

That’s it! Now run the project!

The full source code is available here.

Thanks for reading!


LocationListener With Kotlin

Many of the android applications we uses in daily life  needs users current locations continuously,   Here we are going to implement LocationListener with Kotlin using FusedLocationProviderClient . We have previously used FusedLocationProviderApi which is deprecated now.

Add the permissions & Dependency

To access the location from the device add the following permissions to the manifest.xml file .

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

Add the following dependencies into app level  build.gradle ( Module:app) file.

implementation ‘com.google.android.gms:play-services-location:16.0.0’

Setup the Layout file

Setup layout file for our home screen. It has two Buttons and three TextViews as shown below

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_start_upds"
        android:layout_width="match_parent"
        android:layout_marginRight="12dp"
        android:layout_marginLeft="12dp"
        android:layout_marginTop="24dp"
        android:layout_height="wrap_content"
        android:text="Start Location UPDates" />
    <Button
        android:enabled="false"
        android:id="@+id/btn_stop_upds"
        android:layout_width="match_parent"
        android:layout_marginRight="12dp"
        android:layout_marginLeft="12dp"
        android:layout_height="wrap_content"
        android:text="Stop Location UPDates" />


    <TextView
        android:padding="12dp"
        android:layout_marginTop="12dp"
        android:textSize="18sp"
        android:layout_marginRight="12dp"
        android:layout_marginLeft="12dp"
        android:layout_width="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_height="wrap_content"
        android:id="@+id/txtLat"
        />
    <TextView
        android:padding="12dp"
        android:layout_gravity="center_horizontal"
        android:textSize="18sp"
        android:layout_marginRight="12dp"
        android:layout_marginLeft="12dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/txtLong"
        />
    <TextView
        android:layout_gravity="center_horizontal"
        android:padding="12dp"
        android:textSize="18sp"
        android:layout_marginRight="12dp"
        android:layout_marginLeft="12dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/txtTime" />
    
</LinearLayout>

Setup the MainActivity

Here we are going to learn how to implement location Listener in our MainActivity.kt Class with all details.

First we have to initialize

Check Permissions

From android version 6 (Marshmallow ) user have to accept all the permissions in run time. So we have to check whether used accepted all the permissions needed in run time .

We have added the permissions in manifest file already now to show the Runtime permission, You should do the following method.

  
  fun checkPermissionForLocation(context: Context): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            if (context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) ==
                    PackageManager.PERMISSION_GRANTED){
                true
            }else{
                // Show the permission request
                ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
                        REQUEST_PERMISSION_LOCATION)
                false
            }
        } else {
            true
        }
    }
    

Now we have to implement onRequestPermissionsResult method to check if the permission is granted or not by the user.

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    if (requestCode == REQUEST_PERMISSION_LOCATION) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    //We have to add startlocationUpdate() method later instead of Toast
            Toast.makeText(this,"Permission granted",Toast.LENGTH_SHORT).show()
        }
    }
}

Check Location is ON

To check location is on we have to add the following code to our project.

private fun buildAlertMessageNoGps() {

    val builder = AlertDialog.Builder(this)
    builder.setMessage("Your GPS seems to be disabled, do you want to enable it?")
            .setCancelable(false)
            .setPositiveButton("Yes") { dialog, id ->
startActivityForResult(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
                        , 11)
            }
.setNegativeButton("No") { dialog, id ->
dialog.cancel()
                finish()
            }
val alert: AlertDialog  = builder.create()
    alert.show()


}

Setup LocationListener

Now we are going to setup the LocationListener using startLocationUpdates() method. Before that we have to add a LocationCallback as given below.

  
  private val mLocationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult) {
            // do work here
            locationResult.lastLocation
            onLocationChanged(locationResult.lastLocation)
        }
    }

    fun onLocationChanged(location: Location) {
        // New location has now been determined

       mLastLocation = location
        if (mLastLocation != null) {
// Update the UI from here
        }

        
    }
    

Now Add startLocationUpdates() method to your code as follows

 
 protected fun startLocationUpdates() {

        // Create the location request to start receiving updates
        mLocationRequest = LocationRequest()
        mLocationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        mLocationRequest!!.setInterval(INTERVAL)
        mLocationRequest!!.setFastestInterval(FASTEST_INTERVAL)

        // Create LocationSettingsRequest object using location request
        val builder = LocationSettingsRequest.Builder()
        builder.addLocationRequest(mLocationRequest!!)
        val locationSettingsRequest = builder.build()

        val settingsClient = LocationServices.getSettingsClient(this)
        settingsClient.checkLocationSettings(locationSettingsRequest)

        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
        // new Google API SDK v11 uses getFusedLocationProviderClient(this)
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {


            return
        }
        mFusedLocationProviderClient!!.requestLocationUpdates(mLocationRequest, mLocationCallback,
                Looper.myLooper())
    }
    

To Stop Location Updates add the following

 
 private fun stoplocationUpdates() {
        mFusedLocationProviderClient!!.removeLocationUpdates(mLocationCallback)
    }
    

Now we are all set to run the project. Please find the Complete code for MainActivity.kt file below.

MainActivity.kt

package com.kotlincodes.locationlistenerwithkotlin

import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationManager
import android.os.Build
import android.os.Bundle
import android.os.Looper
import android.provider.Settings
import android.support.v4.app.ActivityCompat
import android.support.v7.app.AlertDialog
import android.support.v7.app.AppCompatActivity
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import com.google.android.gms.location.*
import java.text.SimpleDateFormat
import java.util.*


class MainActivity : AppCompatActivity() {
    private var mFusedLocationProviderClient: FusedLocationProviderClient? = null
    private val INTERVAL: Long = 2000
    private val FASTEST_INTERVAL: Long = 1000
    lateinit var mLastLocation: Location
    internal lateinit var mLocationRequest: LocationRequest
    private val REQUEST_PERMISSION_LOCATION = 10

    lateinit var btnStartupdate: Button
    lateinit var btnStopUpdates: Button
    lateinit var txtLat: TextView
    lateinit var txtLong: TextView
    lateinit var txtTime: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mLocationRequest = LocationRequest()

        btnStartupdate = findViewById(R.id.btn_start_upds)
        btnStopUpdates = findViewById(R.id.btn_stop_upds)
        txtLat = findViewById(R.id.txtLat);
        txtLong = findViewById(R.id.txtLong);
        txtTime = findViewById(R.id.txtTime);

        val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
        if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            buildAlertMessageNoGps()
        }


        btnStartupdate.setOnClickListener {
            if (checkPermissionForLocation(this)) {
                startLocationUpdates()
                btnStartupdate.isEnabled = false
                btnStopUpdates.isEnabled = true
            }
        }

        btnStopUpdates.setOnClickListener {
            stoplocationUpdates()
            txtTime.text = "Updates Stoped"
            btnStartupdate.isEnabled = true
            btnStopUpdates.isEnabled = false
        }

    }

    private fun buildAlertMessageNoGps() {

        val builder = AlertDialog.Builder(this)
        builder.setMessage("Your GPS seems to be disabled, do you want to enable it?")
                .setCancelable(false)
                .setPositiveButton("Yes") { dialog, id ->
                    startActivityForResult(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
                            , 11)
                }
                .setNegativeButton("No") { dialog, id ->
                    dialog.cancel()
                    finish()
                }
        val alert: AlertDialog = builder.create()
        alert.show()


    }


    protected fun startLocationUpdates() {

        // Create the location request to start receiving updates

        mLocationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        mLocationRequest!!.setInterval(INTERVAL)
        mLocationRequest!!.setFastestInterval(FASTEST_INTERVAL)

        // Create LocationSettingsRequest object using location request
        val builder = LocationSettingsRequest.Builder()
        builder.addLocationRequest(mLocationRequest!!)
        val locationSettingsRequest = builder.build()

        val settingsClient = LocationServices.getSettingsClient(this)
        settingsClient.checkLocationSettings(locationSettingsRequest)

        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
        // new Google API SDK v11 uses getFusedLocationProviderClient(this)
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {


            return
        }
        mFusedLocationProviderClient!!.requestLocationUpdates(mLocationRequest, mLocationCallback,
                Looper.myLooper())
    }

    private val mLocationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult) {
            // do work here
            locationResult.lastLocation
            onLocationChanged(locationResult.lastLocation)
        }
    }

    fun onLocationChanged(location: Location) {
        // New location has now been determined

        mLastLocation = location
        val date: Date = Calendar.getInstance().time
        val sdf = SimpleDateFormat("hh:mm:ss a")
        txtTime.text = "Updated at : " + sdf.format(date)
        txtLat.text = "LATITUDE : " + mLastLocation.latitude
        txtLong.text = "LONGITUDE : " + mLastLocation.longitude
        // You can now create a LatLng Object for use with maps
    }

    private fun stoplocationUpdates() {
        mFusedLocationProviderClient!!.removeLocationUpdates(mLocationCallback)
    }


    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        if (requestCode == REQUEST_PERMISSION_LOCATION) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                startLocationUpdates()
                btnStartupdate.isEnabled = false
                btnStopUpdates.isEnabled = true
            } else {
                Toast.makeText(this@MainActivity, "Permission Denied", Toast.LENGTH_SHORT).show()
            }
        }
    }

    fun checkPermissionForLocation(context: Context): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            if (context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) ==
                    PackageManager.PERMISSION_GRANTED) {
                true
            } else {
                // Show the permission request
                ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
                        REQUEST_PERMISSION_LOCATION)
                false
            }
        } else {
            true
        }
    }

}

That’s it! Now run the project!

The full source code is available here.

Thanks for reading!


RecyclerView With Kotlin – Android

We know that if we need to display a scrolling list of elements based on a large set of data sets which may frequently change we should use RecyclerView.

RecyclerView is a much-advanced version of ListView with a lot of improvements made. You might have Implemented RecyclerView in android with Java but here we are going to learn how to implement a RecyclerView with Kotlin.

Lets go for a detailed tutorial for implementation of RecyclerView with Kotlin Android.

Import the following dependency to the app level build.gradle to add the RecyclerView In your project.


implementation ‘com.android.support:recyclerview-v7:27.1.1’

N we are going to set up the MainActivity layout file activity_main.xml. The Layout consists of a RecyclerView as given below.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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=".activity.MainActivity">

   <android.support.v7.widget.RecyclerView
       android:id="@+id/recycler_view"
       android:layout_width="match_parent"
       android:layout_height="wrap_content">

   </android.support.v7.widget.RecyclerView>

</android.support.constraint.ConstraintLayout>

Now we are going to set up a list_item_view for RecyclerView which includes only one TextView. The layout file is given below.

list_item_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/title"
        android:textSize="18sp"
        android:padding="6dp"
        android:maxLines="1"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <View
        android:background="#000"
        android:layout_width="match_parent"
        android:layout_height="1dp"/>

</LinearLayout>

To populate our data with RecyclerView, We need a RecyclerViewAdapter class RecyclerViewAdapter.kt. Which is given below. This class inherited from RecyclerView.Adapter() . It has three abstract methods.

  • getItemCount(): Returns the total number of items in the data set held by the adapter. In our project, we return the size of our dataList Array.
  • onCreateViewHolder(parent : ViewGroup, viewType:int) ; Viewholder :
    This method onCreateViewHolder(ViewGroup, int) create a RecyclerView.ViewHolder initializes some private fields to be used by RecyclerView.
  • onBindViewHolder(holder:,position :int) :
    This method internally onBindViewHolder(ViewHolder, int) update RecyclerView.ViewHolder with the item at the given position and also sets up some private fields to be used by RecyclerView.  in this method we can set up our TextView or any other  Views with our data.

Our RecyclerViewAdapter.kt is shown below.

RecyclerViewAdapter.kt

import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.TextureView
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.shrishtionline.recyclerviewwithkotlin.R

class RecyclerViewAdapter(private var context: Context,private var dataList:ArrayList<String>):RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {
    override fun getItemCount(): Int {
        return dataList.size;
    }
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(LayoutInflater.from(context).inflate(R.layout.list_item_view, parent, false))
    }

    override fun onBindViewHolder(holder:ViewHolder, position: Int) {
        holder.textView.text=dataList.get(position);
    }


    class ViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView) {
        var textView:TextView =itemView!!.findViewById(R.id.text_view)
    }
}

Now we need to set up our MainActivity.kt class.

  • The class includes a function addAnimals() to add some data to our list.

MainActivity.kt

package com.shrishtionline.recyclerviewwithkotlin

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView

class MainActivity : AppCompatActivity() {

    lateinit var recyclerView: RecyclerView
    lateinit var adapter: RecyclerViewAdapter
    var dataList:ArrayList<String> = ArrayList();

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //Initializing RecyclerView
        recyclerView=findViewById(R.id.recycler_view)


        adapter= RecyclerViewAdapter(this,dataList)

        //Set up recyclerview with Vertical LayoutManager and the adapter

        recyclerView.layoutManager=LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false)

        //Adding animal names
        addAnimals();

        // Notify the adapter for data change.
        adapter.notifyDataSetChanged()

    }

    private fun addAnimals() {
        dataList!!.add("Dog")
        dataList!!.add("Cat")
        dataList!!.add("Monkey")
        dataList!!.add("lion")
        dataList!!.add("Elephent")
        dataList!!.add("Cheetah")
        dataList!!.add("Snake")
        dataList!!.add("Cow")
        dataList!!.add("Ant")
        dataList!!.add("Tiger")
        dataList!!.add("Lizard")

    }
}

That’s it! Now run the project!

The full source code is available here.

Thanks for reading!


Retrofit with Kotlin-Android

In this tutorial we will learn how to implement Retrofit HTTP client in Android with Kotlin.

Retrofit is a powerful HTTP client for an Android and Java built by awesome folks at Square . Retrofit Configured with convertors makes it easy to serialize structured data sets. Typically for JSON  we uses Gson convertors to serialization and De-serialization process.

Retrofit uses the Okhttp library for for HTTP requests.

Please find the sample project given below.

  • Open your project and add dependencies into app level  build.gradle ( Module:app) file.  Here we adds Gson,RecyclerView,CardView,Piccasso and Retrofit libraries
dependencies {
    ...

    implementation 'com.google.code.gson:gson:2.8.4'
    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.8.0'
    implementation "com.android.support:cardview-v7:27.1.1"
    implementation 'com.android.support:recyclerview-v7:27.1.1'
    implementation 'com.squareup.picasso:picasso:2.71828'

    ...
}
  • Make sure you have added the INTERNET permission in AndroidManifest.xml file like this.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="kotlincodes.com.retrofitwithkotlin">
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".activity.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
  • Next we need to create data model to parse our sample Json response . The sample response is given below.
Sample response

  • Now Create a Kotlin Class named DataModel.kt under model package like shown below.

DataModel.kt 

package kotlincodes.com.retrofitwithkotlin.model

import com.google.gson.annotations.Expose
import com.google.gson.annotations.SerializedName


data class DataModel(

        @Expose
        @SerializedName("albumId")
        val albumid: Integer,
        @Expose
        @SerializedName("id")
        val id: Integer,
        @Expose
        @SerializedName("title")
        val title: String,
        @Expose
        @SerializedName("url")
        val url: String,
        @Expose
        @SerializedName("thumbnailUrl")
        val thumbnailurl: String
)
  • Now create a retrofit instance to make a network request to a REST API with Retrofit.
  • Here we creates a Kotlin object ApiClient.kt under retrofit package.
  • The BASE_URL is the basic URL of your API where we will make a call

ApiClient.kt

import com.google.gson.GsonBuilder
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object ApiClient {

    var BASE_URL:String="https://jsonplaceholder.typicode.com/"
    val getClient: ApiInterface
        get() {

            val gson = GsonBuilder()
                    .setLenient()
                    .create()
            val interceptor = HttpLoggingInterceptor()
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
            val client = OkHttpClient.Builder().addInterceptor(interceptor).build()

            val retrofit = Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .client(client)
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .build()

            return retrofit.create(ApiInterface::class.java)

        }

}
  • Define End Points : Now we create an interface ApiInterface.kt under retrofit package to define the api end points

ApiInterface.kt

import kotlincodes.com.retrofitwithkotlin.model.DataModel
import retrofit2.Call
import retrofit2.http.GET

interface ApiInterface {

    @GET("photos")
    fun getPhotos(): Call<List<DataModel>>

}
  • Set up MainActivity Class
  • Now we are all set to make an api call in MainActivity.kt .
  • getData() method is used to make HTTP request using Retrofit
  • Here we fetch data and populate it in to a RecyclerView ,  the RecyclerViewAdapter DataAdapter and RecyclerView layouts are described later.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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=".activity.MainActivity">

   <android.support.v7.widget.RecyclerView
       android:id="@+id/recycler_view"
       android:layout_width="match_parent"
       android:layout_height="wrap_content">

   </android.support.v7.widget.RecyclerView>

</android.support.constraint.ConstraintLayout>

MainActivity.kt 

class MainActivity : AppCompatActivity() {

    lateinit var progerssProgressDialog: ProgressDialog
    var dataList = ArrayList<DataModel>()
    lateinit var recyclerView: RecyclerView
    lateinit var adapter:DataAdpter
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        recyclerView = findViewById(R.id.recycler_view)

        //setting up the adapter
        recyclerView.adapter= DataAdpter(dataList,this)
        recyclerView.layoutManager=LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false)

        progerssProgressDialog=ProgressDialog(this)
        progerssProgressDialog.setTitle("Loading")
        progerssProgressDialog.setCancelable(false)
        progerssProgressDialog.show()
        getData()

    }

    private fun getData() {
        val call: Call<List<DataModel>> = ApiClient.getClient.getPhotos()
        call.enqueue(object : Callback<List<DataModel>> {

            override fun onResponse(call: Call<List<DataModel>>?, response: Response<List<DataModel>>?) {
                progerssProgressDialog.dismiss()
                dataList.addAll(response!!.body()!!)
                recyclerView.adapter.notifyDataSetChanged()
            }

            override fun onFailure(call: Call<List<DataModel>>?, t: Throwable?) {
                progerssProgressDialog.dismiss()
            }

        })
    }


}
  • Set up RecyclerView 
  • To set up RecyclerView we need a list layout and RecyclerView.Adapter DataAdapter.kt as given below.
  • The layout includes only a text view to show the title.

list_item_home.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_margin="6dp"
    app:contentPadding="12dp"
    android:layout_height="wrap_content">

    <TextView
        android:maxLines="1"
        android:id="@+id/title"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</android.support.v7.widget.CardView>

DataAdapter.kt

package kotlincodes.com.retrofitwithkotlin.adapters

import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import kotlincodes.com.retrofitwithkotlin.R
import kotlincodes.com.retrofitwithkotlin.model.DataModel

class DataAdpter(private var dataList: List<DataModel>, private val context: Context) : RecyclerView.Adapter<DataAdpter.ViewHolder>() {


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(LayoutInflater.from(context).inflate(R.layout.list_item_home, parent, false))
    }

    override fun getItemCount(): Int {
       return dataList.size
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val dataModel=dataList.get(position)

        holder.titleTextView.text=dataModel.title
    }


    class ViewHolder(itemLayoutView: View) : RecyclerView.ViewHolder(itemLayoutView) {
        lateinit var titleTextView:TextView
        init {
            titleTextView=itemLayoutView.findViewById(R.id.title)

        }

    }

}

Now we are all done. We have how to implement Retrofit with Kotlin and Implantation of   You can also find the Source the project from 


Get Started with Kotlin in Android studio

Kotlin is fully supported with android studio v3.0 and Higher.

  • Setup Kotlin to Android Studio

Important : The android studio version must be 3.0 or higher

To add Kotlin support to the android studio we need to install the Kotlin plugin for your Android Studio.

To add the Kotlin plugin open

Android Studio File → Settings  → Plugins →type “Kotlin” in search box → Click Browse in Repositories → install →  Restart Android studio to activate the Plugin

 

Add Kotlin to the existing project

Add classpath in project level build.gradle.

Also here defined a variable kotlin_version as ext.kotlin_version = ‘1.2.41’ to share the version to all.

<// Top-level build file where you can add configuration options common to all sub-projects/modules.

    buildscript {
        ext.kotlin_version = '1.2.41'
        repositories {
            google()
            jcenter()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.0.1'
            classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

            // NOTE: Do not place your application dependencies here; they belong
            // in the individual module build.gradle files
        }
    }

    allprojects {
        repositories {
            google()
            jcenter()
        }
    }

    task clean(type: Delete) {
        delete rootProject.buildDir
    }

2. Add dependencies to app level build.gradle

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

dependencies {

implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

} 

 

Create a new project with Kotlin

Open android studio then click File –> New project you will get a window like below

Mark Include Kotlin Support 

Press Next–>Opens a page to select minimum SDK version — select API v15

Press Next –>Opens a page to select the default activity type — Choose Empty Activity from the list

Press Next –> Opens a page to change the default activity name

Press Finish — >Opens A new Android Project with Kotlin Support.