Learn Pain Less

HomeOur TeamContact
Android
Android 6.0 Runtime Permission example (Real Example)
Pawneshwer Gupta
Pawneshwer Gupta
June 12, 2016
1 min

Table Of Contents

01
Android 6.0 Runtime Permission example (Real Example)
02
Important note !!!!
Android 6.0 Runtime Permission example (Real Example)

Android 6.0 Runtime Permission example (Real Example)

As you know that in API 23 (Marshmallows) new Runtime Permission is added to android development. This feature make App installation more faster than before, because on Android Marshmallows above device your app will not ask for Permission at installation time. Permissions will be granted dynamically to your app when you actually need it. That’s a cool Idea. But if you have existing App and you try to install that app on Android Marshmallows device then your app will install without Permissions as expected but if you try to access Camera, Storage then your app will crash saying “No Permissions etc. Exception”. Because you haven’t yet defined runtime Permissions in your app. So you need to modify your app to ask for Permissions when required.

But maybe you tried adding some codes to make runtime Permission work on your app but you still got crash, then here is simple tutorial to embed runtime Permission in your app.

I will explain it everything.

So in this demo I will make an App having an ImageView and Button, when I click on button it will capture Image and display in ImageView. So below is code without runtime permissions. And its working fine on Below Marshmallows devices. But getting crash in Android Marshmallows.

here is code of activity_main.xml file :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.edablogs.runtimepermissiondemo.MainActivity">
<ImageView
android:layout_width="300dp"
android:id="@+id/image"
android:layout_centerHorizontal="true"
android:layout_height="300dp" />
<Button
android:layout_width="match_parent"
android:text="capture"
android:id="@+id/btn"
android:layout_below="@id/image"
android:layout_height="wrap_content" />
</RelativeLayout>

below is code of AndroidManifest.xml file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.edablogs.runtimepermissiondemo">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

and here is MainActivity.java :

package com.edablogs.runtimepermissiondemo;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
private Button btn;
private ImageView imageView;
// Request code for camera
private final int CAMERA_REQUEST_CODE = 100;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn);
imageView = (ImageView) findViewById(R.id.image);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
dispatchTakePictureIntent();
} else {
Toast.makeText(MainActivity.this, "Camera not supported", Toast.LENGTH_LONG).show();
}
}
});
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
Log.e("lpl", ex.getMessage());
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, CAMERA_REQUEST_CODE);
}
}
}
private void setPic() throws Exception {
// Get the dimensions of the View
int targetW = imageView.getWidth();
int targetH = imageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
imageView.setImageBitmap(bitmap);
}
public String mCurrentPhotoPath;
public File createImageFile() throws IOException {
// Create an image file name
String folderName = "test";
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File f = new File(Environment.getExternalStorageDirectory(), folderName);
if (!f.exists()) {
f.mkdirs();
}
File storageDir = new File(Environment.getExternalStorageDirectory()+"/"+folderName);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK){
try {
setPic();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

So we need to do changes in java file only. So I will modify MainActivity.java file to add runtime permissions. below is code after adding runtime permissions into our app. I need only 2 permissions at this time, Camera and External Storage.

so here is new code :

package com.edablogs.runtimepermissiondemo;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
private Button btn;
private ImageView imageView;
// Request code for camera
private final int CAMERA_REQUEST_CODE = 100;
// Request code for runtime permissions
private final int REQUEST_CODE_STORAGE_PERMS = 321;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn);
imageView = (ImageView) findViewById(R.id.image);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
if (!hasPermissions()){
// your app doesn't have permissions, ask for them.
requestNecessaryPermissions();
}
else {
// your app already have permissions allowed.
// do what you want.
dispatchTakePictureIntent();
}
} else {
Toast.makeText(MainActivity.this, "Camera not supported", Toast.LENGTH_LONG).show();
}
}
});
}
private boolean hasPermissions() {
int res = 0;
// list all permissions which you want to check are granted or not.
String[] permissions = new String[] {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
for (String perms : permissions){
res = checkCallingOrSelfPermission(perms);
if (!(res == PackageManager.PERMISSION_GRANTED)){
// it return false because your app dosen't have permissions.
return false;
}
}
// it return true, your app has permissions.
return true;
}
private void requestNecessaryPermissions() {
// make array of permissions which you want to ask from user.
String[] permissions = new String[] {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// have arry for permissions to requestPermissions method.
// and also send unique Request code.
requestPermissions(permissions, REQUEST_CODE_STORAGE_PERMS);
}
}
/* when user grant or deny permission then your app will check in
onRequestPermissionsReqult about user's response. */
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grandResults) {
// this boolean will tell us that user granted permission or not.
boolean allowed = true;
switch (requestCode) {
case REQUEST_CODE_STORAGE_PERMS:
for (int res : grandResults) {
// if user granted all required permissions then 'allowed' will return true.
allowed = allowed && (res == PackageManager.PERMISSION_GRANTED);
}
break;
default:
// if user denied then 'allowed' return false.
allowed = false;
break;
}
if (allowed) {
// if user granted permissions then do your work.
dispatchTakePictureIntent();
}
else {
// else give any custom waring message.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
Toast.makeText(MainActivity.this, "Camera Permissions denied", Toast.LENGTH_SHORT).show();
}
else if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)){
Toast.makeText(MainActivity.this, "Storage Permissions denied", Toast.LENGTH_SHORT).show();
}
}
}
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
Log.e("lpl", ex.getMessage());
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, CAMERA_REQUEST_CODE);
}
}
}
private void setPic() throws Exception {
// Get the dimensions of the View
int targetW = imageView.getWidth();
int targetH = imageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
imageView.setImageBitmap(bitmap);
}
public String mCurrentPhotoPath;
public File createImageFile() throws IOException {
// Create an image file name
String folderName = "test";
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File f = new File(Environment.getExternalStorageDirectory(), folderName);
if (!f.exists()) {
f.mkdirs();
}
File storageDir = new File(Environment.getExternalStorageDirectory()+"/"+folderName);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK){
try {
setPic();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

Important note !!!!

In AndroidManifest.xml don’t remove Permissions, otherwise your app will not ask for runtime Permissions and also it will not work on below Android Marshmallows devices.

Here is Video Tutorial of Runtime Permissions.

and here is demo video how Runtime Permissions look when you embed this code in your app.

Subscribe to our newsletter!

We'll send you the best of our blog just once a month. We promise.

Tags

androidMarshmallowsruntime permissions

Share


Pawneshwer Gupta

Pawneshwer Gupta

Software Developer

Pawneshwer Gupta works as a software engineer who is enthusiastic in creating efficient and innovative software solutions.

Expertise

Python
Flutter
Laravel
NodeJS

Social Media

Related Posts

How to use Text To Speech inside RecyclerView in Android
How to use Text To Speech inside RecyclerView in Android
July 27, 2020
1 min
Learn Pain Less  © 2024, All Rights Reserved.
Crafted with by Prolong Services

Quick Links

Advertise with usAbout UsContact Us

Social Media