Android WorkManager example for periodic tasks

 1. Added JAVA 1.8 compile options in the gradle file.

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

kotlinOptions {
    jvmTarget = "1.8"
}

2. Add the workmanager dependency in the gradle file.

implementation "androidx.work:work-runtime-ktx:2.3.4"

3. Create a worker class MyWorker.kt that does nothing but to sleep for 10 seconds and show a notification before and after it sleeps.

import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters

class MyWorker(ctx: Context, params: WorkerParameters) : Worker(ctx, params) {

    override fun doWork(): Result {
        val appContext = applicationContext

        makeStatusNotification("Worker started work.", appContext)
        sleep(10)
        makeStatusNotification("Worker finshed work.", appContext)

        return Result.success()
    }

}

4. Run the worker. It can be run from anywhere in the app, in this case, we are running it when a button is clicked in MainActivity. It is set to run only when the phone is charging and battery is not low. It will be run once every 15 minute. It will run even if the activity is killed or the entire app is killed. To stop it, call WorkManager.getInstance().cancelAllWorkByTag("com.example.workmanagerexample.MyWorker"); The class path of the worker class is used as default TAG for the worker class if it is not set.

class MainActivity : AppCompatActivity() {

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

        start_worker.setOnClickListener {
            startWork()
        }
    }

    fun createConstraints() = Constraints.Builder()
            .setRequiresCharging(true)
            .setRequiresBatteryNotLow(true)
            .build()

    fun createWorkRequest(data: Data) = PeriodicWorkRequestBuilder<MyWorker>(15, TimeUnit.MINUTES)
            .setInputData(data)
            .setConstraints(createConstraints())
            .setBackoffCriteria(BackoffPolicy.LINEAR, PeriodicWorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)
            .build()

    fun startWork() {
        val work = createWorkRequest(Data.EMPTY)
        WorkManager.getInstance(applicationContext).enqueueUniquePeriodicWork("Sleep work", ExistingPeriodicWorkPolicy.REPLACE, work)
    }

}

The utility class for showing the notification WorkerUtil.kt

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import timber.log.Timber

/**
 * Create a Notification that is shown as a heads-up notification if possible.
 *
 * For this codelab, this is used to show a notification so that you know when different steps
 * of the background work chain are starting
 *
 * @param message Message shown on the notification
 * @param context Context needed to create Toast
 */
fun makeStatusNotification(message: String, context: Context) {

    // Make a channel if necessary
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        val name = VERBOSE_NOTIFICATION_CHANNEL_NAME
        val description = VERBOSE_NOTIFICATION_CHANNEL_DESCRIPTION
        val importance = NotificationManager.IMPORTANCE_HIGH
        val channel = NotificationChannel(CHANNEL_ID, name, importance)
        channel.description = description

        // Add the channel
        val notificationManager =
            context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?

        notificationManager?.createNotificationChannel(channel)
    }

    // Create the notification
    val builder = NotificationCompat.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_launcher_foreground)
        .setContentTitle(NOTIFICATION_TITLE)
        .setContentText(message)
        .setPriority(NotificationCompat.PRIORITY_HIGH)
        .setVibrate(LongArray(0))

    // Show the notification
    NotificationManagerCompat.from(context).notify(NOTIFICATION_ID, builder.build())
}

/**
 * Method for sleeping for a fixed about of time to emulate slower work
 */
fun sleep(durationInSec: Long) {
    try {
        Thread.sleep(ONE_SECOND_IN_MILLIS * durationInSec, 0)
    } catch (e: InterruptedException) {
        Timber.e(e)
    }
}

The constants used in the above classes, Constants.kt

// Name of Notification Channel for verbose notifications of background work
@JvmField val VERBOSE_NOTIFICATION_CHANNEL_NAME: CharSequence =
    "Verbose WorkManager Notifications"
const val VERBOSE_NOTIFICATION_CHANNEL_DESCRIPTION =
    "Shows notifications whenever work starts"
@JvmField val NOTIFICATION_TITLE: CharSequence = "WorkRequest Starting"
const val CHANNEL_ID = "VERBOSE_NOTIFICATION"
const val NOTIFICATION_ID = 1
const val ONE_SECOND_IN_MILLIS: Long = 1000

App icon for Android, IOS, React Native

Android and IOS both have their own set of rules for creating app icons. For React Native, since it’s cross platform, but it still has to follow the app icon rules for Android and IOS.

App icon for Android

App Icon file name: ic_launcher.png, ic_launcher_round.png
App Icon file size: mipmap-hdpi, mipmap-mdpi, mipmap-xhdpi, mipmap-xxhdpi, mipmap-xxxhdpi
App Icon file locations:
app/src/main/res/mpimap-hdpi/ic_launcher.png
app/src/main/res/mpimap-hdpi/ic_launcher_round.png
app/src/main/res/mpimap-mdpi/ic_launcher.png
app/src/main/res/mpimap-mdpi/ic_launcher_round.png
app/src/main/res/mpimap-xhdpi/ic_launcher.png
app/src/main/res/mpimap-xhdpi/ic_launcher_round.png
app/src/main/res/mpimap-xxhdpi/ic_launcher.png
app/src/main/res/mpimap-xxhdpi/ic_launcher_round.png
app/src/main/res/mpimap-xxxhdpi/ic_launcher.png
app/src/main/res/mpimap-xxxhdpi/ic_launcher_round.png

To change or update the app icon for Android, just replace the icon images in those image folders.

App icon for Android

App Icon file name: Icon-size.png
App Icon file size: 40, 58, 60, 80, 87, 120, ,121, 180, 1024, etc
App Icon file locations: Images.xcassets/AppIcon.appiconset

To change or update the app icon for IOS, launch XCode, navigate to Images.xcassets folder from the left directory panel, and then select AppIcon, then drag icon images to the appropriate location.

Generate App Icons

For Android, it can be done in Android Studio. File -> New -> Image Asset, or it can be done via a online Android icon generator at https://romannurik.github.io/AndroidAssetStudio/icons-generic.html

For IOS, search for IOS app icon generator and you should find a lot of online tools for generating IOS and Android app icons. 

How to create Android instant app

 1. Create a simple application by following the project creation wizard in Android Studio, File -> New -> New Project -> Empty Activity -> Next -> Finish.

2. In Android Studio, go to SKD manager -> SDK Tools, and make sure Google Play Instant Development SDK is installed.

3. Create a new module for the instant app within the existing app. File -> New -> New Module -> Instant Dynamic Feature Module -> Next, make sure the package name is the same as the base app’s package name. If the package name for the base app is com.example.instantappex, the package name for the instant app also need to be com.example.instantappex

4. Add design libraries and instant app library in dependencies block in the instant app’s app gradle. The instantapp app gradle should look like this.

plugins {
    id 'com.android.application'
    id 'kotlin-android'
}
android {
    compileSdkVersion 30
    buildToolsVersion "29.0.3"

    defaultConfig {
        applicationId "com.example.instantappex"
        minSdkVersion 26
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.6.0'

    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    androidTestImplementation 'androidx.annotation:annotation:1.2.0'

    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'

    implementation 'com.google.android.gms:play-services-instantapps:17.0.0'
}

5. Create a main activity in instant app and name it InstantMainActivity.kt with the following content.

package com.example.instantappex

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

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

6. Copy over the res folder from base app to instant app’s directory(copy project_base_dir/app/src/main/res -> project_base_dir/instantapp/src/main/res), update the activity_main.xml file with the following. The only change is changing the hello text to ‘Hello instant app!’

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".InstantMainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello instant app!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

7. Update the Manifest file in instant app’s module with the following.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:dist="http://schemas.android.com/apk/distribution"
    package="com.example.instantappex"
    android:targetSandboxVersion="2">

    <dist:module dist:instant="true" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.InstantAppEx">
        <activity
            android:name=".InstantMainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

8. Uninstall the base app if it’s installed, then select instantapp and go to Edit run configuration in Android Studio, and check the box for Deploy as Instant app under Installation options, and run the instantapp. If everything goes correctly, you should see a screen says ‘Hello instant app!’. Then if you quit the app, you won’t see app icon from your device for the instant app. It is installed or downloaded to device’s system cache, user has no direct access to launch it, and it will get deleted when device is restarted or if the system runs out of storage.

9. Make sure the base app always have a higher version code than the instant app. For a brand new app, you can set the version code for base app to 1000, and the version code for instant app to 1, and increase from there for new releases. For existing app, if the base app already has a very high version code, you might not need to worry about it as long as the instant app starts the version code at 1.

10. To release the app as instant app and make the try now button to show in play store, it has to be built as bundle aab file and make sure Instant Apps Only is selected when clicking the Create new release button in Google Play Console.

Android Apply Blur Effect on Application Background Image Programmatically

 Blurry effect image is common in most of android application because using the blur image effect android developer can set normal image as awesome background. So in this tutorial we would going to make App.ly Blur Effect on Application Background Image Programmatically.

Android Apply Blur Effect on Application Background Image Programmatically



1. Open Your project’s build.gradle(Project) file.

2. Add maven { url “https://jitpack.io” } inside the allprojects -> repositories block .

3. Now open build.gradle(Module: app) file.

4. Add compile ‘com.github.jgabrielfreitas:BlurImageView:1.0.1’ inside the dependencies block.

5. Download the below image and paste into res -> drawable folder.

blur

Code for MainActivity.java file.

package com.android_examples.blurimageview_android_examplescom; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import com.jgabrielfreitas.core.BlurImageView; public class MainActivity extends AppCompatActivity { BlurImageView blurImageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); blurImageView = (BlurImageView)findViewById(R.id.BlurImageView); blurImageView.setBlur(5); } }

Code for activity_main.xml layout file.

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/app" android:layout_width="match_parent" android:layout_height="match_parent" app:context="com.android_examples.blurimageview_android_examplescom.MainActivity"> <com.jgabrielfreitas.core.BlurImageView android:id="@+id/BlurImageView" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:src="@drawable/nature" /> </RelativeLayout>

Screenshot:

How to extract filename from Uri?

Now, we can extract filename with and without extension :) You will convert your bitmap to uri and get the real path of your file. Now w...