Friday, June 23, 2017

Android: Job Scheduler schedule you job

Welcome to the android tutorial.
android
Android

In this post, we talk about JobSchedular. A job scheduler is more effective than alarm manager. Want to see it benefits then check out this link.

For scheduling, you have many options to use.
1. Android Alarm manager
2. Job Scheduler
3. Gcm Network Manager

In the previous post, we talk about android alarm manager. Are you confused about those? which one is appropriate for your android app. Read this document Become a pro at scheduling tasks in Android

Now come to code- Before starting we have to add below line in the build.gradle file
compile 'com.firebase:firebase-jobdispatcher:0.5.0'
Now we need to a service class. Create a services class and extend it to JobService. In this case, my class name is EverydayJobTask.java
public class EverydayJobTask extends JobService {
}
we need to override two class-
1. onStartJob()
2. onStopJob()

onStartJob() will call when the job is started. So we need to implement the start logic in this methods.
onStopJob() will call after job will finish. In my case, I show a notification on start Job.

Full Java code of service class-
public class EverydayJobTask extends JobService {

  @Override
  public boolean onStartJob(JobParameters job) {

  //if job schedule then set a notification
  TaskNotification.notify(EverydayJobTask.this,
  "Start sync Task... ", 0);

  return true;
  }

  @Override
  public boolean onStopJob(JobParameters job) {
  return true;
  }
}
Now we need to build FirebaseJobDispatcher. we need to create a google play driver
Driver driver = new GooglePlayDriver(context);
now create a firebase job dispatcher variable and pass this driver
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(driver);
next step is to create a job this job will help to do the task with time-
Job syncJob = dispatcher.newJobBuilder()
set service to the job by calling setService and parameter will be a service class and its super class must be JobService.
.setService(EverydayJobTask.class)
set a tag and this tag must be unique. this tag is used to identify this job.
.setTag("Everyday_Task")
set it's lifetime by calling setLifeTime(). setLifetime sets how long this job should persist you two option
1. UNTIL_NEXT_BOOT
2.FOREVER
.setLifetime(Lifetime.FOREVER)
set a Network constraints on which this Job should run. You have some option
1. DEVICE_CHARGING -> the will be run only while the device is running.
2. ON_ANY_NETWORK -> for this case job will be running on any network
3. ON_UNMETERED_NETWORK-> on unmetered connection.

In my case, I set on any network
.setConstraints(Constraint.ON_ANY_NETWORK)
Note: It might be a good idea to include a preference for this, as some users may not want to download any data on their mobile plan.

set trigger for the job to start by calling setTrigger and the parameter will be another method Trigger.executionWindow(). This method has two parameters.The first argument for * which the data should be synced Note: this end time is not * guaranteed, but is more of a guideline for FirebaseJobDispatcher to go off we need two time interval time and flex time for that add those below line-
private static final int HOURS = 3;
private static final int INTERVAL_SECONDS = (int) TimeUnit.HOURS.toSeconds(HOURS);
private static final int FLEXTIME_SECONDS = INTERVAL_SECONDS / 3;
Note: I set interval time three hours. If you want to set more hour then change hours variable. After that add below code-
.setTrigger(Trigger.executionWindow(INTERVAL_SECONDS,INTERVAL_SECONDS+FLEXTIME_SECONDS))
If you want to set this job requiring the set true in the setRecurring or don't set false-
.setRecurring(true)
once the job is finished then call build method. this method has returned a job.
.build();
we finished making the job. But we have one more step to finish. we need to set schedule this job with the dispatcher.
dispatcher.schedule(syncJob);

oh! we done. Now I think you can use this job scheduler in your next android project.
That's it's today post
Happy coding.

Tuesday, June 20, 2017

Kotlin: Array and Loop

Welcome to kotlin Series

kotlin
Kotlin Series

In this post, we are going to learn about Array. The array is really helpful for saving the collection of data. Let's start- we declare a variable and name arrays and assign with Array.
val arrays = Array(5) { 0 }
Now currently our arrays variable has only one index and index position is 0 now add some other index and also print an index for checking.
val arrays = Array(5) { 0 }

arrays[1] = 1
arrays[2] = 2
println(arrays[2])
Note: here Array(5) it indicates that it's size is 5. See an another example-
val arrayStr = Array(5) { "Shudipto" }
arrays[1] = 2
println(arrayStr[0])
Code analysis-
if we don't define this array with a data type then we can insert any type of data type in it. Now add an another variable and initialize it by calling listOf()
val arraysNew = listOf(1, "shudipto", 2.5, 0.234, "Trafder", false)
Code analysis- you might notice that in this array we insert
1. integer
2. string
3. double
4. float
5. boolean
many data types. It's work fine. we don't put the same type of data in the array. That's are array declaring.

Now we use some practices with the loop that's print all the value in an array. first, we using while loop we create a variable that value is zero first and after working with loop this value will increase.
While Loop
var size = 0

//using while loop
while (size < arraysNew.size) {
    println("Position $size value ${arraysNew[size]}")
    size++

}
For Loop:
// using for loop
for (i in arraysNew) {
    println("value: $i")
}
Note: here i is predefined in kotlin it looks like Val i If we want to print value with position then we need two variable in for loop. In the previous we have one variable now we need two variables. How can we do that? see the code-
for ((position, i) in arraysNew.withIndex()) {
     println("position: $position value: $i")
}
Now we do some advance practice: 1. we create a variable and fill this variable this user input after that we show all the data that in the array we for loop(essay to use). we also know how to use for loop.(we just learn it)
for ((position) in arrayFill.withIndex()) {
    print("Insert a value:")
    val input = readLine()!!.toInt()
    arrayFill[position] = input
}
Code Analysis: we need the only position so we declare only one variable. (In the previous code we work with two variables and because we also learn the value along with the position). we also need an array with the index. if don't understand below the line, ignore this list for now. This is null safety. I will talk about null safety in another post.
val input = readLine()!!.toInt()
Now time to print what we are inserted in the array. Try yourself. You already learn how to print all the data of any array. Code-
for ((position, i) in arrayFill.withIndex()) {
    println("position: $position value: $i")
}
Today Full Code-
/**
 * Created by Shudipto Trafder on 6/20/2017.
 */

fun main(args: Array<String>) {

    val arrays = Array(5) { 0 }

    arrays[1] = 1
    arrays[2] = 2
    println(arrays[2])

    val arrayStr = Array(5) { "Shudipto" }
    arrays[1] = 2
    println(arrayStr[0])

    val arraysNew = listOf(1, "shudipto", 2.5, 0.234, "Trafder", false)

    var size = 0

    //using while loop
    while (size < arraysNew.size) {
        println("Position $size value ${arraysNew[size]}")
        size++

    }

    // using for loop
    for (i in arraysNew) {
        println("value: $i")
    }

    for ((position, i) in arraysNew.withIndex()) {
        println("position: $position value: $i")
    }

    println("Please help us to fill some data")
    val arrayFill = Array(5) { 0 }
    for ((position) in arrayFill.withIndex()) {
        print("Insert a value:")
        val input = readLine()!!.toInt()
        arrayFill[position] = input
    }

    println("Your inserted data")
    for ((position, i) in arrayFill.withIndex()) {
        println("position: $position value: $i")
    }
}

Thank you very much for reading this post.
Happy coding

Friday, June 16, 2017

Android: Alarm Manger with broadcast receiver

Welcome to this post. In this post, we are going to learn about Alarm manager and BroadCast Receiver. As usual before start please check official documentation.
1.Alarm Manager official documentation
2.BroadCast Receiver official documentation

Alarm manager is used for scheduling task. If you want to do a task after some time intervals or if want to do some task at 11 am. of the daytime, you have to use alarm manager. Because there is a possibility that user is not using this app at that particular time. So If you are using alarm manager and schedule some task then you don't have to tense about your task is executed or not. More accurately, when phone time is 11.am (example time) then system send a broadcast and from the broadcast receiver, you can receive this signal and execute the task.

Ok, enough talk.

First Alarm Manager-

* we have to create a calendar variable like-
Calendar calendar = Calendar.getInstance();
Now set a time when you do the task. In this case, I want to set 23.59.00 this time. you can also set a specific date. But I don't need a date I just need time so I set time only. But you can also add a date in similar ways.
calendar.set(Calendar.HOUR_OF_DAY,23);
calendar.set(Calendar.MINUTE,59);
calendar.set(Calendar.SECOND,0);

Now we have to do-
 * create an alarm manager and get system alarm services
* create an Intent and Intent class must be a broadcast receiver extend the class (we will create in later in this post).
* set an intent action (so we can filter on broadcast receiver, in this case, I use package name)
* now create a pending intent and get broadcast receiver
*now set alarm manager with set repeating
see the code-
//alarm manager
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

Intent intent = new Intent(this, TaskManager.class);
intent.setAction("com.blogspot.shudiptotrafder.lifeschedular");

PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);

alarmManager.setRepeating(AlarmManager.RTC_W
  AKEUP, calendar.getTimeInMillis(),
  AlarmManager.INTERVAL_DAY, pendingIntent);
Note: here I set interval time AlarmManager.INTERVAL_DAY so it will be trigger at once in every day. you can set a custom time limit.
That's it on alarm manager.

BroadCast Reciever 

the broadcast receiver receives system and custom broadcast. we also explain in the first section of this post. Create a class extend with the broadcast receiver
public class TaskManager extends BroadcastReceiver {
}
you have to override onRecive method.
@Override
public void onReceive(Context context, Intent intent) {
}
we check that if intent has the same action that we have passed through pending intent on alarm manager. If the answer is true then we do our task. For simplicity, I show a toast message.
if (intent.getAction().equalsIgnoreCase("com.blogspot.shudiptotrafder.lifeschedular")) {

  Toast.makeText(context, "Received", Toast.LENGTH_SHORT).show();
}
Now we have to declare this receiver on manifest (AndroidMenifest.xml)
<!-- Broadcast Receiver -->
<receiver
  android:name=".manager.TaskManager"
  android:enabled="true"
  android:exported="false">
  <intent-filter>
  <action android:name="com.blogspot.shudiptotrafder.lifeschedular"/>

  <category android:name="android.intent.category.DEFAULT"/>
  </intent-filter>
</receiver>
we set the specific broadcast receiver on the intent filter. If you want to receive more action then set on action tag. Full receiver class-
public class TaskManager extends BroadcastReceiver {
  
  @Override
  public void onReceive(Context context, Intent intent) {

  if (intent.getAction().equalsIgnoreCase("com.blogspot.shudiptotrafder.lifeschedular")) {

  Toast.makeText(context, "Received", Toast.LENGTH_SHORT).show();
}
That's all.
Happy coding.

Android Spinner and it's adapter

Welcome to this post. In this post, we going to learn about Spinner.

Spinner is really awesome to give user choice to select from a small list. you can use the spinner to get a value from a list.

In this project, we are going to create a list that shows a list in the spinner.
The list has 3 items-

  • Everyday
  • Today
  • Schedule


Let's start- layout name as you want.

I create a fragment that contains a spinner and a text view. I am currently using the same spinner in two or more file so I use the fragment. But you can use on your desired layout.

Note: I use Java and Kotlin code simultaneously. First is java and the second one is Kotlin.

Let's add XML Code-
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="8dp"
        android:padding="10dp"
        android:text="@string/select_task_type"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <Spinner
        android:id="@+id/spinner"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="16dp"
        android:padding="10dp"
        android:visibility="visible"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView2"/>

</android.support.constraint.ConstraintLayout>
Now you can use this layout in any other layout. Now time to write java code-
private Spinner spinner;
assign view
spinner = (Spinner) findViewById(R.id.spinner);

In kotlin, we need to add only one line.
val spinner: Spinner = findViewById(R.id.spinner)

Now create a list
 // Spinner Drop down elements
List<String> categories = new ArrayList<>();
categories.add(MainActivity.EVERYDAY);
categories.add(MainActivity.TODAY);
categories.add(MainActivity.SCHEDULE);
Kotlin:
val categories = ArrayList<String>()
categories.add("EVERYDAY")
categories.add("TODAY")
categories.add("SCHEDULE")
Now create an adapter for this spinner-
 // Creating adapter for spinner
ArrayAdapter dataAdapter = new ArrayAdapter<>
     (this, android.R.layout.simple_spinner_item, categories);
Kotlin:
val dataAdapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, categories)
Now add a drop-down layout style with list view with radio button
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Kotlin:
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
set data adapter to spinner
spinner.setAdapter(dataAdapter);
Kotlin:
spinner.adapter = dataAdapter

I add a method to get selected data from the list- In my case method name is getTaskType.
we have to do-
1. we need to add setOnItemSelectedListener to our spinner
2. so we also override two methods name
i) onItemSelected -> when we select something then this method is called
ii) onNothingSelected -> if the user is not select anything

Let's see the code-
//get task type from spinner
private String getTaskType() {

      final String[] tasks = new String[]{null};

      // Spinner click listener
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
          @Override
          public void onItemSelected(AdapterView<?> parent, View view, 
                    int position, long id) {
              tasks[0] = parent.getItemAtPosition(position).toString();
            }

          @Override
          public void onNothingSelected(AdapterView<?> parent) {
              //do nothing
          }
      });

     return tasks[0];
}

Kotlin:
private fun getTaskType(spinner:Spinner):String {

        var tasks = "no text"

        // Spinner click listener
        spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
                tasks = parent.getItemAtPosition(position).toString()
            }
            
            override fun onNothingSelected(parent: AdapterView<*>) {
                //do nothing
            }
        }
        
        return tasks
    }

That's it.
this post will help you in both case, if you are working with java or kotlin.
Now you can use the spinner in your project.
Happy coding.

Thursday, June 15, 2017

RecyclerView OnClick Listener again

RecyclerVIew On Click listener Image
RecyclerView is the more flexible than ListView. Now we all use RecyclerView. But In the RecyclerVIew there is a problem that it's not come with the listener. So we can not handle click event easily. I already post a method to handle click event click here. Here are an another methods to handle click event.
Note: In this post, I just show only some methods where you have to change not full code.

Benefits of the methods are you can use this click listener in your activity, not adapter class.
If you want to learn about full recycle view code like the adapter and viewHolder class sees this post. 

Processes-
 1. First, you need to add an interface (you can add interface in separate interface file or declare in on inner class). I add on Adapter class
public interface ClickListener{
    void onItemClickListener(String s);
}
Note: If you need long click listener then create another method and add on view holder class. I add a method on interface name  OnItemClickListener and add parameter String because we need a string to send another activity.

 2.Now modify the default constructor of adapter class
private ClickListener clickListener;

    /**
     * Constructor for the CustomCursorAdapter
     * @param clickListener to handle click event
     */
    public CustomCursorAdapter(ClickListener clickListener) {
        this.clickListener = clickListener;
    }
3. Implements view.OnClickListener on viewHolder class. See this
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        // Class variables for the task description and priority TextViews
        TextView word;

        /**
         * Constructor for the TaskViewHolders.
         *
         * @param itemView The view inflated in onCreateViewHolder
         */
        private MyViewHolder(View itemView) {
            super(itemView);

            word = (TextView) itemView.findViewById(R.id.mainRecycleView_TV);

            word.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            mCursor.moveToPosition(getAdapterPosition());
            int wordIndex = mCursor.getColumnIndex(COLUMN_WORD);
            String word = mCursor.getString(wordIndex);
            //get word from cursor and set it to click listener parameter
            // we can easily access form click event methods
            clickListener.onItemClickListener(word);
        }
    }
on the Onclick listener method, we take String from array or Cursor and send as our interface method parameter. Now can easily access this string on the main activity. 4. Now time to  Use - implements the interface that's we created earlier,
public class MainActivity extends AppCompatActivity
        implements CustomCursorAdapter.ClickListener {
   

       //some code

}

After that's
/** onClick listener for recycler view
     * called if click any item on recycler view
     * @param word is the selected word from data base
     */
    @Override
    public void onItemClickListener(String word) {
        Intent intent = new Intent(MainActivity.this, DetailsActivity.class);
        intent.putExtra(Intent.EXTRA_TEXT,word);
        startActivity(intent);
}


Using adapter
CustomCursorAdapter mAdapter = new CustomCursorAdapter(this);
recyclerView.setAdapter(mAdapter);

Thanks for reading this post.

I hope your code is running well. And you can handle the click event on RecyclerView more easily. But once again full code post of recyclerview is here.
 If you have any queries then use comment option I will help you.


Happy coding :p

Bookstore: Kotlin a simple program

Bookstore a Kotlin example code
LEVEL: BEGINNER

kotlin


This example is good for understanding
  1. Array
  2. methods
  3. conditions(if and else)
  4. variable declaration
The program features are-
  1. First, we welcome to our customer to our bookstore
  2. Then we ask the user to which book do you want?
  3. If we found that book we show a price about the book.
  4. Then we say to our customer that we have a discount for student and teacher only.
  5. we ask the customer about his profession.
  6. If our customer's profession is student and teachers then we give different discount
  7. After that, we show the discount prices and give a thank message
That's our today's main target.

I also a publish a post about the same program in Java you can also see that post.(Click here)

First, we declare an array
//books name
val booksName = arrayOf("java","c","c++","kotlin","c#","html")
Now add a scanner that's scan user input
val scanner = Scanner(System.`in`)
Now add two variable for two type of discount
val studentDiscount = .25f
val teacherDiscount = .15f
Now time to welcome to our customer and get customer input
println("*************WELCOME TO OUR BOOK STORE**********")
println("Which book do you want?")
print("Answer: ")
val book = scanner.nextLine()
Now create a method that calculates price after discount-
private fun calculatePrice(x: Float): Unit {
    var price = 200f
    price -= price * x

    println("Your total payable price is $price TK.")
}
Time to write some conditions against user input-
if (booksName.contains(book.toLowerCase())){
        println("You Want $book book. price 200 Tk.")
        println("we have some discount for student and teacher.\nWhat is your occupation?")
        print("Answer: ")
        val occupation = scanner.nextLine()

        when(occupation.toLowerCase()){
            "student" -> {
                calculatePrice(studentDiscount)
            }

            "teacher" ->{
                calculatePrice(teacherDiscount)
            }

            else -> println("Sorry you don't get any discount."+
                    "\nYour total payable price is 200 TK.")
        }

    } else{
        println("Sorry we don't have $book book")
    }
Code analysis-
1.If we have customer desire book that we show a price 200 and If we don't then we print Sorry we don't have that book.
2.If we found the book then we ask again user about his/her occupation
3.If he/she is a student or teacher then we give some discount
4.If the student then we call to calculate the price and pass the student discount value or If the teacher, then we call to calculate the price and pass the teacher discount value.

Full code-
package firstKotlin

import java.util.*

fun main(arg: Array<String>){

    //books name
    val booksName = arrayOf("java","c","c++","kotlin","c#","html")

    val scanner = Scanner(System.`in`)

    val studentDiscount = .25f
    val teacherDiscount = .15f

    println("*************WELCOME TO OUR BOOK STORE**********")
    println("Which book do you want?")
    print("Answer: ")
    val book = scanner.nextLine()

    if (booksName.contains(book.toLowerCase())){
        println("You Want $book book. price 200 Tk.")
        println("we have some discount for student and teacher.\nWhat is your occupation?")
        print("Answer: ")
        val occupation = scanner.nextLine()

        when(occupation.toLowerCase()){
            "student" -> {
                calculatePrice(studentDiscount)
            }

            "teacher" ->{
                calculatePrice(teacherDiscount)
            }

            else -> println("Sorry you don't get any discount."+
                    "\nYour total payable price is 200 TK.")
        }

    } else{
        println("Sorry we don't have $book book")
    }
}

private fun calculatePrice(x: Float): Unit {
    var price = 200f
    price -= price * x

    println("Your total payable price is $price TK.")
}
Thanks for reading.
Happy coding

Android Night Mode

welcome to this post.In this post we are going to learn about how to use night mode on Android app. you can turn on night mode in your app by using android support library. you can use this option in settings or in the menu item.

night_mode
Night mode


In this case, I use this on settings. In a past post, we learn how to make app settings you can take a look
Let's start-
First, add new file name colors.xml in values-night folder and some colors-
<resources>
  <color name="colorPrimary">#051358</color>
  <color name="colorPrimaryDark">#020620</color>
  <color name="colorAccent">#800931</color>
  <color name="textColorPrimary">#e2dede</color>

  <color name="colorFabPressed">#1e710b</color>
  <color name="colorFabRipple">#0b0b3d</color>
  <color name="colorFabShadow">#66030303</color>

  <color name="colorFabToday">#385437</color>
  <color name="colorFabEveryday">#54364a</color>

  <color name="colorFabLabel_txt">#f2f1f1</color>
  <color name="colorFabLabelNormal">#232520</color>
  <color name="colorFabLabelPressed">#66626660</color>
  <color name="colorFabLabelRipple">#66844182</color>

</resources>
Note: add this color but you can only just add that's the color you want to override in night mode. Take a look on my values->colors.xml file then you can take a clear look on it.
<resources>
  <color name="colorPrimary">#3F51B5</color>
  <color name="colorPrimaryDark">#303F9F</color>
  <color name="colorAccent">#FF4081</color>
  <color name="textColorPrimary">#0e0e0e</color>

  <color name="colorFabPressed">#50ea2d</color>
  <color name="colorFabRipple">#2a23e7</color>
  <color name="colorFabShadow">#66626660</color>

  <color name="colorFabToday">#5d895a</color>
  <color name="colorFabEveryday">#704862</color>

  <color name="colorFabLabel_txt">#f2f1f1</color>
  <color name="colorFabLabelNormal">#232520</color>
  <color name="colorFabLabelPressed">#66626660</color>
  <color name="colorFabLabelRipple">#66844182</color>
</resources>
Now time to change your style- your style might look like this-
<!-- 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>
Now change Theme.AppCompat.Light.DarkActionBar to Theme.AppCompat.DayNight.DarkActionBar. Let's do this-
<!-- Base application theme. -->
  <style name="AppTheme" parent="Theme.AppCompat.DayNight.DarkActionBar">
  <!-- Customize your theme here. -->
  <item name="colorPrimary">@color/colorPrimary</item>
  <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
  <item name="colorAccent">@color/colorAccent</item>
  
  </style>
Look like you complete 50% work Now come to the java code- I am using settings so night is enabled not that's saved in a shared preference. Shared preferences key-
<string name="switchKey">SwitchKey</string>
Now create a method that is checked is night mode is enable or not. The default value is false-
public static boolean getNightModeEnabled(Context context) {

        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);

        return preferences.getBoolean(context.getString(R.string.switchKey), false);
    }
Now Create a new Methods that's set Night mode in any activity-
Follow those steps-
1. call the newly created methods and save the return value on a boolean.
2 If the value is true the we write AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) on the if condition.
3. If it false then we add AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)this line.

see the code-
//set night mode for app
    private void setNightMode() {

        //get from setting check bok preference is true or false
        boolean isEnabled = getNightModeEnabled(this);

        if (isEnabled) {
            AppCompatDelegate.setDefaultNightMode(
                    AppCompatDelegate.MODE_NIGHT_YES);
        } else {
            AppCompatDelegate.setDefaultNightMode(
                    AppCompatDelegate.MODE_NIGHT_NO);
        }
    }
Final Screen short

day_mode
Day Mode

night_mode
Night mode


Thank you for reading this post hope you can use this option in your app
Happy coding

Wednesday, June 14, 2017

Android Material SearchView

Welcome to this post.
Android Material Search view tutorial. In this tutorial, we going to make a project and Implement A search view on the toolbar.
For search view, I use a 3rd party library Material SearchView

Note: If you don't want to use 3rd party library see this post,  Android Material SearchView with Recent Search Suggestions

Let's start-
Before starting, see a screenshot-

material_search_view
Material Search View


we have to do with this project-
1. we set search view on the toolbar.
2. Filter RecyclerView with text input
3. voice search

some bonus- In this project,
1. use SQL database for store data2. use the content provider to access data.
3. use Loaders for load data(Curser loaders).

Let's Start- First, add this line to your build.gradle file and sync gradle.
compile 'br.com.mauker.materialsearchview:materialsearchview:1.2.2'
Now go to on your style.xml file and below style-
<style name="MaterialSearchViewStyle">
  <item name="searchBackground">@color/white_ish</item>
  <item name="searchVoiceIcon">@drawable/ic_action_voice_search</item>
  <item name="searchCloseIcon">@drawable/ic_action_navigation_close</item>
  <item name="searchBackIcon">@drawable/ic_action_navigation_arrow_back</item>
  <item name="searchSuggestionBackground">@color/search_layover_bg</item>
  <item name="searchBarHeight">?attr/actionBarSize</item>
  <item name="voiceHintPrompt">@string/hint_prompt</item>
  <item name="android:textColor">@color/black</item>
  <item name="android:textColorHint">@color/gray_50</item>
  <item name="android:hint">@string/search_hint</item>
  <item name="android:inputType">textCapWords</item>
  </style>
OK, now time to add a toolbar to the layout. In this case, I add on activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="?attr/actionBarSize"
  tools:context=".MainActivity"
  android:background="@color/colorPrimary"
  android:layout_marginBottom="2dp"
  android:elevation="6dp">
  <!-- don't forget to set elevation or it look like old action bar-->

  <android.support.v7.widget.Toolbar
  android:id="@+id/toolbar"
  android:layout_width="match_parent"
  android:layout_height="?attr/actionBarSize"
  android:background="?attr/colorPrimary"
  android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
  app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

  <br.com.mauker.materialsearchview.MaterialSearchView
  android:id="@+id/search_view"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  style="@style/MaterialSearchViewStyle"/>

  </RelativeLayout>
Note: I will provide GitHub link to this project later in this post

Now add a menu button on menu.xml-
<item
  android:id="@+id/action_search"
  android:icon="@drawable/ic_search"
  android:orderInCategory="100"
  android:title="@string/abc_search_hint"
  app:showAsAction="always" />

options menu looks like:

menu
Material Search View (options menu)


Now time to write java code- In this case MainActivity.java
MaterialSearchView searchView;
and again this view on onCreate-
searchView = (MaterialSearchView) findViewById(R.id.search_view);

now set all search operation I created a private method and call it on Oncreate-
In this method, we add three listeners to the search view-
1. setOnQueryTextListener
2. setSearchViewListener
3. setOnVoiceClickedListener In listener

1. setOnQueryTextListener is fired when we type text in the search view. In this listener, we have to override two methods name-
i. onQueryTextSubmit
ii. onQueryTextChange

i. onQueryTextSubmit is called when we put the query data with submit button.
after submit-
* build a URI
* call getContentResolver and query database and save it on cursor variable.
 * if the cursor is not null and cursor data is more than 0 we have data(Call cursor.getCount())
* so we go to the details activity with intent and set this URI with intent
*close search view

ii. onQueryTextChange is called every time when you write.
So we have to set-
* we are going to update recycler view with type text
* we check the text length is greater than zero
* then we create a selection string variable for cursor query. we use SQL LIKE statement not where statement.
String selection = MainWordDBContract.Entry.COLUMN_WORD +" like ? ";
* add also selection Argument-
String[] selectionArg = new String[]{newText+"%"};
* same way to get cursor and same condition for update UI as onQueryTextSubmit

Let's see the code-
searchView.setOnQueryTextListener(new MaterialSearchView.OnQueryTextListener() {
  @Override
  public boolean onQueryTextSubmit(String query) {

  Uri uri = MainWordDBContract.Entry.buildUriWithWord(query.toUpperCase());
  Cursor cursor = getContentResolver().query(uri,
  MainActivity.projection,null,null,null);

  if (cursor != null && cursor.getCount() > 0){
  Intent intent = new Intent(MainActivity.this,
  DetailsActivity.class);
  intent.setData(uri);
  startActivity(intent);
  searchView.closeSearch();
  searchView.setCloseOnTintClick(false);
  }

  if (cursor != null){
  cursor.close();
  }
  return true;
  }

  @Override
  public boolean onQueryTextChange(String newText) {

  if (newText.length() > 0){
  String selection = MainWordDBContract.Entry.COLUMN_WORD +" like ? ";
  //if you are try to search from any position of word
  //then use
  //String[] selectionArg = new String[]{"%"+newText+"%"};
  //if you try to search from start of word the use this line
  String[] selectionArg = new String[]{newText+"%"};

  Cursor cursor = getContentResolver().query(MainWordDBContract.Entry.CONTENT_URI,
  MainActivity.projection,selection,selectionArg,null);

  if (cursor != null && cursor.getCount() > 0){
  mAdapter.swapCursor(cursor);
  }

  return true;
  } else {
  return false;
  }
  }
  });
Now add the setSearchViewListener listener and there are also two methods.
* if search view is open then hide the fab
* if searchView close the show the fab again Code-
searchView.setSearchViewListener(new MaterialSearchView.SearchViewListener() {
  @Override
  public void onSearchViewOpened() {
  fab.hide();
  }

  @Override
  public void onSearchViewClosed() {
  fab.show();
  }
  });
On the last, we have added setOnVoiceClickedListener if you are using this option. for this, I write another method name askSpeechInput so let's see the code one by one- the listener-
searchView.setOnVoiceClickedListener(new MaterialSearchView.OnVoiceClickedListener() {
  @Override
  public void onVoiceClicked() {
  askSpeechInput();
  }
  });
method-
private void askSpeechInput() {
  Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

  intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
  RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);

  intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
  intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
  "Speak your desire word");
  try {
  startActivityForResult(intent, MaterialSearchView.REQUEST_VOICE);
  } catch (ActivityNotFoundException a) {
  a.printStackTrace();
  slet("Activity not found", a);
  Toast.makeText(this, "Sorry Speech To Text is not " +
  "supported in your device", Toast.LENGTH_SHORT).show();
  }
  }
one more method to go. we are now overriding onActivityResult for getting voice input-
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (requestCode == MaterialSearchView.REQUEST_VOICE && resultCode == RESULT_OK) {
            ArrayList<String> matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
            if (matches != null && matches.size() > 0) {
                String searchWrd = matches.get(0);
                if (!TextUtils.isEmpty(searchWrd)) {

                    //Todo more accure on settings
                    searchView.setQuery(searchWrd, false);
                    Uri uri = MainWordDBContract.Entry.buildUriWithWord(searchWrd.toUpperCase());

                    Cursor cursor = getContentResolver().query(uri,
                            MainActivity.projection,null,null,null);

                    if (cursor != null && cursor.getCount() > 0){
                        Intent intent = new Intent(MainActivity.this, DetailsActivity.class);
                        intent.setData(uri);
                        startActivity(intent);
                        searchView.closeSearch();
                        searchView.setCloseOnTintClick(false);
                    }

                    if (cursor != null){
                        cursor.close();
                    }
                }
            }

            return;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

voice search screen short:
voice
Material Search View (voice search)


add this line onResume method
searchView.activityResumed();
and last one-
@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        switch (item.getItemId()) {
            case R.id.action_search:
                // Open the search view on the menu item click.
                searchView.openSearch();
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }
Now run your app and see the material search view

It will work fine.

Note: If you don't want to use 3rd party library to add search functionality, see this post.Android Material SearchView with Recent Search Suggestions
Thank you for reading

Happy coding