Reputation: 11
I was working on a simple phone app that shows the Call log and contacts also offers the possibility to call someone " It's Simply A Phone Caller ". The problem is when I was trying to retrieve the call log list using the cursor I got an error (Redline) that says the value must be >= 0.
Here is my fragment code
public class CallLogFragment extends Fragment {
private RecyclerView recyclerView;
private ArrayList<ModelCalls> arrayList;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.call_log_fragment, container, false);
recyclerView = view.findViewById(R.id.call_log_rv);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
RecyclerView.LayoutManager layoutManager = linearLayoutManager;
recyclerView.setLayoutManager(layoutManager);
CallLogAdapter adapter = new CallLogAdapter(getContext(), getCallLog());
recyclerView.setAdapter(adapter);
return view;
}
private ArrayList<ModelCalls> getCallLog() {
Cursor cursor = getContext().getContentResolver().query(
CallLog.Calls.CONTENT_URI,
null,
null,
null,
CallLog.Calls.DATE + " ASC"
);
String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
String duration = cursor.getString(cursor.getColumnIndex(CallLog.Calls.DURATION));
String date = cursor.getString(cursor.getColumnIndex(CallLog.Calls.DATE));
String name = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME));
cursor.moveToFirst();
while (cursor.moveToNext()) {
ModelCalls modelCalls = new ModelCalls(date, number, duration, name);
arrayList.add(modelCalls);
}
return arrayList;
}
}
And This is MainActivity Code :
public class MainActivity extends AppCompatActivity {
private String[] PERMISSIONS;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PERMISSIONS = new String[]{
Manifest.permission.READ_CONTACTS,
Manifest.permission.READ_CALL_LOG,
Manifest.permission.WRITE_CALL_LOG
};
if (!EasyPermissions.hasPermissions(this, PERMISSIONS)){
EasyPermissions.requestPermissions(this,
"Please allow Phone to access all the permissions",
123,
PERMISSIONS);
}
MaterialToolbar toolbar = findViewById(R.id.toolbar);
BottomNavigationView navigationView = findViewById(R.id.bottom_nav_view);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Phone");
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new CallLogFragment()).commit();
navigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
Fragment selectedFragment = null;
switch (id){
case R.id.nav_phone:
selectedFragment = new CallLogFragment();
getSupportActionBar().setTitle("Phone");
break;
case R.id.nav_contacts:
selectedFragment = new ContactsFragment();
getSupportActionBar().setTitle("Contacts");
break;
case R.id.nav_favorites:
selectedFragment = new FavoritesFragment();
getSupportActionBar().setTitle("Favorites");
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
selectedFragment).commit();
return true;
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
}
and I added those permissions to the manifest file:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS"/>
<uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
And Here is my error when running the app :
2021-09-20 16:13:32.725 10584-10584/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.highui.myphone, PID: 10584 android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1285 at android.database.AbstractCursor.checkPosition(AbstractCursor.java:515) at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:138) at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:52) at android.database.CursorWrapper.getString(CursorWrapper.java:141) at com.highui.myphone.CallLogFragment.getCallLog(CallLogFragment.java:50) at com.highui.myphone.CallLogFragment.onCreateView(CallLogFragment.java:36) at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963) at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282) at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189) at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100) at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002) at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3138) at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3072) at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:251) at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:502) at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246) at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1440) at android.app.Activity.performStart(Activity.java:8109) at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3806) at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:235) at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:215) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:187) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:105) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2386) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loop(Looper.java:213) at android.app.ActivityThread.main(ActivityThread.java:8178) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
Upvotes: 0
Views: 419
Reputation: 1472
you are trying to get information from outside the loop and also there is no specific projection for cursor.
Add projection in cursor and fetch information from cursor inside while loop.
like below code
private ArrayList<ModelCalls> getCallLog() {
String[] projection = new String[]{
CallLog.Calls.CACHED_NAME,
CallLog.Calls.NUMBER,
CallLog.Calls.DURATION,
CallLog.Calls.DATE
};
Cursor cursor = getContext().getContentResolver().query(
CallLog.Calls.CONTENT_URI,
projection,
null,
null,
CallLog.Calls.DATE + " ASC"
);
cursor.moveToFirst();
while (cursor.moveToNext()) {
String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
String duration = cursor.getString(cursor.getColumnIndex(CallLog.Calls.DURATION));
String date = cursor.getString(cursor.getColumnIndex(CallLog.Calls.DATE));
String name = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME));
ModelCalls modelCalls = new ModelCalls(date, number, duration, name);
arrayList.add(modelCalls);
}
cursor.close();
return arrayList;
}
Upvotes: 1