Skip to main content

Working with Android 11 (Changes and Security Features)

 Hello everyone , I am here with new article which is hot topic nowadays "Android 11" .The stable version of Android.

 Android 11 is the eleventh major release and 18th version of Android, the mobile operating system developed by the Open Handset Alliance led by Google. It was released on September 8, 2020.It is comes with many security features and other features as well .

And it is now compulsory in play store  to upload new apps with API lavel 30 which is compatible with Android 11 and from November onwards old apps also have to update with API 30 .Some other guidelines you can check out from here .Play Store Guidelines

So its clear that we have to update our apps with API level 30 .But Android 11 comes with some changes as well which we have to do in our projects.

For example from Android developer site "Android 11 (API level 30) further enhances the platform, giving better protection to app and user data on external storage. ".

Scoped storage enforcement:

Apps that run on Android 11 but target Android 10 (API level 29) can still request the requestLegacyExternalStorage attribute. This flag allows apps to temporarily opt out of the changes associated with scoped storage, such as granting access to different directories and different types of media files. After you update your app to target Android 11, the system ignores the requestLegacyExternalStorage flag.

If your app targets Android 11, both the WRITE_EXTERNAL_STORAGE permission and the WRITE_MEDIA_STORAGE privileged permission no longer provide any additional access.

Whats does it mean ? 

It means we have limited access of Write External Storage in Android 11 .Android introduce a new permission which is MANAGE_EXTERNAL_STORAGE

It will gives you some other access:

  • Read and write access to all files within shared storage.
  • Access to the contents of the MediaStore.Files table.
  • Access to the root directory of both the USB on-the-go (OTG) drive and the SD card.
  • Write access to all internal storage directories, except for /Android/data/, /sdcard/Android, and most subdirectories of /sdcard/Android. This write access includes direct file path access.
But here is some disclaimer that you have to justify why you are using this permission during uploading it to play store or other stores. You can take this permission when your app is one of them .Then you have to convince and your request will be approve by Google team.

  • File managers
  • Backup and restore apps
  • Anti-virus apps
  • Document management apps
  • On-device file search
  • Disk and file encryption
  • Device-to-device data migration
Access media files from shared storage programmatically, here we use capture current activity and share this.We are using MediaStore API here :

Uri imageUri = null;

.........
share=(ImageView)findViewById(R.id.share);
        share.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Bitmap bitmap = takeScreenshot();
                saveBitmap(bitmap);
                shareIt();
            }
        });

.................

public Bitmap takeScreenshot() {
        View rootView = findViewById(android.R.id.content).getRootView();
        rootView.setDrawingCacheEnabled(true);
        return rootView.getDrawingCache();
    }


 public void saveBitmap(Bitmap bitmap) {


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

            OutputStream fos = null;
             imageUri = null;

            ContentResolver resolver = ctx.getContentResolver();
            ContentValues contentValues = new ContentValues();
            contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "screen"+System.currentTimeMillis());
            contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/png");
            contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + File.separator);
            imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);

            if (imageUri == null)
                try {
                    throw new IOException("Failed to create new MediaStore record.");
                } catch (IOException e) {
                    e.printStackTrace();
                }

            try {
                fos = resolver.openOutputStream(imageUri);
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
                fos.flush();
                fos.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } 

    }

 private void shareIt() {


        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.Q)
        {

            Intent sharingIntent = new Intent(Intent.ACTION_SEND);

            sharingIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
            sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            sharingIntent.setDataAndType(imageUri, "image/*");
            //  sharingIntent.setType("image/*");
            String shareBody = "Please Find the screenshot.";
            sharingIntent.putExtra(Intent.EXTRA_SUBJECT, "Your Subject here");
            sharingIntent.putExtra(Intent.EXTRA_TEXT, shareBody);
            sharingIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
            startActivity(Intent.createChooser(sharingIntent, "Share via"));

        }

}


How to access contact list without using READ_CONTACTS permission:

contct.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
                if (intent.resolveActivity(getPackageManager()) != null) {
                    startActivityForResult(intent, PICK_CONTACT);
                }
            }
        });


........

public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(resultCode==Activity.RESULT_OK) {

            if (requestCode == PICK_CONTACT) {

                try {
                    Uri contactUri = data.getData();
                    String[] projection = new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER};
                    Cursor cursor = getContentResolver().query(contactUri, projection,
                            null, null, null);
                    // If the cursor returned is valid, get the phone number
                    if (cursor != null && cursor.moveToFirst()) {
                        int numberIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
                        String number = cursor.getString(numberIndex).replaceAll("-", "");


                        String selectedNumber = number.toString();
                        selectedNumber = selectedNumber.replace("-", "");
                        selectedNumber = selectedNumber.replace(" ", "");
                        selectedNumber =selectedNumber.replace("(","");
                        selectedNumber=selectedNumber.replace(")","");
                        selectedNumber = selectedNumber.replace("+91", "");
                        selectedNumber = selectedNumber.replace(" ", "");
                        if (selectedNumber.toString().length() >= 10) {
                            enteredMobile.setText(selectedNumber);
                        } else {
                            Toast.makeText(ctx, "Choose Valid mobile number",
                                    Toast.LENGTH_SHORT).show();
                        }

                    }

                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }

            }
        }

    }

but this will not work properly in Android 11 .To run smoothly in Android 11 as well we have to add some lines in AndroidManifest.xml file

  <queries>  
     <intent>  
       <action android:name="android.intent.action.VIEW" />  
     </intent>  
   </queries>  

you have question what is this ?

Package Visibility:

The new <queries> element in your app or library's Android manifest allows you to describe which other apps you might need to interact with.

You are trying to open some other third party app from your own app you can not open it directly .You have to mention that apps package in <queries> Tag in AndroidManifest.xml itself.like


 <queries>  
    ....  
     <package android:name="com.example.firstapp" />  
     <package android:name="com.example.secondapp" />  
     <package android:name="com.example.thirdapp" />   
   .....  
   </queries>  
To allow your app to see all other installed apps, Android 11 introduces the QUERY_ALL_PACKAGES permission. but you have to justify why you using this permission while uploading to play store.


If you are using Text to Speech in app you have to declare interaction with TTS engines in manifest file
Because of changes to package visibility, apps that target Android 11 and interact with a text-to-speech (TTS) engine need to add the following <queries> element to their manifest files:

 <queries>  
  <intent>  
   <action  
     android:name="android.intent.action.TTS_SERVICE" />  
  </intent>  
 </queries>  

If you use Custom Tabs to open URLs, you might be calling resolveActivity() and queryIntentActivities() in order to launch a non-browser app if one is available for the URL. In Android 11 there’s a better way to do this, which avoids the need to query other apps: the FLAG_ACTIVITY_REQUIRE_NON_BROWSER intent flag. 


Other than this Android 11 introduce:

One Time Permission:

Starting in Android 11, whenever your app requests a permission related to location, microphone, or camera, the user-facing permissions dialog contains an option called Only this time. If the user selects this option in the dialog, your app is granted a temporary one-time permission.

Phone Numbers Permission:

Android 11 changes the phone-related permission that your app uses when reading phone numbers.

Location Permission:

Android 11 adds one-time location access and changes how users grant background location access. These updates affect all apps that run on Android 11 and higher.


and some other changes also in Android 11 for security purpose .That's all guys for now. Share this article with your friends if you like this .

Thank you !! 😊😊😊






Comments

Popular posts from this blog

How to Download Apk file from Url and Install Programmatically

In this post we learn about download apk file from server or website and then install it Programmatically in Phone. Sometimes we have to download external apk file from server and then install if downloading successfully finished.For this we use AsyncTask class  for background process. So here is Code Snippet for this task.Lets Start :- Before this we have to add these Permissions in Manifest.xml file : <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> DownloadNewVersion.java class DownloadNewVersion extends AsyncTask<String,Integer,Boolean> { @Override protected void onPreExecute() { super.onPreExecute(); bar = new ProgressDialog(getActivity()); bar.setCancelable(false); bar.setMessage("Downl

How to open pdf file url using webview in Android

 Sometimes we have requirement of showing pdf file in our Android Application. Although there are many third party gradle dependencies available online by which you can show your pdf file easily but one of the major drawback of using these libraries are they will increase you apk size .In some cases they will increase apk size upto ~14 MB. Alternatively you can access and show pdf file using assets and from storage options. This can take less size than any third party library. Here we use pdf using url and if you directly open your pdf file url in webview you will get no result because it will start downoad if you open this link in any web browser.  So in this article we will learn how we can open our pdf url using webview and without using any third party library. So lets Start step by Step:- Lets Suppose you have a pdf file url something like   http://yourwebsite.com/files/mydocumentfile.pdf Step 1: So we you this pdf file url to embed in our webview .First of all you have to host yo

How to use UPI Deep Linking in Android

 In this Article we will discuss about the UPI Deep linking. By this Deep linking we can perform UPI Payments through intent .Basically it open the All UPI supported Application in our mobile then user choose their preference and initiate the Payment and through this we get the payment credentials like payment id ,transaction id ,etc. without any payment gateway. So lets start with what is UPI? Unified Payments Interface(UPI) is an instant real-time payment system developed by National Payments Corporation of India facilitating inter-bank transactions. The interface is regulated by the Reserve Bank of India and works by instantly transferring funds between two bank accounts on a mobile platform. (from Wikipedia) Coding part: package com.example.droidmedium; import android.content.Intent; import android.net.Uri; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Butt