应用程序安装后屏幕变空白(无法从设备获取文件夹)。

3

我已经建立了视频播放器,第一次安装后允许权限后屏幕会变空白,但之后应用程序就可以正常工作了。

这种情况只会在第一次允许权限后发生,在此之后应用程序都可以正常工作。

下面是允许权限之前的屏幕截图:

enter image description here

允许权限后屏幕会变空白,下面是屏幕截图:

enter image description here

如果我重新启动应用程序,它将开始显示所有包含视频的文件夹,以下是屏幕截图(从内存中删除应用程序并重新打开它):

enter image description here

以下是HomeActivity(MainActivity)代码的示例:

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);
            }
        }
    }
}

我已经使用了MVVM架构。

提前感谢你。


1
一旦您获得了权限,似乎您没有触发mFolderViewModel。尝试在授予权限后要求视图模型重新加载文件夹。 - Rahul Shukla
1
在用户授权后尝试使用“重新创建”。 - HARSH ASHRA
1
或者,您也可以尝试将以下代码行移动到函数initRecyclerView()中的subscribeObservers()上方: mFolderViewModel = new ViewModelProvider(this, new FolderViewModelFactory(this.getApplication(),"new awesome param")).get(FolderViewModel.class); - Rahul Shukla
2个回答

1

尝试使用 Dexter 库来解决这个问题

这是我用来解决相同问题的代码

 @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();

    }

这是showPermissionDeniedDialog()方法。
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();
    }

现在您不需要使用以前的权限请求逻辑...

这是完整的代码

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();
        }


希望这可以帮到你。如有需要澄清的地方,请随时提问...

第一次授权后,应用程序仍然出现空白问题。 - Dhananjay pathak
我猜问题出在onRequestPermissionsResult()方法上,这个方法会在权限被授予后运行。在运行完这个方法后,如果列表没有得到更新,我猜不知道为什么。请检查我在问题中提到的应用程序代码。 - Dhananjay pathak
@Dhananjaypathak 这有帮助吗? - Vishnu

1
这是更新后的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;
    }


    
}

请将您的HomeActivity.java更改为以下内容:

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);
            }
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接