Blog

Simple SharedPreference Functions – Kotlin

Android provides many ways of storing data of an application. One of these ways is called Shared Preferences. Shared Preferences allow you to save and retrieve data in the form of key, value pair.

Here I share a simple custom SharedPreferences.kt class that can be used for every Android application if needed.

import android.content.Context
import android.content.SharedPreferences
import com.securepreferences.SecurePreferences

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

class SharedPreference(val context: Context) {
    private val PREFS_NAME = "your_app_preference_name"

    private 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()
    }

}

You can find the Github repo for this class here

Room Database with Kotlin

Room is a persistence library, part of the Android Jetpack.
The Room is now considered as a better approach for data storing than SQLiteDatabase.
The Room persistence library provides an abstraction layer over SQLite to allow for more robust database access while harnessing the full power of SQLite.

Why Room?

  • Compile-time verification of SQL queries.
  • You need to use lots of boilerplate code to convert between SQL queries and Java/Kotlin data objects. But, Room maps our database objects to Java Object without boilerplate code.
  • Room is built to work with Live data and RxJava

Room has 3 main components

  1. Entity: Represents table within the database. We can create a table in room database using @Entity annotation
  2. Dao: Contains all the methods used for accessing data from the database.
  3. Database: Contains the database holder and serves as the main access point for the underlying connection to your app’s persisted, relational data.

Implementation

To add Room database add the below lines into your app-level build.gradle file

implementation "androidx.room:room-runtime:2.2.4"
kapt "androidx.room:room-compiler:2.2.4"
implementation "androidx.room:room-ktx:2.2.4"

Don’t forget to add apply plugin: ‘kotlin-kapt’ in top your app-level build.gradle file

Creating Model Class

Room creates a table for each model class annotated with @Entity, the fields in the class correspond to a column in the table. Therefore each entity class tends to be a small model class contains no logic.

We are going to create a small class User represents a model for the data in the database.

Create a model class as shown below.

package com.kotlincodes.roomdatabasekotlin.model

import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "users")
data class UserModel (
    @PrimaryKey(autoGenerate = true)
    var id:Int,
    var name:String,
    var mobile:String,
    var age:Int
)

Creating DAOs (Data Access Object)

DAOs contain all methods that are used to access data from database.

To create a DAO we need to create an interface annotated with @Dao

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.kotlincodes.roomdatabasekotlin.model.UserModel

@Dao
interface UserDao {

    @Insert
    fun insert(user:UserModel)

    @Update
    fun update(user:UserModel)

    @Update
    fun delete(user:UserModel)

    @Query("SELECT * FROM USERS")
    fun getAllUsers():List<UserModel>

    @Query("SELECT * FROM USERS WHERE id==:id")
    fun getUserWithId(id:Int):UserModel
}

Creating Database

To create a database we need to define an abstract class that extends RoomDatabase. This class is annotated with @Database, lists the entities contained in the database, and the DAOs which access them.

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import com.kotlincodes.roomdatabasekotlin.model.UserModel


@Database(entities = [UserModel::class], version =1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
    abstract fun users():UserDao


    companion object {
        private var INSTANCE: AppDatabase? = null
        fun getAppDatabase(context: Context): AppDatabase? {
            if (INSTANCE == null) {
                INSTANCE = Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java, "room-kotlin-database"
                ).build()
            }
            return INSTANCE
        }

        fun destroyInstance() {
            INSTANCE = null
        }
    }
}

Now we are ready to access the database using Room.

Make sure that you are not performing any database operations on the main thread. We need to execute all database operations in a separate thread otherwise the application will crash.

Initialize

val locaDb= AppDatabase.getAppDatabase(this)!!

Insert

locaDb.users().insert(user)

Update

locaDb.users().update(user)

Delete

locaDb.users().update(user)

That’s it!! I have created a repo with a small project with Room database operations Here

Bluetooth Printer In Android

1 Open Android Studio.
 2 Go to File => New => New Project. Write application name . Then, check Include Kotlin Support and click next button.
 3Select minimum SDK you need. However, we have selected 17 as minimum SDK. Then, click next button
 4 Then, select Empty Activity => click next => click finish.
 5 You will get a newly created project successfully if you have followed steps properly.




Main.java

        import java.io.IOException;
        import java.io.OutputStream;
        import java.nio.ByteBuffer;
        import java.util.Set;
        import java.util.UUID;

        import android.app.Activity;
        import android.app.ProgressDialog;
        import android.bluetooth.BluetoothAdapter;
        import android.bluetooth.BluetoothDevice;
        import android.bluetooth.BluetoothSocket;
        import android.content.Intent;
        import android.os.Bundle;
        import android.os.Handler;
        import android.os.Message;
        import android.util.Log;
        import android.view.View;
        import android.view.Window;
        import android.view.WindowManager;
        import android.widget.Button;
        import android.widget.Toast;

        public class Main extends Activity implements Runnable {
            protected static final String TAG = "TAG";
            private static final int REQUEST_CONNECT_DEVICE = 1;
            private static final int REQUEST_ENABLE_BT = 2;
            Button mScan, mPrint, mDisc;
            BluetoothAdapter mBluetoothAdapter;
            private UUID applicationUUID = UUID
                    .fromString("00001101-0000-1000-8000-00805F9B34FB");
            private ProgressDialog mBluetoothConnectProgressDialog;
            private BluetoothSocket mBluetoothSocket;
            BluetoothDevice mBluetoothDevice;

            @Override
            public void onCreate(Bundle mSavedInstanceState) {
                super.onCreate(mSavedInstanceState);
                requestWindowFeature(Window.FEATURE_NO_TITLE);
                getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                        WindowManager.LayoutParams.FLAG_FULLSCREEN);
                setContentView(R.layout.main);
                mScan = (Button) findViewById(R.id.Scan);
                mScan.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View mView) {
                        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
                        if (mBluetoothAdapter == null) {
                            Toast.makeText(Main.this, "Message1", 2000).show();
                        } else {
                            if (!mBluetoothAdapter.isEnabled()) {
                                Intent enableBtIntent = new Intent(
                                        BluetoothAdapter.ACTION_REQUEST_ENABLE);
                                startActivityForResult(enableBtIntent,
                                        REQUEST_ENABLE_BT);
                            } else {
                                ListPairedDevices();
                                Intent connectIntent = new Intent(Main.this,
                                        DeviceListActivity.class);
                                startActivityForResult(connectIntent,
                                        REQUEST_CONNECT_DEVICE);
                            }
                        }
                    }
                });

                mPrint = (Button) findViewById(R.id.mPrint);
                mPrint.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View mView) {
                        Thread t = new Thread() {
                            public void run() {
                                try {
                                    OutputStream os = mBluetoothSocket
                                            .getOutputStream();
                                    String BILL = "";

                                    BILL = "\nInvoice No: 00000000000000000 " + "    "
                                            + "04-08-2011\n";
                                    BILL = BILL
                                            + "-----------------------------------------";
                                    BILL = BILL + "\n\n";
                                    BILL = BILL + "Total Qty:" + "      " + "1.0\n";
                                    BILL = BILL + "Total Value:" + "     "
                                            + "80000.0\n";
                                    BILL = BILL
                                            + "-----------------------------------------\n";
                                    os.write(BILL.getBytes());
                                        //This is printer specific code you can comment ==== > Start

                                    // Setting height
                                    int gs = 29;
                                    os.write(intToByteArray(gs));
                                    int h = 104;
                                    os.write(intToByteArray(h));
                                    int n = 162;
                                    os.write(intToByteArray(n));

                                    // Setting Width
                                    int gs_width = 29;
                                    os.write(intToByteArray(gs_width));
                                    int w = 119;
                                    os.write(intToByteArray(w));
                                    int n_width = 2;
                                    os.write(intToByteArray(n_width));

                                    // Print BarCode
                                    int gs1 = 29;
                                    os.write(intToByteArray(gs1));
                                    int k = 107;
                                    os.write(intToByteArray(k));
                                    int m = 73;
                                    os.write(intToByteArray(m));

                                    String barCodeVal = "ASDFC028060000005";// "HELLO12345678912345012";
                                    System.out.println("Barcode Length : "
                                            + barCodeVal.length());
                                    int n1 = barCodeVal.length();
                                    os.write(intToByteArray(n1));

                                    for (int i = 0; i < barCodeVal.length(); i++) {
                                        os.write((barCodeVal.charAt(i) + "").getBytes());
                                    }
       //printer specific code you can comment ==== > End
                                } catch (Exception e) {
                                    Log.e("Main", "Exe ", e);
                                }
                            }
                        };
                        t.start();
                    }
                });

                mDisc = (Button) findViewById(R.id.dis);
                mDisc.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View mView) {
                        if (mBluetoothAdapter != null)
                            mBluetoothAdapter.disable();
                    }
                });

            }// onCreate

            @Override
            protected void onDestroy() {
                // TODO Auto-generated method stub
                super.onDestroy();
                try {
                    if (mBluetoothSocket != null)
                        mBluetoothSocket.close();
                } catch (Exception e) {
                    Log.e("Tag", "Exe ", e);
                }
            }

            @Override
            public void onBackPressed() {
                try {
                    if (mBluetoothSocket != null)
                        mBluetoothSocket.close();
                } catch (Exception e) {
                    Log.e("Tag", "Exe ", e);
                }
                setResult(RESULT_CANCELED);
                finish();
            }

            public void onActivityResult(int mRequestCode, int mResultCode,
                    Intent mDataIntent) {
                super.onActivityResult(mRequestCode, mResultCode, mDataIntent);

                switch (mRequestCode) {
                case REQUEST_CONNECT_DEVICE:
                    if (mResultCode == Activity.RESULT_OK) {
                        Bundle mExtra = mDataIntent.getExtras();
                        String mDeviceAddress = mExtra.getString("DeviceAddress");
                        Log.v(TAG, "Coming incoming address " + mDeviceAddress);
                        mBluetoothDevice = mBluetoothAdapter
                                .getRemoteDevice(mDeviceAddress);
                        mBluetoothConnectProgressDialog = ProgressDialog.show(this,
                                "Connecting...", mBluetoothDevice.getName() + " : "
                                        + mBluetoothDevice.getAddress(), true, false);
                        Thread mBlutoothConnectThread = new Thread(this);
                        mBlutoothConnectThread.start();
                        // pairToDevice(mBluetoothDevice); This method is replaced by
                        // progress dialog with thread
                    }
                    break;

                case REQUEST_ENABLE_BT:
                    if (mResultCode == Activity.RESULT_OK) {
                        ListPairedDevices();
                        Intent connectIntent = new Intent(Main.this,
                                DeviceListActivity.class);
                        startActivityForResult(connectIntent, REQUEST_CONNECT_DEVICE);
                    } else {
                        Toast.makeText(Main.this, "Message", 2000).show();
                    }
                    break;
                }
            }

            private void ListPairedDevices() {
                Set<BluetoothDevice> mPairedDevices = mBluetoothAdapter
                        .getBondedDevices();
                if (mPairedDevices.size() > 0) {
                    for (BluetoothDevice mDevice : mPairedDevices) {
                        Log.v(TAG, "PairedDevices: " + mDevice.getName() + "  "
                                + mDevice.getAddress());
                    }
                }
            }

            public void run() {
                try {
                    mBluetoothSocket = mBluetoothDevice
                            .createRfcommSocketToServiceRecord(applicationUUID);
                    mBluetoothAdapter.cancelDiscovery();
                    mBluetoothSocket.connect();
                    mHandler.sendEmptyMessage(0);
                } catch (IOException eConnectException) {
                    Log.d(TAG, "CouldNotConnectToSocket", eConnectException);
                    closeSocket(mBluetoothSocket);
                    return;
                }
            }

            private void closeSocket(BluetoothSocket nOpenSocket) {
                try {
                    nOpenSocket.close();
                    Log.d(TAG, "SocketClosed");
                } catch (IOException ex) {
                    Log.d(TAG, "CouldNotCloseSocket");
                }
            }

            private Handler mHandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    mBluetoothConnectProgressDialog.dismiss();
                    Toast.makeText(Main.this, "DeviceConnected", 5000).show();
                }
            };

            public static byte intToByteArray(int value) {
                byte[] b = ByteBuffer.allocate(4).putInt(value).array();

                for (int k = 0; k < b.length; k++) {
                    System.out.println("Selva  [" + k + "] = " + "0x"
                            + UnicodeFormatter.byteToHex(b[k]));
                }

                return b[3];
            }

            public byte[] sel(int val) {
                ByteBuffer buffer = ByteBuffer.allocate(2);
                buffer.putInt(val);
                buffer.flip();
                return buffer.array();
            }

        }

UnicodeFormatter.java

  import java.io.*;

    public class UnicodeFormatter {

        static public String byteToHex(byte b) {
                // Returns hex String representation of byte b
                char hexDigit[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                        'a', 'b', 'c', 'd', 'e', 'f' };
                char[] array = { hexDigit[(b >> 4) & 0x0f], hexDigit[b & 0x0f] };
                return new String(array);
        }

        static public String charToHex(char c) {
                // Returns hex String representation of char c
                byte hi = (byte) (c >>> 8);
                byte lo = (byte) (c & 0xff);
                return byteToHex(hi) + byteToHex(lo);
        }

    } // class

DeviceListActivity.java

 import java.util.Set; 
          import android.app.Activity; 
          import android.bluetooth.BluetoothAdapter; 
          import android.bluetooth.BluetoothDevice; 
          import android.content.Intent; 
          import android.os.Bundle; 
          import android.util.Log; 
          import android.view.View; 
          import android.view.Window; 
          import android.widget.AdapterView; 
          import android.widget.ArrayAdapter; 
          import android.widget.ListView; 
          import android.widget.TextView; 
          import android.widget.AdapterView.OnItemClickListener; 

    public class DeviceListActivity extends Activity 
    { 
    protected static final String TAG = "TAG"; 
    private BluetoothAdapter mBluetoothAdapter; 
    private ArrayAdapter<String> mPairedDevicesArrayAdapter; 

    @Override 
    protected void onCreate(Bundle mSavedInstanceState) 
    { 
        super.onCreate(mSavedInstanceState); 
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 
        setContentView(R.layout.device_list); 

        setResult(Activity.RESULT_CANCELED); 
        mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); 

        ListView mPairedListView = (ListView) findViewById(R.id.paired_devices); 
        mPairedListView.setAdapter(mPairedDevicesArrayAdapter); 
        mPairedListView.setOnItemClickListener(mDeviceClickListener); 

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
        Set<BluetoothDevice> mPairedDevices = mBluetoothAdapter.getBondedDevices(); 

        if (mPairedDevices.size() > 0) 
        { 
            findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE); 
            for (BluetoothDevice mDevice : mPairedDevices) 
            { 
                mPairedDevicesArrayAdapter.add(mDevice.getName() + "\n" + mDevice.getAddress()); 
            } 
        } 
        else 
        { 
            String mNoDevices = "None Paired";//getResources().getText(R.string.none_paired).toString(); 
            mPairedDevicesArrayAdapter.add(mNoDevices); 
        } 
    } 

    @Override 
    protected void onDestroy() 
    { 
        super.onDestroy(); 
        if (mBluetoothAdapter != null) 
        { 
            mBluetoothAdapter.cancelDiscovery(); 
        } 
    } 

    private OnItemClickListener mDeviceClickListener = new OnItemClickListener() 
    { 
        public void onItemClick(AdapterView<?> mAdapterView, View mView, int mPosition, long mLong) 
        { 
            mBluetoothAdapter.cancelDiscovery(); 
            String mDeviceInfo = ((TextView) mView).getText().toString(); 
            String mDeviceAddress = mDeviceInfo.substring(mDeviceInfo.length() - 17); 
            Log.v(TAG, "Device_Address " + mDeviceAddress); 

            Bundle mBundle = new Bundle(); 
            mBundle.putString("DeviceAddress", mDeviceAddress); 
            Intent mBackIntent = new Intent(); 
            mBackIntent.putExtras(mBundle); 
            setResult(Activity.RESULT_OK, mBackIntent); 
            finish(); 
        } 
    }; 

     } 

main.xml

<?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">
        <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
        <Button android:text="Scan" 
        android:id="@+id/Scan"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"></Button>
        <Button android:text="Print"
        android:id="@+id/mPrint"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"></Button>
        <Button android:text="Dissable"
        android:id="@+id/dis"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"></Button>
        </LinearLayout>

device_name.xml

 <?xml version="1.0" encoding="utf-8"?> 
    <TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:textSize="18sp"
    android:padding="5dip" /> 

device_list.xml

    <?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"> 
    <TextView android:id="@+id/title_paired_devices" 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" 
    android:text="My Text"
    android:visibility="gone" 
    android:background="#666" 
    android:textColor="#fff" 
    android:paddingLeft="5dip" /> 
    <ListView android:id="@+id/paired_devices" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:stackFromBottom="true" 
    android:layout_weight="1" /> 
    </LinearLayout>

Manifest


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

Edittext Text ChangeListener Kotlin

Action whenever the text is changed in the EditText View.

Application to implement a listener
TextWatcher object, for EditText to trigger an action on text change.

Create a new Project in Kotlin

Message can display outside of our application normal UI

1 Open Android Studio.
2 Go to File => New => New Project. Write application name . Then, check Include Kotlin Support and click next button.
3Select minimum SDK you need. However, we have selected 17 as minimum SDK. Then, click next button
4 Then, select Empty Activity => click next => click finish.
5 You will get a newly created project successfully if you have followed steps properly.

Use the below code to Implement a Edittext with Kotlin

MainActivity.kt

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

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

        editTextSample.addTextChangedListener(object : TextWatcher {

            override fun afterTextChanged(s: Editable) {}

            override fun beforeTextChanged(s: CharSequence, start: Int,
                                           count: Int, after: Int) {
            }

            override fun onTextChanged(s: CharSequence, start: Int,
                                       before: Int, count: Int) {
                tvSample.setText("Text is : "+s)
            }
        })
    }
}


main_activity.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=".MainActivity">

    <LinearLayout
            android:layout_marginTop="20dp"
            android:orientation="vertical"
            android:padding="10sp"
            android:gravity="center_horizontal"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            android:layout_height="wrap_content" />

        <EditText
                android:id="@+id/editTextSample"
                android:textSize="20sp"
                android:layout_marginTop="50dp"
                android:hint="Enter Text ..."
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>



        <TextView
                android:id="@+id/tvSample"
                android:layout_marginTop="20dp"
                android:textColor="@color/colorPrimary"
                android:textStyle="bold"
                android:textSize="16dp"
                android:layout_width="wrap_content"
                  android:layout_height="wrap_content"/>

    </LinearLayout>

</android.support.constraint.ConstraintLayout>

Notifications in Kotlin Oreo (8+)

Create a new Project in Kotlin

Message can display outside of our application normal UI

1 Open Android Studio.
2 Go to File => New => New Project. Write application name . Then, check Include Kotlin Support and click next button.
3Select minimum SDK you need. However, we have selected 17 as minimum SDK. Then, click next button
4 Then, select Empty Activity => click next => click finish.
5 You will get a newly created project successfully if you have followed steps properly.

added line in the build.gradle (Module: app) dependencies:

implementation 'com.android.support:appcompat-v7:26.1.0'

Use the below code to Implement a Notification with Kotlin

 MainActivity.k
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.*
import kotlinx.android.synthetic.main.activity_main.*
import android.widget.RadioGroup
import android.widget.Toast
import android.app.NotificationManager
import android.support.v4.app.NotificationCompat
import android.os.Build
import android.app.NotificationChannel
import android.content.Context
import android.support.annotation.RequiresApi
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
   val button:Button=findViewById(R.id.button);
        button.setOnClickListener()

        {

            issueNotification()

        }
    }


    @RequiresApi(api = Build.VERSION_CODES.O)
    fun makeNotificationChannel(id: String, name: String, importance: Int) {
        val channel = NotificationChannel(id, name, importance)
        channel.setShowBadge(true) // set false to disable badges, Oreo exclusive

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        notificationManager.createNotificationChannel(channel)
    }


    fun issueNotification() {

        // make the channel. The method has been discussed before.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            makeNotificationChannel("CHANNEL_1", "Example channel", NotificationManager.IMPORTANCE_DEFAULT)
        }
        // the check ensures that the channel will only be made
        // if the device is running Android 8+

        val notification = NotificationCompat.Builder(this, "CHANNEL_1")
        // the second parameter is the channel id.
        // it should be the same as passed to the makeNotificationChannel() method

        notification
            .setSmallIcon(R.mipmap.ic_launcher) // can use any other icon
            .setContentTitle("Notification!")
            .setContentText("This is an Oreo notification!")
            .setNumber(3) // this shows a number in the notification dots

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        notificationManager.notify(1, notification.build())
        // it is better to not use 0 as notification id, so used 1.
    }


}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/root_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
 <Button

            android:id="@+id/button"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:text="click"
    />
</LinearLayout>

Android Radio Buttons Using Kotlin With Example

Radio buttons allow the user to select one option at a time. A RadioButton as two states, selected and unselected.

Create a new Project in Kotlin

  1. Open Android Studio.
  2. Go to File => New => New Project. Write application name . Then, check Include Kotlin Support and click next button.
  3. Select minimum SDK you need. However, we have selected 17 as minimum SDK. Then, click next button
  4. Then, select Empty Activity => click next => click finish.
  5. You will get a newly created project successfully if you have followed steps properly.

Use the below code to Implement a Radio Buttons with Kotlin

MainActivity.kt




activity_main.xml

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.*
import kotlinx.android.synthetic.main.activity_main.*
import android.widget.RadioGroup
import android.widget.Toast

class MainActivity : AppCompatActivity() {

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


//Radio button on click change

radio_group.setOnCheckedChangeListener(
    RadioGroup.OnCheckedChangeListener{
        group, checkedId ->

        val radio_langange: RadioButton = findViewById(checkedId)


        Toast.makeText(applicationContext," On Checked change :${radio_langange.text}",Toast.LENGTH_SHORT).show()


    }
)

        // Get radio group selected status and text using button click event
      button.setOnClickListener{
           // Get the checked radio button id from radio group
           var id: Int = radio_group.checkedRadioButtonId
          if (id!=-1){ // If any radio button checked from radio group
              // Get the instance of radio button using id
               val radio:RadioButton = findViewById(id)
            Toast.makeText(applicationContext,"On button click : ${radio.text}",
                 Toast.LENGTH_SHORT).show()
            }else{
                // If no radio button checked in this radio group
               Toast.makeText(applicationContext,"On button click : nothing selected",
                   Toast.LENGTH_SHORT).show()
          }
      }
   }

    // Get the selected radio button text using radio button on click listener
    fun radio_button_click(view: View){
      // Get the clicked radio button instance
      val radio: RadioButton = findViewById(radio_group.checkedRadioButtonId)
       Toast.makeText(applicationContext,"On click : ${radio.text}",
         Toast.LENGTH_SHORT).show()
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/root_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="16dp"
>
    <RadioGroup
            android:layout_marginTop="30dp"
            android:id="@+id/radio_group"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#bccdd5"
            android:padding="15dp"
    >
        <TextView
                android:id="@+id/title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Which is your favorite languages?"
                android:textStyle="bold"
                android:textSize="20sp"
        />
        <RadioButton
                android:id="@+id/tvenglish"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="English"
                android:onClick="radio_button_click"
        />
        <RadioButton
                android:id="@+id/tvspanish"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Spanish"
                android:onClick="radio_button_click"
        />
        <RadioButton
                android:id="@+id/tvfrench"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="French"
                android:onClick="radio_button_click"
        />
        <RadioButton
                android:id="@+id/tvmalayalam"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Malayalam"
                android:onClick="radio_button_click"
        />
    </RadioGroup>

    <Button

            android:id="@+id/button"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:text="Get Selected Language"
    />
</LinearLayout>

Android spinner Using Kotlin With Example

Spinners provide a way to select one value from a list set.
In the default state, a spinner shows its currently selected value.

Create a new Project in Kotlin

  1. Open Android Studio.
  2. Go to File => New => New Project. Write application name as Spinner. Then, check Include Kotlin Support and click next button.
  3. Select minimum SDK you need. However, we have selected 17 as minimum SDK. Then, click next button
  4. Then, select Empty Activity => click next => click finish.
  5. You will get a newly created project successfully if you have followed steps properly.

Use the below code to Implement a Spinner with Kotlin

MainActivity.kt
package com.example.myapplicationkotlinetest

import android.support.v7.app.AppCompatActivity

import android.os.Bundle

import kotlinx.android.synthetic.main.activity_main.*

import android.view.View

import android.widget.*

import java.util.ArrayList as ArrayList1

class MainActivity : AppCompatActivity(),AdapterView.OnItemSelectedListener {
val languagesList = ArrayList()
var spinnerlanguages:Spinner? = null
var textView_languages:TextView? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    textView_languages = this.msg
    spinnerlanguages = this.spinner_sample
    languagesList.add("English")
    languagesList.add("French")
    languagesList.add("Hindi")

    spinnerlanguages!!.setOnItemSelectedListener(this)

    // Create an ArrayAdapter using a simple spinner layout and languages array
    val aa = ArrayAdapter(this, android.R.layout.simple_spinner_item, languagesList)
    // Set layout to use when the list of choices appear
    aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
    // Set Adapter to Spinner
    spinnerlanguages!!.setAdapter(aa)

}

override fun onItemSelected(arg0: AdapterView<*>, arg1: View, position: Int, id: Long) {
    textView_languages!!.text = "Selected language: "+languagesList[position]
}

override fun onNothingSelected(arg0: AdapterView<*>) {

}
}

activity_main.xml

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

    android:orientation="vertical   " 
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

<TextView
        android:id="@+id/msg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="25dp"
        android:padding="20dp"/>

<Spinner
        android:id="@+id/spinner_sample"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
        
</LinearLayout>

Bottom Navigation View Android

BottomNavigationView creates bottom navigation bars, making it easy to explore and switch between top-level content views with a single tap.

Bottom Navigation Bar always stays at the bottom of your application and provides navigation between the views of your application.

Prerequisites

To be able to follow this tutorial, you’ll need:

Adding the Bottom NavigationView

To use BottomNavigationView in your project, make sure you have added the design support and the Android support artifact. To add these in your project add the below dependencies in your buid.gardle file

implementation 'com.android.support:design:28.0.0'

Now add the BottomNavigationView in the activity_main.xml file. Note that the FrameLayout serve as a container for the different fragments that are placed on it whenever the BottomNavigationView menu items are clicked. Add the below code in the activity_main.xml file.

<?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" xmlns:app="http://schemas.android.com/apk/res-auto"
        tools:context=".MainActivity">

    <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>


    <android.support.design.widget.BottomNavigationView
            android:id="@+id/navigationView"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="0dp"
            android:layout_marginStart="0dp"
            android:background="?android:attr/windowBackground"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:itemBackground="@color/colorPrimary"
    />
</android.support.constraint.ConstraintLayout>

Here in the BottomNavigationView the menu items are added with bottom_menu.xml file

Add a file bottom_menu.xml in res/menu directory.

bottom_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
            android:id="@+id/navigation_songs"
            android:icon="@drawable/ic_action_favorites"
            android:title="@string/favorites"/>

    <item
            android:id="@+id/navigation_albums"
            android:icon="@drawable/ic_action_home"
            android:title="@string/home"/>

    <item
            android:id="@+id/navigation_artists"
            android:icon="@drawable/ic_action_settings"
            android:title="@string/settings"/>

</menu>

Setting the Activity class

Now we are going to setup NavigationView and NavigationItemSelectedListener .

package com.kotlincodes.bottomnavigationview

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v4.app.Fragment
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity()  {

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

        title=resources.getString(R.string.favorites)
        loadFragment(FavoriteFragment())

        navigationView.setOnNavigationItemSelectedListener {
            when(it.itemId){
                R.id.navigation_fav-> {
                    title=resources.getString(R.string.favorites)
                    loadFragment(FavoriteFragment())
                    return@setOnNavigationItemSelectedListener true
                }

                R.id.navigation_home-> {
                    title=resources.getString(R.string.home)
                    loadFragment(HomeFragment())
                    return@setOnNavigationItemSelectedListener true
                }

                R.id.navigation_settings-> {
                    title=resources.getString(R.string.settings)
                    loadFragment(SettingsFragment())
                    return@setOnNavigationItemSelectedListener true
                }

            }
            false

        }
    }

    private fun loadFragment(fragment: Fragment) {
        // load fragment
        val transaction = supportFragmentManager.beginTransaction()
        transaction.replace(R.id.container, fragment)
        transaction.addToBackStack(null)
        transaction.commit()
    }
}

Here we are not using the findViewById method to bind the views, we are just using synthetic binding extensions from Kotlin by importing the following

import kotlinx.android.synthetic.main.activity_main.*

We’ll start with the FavoriteFragment.kt class and you should follow a similar process for the remaining two fragment classes—HomeFragment.kt and SettingsFragment.kt.

The fragment added here is the basic one just uses one TextView, you can replace it with any Fragment.

FavoriteFragment.kt

package com.kotlincodes.bottomnavigationview

import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

class FavoriteFragment : Fragment(){
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_fav,container,false)

    }
}

fragmet_fav.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <TextView android:layout_width="match_parent"
              android:layout_centerInParent="true"
              android:textAlignment="center"
              android:textSize="18sp"
              android:text="@string/favorites"
              android:layout_height="wrap_content"/>
</RelativeLayout>

That’s it! Now run the project! The full source code is available here.

Thanks for reading!

Android Splash Screen with Kotlin

Android Splash Screen is the 1st screen visible to user when app launches. Splash screen displays some animations or App logo for a short time while some data for the next screen are fetched.

Here we are going to implement a Splash Screen for Android with Kotlin.

Splash Screen is very common to most of the Android Applications. It is very easy to create Splash Screen using Handler class.

Create a Style resource

Update your style.xml file as shown below

style.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

</resources>

Create Layout XML file for SplashScreen

activity_splash.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#464545"
    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">

    <ImageView
        android:id="@+id/image"
        android:src="@drawable/kotlincodes"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerInParent="true"
        />
    <TextView
        android:id="@+id/text"
        android:textColor="#fff"
        android:gravity="center"
        android:text="kotlincodes.com"
        android:layout_below="@id/image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <ProgressBar
        android:layout_below="@id/text"
        android:layout_centerHorizontal="true"
        android:padding="6dp"
        android:layout_width="45dp"
        android:layout_height="45dp" />

</RelativeLayout>

This layout contains an ImageViw ,TextView and a ProgressBar. 

You can replace android:src of the ImageView with your own Image.

Create Splash Screen Activity Class

Here we uses a Handler to make a small delay. You can implement data fetching or any function in postDelayed method in Handler.

SplashScreenActivity.kt

package com.kotlincodes.splashscreenwithkotlin

import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.support.v7.app.AppCompatActivity

class SplashScreenActivity : AppCompatActivity() {
    private val SPLASH_TIME_OUT:Long=3000 // 3 sec
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)


        Handler().postDelayed({
            // This method will be executed once the timer is over
            // Start your app main activity

            startActivity(Intent(this,MainActivity::class.java))

            // close this activity
            finish()
        }, SPLASH_TIME_OUT)
    }
}

Create a MainActivity 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#464545"
    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">

    <TextView
        android:textSize="22dp"
        android:layout_centerInParent="true"
        android:text="Home Page"
        android:textColor="#fff"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

MainActivity.kt

package com.kotlincodes.splashscreenwithkotlin

import android.support.v7.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

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

Add SplashScreen Activity as Launch page in manifest

Add the below code in manifets.xml file under application tag.

<activity android:name=".SplashScreenActivity"
            android:theme="@style/AppTheme.NoActionBar"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

That’s it! Now run the project!

The full source code is available here.

Thanks for reading!


Google Map API with Kotlin

Here we are going to learn how to add a google map our project using google maps API with Kotlin.

Here we are developing a simple app with Google map and adding a marker to it.

Generate Google Maps API Key

Before we are starting to use a google map in our project we need to generate a Google Maps API key from Google API Console .

  • Login to Google API Console with your google account
  • Create a project then create credentials –>API Key as shown below
  • Copy Api Key Credential

Add Google Map into our Project

Now we need to add our API Key into our manifest.xml file under application tag.  Copy the below code and add it into the
manifest.xml under application tag.

manifest.xml

<meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="YOUR_API_KEY"
            />

Don’t forget to replace “YOUR_API_KEY” with your API key from Google API Console

Setup Layout

Now we need to setup our Layout for Google maps. Copy and paste the below code into activity_mail.xml file.

activity_mail.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <fragment xmlns:tools="http://schemas.android.com/tools"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    </fragment>

</LinearLayout> 

Setup MainActivity.kt

To set up map in our application please copy and paste below code into your activity class.

package com.kotlincodes.googlemapwithkotlin

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions

class MainActivity : AppCompatActivity() ,OnMapReadyCallback {
    private var googleMap:GoogleMap?=null
   override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val mapFragment = supportFragmentManager
                .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)

    }
    override fun onMapReady(p0: GoogleMap?) {
        googleMap=p0

        //Adding markers to map

        val latLng=LatLng(28.6139,77.2090)
        val markerOptions:MarkerOptions=MarkerOptions().position(latLng).title("New Delhi")

        // moving camera and zoom map

        val zoomLevel = 12.0f //This goes up to 21


        googleMap.let {
            it!!.addMarker(markerOptions)
            it.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, zoomLevel))
        }
    }
}

That’s it! Now run the project!

The full source code is available here.

Thanks for reading!