In my app, i am calling cursor and then sending the cursor to recyclerView adapter but the problem is: At the 1st time when user-permissions were ask then the cursor returns null and so the recyclerView doesn't populate the data.
I have read these solution but they did not solve my problem. 1. Android READ_EXTERNAL_STORAGE permission not working 2. READ_EXTERNAL_STORAGE permission for Android 3. Android 6.0 (Marshmallow) READ_CONTACTS permission allows to read Contact's name when permission is denied 4. permission.READ_CONTACTS does not seem to work
My app is showing the data when i restart the app as then it doesn't ask for user-permissions.
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
Cursor mCursor=null;
recyclerViewSongAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestStoragePermission();
mCursor = getSongCursor();
if(mCursor==null)
Log.v("cursor_nullification","NO");
View playButton = findViewById(R.id.myPlayButtonId);
playButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "PLAY music", Toast.LENGTH_SHORT).show();
//Intent intent = new Intent(getBaseContext(),SongPlaying.class);
//intent.putExtra("song_")
}
});
recyclerView = findViewById(R.id.SongListId);
mAdapter = new recyclerViewSongAdapter(this,mCursor);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext(),LinearLayoutManager.VERTICAL,false);
//RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getApplicationContext(),2);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
//Toast.makeText(this, "Toast calling", Toast.LENGTH_SHORT).show();
recyclerView.setAdapter(mAdapter);
}
public Cursor getSongCursor(){
try{
Log.v("cursor_method_start","till now okay");
Uri externalUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] projection = new String[]{
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.SIZE,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.TRACK,
MediaStore.Audio.Media.YEAR
};
String selection = null;
String[] selectionArgs = null;
String sortOrder = MediaStore.Audio.Media.TITLE+" ASC";
Log.v("calling_cursor_formation","Okay till now");
Cursor songCursor = getContentResolver().query(externalUri,projection,selection,selectionArgs,sortOrder);
Toast.makeText(this, "Cursor formation", Toast.LENGTH_SHORT).show();
return songCursor;
}catch (Exception e) {
Toast.makeText(this, "ERROR!!!", Toast.LENGTH_SHORT).show();
return null;
}
}
private static final int MY_PERMISSIONS_REQUEST = 100;
private void requestStoragePermission() {
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST);
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// file-related task you need to do.
}
else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
}
}
}
I am quite new to cursor so i don't know where to use them. Do i have to call the cursor in background or is this line of code correct for calling cursor and how can i get my cursor data just after taking user-permissions. Thanks
Initially from onCreate()
, you should call getSongCursor()
after checking OS version & if Permission is granted on above M devices:
if (android.os.Build.VERSION.SDK_INT < M || (android.os.Build.VERSION.SDK_INT >= M && context.checkSelfPermission(GlobalConstants.WRITE_EXTERNAL_PERMISSION) == PackageManager.PERMISSION_GRANTED)){
mCursor = getSongCursor();
setAdapterInRecyclerView(); // created below
}else {
requestStoragePermission();
}
And call mCursor = getSongCursor();
after receiving permission from user :
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mCursor = getSongCursor(); // here
setAdapterInRecyclerView(); // created below
}
else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
}
}
Please feel free to ask any further
UPDATE :
create a method for setting Adapter & call after getSongCursor()
:
private void setAdapterInRecyclerView(){
mAdapter = new recyclerViewSongAdapter(this,mCursor);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext(),LinearLayoutManager.VERTICAL,false);
//RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getApplicationContext(),2);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
//Toast.makeText(this, "Toast calling", Toast.LENGTH_SHORT).show();
recyclerView.setAdapter(mAdapter);
}