





















































In this tutorial, we will discuss adding finishing touches to your Android app before you release it to the play store such as using the Android 6.0 Runtime permission model, scheduling an alarm, receiving notification of a device boot, Using AsyncTask for background work recipe, adding speech recognition to your app, and adding Google sign-in to your app.
This tutorial is an excerpt taken from the book 'Android 9 Development Cookbook - Third Edition', written by Rick Boyer. The book explores more than 100 proven industry standard recipes and strategies to help you build feature-rich and reliable Android Pie apps.
The old security model was a sore point for many in Android. It's common to see reviews commenting on the permissions an app requires. Sometimes, permissions were unrealistic (such as a Flashlight app requiring internet permission), but other times, the developer had good reasons to request certain permissions. The main problem was that it was an all-or-nothing prospect.
This finally changed with the Android 6 Marshmallow (API 23) release. The new permission model still declares permissions in the manifest as before, but users have the option of selectively accepting or denying each permission. Users can even revoke a previously granted permission.
Although this is a welcome change for many, for a developer, it has the potential to break the code that was working before. Google now requires apps to target Android 6.0 (API 23) and above to be included on the Play Store. If you haven't already updated your app, apps not updated will be removed by the end of the year (2018).
Create a new project in Android Studio and call it RuntimePermission. Use the default Phone & Tablet option and select Empty Activity when prompted for Activity Type.
The sample source code sets the minimum API to 23, but this is not required. If your compileSdkVersion is API 23 or above, the compiler will flag your code for the new security model.
We need to start by adding our required permission to the manifest, then we'll add a button to call our check permission code. Open the Android Manifest and follow these steps:
private final int REQUEST_PERMISSION_SEND_SMS=1;
private boolean checkPermission(String permission) { int permissionCheck = ContextCompat.checkSelfPermission( this, permission); return (permissionCheck == PackageManager.PERMISSION_GRANTED); }
private void requestPermission(String permissionName, int permissionRequestCode) { ActivityCompat.requestPermissions(this, new String[]{permissionName}, permissionRequestCode); }
private void showExplanation(String title, String message, final String permission, final int permissionRequestCode) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(title) .setMessage(message) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog,int id) { requestPermission(permission, permissionRequestCode); } }); builder.create().show(); }
public void doSomething(View view) { if (!checkPermission(Manifest.permission.SEND_SMS)) { if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.SEND_SMS)) { showExplanation("Permission Needed", "Rationale", Manifest.permission.SEND_SMS, REQUEST_PERMISSION_SEND_SMS); } else { requestPermission(Manifest.permission.SEND_SMS, REQUEST_PERMISSION_SEND_SMS); } } else { Toast.makeText(MainActivity.this, "Permission (already) Granted!", Toast.LENGTH_SHORT) .show(); } }
@Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case REQUEST_PERMISSION_SEND_SMS: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(MainActivity.this, "Granted!", Toast.LENGTH_SHORT) .show(); } else { Toast.makeText(MainActivity.this, "Denied!", Toast.LENGTH_SHORT) .show(); } return; } } }
Using the new Runtime Permission model involves the following:
Here are the corresponding methods:
Android provides AlarmManager to create and schedule alarms. Alarms offer the following features:
Alarms are not the best solution if you need a simple delay while your application is running (such as a short delay for a UI event.) For short delays, it's easier and more efficient to use a Handler, as we've done in several previous recipes.
When using alarms, keep these best practices in mind:
Alarms have three properties, as follows:
A repeating alarm has the same three properties, plus an Interval:
There are four alarm types:
Elapsed Real Time is better for time interval alarms, such as every 30 minutes.
The following recipe will demonstrate how to create alarms with AlarmManager.
Create a new project in Android Studio and call it Alarms. Use the default Phone & Tablet option and select Empty Activity when prompted for Activity Type.
Setting an alarm requires a Pending Intent, which Android sends when the alarm is triggered. Therefore, we need to set up a Broadcast Receiving to capture the alarm intent. Our UI will consist of just a simple button to set the alarm. To start, open the Android Manifest and follow these steps:
public class AlarmBroadcastReceiver extends BroadcastReceiver { public static final String ACTION_ALARM= "com.packtpub.alarms.ACTION_ALARM"; @Override public void onReceive(Context context, Intent intent) { if (ACTION_ALARM.equals(intent.getAction())) { Toast.makeText(context, ACTION_ALARM, Toast.LENGTH_SHORT).show(); } } }
public void setAlarm(View view) { Intent intentToFire = new Intent(getApplicationContext(), AlarmBroadcastReceiver.class); intentToFire.setAction(AlarmBroadcastReceiver.ACTION_ALARM); PendingIntent alarmIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intentToFire, 0); AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); long thirtyMinutes=SystemClock.elapsedRealtime() + 30 * 1000; alarmManager.set(AlarmManager.ELAPSED_REALTIME, thirtyMinutes, alarmIntent); }
Creating the alarm is done with this line of code:
alarmManager.set(AlarmManager.ELAPSED_REALTIME, thirtyMinutes, alarmIntent);
Here's the method signature:
set(AlarmType, Time, PendingIntent);
To set the alarm, we create a Pending Intent with our previously defined alarm action:
public static final String ACTION_ALARM= "com.packtpub.alarms.ACTION_ALARM";
This is an arbitrary string and could be anything we want, but it needs to be unique, so we prepend our package name. We check for this action in the Broadcast Receiver's onReceive() callback.
If you click the Set Alarm button and wait for thirty minutes, you will see the Toast when the alarm triggers. If you are too impatient to wait and click the Set Alarm button again before the first alarm is triggered, you won't get two alarms. Instead, the OS will replace the first alarm with the new alarm, since they both use the same Pending Intent. (If you need multiple alarms, you need to create different Pending Intents, such as using different Actions.)
If you want to cancel the alarm, call the cancel() method by passing the same Pending Intent you have used to create the alarm. If we continue with our recipe, this is how it would look:
alarmManager.cancel(alarmIntent);
If you want to create a repeating alarm, use the setRepeating() method. The Signature is similar to the set() method, but with an interval. This is shown as follows:
setRepeating(AlarmType, Time (in milliseconds), Interval, PendingIntent);
For the Interval, you can specify the interval time in milliseconds or use one of the predefined AlarmManager constants:
Android sends out many intents during its lifetime. One of the first intents sent is ACTION_BOOT_COMPLETED. If your application needs to know when the device boots, you need to capture this intent.
This recipe will walk you through the steps required to be notified when the device boots.
Create a new project in Android Studio and call it DeviceBoot. Use the default Phone & Tablet option and select Empty Activity when prompted for Activity Type.
To start, open the Android Manifest and follow these steps:
public class BootBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals( "android.intent.action.BOOT_COMPLETED")) { Toast.makeText(context, "BOOT_COMPLETED", Toast.LENGTH_SHORT).show(); } } }
When the device boots, Android will send the BOOT_COMPLETED intent. As long as our application has the permission to receive the intent, we will receive notifications in our Broadcast Receiver.
There are three aspects to make this work:
Obviously, you'll want to replace the Toast message with your own code, such as for recreating any alarms you might need.
Thus, in this article, we looked at different factors that need to be checked off before your app gets ready for the play store. We discussed three topics: Android 6.0 Runtime permission model, scheduling an alarm and detecting a device reboot. If you found this post useful, be sure to check out the book 'Android 9 Development Cookbook - Third Edition', to learn about using AsyncTask for background work recipe, adding speech recognition to your app, and adding Google sign-in to your app.
Building an Android App using the Google Faces API [ Tutorial]
How Android app developers can convert iPhone apps
6 common challenges faced by Android App developers