Download apk file using Download Manager on Android

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
//get destination to update file and set Uri
   //TODO: First I wanted to store my update .apk file on internal storage for my app but apparently android does not allow you to open and install
   //aplication with existing package from there. So for me, alternative solution is Download directory in external storage. If there is better
   //solution, please inform us in comment
   String destination = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
   String fileName = "AppName.apk";
   destination += fileName;
   final Uri uri = Uri.parse("file://" + destination);

   //Delete update file if exists
   File file = new File(destination);
   if (file.exists())
   //file.delete() - test this, I think sometimes it doesnt work
       file.delete();

   //get url of app on server
   String url = Main.this.getString(R.string.update_app_url);

   //set downloadmanager
   DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
   request.setDescription(Main.this.getString(R.string.notification_description));
   request.setTitle(Main.this.getString(R.string.app_name));

   //set destination
   request.setDestinationUri(uri);

   // get download service and enqueue file
   final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
   final long downloadId = manager.enqueue(request);

   //set BroadcastReceiver to install app when .apk is downloaded
   BroadcastReceiver onComplete = new BroadcastReceiver() {
       public void onReceive(Context ctxt, Intent intent) {
           Intent install = new Intent(Intent.ACTION_VIEW);
           install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
           install.setDataAndType(uri,
                   manager.getMimeTypeForDownloadedFile(downloadId));
           startActivity(install);

           unregisterReceiver(this);
           finish();
       }
   };
   //register receiver for when .apk download is compete
   registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

References
https://stackoverflow.com/questions/4967669/android-install-apk-programmatically
https://stackoverflow.com/questions/39147608/android-install-apk-with-intent-view-action-not-working-with-file-provider/40131196#40131196

Upgrade to Android Oreo and issue with Firebase Cloud Messaging

create a channel id

<string name="default_notification_channel_id" translatable="false">fcm_default_channel</string>

add a meta-data in manifest file

<application>
...
<meta-data        android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/default_notification_channel_id"/>
</application>

channel assignment

...
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    String channelId = context.getString(R.string.default_notification_channel_id);
    NotificationChannel channel = new NotificationChannel(channelId,   title, NotificationManager.IMPORTANCE_DEFAULT);
    channel.setDescription(body);
    mNotificationManager.createNotificationChannel(channel);
    builder.setChannelId(channelId);
}
mNotificationManager.notify(1, notification);
...

References
https://medium.com/globallogic-latinoamerica-mobile/firebase-cloud-messaging-warning-updating-to-android-oreo-1343fe894bd5
https://firebase.google.com/docs/cloud-messaging/android/receive

Declare a variable in Gradle usable in Java using buildConfigField and resValue

Generate Java Constants

android {
    buildTypes {
        debug {
            buildConfigField "int", "FOO", "42"
            buildConfigField "String", "FOO_STRING", "\"foo\""
            buildConfigField "boolean", "LOG", "true"
        }

        release {
            buildConfigField "int", "FOO", "52"
            buildConfigField "String", "FOO_STRING", "\"bar\""
            buildConfigField "boolean", "LOG", "false"
        }
    }
}

You can access them with BuildConfig.FOO

Generate Android resources

android {
    buildTypes {
        debug{
            resValue "string", "app_name", "My App Name Debug"
        }
        release {
            resValue "string", "app_name", "My App Name"
        }
    }
}

You can access them in the usual way with @string/app_name or R.string.app_name

String type build config fields should be declared like this:

buildConfigField "String", "SERVER_URL", "\"http://dev.myserver.com\""

References
https://stackoverflow.com/questions/17197636/is-it-possible-to-declare-a-variable-in-gradle-usable-in-java
https://stackoverflow.com/questions/30796533/how-to-generate-buildconfigfield-with-string-type

Customize Glide Network Timeouts on Android

build.gradle

implementation 'com.squareup.okhttp3:okhttp:3.12.0'
implementation "com.github.bumptech.glide:okhttp3-integration:4.9.0"
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'

create a new GlideModule

@GlideModule
public class CustomTimeOutOkHttpGlideModule extends LibraryGlideModule {

    @Override
    public void registerComponents(Context context, Glide glide, Registry registry) {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();

        // customize connection timeouts here
        // ...

        OkHttpClient okHttpClient = builder.build();

        registry.replace(GlideUrl.class, InputStream.class,
                new OkHttpUrlLoader.Factory(okHttpClient));
    }

}

References
https://futurestud.io/tutorials/glide-4-customize-network-timeouts
https://futurestud.io/tutorials/glide-module-example-accepting-self-signed-https-certificates
https://bumptech.github.io/glide/int/okhttp3.html