cursor 第一次为空,recyclerView 不显示游标数据
Posted
技术标签:
【中文标题】cursor 第一次为空,recyclerView 不显示游标数据【英文标题】:cursor is null first time and recyclerView doesn't show the cursor data 【发布时间】:2019-11-03 21:34:39 【问题描述】:在我的应用程序中,我正在调用游标,然后将游标发送到 recyclerView 适配器,但问题是:在第一次询问用户权限时,游标返回 null,因此 recyclerView 不会填充数据。
我已阅读这些解决方案,但它们并没有解决我的问题。 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
当我重新启动应用程序时,我的应用程序会显示数据,因为它不会请求用户权限。
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;
我对光标很陌生,所以我不知道在哪里使用它们。我是否必须在后台调用光标,或者这行代码对于调用光标是否正确,以及如何在获得用户权限后获取光标数据。 谢谢
【问题讨论】:
【参考方案1】:最初从onCreate()
,您应该在检查操作系统版本后调用getSongCursor()
,如果在上述M设备上授予权限:
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();
并在收到用户许可后致电mCursor = getSongCursor();
:
@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;
如有任何疑问,请随时询问
更新:
在getSongCursor()
之后创建一个设置Adapter & call的方法:
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);
【讨论】:
成功了。谢谢。你能帮我解决另一个问题吗? ***.com/questions/56692150/…【参考方案2】:将以下代码添加到您的 mainactivity 中并删除 null 表单初始化Cursor mCursor=null;
private void onStart()
super.onStart();
requestStoragePermission();
【讨论】:
以上是关于cursor 第一次为空,recyclerView 不显示游标数据的主要内容,如果未能解决你的问题,请参考以下文章
当 RecyclerView 为空时,CollapsingToolbarLayout 不应折叠