i have no interest in the call log, but i can access it
with the limit and offset constraints you want using
the contentresolver, not the contentresolver
library. as i mentioned, the library uses a different
query() method than the one you need to use the
limit and offset constraints (at least according to
SO). you can access the contentresolver api
directly in java and with a javaobject in b4a to run
the necessary version of query().
please copy the permissions to the manifest:
AddPermission(android.permission.READ_CALL_LOG)
AddPermission(android.permission.READ_CONTACTS)
IN ADDITION: you need to access the permission manager
in your device's settings (capture2.png, attached), once the
app has been deployed. this is new.
add this to your b4a code: (as in capture.png, attached)
Dim jo As JavaObject
jo.InitializeContext
jo.RunMethod("callLog", Array(10,0))
at the end of your app, add the inline java code:
#if Java
import android.content.Context;
import android.content.ContentResolver;
import android.provider.MediaStore;
import android.database.Cursor;
import android.provider.MediaStore.Images.Media;
import android.provider.MediaStore.MediaColumns;
import android.content.res.AssetFileDescriptor;
import android.content.ContentValues;
import android.net.Uri;
import android.content.res.AssetManager;
import android.provider.CallLog;
import android.provider.CallLog.Calls;
import java.io.IOException;
import java.util.*;
import java.lang.String;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
public void callLog(int limit, int offset) {
if ( (limit < 1) || (offset < 0) ) {
BA.Log("limit and offset required");
return;
}
Bundle bundle = new Bundle();
bundle.putInt(ContentResolver.QUERY_ARG_OFFSET, offset);
bundle.putInt(ContentResolver.QUERY_ARG_LIMIT, limit);
bundle.putString(ContentResolver.QUERY_ARG_SORT_DIRECTION,CallLog.Calls.DATE + " DESC"); // if unspecified, it's supposed to default to default...
Cursor cursor = getContentResolver()
.query(
Uri.parse("content://call_log/calls"), // Uri
null, // projection
bundle, // bundle limit and offset
null); // cancellation
BA.Log( cursor.getCount() + " found.");
cursor.moveToFirst();
int number = cursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = cursor.getColumnIndex(CallLog.Calls.TYPE);
int date = cursor.getColumnIndex(CallLog.Calls.DATE);
int duration = cursor.getColumnIndex(CallLog.Calls.DURATION);
while(!cursor.isAfterLast()) {
String phNumber = cursor.getString(number);
String callDate = cursor.getString(date);
java.util.Date time = new java.util.Date(Long.parseLong(callDate));
BA.Log(phNumber + " " + time);
cursor.moveToNext();
}
cursor.close();
}
#end if
note: not all of the imports are necessary. they belong to some other code
i was using. i changed some of that code to access the call log, but i left
the imports that were already there. they won't hurt, and they can be removed
later. i also only show a couple fields available. that can also be changed.
let's see what you get when you try the routine. it works on my test device
running android 12 and sdk30.
oh, by the way, i only have 1 call on my test device, so i couldn't actually test
the limit and offset. you'll see what you get.