App screen gets blank after first installation (unable to fetch folders from device)

Viewed 61

I have build video player , it is working fine after installing for first time screen gets blank on first installation (after allowing permission)

this happens only after allowing permission for fist time after that app works fine ..

below is the screen shot of before allowing permission enter image description here

after allowing permission screen gets blank

below is the screen shot -

enter image description here

If i restart application it start showing all folder that are having videos in it

below it the screen shot (after removing app from ram and opening it again)

enter image description here

here is a code for HomeActivity (MainActivity) code -

public class HomeActivity extends AppCompatActivity {

//    ui
    RecyclerView mRecyclerView;
    TextView titleText;
    ImageView backButton;

    //var
    private static final String TAG = "HomeActivity";
    private static final int REQUEST_CODE_PERMISSION = 123;
    FolderAdapter mFolderAdapter;
    List<String> mFolderList;
    FolderViewModel mFolderViewModel;

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

        titleText = findViewById(R.id.top_folder_name);
        backButton = findViewById(R.id.back_button);
        backButton.setVisibility(View.INVISIBLE);
        mFolderViewModel = new ViewModelProvider(this, new FolderViewModelFactory(this.getApplication(),"new awesome param")).get(FolderViewModel.class);
        permission();
        Toast.makeText(this,"on create",Toast.LENGTH_SHORT).show();
        mFolderList = new ArrayList<>();
        titleText.setText("Folders");


    }

    private void subscribeObservers(){
        mFolderViewModel.getFolders().observe(this, new Observer<List<String>>() {
            @Override
            public void onChanged(List<String> Folders) {
                mFolderAdapter.setFolder(Folders);
            }
        });
    }
    private void initRecyclerView() {
        mRecyclerView = findViewById(R.id.folder_recyclerView);
        mFolderAdapter = new FolderAdapter(this);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this,RecyclerView.VERTICAL,false);
        subscribeObservers();
        mRecyclerView.setAdapter(mFolderAdapter);
        mRecyclerView.setLayoutManager(linearLayoutManager);
        Toast.makeText(HomeActivity.this,"yes",Toast.LENGTH_SHORT).show();

    }


    private void permission() {
        if(ContextCompat.checkSelfPermission(getApplicationContext(),
                Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){

            ActivityCompat.requestPermissions(HomeActivity.this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUEST_CODE_PERMISSION);
        }
        else{
              Toast.makeText(HomeActivity.this,"permission 1",Toast.LENGTH_SHORT).show();
                //setting observer in recyclerview
            initRecyclerView();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if(requestCode == REQUEST_CODE_PERMISSION){
            if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
                Toast.makeText(HomeActivity.this, "Permission Granted 2", Toast.LENGTH_SHORT).show();
                //setting observer in recyclerview
                initRecyclerView();
            }
            else{
                ActivityCompat.requestPermissions(HomeActivity.this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUEST_CODE_PERMISSION);
            }
        }
    }
}

I have used MVVM architecture .

thank you in advance

2 Answers

Try using Dexter library for solving this

Here's the code that I used to solve the same problem

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

        Dexter.withContext(this)
                .withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
                .withListener(new PermissionListener() {
                    @Override
                    public void onPermissionGranted(PermissionGrantedResponse permissionGrantedResponse) {
                        initRecyclerView();
                    }

                    @Override
                    public void onPermissionDenied(final PermissionDeniedResponse permissionDeniedResponse) {
                        showPermissionDeniedDialog();
                    }

                    @Override
                    public void onPermissionRationaleShouldBeShown(PermissionRequest permissionRequest, PermissionToken permissionToken) {
                        Toast.makeText(MainActivity.this, "App requires these permissions to run properly", Toast.LENGTH_SHORT).show();
                        permissionToken.continuePermissionRequest();
                    }
                })
                .check();

    }

Here's the showPermissionDeniedDialog() method

private void showPermissionDeniedDialog() {
        final androidx.appcompat.app.AlertDialog.Builder builder =
                new androidx.appcompat.app.AlertDialog.Builder(this);
        builder.setTitle("Permission Denied");
        builder.setMessage("Please Accept Necessary Permissions");
        builder.setCancelable(true);
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface imageDialog, int which) {
                imageDialog.cancel();
                startActivity(
                        new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                                .setData(Uri.fromParts("package", getPackageName(), null))
                );
            }
        });
        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface imageDialog, int which) {
                imageDialog.cancel();
                Toast.makeText(MainActivity.this, "App requires these permissions to run properly", Toast.LENGTH_SHORT).show();
            }
        });
        builder.show();
    }

You need not use the previous Permission Request logic now...

Here's the full code

public class HomeActivity extends AppCompatActivity {

        //    ui
        RecyclerView mRecyclerView;
        TextView titleText;
        ImageView backButton;

        //var
        private static final String TAG = "HomeActivity";
        private static final int REQUEST_CODE_PERMISSION = 123;
        FolderAdapter mFolderAdapter;
        List<String> mFolderList;
        FolderViewModel mFolderViewModel;

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



            titleText = findViewById(R.id.top_folder_name);
            backButton = findViewById(R.id.back_button);
            backButton.setVisibility(View.INVISIBLE);
            mFolderViewModel = new ViewModelProvider(this, new FolderViewModelFactory(this.getApplication(),"new awesome param")).get(FolderViewModel.class);


            Dexter.withContext(this)
                    .withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
                    .withListener(new PermissionListener() {
                        @Override
                        public void onPermissionGranted(PermissionGrantedResponse permissionGrantedResponse) {
                            initRecyclerView();
                        }

                        @Override
                        public void onPermissionDenied(final PermissionDeniedResponse permissionDeniedResponse) {
                            showPermissionDeniedDialog();
                        }

                        @Override
                        public void onPermissionRationaleShouldBeShown(PermissionRequest permissionRequest, PermissionToken permissionToken) {
                            Toast.makeText(MainActivity.this, "App requires these permissions to run properly", Toast.LENGTH_SHORT).show();
                            permissionToken.continuePermissionRequest();
                        }
                    })
                    .check();



            Toast.makeText(this,"on create",Toast.LENGTH_SHORT).show();
            mFolderList = new ArrayList<>();
            titleText.setText("Folders");


        }

        private void subscribeObservers(){
            mFolderViewModel.getFolders().observe(this, new Observer<List<String>>() {
                @Override
                public void onChanged(List<String> Folders) {
                    mFolderAdapter.setFolder(Folders);
                }
            });
        }
        private void initRecyclerView() {
            mRecyclerView = findViewById(R.id.folder_recyclerView);
            mFolderAdapter = new FolderAdapter(this);
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this,RecyclerView.VERTICAL,false);
            subscribeObservers();
            mRecyclerView.setAdapter(mFolderAdapter);
            mRecyclerView.setLayoutManager(linearLayoutManager);
            Toast.makeText(HomeActivity.this,"yes",Toast.LENGTH_SHORT).show();
        }


        private void showPermissionDeniedDialog() {
            final androidx.appcompat.app.AlertDialog.Builder builder =
                    new androidx.appcompat.app.AlertDialog.Builder(this);
            builder.setTitle("Permission Denied");
            builder.setMessage("Please Accept Necessary Permissions");
            builder.setCancelable(true);
            builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface imageDialog, int which) {
                    imageDialog.cancel();
                    startActivity(
                            new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                                    .setData(Uri.fromParts("package", getPackageName(), null))
                    );
                }
            });
            builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface imageDialog, int which) {
                    imageDialog.cancel();
                    Toast.makeText(MainActivity.this, "App requires these permissions to run properly", Toast.LENGTH_SHORT).show();
                }
            });
            builder.show();
        }

Hope this helps. Feel free to ask for clarifications...

Here's the updated code to your FolderViewModel:

package in.xparticle.divplayer.viewmodels;

import android.app.Application;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import java.util.ArrayList;
import java.util.List;

import in.xparticle.divplayer.HomeActivity;
import in.xparticle.divplayer.models.VideoFile;

public class FolderViewModel extends ViewModel {

    private static final String TAG = "FolderViewModel";
    private MutableLiveData<List<String>> mFolders = new MutableLiveData<>();

    public FolderViewModel(Context context,String Str) {
    //no need to call getAllFolders() here since we aren't sure if we have the permission
    }

    //Changed this function to public since we need to call it once the permission is granted
    public void getAllFolders(Context context) {
        List<String> tempVideoFolder = new ArrayList<>();
        List<VideoFile> tempVideoFiles = new ArrayList<>();

        Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        String projection[] ={
                MediaStore.Video.Media._ID,
                MediaStore.Video.Media.DATA,
                MediaStore.Video.Media.TITLE,
                MediaStore.Video.Media.SIZE,
                MediaStore.Video.Media.DATE_ADDED,
                MediaStore.Video.Media.DURATION,
                MediaStore.Video.Media.DISPLAY_NAME
        };


        Cursor cursor = context.getContentResolver().query(uri,projection,
                        null,null,null);

//you were checking "context != null"
        if(cursor != null){
            cursor.moveToFirst();
            Log.d(TAG, "getAllFolders folder count = " + cursor.getCount());
            do{
                String id = cursor.getString(0);
                String path = cursor.getString(1);
                String title = cursor.getString(2);
                String size = cursor.getString(3);
                String dataAdded = cursor.getString(4);
                String duration = cursor.getString(5);
                String fileName = cursor.getString(6);

                VideoFile videoFile = new VideoFile(id,path,title,size,dataAdded,duration,fileName);

                // /storage/sd_card/VideoDir/Abc/MyVideoFile.mp4
                int slashFirstIndex = path.lastIndexOf("/");
                String subString = path.substring(0,slashFirstIndex);
                // /storage/sd_card/VideoDir/Abc because last index excluded so slash excluded
                int index = subString.lastIndexOf("/");

                String folderName = subString.substring(index + 1 ,slashFirstIndex);
                //after doing this it will give us "Abc" as a folder name;
                Log.d(TAG, "getAllFolders: "+folderName);

                if(!tempVideoFolder.contains(folderName)){
                    tempVideoFolder.add(folderName);
                }


                //can be use to access video files for future use
                tempVideoFiles.add(videoFile);



            }while(cursor.moveToNext());
        }
        mFolders.postValue(tempVideoFolder);

    }


    public LiveData<List<String>> getFolders(){
        return mFolders;
    }


    
}

And change your HomeActivity.java as follows:

package in.xparticle.divplayer;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

import in.xparticle.divplayer.adapters.FolderAdapter;
import in.xparticle.divplayer.viewmodels.FolderViewModel;
import in.xparticle.divplayer.viewmodels.FolderViewModelFactory;

public class HomeActivity extends AppCompatActivity {

//    ui
    RecyclerView mRecyclerView;
    TextView titleText;
    ImageView backButton;

    //var
    private static final String TAG = "HomeActivity";
    private static final int REQUEST_CODE_PERMISSION = 123;
    FolderAdapter mFolderAdapter;
    List<String> mFolderList;
    FolderViewModel mFolderViewModel;

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

        titleText = findViewById(R.id.top_folder_name);
        backButton = findViewById(R.id.back_button);
        backButton.setVisibility(View.INVISIBLE);
        mFolderViewModel = new ViewModelProvider(this, new FolderViewModelFactory(this.getApplication(),"new awesome param")).get(FolderViewModel.class);
        Toast.makeText(this,"on create",Toast.LENGTH_SHORT).show();
        mFolderList = new ArrayList<>();
        titleText.setText("Folders");
        permission();

    }

    private void subscribeObservers(){
        mFolderViewModel.getFolders().observe(this, new Observer<List<String>>() {
            @Override
            public void onChanged(List<String> Folders) {
                mFolderAdapter.setFolder(Folders);
            }
        });
    }
    private void initRecyclerView() {
        mRecyclerView = findViewById(R.id.folder_recyclerView);
        mFolderAdapter = new FolderAdapter(this);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this,RecyclerView.VERTICAL,false);
        subscribeObservers();
        mFolderViewModel.getAllFolders(this);///explicit call to getAllFolders() since we are sure the permissions are granted
        mRecyclerView.setAdapter(mFolderAdapter);
        mRecyclerView.setLayoutManager(linearLayoutManager);
        Toast.makeText(HomeActivity.this,"yes",Toast.LENGTH_SHORT).show();

    }


    private void permission() {
        if(ContextCompat.checkSelfPermission(getApplicationContext(),
                Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){

            ActivityCompat.requestPermissions(HomeActivity.this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUEST_CODE_PERMISSION);
        }
        else{
//            Toast.makeText(HomeActivity.this,"first",Toast.LENGTH_SHORT).show();
                //setting observer in recyclerview
            initRecyclerView();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if(requestCode == REQUEST_CODE_PERMISSION){
            if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
                Toast.makeText(HomeActivity.this, "Permission Granted 2", Toast.LENGTH_SHORT).show();


                //setting observer in recyclerview
                permission();

            }
            else{
                ActivityCompat.requestPermissions(HomeActivity.this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUEST_CODE_PERMISSION);
            }
        }
    }
}
Related