How to Handle storage permissions in Marshmallow.

Explain why the app needs permissions

In some circumstances, we recommend helping the user understand why your app needs permission. For example, if a user initiates a photo app, they probably will not be surprised if the app asks for permission to use the camera. However, the user may not understand why the app seeks to access the user's location or contacts. Before requesting a permit, you should consider providing an explanation to the user. Remember that you will not want to overwhelm the user with explanations; if you do, the user may feel frustrated and delete the app.

One approach you could use is to provide an explanation only if the user rejects the permission request. If the user continues to try to use a functionality that requires a permission, but continues to reject the permission request, this probably tells us not to understand why the app needs permission to provide that functionality. In a situation like this, you probably want to show an explanation.

To help detect situations in which the user might need an explanation, Android provides a utility method: shouldShowRequestPermissionRationale(). This method shows trueif the app requests the permission previously and the user rejects the request.


Runtime Permission


Android-M ie, API 23 introduced Runtime Permissions for reducing security flaws in android device, where users can now directly manage app permissions at runtime.so if the user denies a particular permission of your application you have to obtain it by asking the permission dialog that you mentioned in your query.
So check before action ie, check you have permission to access the resource link and if your application doesn't have that particular permission you can request the permission link and handle the the permissions request response like below.
@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        Log.v(TAG, "Permission: " + permissions[0] + "was " + grantResults[0]);
        //resume tasks needing this permission
    }
}

public boolean isStoragePermissionGranted() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            Log.v(TAG, "Permission is granted");
            // permission was granted, related task you need to do.
            return true;
        } else {
            Log.v(TAG, "Permission is revoked");
            // permission denied, boo! Disable the
            // functionality that depends on this permission.
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            return false;
        }
    } else { 
        //permission is automatically granted on sdk<23 upon installation        
        Log.v(TAG, "Permission is granted");
        return true;
    }
}

Download PDF using AsyncTask.

Hi all here i'm introducing new simple example how to download PDF file with AsyncTask, in this example you get idea how to download file, If you already downloaded  it will ask view of the article with respect pdf viewers.

DownloadFileAsync.java

call this method where ever we want

new DownloadFileAsync(this).execute();

public class DownloadFileAsync extends AsyncTask<String, Integer, Integer> {
    private Context mContext;
    private ProgressDialog mProgressDialog;
    private NotificationManager mNotifyManager;
    private NotificationCompat.Builder build;
    int id = 1;
    private File existingfile;
    private Uri pathUri;

    public DownloadFileAsync(Context context) {
        this.mContext = context;
        pathUri = Uri.parse("file:///" + Environment.getExternalStorageDirectory().getPath() + "/download/"+ArticleTitle+".pdf");
        existingfile = new File((Environment.getExternalStorageDirectory().getPath() + "/download/"+ArticleTitle+".pdf"));
        if (!existingfile.exists()) {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(pathUri, "application/pdf");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
            mNotifyManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
            build = new NotificationCompat.Builder(mContext);
            build.setContentTitle("Download").setContentText("Download in progress")
                    .setSmallIcon(R.mipmap.ic_launcher).setPriority(NotificationCompat.PRIORITY_DEFAULT)
                    // Set the intent that will fire when the user taps the notification                    .setContentIntent(pendingIntent).setAutoCancel(true);
        } else {
            Intent i = new Intent(Intent.ACTION_VIEW);
            i.setDataAndType(pathUri, "application/pdf");
            mContext.startActivity(i);
        }
    }

    @Override    protected void onPreExecute() {
        super.onPreExecute();
        if (!existingfile.exists()) {
            mProgressDialog = ProgressDialog.show(mContext, "", "please wait.....");
            build.setProgress(100, 0, false);
            mNotifyManager.notify(id, build.build());
        }
    }

    @Override    protected Integer doInBackground(String... aurl) {
        if (!existingfile.exists()) {
            mProgressDialog.show();

            int count;
            try {
                URL url = new URL(PDFURL);
                URLConnection conection = url.openConnection();
                conection.connect();
                // getting file length                int lenghtOfFile = conection.getContentLength();
                // input stream to read file - with 8k buffer                InputStream input = new BufferedInputStream(url.openStream(), 8192);
                // Output stream to write file                OutputStream output = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/download/"+ArticleTitle+".pdf");

                byte data[] = new byte[1024];
                long total = 0;
                while ((count = input.read(data)) != -1) {
                    //total += count;                    output.write(data, 0, count);
                }
                output.flush();
                output.close();
                input.close();

            } catch (Exception e) {
                Log.e("Error: ", e.getMessage());
            }
            int i;
            for (i = 0; i <= 100; i += 5) {
                // Sets the progress indicator completion percentage                publishProgress(Math.min(i, 100));
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Log.d("Failure", "sleeping failure");
                }
            }
        }
        return null;
    }

    protected void onProgressUpdate(Integer... progress) {
        if (!existingfile.exists()) {
            build.setProgress(100, progress[0], false);
            mNotifyManager.notify(id, build.build());
            super.onProgressUpdate(progress);
        }
    }

    @Override    protected void onPostExecute(Integer unused) {
        if (mProgressDialog != null && mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
            build.setContentText("Download complete");
            // Removes the progress bar            build.setProgress(0, 0, false);
            mNotifyManager.notify(id, build.build());
            super.onPostExecute(unused);
        }
    }
}


How to play YouTube video in android Application.

In this tutorial we are going to learn how to play YouTube video in the app.  This article covers very basics of YouTube Android API. If you want refer youtube API in developer, please go through  Android Youtube API docs provided by Google.



As we are interacting with Google APIs, we need to get the Google Developer API Key first. Follow below steps to obtain your Google Developer Android API Key.

1. Android API Key

1. First we need to get the SHA-1 fingerprint on your machine using java keytool. Execute the below command in cmd/terminal to get the SHA-1 fingerprint.
On Windows
keytool -list -v -keystore "your android\degug.keystore path" -alias androiddebugkey -storepass android -keypass android
2. Go to Google Developer Console and select or create a new project. And turn the status ON for YouTube Data API v3.
3. On the left sidebar, select Credentials and Create new key.
4. When popup comes asking you to choose platform, select Android Key.
5. Paste the SHA-1 key and your project’s package name
6. Click on create. Now you should see the API KEY on the dashboard.

2. Creating the Android Project

1.In Android studio create a new android project by navigating to File ⇒ New ⇒ Android Application Project and fill out all the required details.
2. Download the latest of version of   YouTube Android Player API - Download and extract it. Once extracted, you can find YouTubeAndroidPlayerApi.jar file inside libs folder.
3. Paste the YouTubeAndroidPlayerApi.jar file in your project’s libs folder.
4. Create a class named Constants.java to keep our app configuration variables like Google Developer Key.
In Constants.java class, you need to replace the DEVELOPER_KEY with your own API KEY that we generated in the Google Developer Console.


Constants.java


public class Constants{
   // Google Console APIs developer key   
// Replace this key with your's  
 public static final String DEVELOPER_KEY = "xxxxxxxxxxxxxxxxx";

}
 5.Now open the layout file of your main activity (activity_main.xml) and add below code. This creates a simple layout with YouTubePlayerView.

activity_main.xml

<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">
    <LinearLayout        
        android:layout_width="fill_parent"        
        android:layout_height="wrap_content"        
        android:background="@drawable/rouned_corner_shadow"        
        android:gravity="center_horizontal"        
        android:orientation="vertical">
        <com.google.android.youtube.player.YouTubePlayerView            
           android:id="@+id/youtube_video_player"            
           android:layout_width="match_parent"            
           android:layout_height="match_parent"            
           android:visibility="visible">
        </com.google.android.youtube.player.YouTubePlayerView>
    </LinearLayout>
</RelativeLayout>
6. Open your main activity class (MainActivity.java) and do the below simple changes. Here the activity is extended from YouTubeBaseActivity which will be present in YouTubeAndroidPlayerApi.jar. In case your not extend YouTubeBaseActivity  application will not run..

7.If your don't have any youtube_ID fetch it from youtube url using  getYouTubeId() function.

  MainActivity.java


import com.google.android.youtube.player.YouTubeBaseActivity;
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayer.PlayerStyle;
import com.google.android.youtube.player.YouTubePlayerView;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MainActivity extends YouTubeBaseActivity implements  YouTubePlayer.OnInitializedListener {

   private static final int RECOVERY_DIALOG_REQUEST = 1;
   private YouTubePlayerView youTubeView;

   @Override   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      youTubeView = (YouTubePlayerView) findViewById(R.id.youtube_video_player);
      // Initializing video player with developer key      
      youTubeView.initialize(Constants.DEVELOPER_KEY, this);

   }

   @Override   public void onInitializationFailure(YouTubePlayer.Provider provider,
                              YouTubeInitializationResult errorReason) {
      if (errorReason.isUserRecoverableError()) {
         errorReason.getErrorDialog(this, RECOVERY_DIALOG_REQUEST).show();
      } else {
         String errorMessage = String.format(
               getString(R.string.error_player), errorReason.toString());
         Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
      }
   }

   @Override   public void onInitializationSuccess(YouTubePlayer.Provider provider,
                              YouTubePlayer player, boolean wasRestored) {
      if (!wasRestored) {
         // loadVideo() will auto play video   
        // Use cueVideo() method, if you don't want to play it automatically
// if you have Youtube_Id pass directly here 
player.loadVideo("Youtube_ID");
         // If you don't have youtube ID get it from youtube url using this methos 
        //player.loadVideo(getYouTubeId("Youtube_URL"));          
       // Hiding player controls        
         player.setPlayerStyle(PlayerStyle.CHROMELESS);
      }
   }

   @Override   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      if (requestCode == RECOVERY_DIALOG_REQUEST) {
         // Retry initialization if user performed a recovery action
         getYouTubePlayerProvider().initialize(Config.DEVELOPER_KEY, this);
      }
   }

   private YouTubePlayer.Provider getYouTubePlayerProvider() {
      return (YouTubePlayerView) findViewById(R.id.youtube_view);
   }

   private String getYouTubeId(String youTubeUrl) {
      String pattern = "(?<=youtu.be/|watch\\?v=|/videos/|embed\\/)[^#\\&\\?]*";
      Pattern compiledPattern = Pattern.compile(pattern);
      Matcher matcher = compiledPattern.matcher(youTubeUrl);
      if (matcher.find()) {
         return matcher.group();
      } else {
         return "error";
      }
   }


Select DateRange UsingRangePicker.

  /* * This Method is for select range from picker. * */ private fun selectDateRangeUsingRangePicker () { pageNumber = 1 val displ...