cursor 第一次为 null 并且 recyclerView 不显示光标数据
cursor is null first time and recyclerView doesn't show the cursor data
在我的应用程序中,我正在调用游标,然后将游标发送到 recyclerView 适配器,但问题是:在第一次询问用户权限时,游标 returns 为空,因此 recyclerView 没有不填充数据。
我已经阅读了这些解决方案,但它们并没有解决我的问题。
1.
2.
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;
}
}
}
}
我对光标很陌生,所以我不知道在哪里使用它们。我是否必须在后台调用游标,或者这行代码是否正确调用游标,以及如何在获得用户权限后立即获取我的游标数据。
谢谢
将以下代码添加到您的主活动中并删除 null 表单初始化 Cursor mCursor=null;
private void onStart()
{
super.onStart();
requestStoragePermission();
}
最初来自 onCreate()
,您应该在检查 OS 版本后调用 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;
}
}
}
欢迎随时提问
更新:
创建一个用于设置 Adapter 并在 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);
}
在我的应用程序中,我正在调用游标,然后将游标发送到 recyclerView 适配器,但问题是:在第一次询问用户权限时,游标 returns 为空,因此 recyclerView 没有不填充数据。
我已经阅读了这些解决方案,但它们并没有解决我的问题。
1.
当我重新启动应用程序时,我的应用程序正在显示数据,因为它不会请求用户权限。
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;
}
}
}
}
我对光标很陌生,所以我不知道在哪里使用它们。我是否必须在后台调用游标,或者这行代码是否正确调用游标,以及如何在获得用户权限后立即获取我的游标数据。 谢谢
将以下代码添加到您的主活动中并删除 null 表单初始化 Cursor mCursor=null;
private void onStart()
{
super.onStart();
requestStoragePermission();
}
最初来自 onCreate()
,您应该在检查 OS 版本后调用 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;
}
}
}
欢迎随时提问
更新:
创建一个用于设置 Adapter 并在 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);
}