Showing posts with label Android. Show all posts
Showing posts with label Android. Show all posts

Friday, October 21, 2016

Read and Write permission for storage and gallery - open failed: EACCES (Permission denied) Cordova

After Android OS upgrade to Marshmallow(6.0), permission has categorized into two sections "Normal and Dangerous Permissions". On this version on wards, users have to grant permission when the app is running but not at the time of app installation via play store. Also app developers have to request permission on "Dangerous Permission" at the time of using device resources such as Camera, Location, Gallery, External Storage.

Normal permissions do not directly risk the user's privacy. If your app lists a normal permission in its manifest, the system grants the permission automatically.

Dangerous permissions can give the app access to the user's confidential data. If your app lists a normal permission in its manifest, the system grants the permission automatically. If you list a dangerous permission, the user has to explicitly give approval to your app.
(Reference: Android API)


Let's create a sample Ionic project using Visual Studio 2015 to see how it is get done beginning of Marshmallow(API Level 23).

Step 01:- Create a Iconic tab template

Step 02:- Install File, FileTransfer, Permission plugins

cordova plugin add cordova-plugin-file
cordova plugin add cordova-plugin-file-transfer
cordova plugin add cordova-plugin-android-permissions@0.10.0

Please refer more details for the API urls listed below:

  • file (https://github.com/apache/cordova-plugin-file)
  • file-transfer (https://github.com/apache/cordova-plugin-file-transfer)
  • permissions (https://github.com/NeoLSN/cordova-plugin-android-permission)
Step 03:- Add a button to your UI and create a method in your control.

angular.module('starter.controllers', ['ionic'])

.controller('DashCtrl', function ($scope, $ionicPlatform) {

    $scope.downloadFile = function () {

        $ionicPlatform.ready(function () {
       // File for download
       var url = "http://www.gajotres.net/wp-content/uploads/2015/04/logo_radni.png";

       // File name only
       var filename = url.split("/").pop();

       // Save location
        var targetPath = cordova.file.externalRootDirectory + 'Download/' + filename;

       var fileTransfer = new FileTransfer();
       var uri = encodeURI(url);
       var trustHosts = true
       var options = {};


            fileTransfer.download(
                uri,
                targetPath,
                function (entry) {
                    console.log("download complete: " + entry.toURL());
                },
                function (error) {
                    console.log("download error source " + error.source);
                    console.log("download error target " + error.target);
                    console.log("download error code" + error.code);
                },
                trustHosts,
                options
            );
        });
    };
})

If you run this code without requesting permission for external storage, it will throw  open failed: EACCES (Permission denied) error message.

Step 04:-  Let's modify the code to request permission for storage.

Note: Go through the API documentation for more details.

//var permissions = cordova.plugins.permissions;
//permissions.hasPermission(permission, successCallback, errorCallback);
//permissions.requestPermission(permission, successCallback, errorCallback);
//permissions.requestPermissions(permissions, successCallback, errorCallback);


var permissions = cordova.plugins.permissions;
permissions.hasPermission(permissions.READ_EXTERNAL_STORAGE, checkPermissionCallback, null);

        function checkPermissionCallback(status) {
            if (!status.hasPermission) {
                var errorCallback = function () {
                    console.warn('Storage permission is not turned on');
                }
                permissions.requestPermission(
                  permissions.READ_EXTERNAL_STORAGE,
                  function (status) {
                      if (!status.hasPermission) {
                          errorCallback();
                      } else {
                          // continue with downloading/ Accessing operation 
                          $scope.downloadFile();
                      }
                  },
                  errorCallback);
            }
        }

Saturday, August 30, 2014

Update status bar notification

By using NotificationManager.notify(ID, notification) you can update existing notification in notification area. ID refers to existing notification. By using that you can update the content of the notification. notification has to be created by using NotificationCompat.Builder object. If the previous notification has been removed from the notification area, a new notification will be created.

  NotificationManager notificationMgt = (NotificationManager) getSystemService(
                                                     Context.NOTIFICATION_SERVICE);
// Use this id to update exsisting one, to create a new one, use a new ID
  notificationMgt.notify(9999, builder.build());


Refer How to create a simple status bar notification in Android article for more information on notifications.

How to create a simple status bar notification in Android

Notifications are the message that you can display to the user out side of your application's UI. When an application issue a notification, it will display within the notification area. Then user can expand the notification drawer to view full set of the the notifications that have been raised by the applications.

There are basically two types of the Notification Views:
  1. Normal view - can display small icon, title, message, notification issued time, count
  2. Big view - can define multiple messages, summary text, Big view style ..etc
Note: If you are planning to issue a notification via application, there should be at least an action to to raise once the user clicks the notification. eg: for an music player you may have pause, play, next..etc. 

Within this example will create a simple notification for the android devices: Click here to view How to create custom notification tutorial for extended status bar notifications.  You can check out how to update status bar notification blog post to know functionality of the  NotificationManager.notify(ID, notification). Using this method you can keep updating same notification within the notification area. such as email unread count, no of files uploaded...etc.

private void creaeSimpleNotification() {
  // Action one
  Intent dismissIntent = new Intent(this, MainActivity.class);
  dismissIntent.setAction("OFF");
  PendingIntent piDismiss = PendingIntent.getService(this, 0,
    dismissIntent, 0);

  // Action two
  Intent snoozeIntent = new Intent(this, MainActivity.class);
  snoozeIntent.setAction("ON");
  PendingIntent piSnooze = PendingIntent.getService(this, 0,
    snoozeIntent, 0);

  // Create notification builder to add notification
  NotificationCompat.Builder builder = new NotificationCompat.Builder(
   this.getApplicationContext())
   .setContentTitle("This is notification title")
   .setContentText("This is notification contnent")
   .setSmallIcon(R.drawable.notification_small_icon)
   .setStyle(new NotificationCompat.BigTextStyle())
   .addAction(R.drawable.notification_small_icon, "Off", piDismiss)  // Add action one   .addAction(R.drawable.notification_small_icon, "On", piSnooze); // Add action two
  Intent intent = new Intent(this, MainActivity.class);
  PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
    intent, 0);

  builder.setContentIntent(pendingIntent);
  NotificationManager notificationMgt = (NotificationManager) getSystemService(
                                                     Context.NOTIFICATION_SERVICE);
  notificationMgt.notify(9999, builder.build());
 }

Then onCreate method add above method as shown below:
        @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  creaeSimpleNotification();
 }


Output

How to create a custom toast in android

Toast messages are used display simple feedback to the user for some certain operations that happens in application. We can use toast messages to display such as Message saved to draft, Message has been sent, Record saved successfully .. etc for given time period.

First, instantiate a Toast object with one of the makeText() methods. This requires the application Context the text message, and the duration for the toast. Once it's initialized, you can display the toast notification with calling show() method.

Following example demonstrate creating a simple toast message:

Context context = getApplicationContext();
CharSequence text = "Hello toast!";
int duration = Toast.LENGTH_SHORT;

Toast toast = Toast.makeText(context, text, duration);
toast.show();

Or else you can directly display a toast message as follows:
Toast.makeText(context, text, duration).show();

To create a custom toast message, first create a layout for the custom view. Will create custome_toast_1.xml.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/toast_layout_root"
              android:orientation="horizontal"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:padding="8dp"
              android:background="#DAAA"
              >
    <ImageView android:src="@drawable/droid"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_marginRight="8dp"
               />
    <TextView android:id="@+id/text"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:textColor="#FFF"
              />
</LinearLayout>
Notice that the ID of the LinearLayout element is "toast_layout_root". You must use this ID to inflate the layout from the XML, as shown here:
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.custom_toast,
                               (ViewGroup) findViewById(R.id.toast_layout_root));

TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("This is a custom toast");

Toast toast = new Toast(getApplicationContext());
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();

Thursday, January 10, 2013

Create a Splash Screen for Android Application

Create a splashscreen.xml in res/layout folder path. Let's look at a simple design for a splash screen.
<linearlayout android:background="#FF7700" 
android:layout_height="fill_parent" 
android:layout_width="fill_parent" 
android:orientation="horizontal" 
xmlns:android="http://schemas.android.com/apk/res/android">

Create a Full Screen Activity In Android Application

Add following code snippet within you activity.
public class FullScreenActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                             WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.main_activity);
    }
}

How to create a Custom ListView In Android Application uisng ArrayAdapter

In this example, you can get to know how to create a custom list view using ArryaAdapter in android application development. I will create a custom header row for the list view and custom row for displaying android version image and version name. Once the row is clicked selected version name will be displayed in a Toast message.

Here is my listview_item_row.xml file. Place this file into layout directory under res folder.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >