简体   繁体   中英

Android Studio Cursor Error code when trying to retrieve call log

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.fragmen t.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(Transactio nExecutor.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)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM