checkIfValid() on a null object reference (Realm 3.1.3) - android

I'm using Realm 3.1.3 and Realm Adapters 2.0 in my project and getting this error when I try to update the adapter using
adapter.updateData(RealmManager.stationsDetailsDAO().loadSearch(newText.toLowerCase(), selectedLanguage, type));
Here's the error thrown
Attempt to invoke virtual method 'void io.realm.BaseRealm.checkIfValid()' on a null object reference
when trying to query from the Database
Here's my code :
public RealmList<Station> loadSearch(String query, String language, String type) {
RealmList<Station> stationRealmList = new RealmList<>();
mRealm.executeTransaction(realm -> mRealm.copyToRealm(stationRealmList));
// To make it a Managed Object
switch (type) {
case "Language": {
RealmQuery<Station> stationRealmQuery = mRealm.where(Station.class);
stationRealmQuery.equalTo("language", language);
RealmResults<Station> realmResults = stationRealmQuery.findAll();
for (int i = 0; i < realmResults.size(); i++) {
if (realmResults.get(i).getName().contains(query)) {
stationRealmList.add(realmResults.get(i));
}
}
return stationRealmList;
}
case "Recent":
HeaderSectionModel realmList = RealmManager.stationsDetailsDAO().loadHeaderData();
for (int i = 0; i < realmList.getLanguageModelArrayList().size(); i++) {
if (realmList.getLanguageModelArrayList().get(i).getName().contains(query)) {
stationRealmList.add(realmList.getLanguageModelArrayList().get(i));
}
}
return stationRealmList;
case "Genre": {
RealmQuery<Station> stationRealmQuery = mRealm.where(Station.class);
stationRealmQuery.equalTo("genreName", language);
RealmResults<Station> realmResults = stationRealmQuery.findAll();
for (int i = 0; i < realmResults.size(); i++) {
if (realmResults.get(i).getName().contains(query)) {
stationRealmList.add(realmResults.get(i));
}
}
return stationRealmList;
}
}
return stationRealmList;
}

because RealmList<Station> stationRealmList = new RealmList<>(); is not a managed view of a link (as in not obtained from a managed RealmObject with getRealmListField()), so RealmRecyclerViewAdapter doesn't work with it.
The solution is that you're supposed to display a RealmResults defined by a RealmQuery instead of manually trying to do a contains operation.
public RealmResults<Station> loadSearch(String query, String language, String type) {
RealmQuery<Station> stationRealmQuery = mRealm.where(Station.class);
if(query != null && !"".equals(query)) {
stationRealmQuery.contains("name", query);
}
switch (type) {
case "Language":
stationRealmQuery.equalTo("language", language);
break;
case "Recent":
// TODO do something about this one
break;
case "Genre":
stationRealmQuery.equalTo("genreName", language);
break;
}
return stationRealmQuery.findAll();
}
If this is not possible, then use a regular RecyclerView.Adapter and your own RealmChangeListener.

Related

How do I write a json field to retrieve this?

I am currently using json for my code to retrieve an array of boolean values. However, i am adding a subfield to achieve another array within, but I am not good with json and kind of stuck how to go about it.
Here's my code so far:
field values :
public enum Field {
/**
* Runtime Config Fields
**/
FIELD_CAN_CHANGE_PASSWORD("canChangePassword", true, canUpdate),
FIELD_MAX_AUTO_DOWNLOAD_SIZE("maxAutoDownloadSize", 5000000L),
FIELD_ALWAYS_REAUTHENTICATE("alwaysReauthenticate", false, canUpdate),
FIELD_CAN_START_CALL("canStartCall", false),
FIELD_ROOMS_ENABLED("roomsEnabled", !Core.isMessenger()),
FIELD_CAN_CREATE_ROOM("canCreateRoom", !Core.isMessenger(), canUpdate),
FIELD_MAX_ENVELOPE_TTL("maxTTL", Core.isMessenger() ? 518400L : 31536000L, canUpdate),
FIELD_MAX_BURN_ON_READ_TTL("maxBOR", 0L, canUpdate),
FIELD_MAX_UPLOAD_SIZE("maxUploadSize", -1L, true),
FIELD_FRIEND_FINDER("friendFinder", !Core.isEnterprise(), canUpdate),
FIELD_ONLY_SHOW_IN_NETWORK_CONTACTS("onlyShowInNetwork", false),
FIELD_CAN_ADD_CONTACT("canAddContact", true, canUpdate),
FIELD_FORCE_DEVICE_LOCKOUT("forceDeviceLockout", 5L, canUpdate),
FIELD_VERIFICATION_MODE("verificationMode", VerificationMode.OPTIONAL.getValue(), true),
FIELD_ENABLE_NOTIFICATION_PREVIEW("enableNotificationPreview", true, true),
FIELD_DIRECTORY_ENABLED("directoryEnabled", true, true);
public String fieldName;
public Object defaultValue;
public boolean updateFromServer;
Field(String key, Object defaultValue) {
this(key, defaultValue, true);
}
Field(String key, Object defaultValue, boolean updateFromServer) {
this.fieldName = key;
this.defaultValue = defaultValue;
this.updateFromServer = updateFromServer;
}
}
putting values in field:
private void putValueForField(JSONObject configuration, Field field) {
try {
if (configuration.isNull(field.fieldName)) {
Object value = field.defaultValue;
if (value instanceof long[]) {
JSONArray array = new JSONArray();
for (long obj : (long[]) field.defaultValue) {
array.put(obj);
}
value = array;
}
runtimeConfiguration.put(field.fieldName, value);
} else {
runtimeConfiguration.put(field.fieldName, configuration.get(field.fieldName));
}
} catch (JSONException e) {
}
}
getting values :
private Object getValueForField(Field field) {
if (runtimeConfiguration.has(field.fieldName) && field.updateFromServer) {
try {
Object value = runtimeConfiguration.get(field.fieldName);
if (value instanceof JSONArray) {
JSONArray values = (JSONArray) value;
if (values.get(0) instanceof Number) {
long[] retVals = new long[values.length()];
for (int i = 0; i < values.length(); i++) {
retVals[i] = ((Number) values.get(i)).longValue();
}
return retVals;
}
} else if (value instanceof Number) {
return ((Number) value).longValue();
} else {
return value;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return field.defaultValue;
}
one of the methods using the fields above:
public boolean canChangePassword() {
return (boolean) getValueForField(Field.FIELD_CAN_CHANGE_PASSWORD);
}
My new json is :
{"enableNotificationPreview":true,"destructOnRead":[30,60,300],"alwaysReauthenticate":false,"forceDeviceLockout":0,"permmod":1516894585,"maxBOR":0,"roomsEnabled":true,"directoryEnabled":true,"canStartCall":true,"canAddContact":true,"legacyDownload":false,"verificationMode":1,"restrictedAdmin":false,"canChangePassword":true,"friendFinder":true,"NEWVALUE":{"canStartNewValue1":true,"canStartroupValue":true,"canVideoCall":true,"canStartRoomValue":true,"canAddtoValue":true,"canStartValueshare":true},"canCreateRoom":true,"maxTTL":2592000,"onlyShowInNetwork":false,"maxUploadSize":null,"availableEnvelopeTTL":[0,600,3600,86400,604800,2592000],"maxAutoDownloadSize":7340032}
where I am plugging in :
"NEWVALUE":{"canStartNewValue1":true,"canStartroupValue":true,"canVideoCall":true,"canStartRoomValue":true,"canAddtoValue":true,"canStartValueshare":true}
Not sure how to update my putValueForField to reflect this new json and the corresponding fields. Any idea?
To check and retrieve JSONObject from the json object you can modify your method to check for instance of JSONObject and assign value to it.
private void putValueForField(JSONObject configuration, Field field) {
try {
if (configuration.isNull(field.fieldName)) {
Object value = field.defaultValue;
if (value instanceof long[]) {
JSONArray array = new JSONArray();
for (long obj : (long[]) field.defaultValue) {
array.put(obj);
}
value = array;
}
// this is how you check if fieldName is of type jsonobject
if (value instanceof JSONObject) {
JSONObject valueObject = configuration.getJSONObject(field.fieldName);
value = valueObject;
}
runtimeConfiguration.put(field.fieldName, value);
} else {
runtimeConfiguration.put(field.fieldName, configuration.get(field.fieldName));
}
} catch (JSONException e) {
}
}
Form what I can understand you are just getting the values from JSON and saving it in field in that case:
I think in this method ultimately you are just storing all values as object only so while retrieving you have to do all this check again.
If you are getting the response from server with fixed Object fields and object values you should be creating a class from that configuration where you will know what exactly it will return. That would really make life easier.
Or maybe if you just need the configuration to get/update or put values you can maintain it in json object itself Android JSON doc reference
For example lets say you have this jsonobject itself, I have added the working example below, hope this helps.
import org.json.*;
class Main {
public static void main(String[] args) throws JSONException {
String jsn = "{\"enableNotificationPreview\":true,\"destructOnRead\":[30,60,300],\"" +
"alwaysReauthenticate\":false,\"forceDeviceLockout\":0,\"NEWVALUE\":{\"canStartNewValue1\":true," +
"\"canStartroupValue\":true,\"canVideoCall\":true,\"canStartRoomValue\":true},\"canCreateRoom\":true," +
"\"maxTTL\":2592000,\"onlyShowInNetwork\":false,\"maxUploadSize\":null,\"availableEnvelopeTTL\"" +
":[0,600,3600,86400,604800,2592000],\"maxAutoDownloadSize\":7340032}";
JSONObject jsnObj = new JSONObject(jsn);
Object enableNotificationPreview = jsnObj.get("enableNotificationPreview");
// or if you know it will be boolean
boolean enableNotificationPreviewBool = jsnObj.getBoolean("enableNotificationPreview");
System.out.println(enableNotificationPreview);
// output : true
System.out.println(enableNotificationPreviewBool);
// output : true
JSONObject NEWVALUEObj = jsnObj.getJSONObject("NEWVALUE");
// now again you can extract values from it
boolean canStartNewValue1 = NEWVALUEObj.getBoolean("canStartNewValue1");
System.out.println(canStartNewValue1);
NEWVALUEObj.put("canStartNewValue1", false);
System.out.println(NEWVALUEObj.toString());
jsnObj.put("forceDeviceLockout", 23456);
// now canStartNewValue1 value is changed to false in the object
// and forceDeviceLockout is also 23456
System.out.println(jsnObj.toString());
}
}

Check if Parse Array contain value android

I use Parse in android. I am trying to check if an array contain an value (ObjectId).
private void getCurrentObject() {
query = ParseQuery.getQuery("Group");
query.getInBackground(objectid, new GetCallback<ParseObject>() {
public void done(ParseObject object, ParseException e) {
object = all;
if (e == null) {
if (userexists(object.getJSONArray("members_array"), currentUser.getObjectId())) {
Toast.makeText(GroupActivity.this, "isDo", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(GroupActivity.this, "isNot", Toast.LENGTH_SHORT).show();
}
}
}
});
}
private boolean userexists(JSONArray jsonArray, String usernameToFind) {
return jsonArray.toString().contains(usernameToFind);
}
While run the app i got this error
"java.lang.NullPointerException: Attempt to invoke virtual method
'org.json.JSONArray
com.parse.ParseObject.getJSONArray(java.lang.String)' on a null object
reference
Remove this line
object = all;
Or, you probably meant all = object
Then, you need to loop over the JSONArray, not toString it.
private boolean userexists(JSONArray jsonArray, String usernameToFind) {
if (jsonArray == null) return false;
for (int i = 0; i < jsonArray.length(); i++) {
String s = jsonArray.optString(i, "");
if (s.equals(usernameToFind)) return true;
}
return false;
}
Using this method
String optString(int index, String fallback)
Returns the value at
index if it exists, coercing it if necessary.

cannot find symbol type token in android studio?

private void loadFromAndToPlaceValues() {
String str = loadJSONFromAsset();
this.places = (List)new Gson().fromJson(str, newTypeToken<List<BusEntity>>().getType());
if (this.places != null && this.places.size() > 0) {
this.places_array = new String[this.places.size()];
for (int i = 0; i < this.places_array.length; i++) {
this.places_array[i] = ((BusEntity) this.places.get(i)).getValue();
}
}
}
You've missed {} braces. Change it like following.
this.places = (List)new Gson().fromJson(str, new TypeToken<List<BusEntity>>(){}.getType());
On a different note, question should be more constructive and descriptive. Posting plain code likely won't yield good answer most of the time.
It may help you :
Option 1 - implement java.lang.reflect.ParameterizedType yourself and pass it to Gson.
private static class ListParameterizedType implements ParameterizedType {
private Type type;
private ListParameterizedType(Type type) {
this.type = type;
}
#Override
public Type[] getActualTypeArguments() {
return new Type[] {type};
}
#Override
public Type getRawType() {
return ArrayList.class;
}
#Override
public Type getOwnerType() {
return null;
}
// implement equals method too! (as per javadoc)
}
Then simply:
Type type = new ListParameterizedType(clazz);
List<T> list = gson.fromJson(json, type);
This will work too, at least with Gson 2.2.4.
Type type = com.google.gson.internal.$Gson$Types.newParameterizedTypeWithOwner(null, ArrayList.class, clazz);

Quickblox Android SDK: Using the or custom operator in custom object query

We need to use the or operator with Quickblox custom object module in Android, but no records are returned.
Below is what tried so far:
myArray is an array of String[] containing the parameters to be compared
Trial 1:
QBCustomObjectRequestBuilder requestBuilder = new QBCustomObjectRequestBuilder();
requestBuilder.setPagesLimit(100);
requestBuilder.or("tag_number", myArray );
QBCustomObjects.getObjects("CollectionNum", requestBuilder, new QBCallbackImpl()
{
#Override
public void onComplete(Result result) {
if (result.isSuccess()) {
QBCustomObjectLimitedResult coresult = (QBCustomObjectLimitedResult) result;
ArrayList<QBCustomObject> co = coresult.getCustomObjects();
Log.d("Records: ", co.toString());
} else {
Log.e("Errors",result.getErrors().toString());
}
}
});
-> This is triggering onComplete function, but is returning NO result
-> Gives warning in eclipse:
The argument of type String[] should explicitly be cast to Object[] for the invocation of the varargs method or(String, Object...) from type QBCustomObjectRequestBuilder. It could alternatively be cast to Object for a varargs invocation
Trial2:
QBCustomObjectRequestBuilder requestBuilder = new QBCustomObjectRequestBuilder();
requestBuilder.setPagesLimit(100);
requestBuilder.or("tag_number", toObjectArray(myArray) );
QBCustomObjects.getObjects("CollectionNum", requestBuilder, new QBCallbackImpl()
{
#Override
public void onComplete(Result result) {
if (result.isSuccess()) {
QBCustomObjectLimitedResult coresult = (QBCustomObjectLimitedResult) result;
ArrayList<QBCustomObject> co = coresult.getCustomObjects();
Log.d("Records: ", co.toString());
} else {
Log.e("Errors",result.getErrors().toString());
}
}
});
public static Object[] toObjectArray(Object array)
{
int length = Array.getLength(array);
Object[] ret = new Object[length];
for(int i = 0; i < length; i++)
ret[i] = array[i];
return ret;
}
-> This is NOT triggering onComplete
-> This is NOT returning results.
Notice the difference is that whether am sending myArray or toObjectArray(myArray).
Please advice, is there a working example for using or operator in custom object in Android?

How to check arraylist contains this particular word in android?

I have ArrayList<String> in that I added 3-4 website names. Like, http://www.google.com, https://www.stackoverflow.com, etc. Now in my application if I type simply "google" then I want to compare that "google" word with the ArrayList<String>.
I am stuck here. Can anyone tell me how can I compare the string with the array object?
Thanks in advance.
To do so, you need to override implementation of contains(). I am giving you a simple example.
Custom ArrayList class
public class MyArrayList extends ArrayList<String> {
private static final long serialVersionUID = 2178228925760279677L;
#Override
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
#Override
public int indexOf(Object o) {
int size = this.size();
if (o == null) {
for (int i = 0; i < size ; i++) {
if (this.get(i) == null) {
return i;
}
}
} else {
for (int i = 0; i < size ; i++) {
if (this.get(i).contains(String.valueOf(o))) {
return i;
}
}
}
return -1;
}
}
How to use
MyArrayList arrayList = new MyArrayList();
arrayList.add("http://www.google.com");
arrayList.add("https://www.stackoverflow.com");
arrayList.add("http://pankajchunchun.wordpress.com");
if (arrayList.contains("google")) {
System.out.println("ArrayList Contains google word");
}
if (arrayList.contains("igoogle")) {
System.out.println("ArrayList Contains igoogle word");
} else {
System.out.println("ArrayList does not Contains igoogle word");
}
Below is output for above code example
ArrayList Contains google word
ArrayList does not Contains igoogle word
See ArrayList Source Code for more custom implementation.
ArrayList.contains() test the the String through equals. From the documentation:
public boolean contains(Object o) Returns true if this list contains
the specified element. More formally, returns true if and only if this
list contains at least one element e such that (o==null ? e==null :
o.equals(e)).
example:
boolean contains = yourArrayListInstance.contains(yourString);
Edit. If you want to check for substring you have to loop on the ArrayList's content and call String.contains
You can iterate through your ArrayList<String> like
public String getWebsiteName(String toMatchString)
{
ArrayList<String> yourArrayList = new ArrayList<String>();
for (String webSiteName : yourArrayList)
{
if (webSiteName.contains(toMatchString))
return webSiteName;
}
return null;
}
and get the matching String
Use a helper function like this
public static boolean containsSubString(ArrayList<String> stringArray, String substring){
for (String string : stringArray){
if (string.contains(substring)) return true;
}
return false;
}

Categories

Resources