Parse library (beta) - simple backend solution

bluedude

Well-Known Member
Licensed User
Longtime User
Support for GEO queries

The new version seems to support GEO queries, becomes more interesting!
 

XverhelstX

Well-Known Member
Licensed User
Longtime User
Hey Erel,

I really need GeoQueries for an app I'm making that has a deadline.
Do you have an idea when it will be supported?

I have also taken a look at it, but I had an error here:
B4X:
/**
         * Finds all objects matching the query.
         *DoneFind event will be raised when the operation completes.
         */
        public void Find(final BA ba, final String EventName, final int TaskId) {
            getObject().findInBackground( new FindCallback() {
                @Override
                public void done(List<ParseObject> objects, ParseException e) {
                    setLastException(ba, e);
                    anywheresoftware.b4a.objects.collections.List l = new anywheresoftware.b4a.objects.collections.List();
                    if (objects != null) {
                        l.Initialize();
                        l.getObject().addAll(objects);
                    }
                    ba.raiseEventFromDifferentThread(getObject(), null, 0, EventName.toLowerCase(BA.cul) + "_donefind", 
                            true,
                            new Object[] {e == null, l, TaskId});
                }
            });
        }

Specifically this line
B4X:
anywheresoftware.b4a.objects.collections.List l = new anywheresoftware.b4a.objects.collections.List();

anywheresoftware.b4a.objects cannot be resolved to a type

Any help?

Tomas
 

XverhelstX

Well-Known Member
Licensed User
Longtime User
Thanks and what about geoqueries? Will it be supported to?
I just cannot seem to find on how to query the location. (However I did at the GeoPoint)

B4X:
/**
     *     
     */
    @Version(1.0f)
    @Events(values={
            "DoneSave (Success As Boolean)",
            "DoneDelete (Success As Boolean)",
            "DoneRefresh (Success As Boolean)"
            })
    @ShortName("ParseGeoPoint")
    public class ParseGeoPointWrapper extends AbsObjectWrapper<ParseGeoPoint>{
        /**
         * Initializes the object and sets  long and latitude
         */
        public void Initialize(double latitude, double longitude) {
            setObject(new ParseGeoPoint(latitude, longitude));
        }
        
        /**
         * Initializes the object and sets  long and latitude = 0
         */
        public void Initialize2() {
            setObject(new ParseGeoPoint());
        }
      
        public void setLatitude(double latitude) {
            getObject().setLatitude(latitude);
        }
        public void setLongitude(double longitude) {
            getObject().setLongitude(longitude);
        }
        public double getLatitude() {
           return getObject().getLatitude();
        }
        public double getLongitude() {
           return getObject().getLongitude();
        }
    }

I also added the wherenear functions at the query's but i'm not sure if I had to add them there:

B4X:
package com.rootsoft.parse;

import java.util.List;

import anywheresoftware.b4a.AbsObjectWrapper;
import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.Events;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;
import anywheresoftware.b4a.keywords.Common;

import com.parse.CountCallback;
import com.parse.DeleteCallback;
import com.parse.FindCallback;
import com.parse.GetCallback;
import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseGeoPoint;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.RefreshCallback;
import com.parse.SaveCallback;

/**
 *     
 */
@Version(1.0f)
@Events(values={
        "DoneSave (Success As Boolean)",
        "DoneDelete (Success As Boolean)",
        "DoneRefresh (Success As Boolean)"
        })
@ShortName("ParseObject")
public class ParseObjectWrapper extends AbsObjectWrapper<ParseObject>{
    /**
     * Initializes the object and sets the class name.
     */
    public void Initialize(String ClassName) {
        setObject(new ParseObject(ClassName));
    }
    public boolean ContainsKey(String Key) {
        return getObject().containsKey(Key);
    }
    public void Put(String Key, Object Value) {
        getObject().put(Key, Value);
    }
    public String GetString(String Key) {
        return getObject().getString(Key);
    }
    public double GetDouble(String Key) {
        return getObject().getDouble(Key);
    }
    public long GetLong(String Key) {
        return getObject().getLong(Key);
    }
    public boolean GetBoolean(String Key) {
        return getObject().getBoolean(Key);
    }
    public int GetInt(String Key) {
        return getObject().getInt(Key);
    }
    public long getCreatedAt() {
        return getObject().getCreatedAt().getTime();
    }
    public long getUpdatedAt() {
        return getObject().getUpdatedAt().getTime();
    }
    public String getObjectId() {
        return getObject().getObjectId();
    }
    /**
     * Saves the object on the server.
     *DoneSave event will be raised when saving completes.
     */
    public void Save(final BA ba, final String EventName) {
        if (EventName.length() == 0) {
            getObject().saveInBackground();
        }
        else {
            getObject().saveInBackground(new SaveCallback() {
    
                @Override
                public void done(ParseException e) {
                    setLastException(ba, e);
                    ba.raiseEventFromDifferentThread(getObject(), null, 0, EventName.toLowerCase(BA.cul) + "_donesave", 
                        true,
                        new Object[] {e == null});
                }
                
            });
        }
    }
    /**
     * Deletes the object from the server.
     *DoneDelete event will be raised when saving completes.
     */
    public void Delete(final BA ba, final String EventName) {
        if (EventName.length() == 0) {
            getObject().deleteInBackground();
        }
        else {
            getObject().deleteInBackground(new DeleteCallback() {

                @Override
                public void done(ParseException e) {
                    setLastException(ba, e);
                    ba.raiseEventFromDifferentThread(getObject(), null, 0, EventName.toLowerCase(BA.cul) + "_donedelete", 
                        true,
                        new Object[] {e == null});
                }
                
            });
        }
    }
    /**
     * Refreshes the object by reading it from the server.
     *DoneRefresh event will be raised when the operation completes.
     */
    public void Refresh(final BA ba, final String EventName) {
        getObject().refreshInBackground(new RefreshCallback() {

            @Override
            public void done(ParseObject object, ParseException e) {
                setLastException(ba, e);
                ba.raiseEventFromDifferentThread(getObject(), null, 0, EventName.toLowerCase(BA.cul) + "_donerefresh", 
                    true,
                    new Object[] {e == null});
            }
            
        });
    }
    static void setLastException(BA ba, Exception e) {
        if (e != null) {
            BA b = ba;
            if (ba.processBA != null)
                b = ba.processBA;
            b.setLastException(e);
            e.printStackTrace();
        }
    }
    
    @ShortName("Parse")
    @Permissions(values = {"android.permission.INTERNET"})
    public static class ParseWrapper {
        /**
         * Initializes the Parse library.
         */
        public static void Initialize(String ApplicationId, String ClientId) {
            Parse.initialize(BA.applicationContext, ApplicationId, ClientId);
        }
    }
    
    @ShortName("ParseQuery")
    @Events(values={
            "DoneGet (Success As Boolean, PO As ParseObject, TaskId As Int)",
            "DoneFind (Success As Boolean, ListOfPO As List, TaskId As Int)",
            "DoneCount (Success As Boolean, Count As Int, TaskId As Int)"})
    public static class ParseQueryWrapper extends AbsObjectWrapper<ParseQuery> {
        /**
         * Initializes the object and sets the class name.
         */
        public void Initialize(String ClassName) {
            setObject(new ParseQuery(ClassName));
        }
        /**
         * Gets an object based on its ObjectId.
         *DoneGet event will be raised when the operation completes.
         */
        public void GetById(final BA ba, final String EventName, final String ObjectId, final int TaskId) {
            getObject().getInBackground(ObjectId, new GetCallback() {

                @Override
                public void done(ParseObject object, ParseException e) {
                    setLastException(ba, e);
                    ba.raiseEventFromDifferentThread(getObject(), null, 0, EventName.toLowerCase(BA.cul) + "_doneget",
                            true,
                            new Object[] {e == null, object, TaskId});
                }
                
            });
        }
        /**
         * Finds all objects matching the query.
         *DoneFind event will be raised when the operation completes.
         */
        public void Find(final BA ba, final String EventName, final int TaskId) {
            getObject().findInBackground( new FindCallback() {
                @Override
                public void done(List<ParseObject> objects, ParseException e) {
                    setLastException(ba, e);
                    anywheresoftware.b4a.objects.collections.List l = new anywheresoftware.b4a.objects.collections.List();
                    if (objects != null) {
                        l.Initialize();
                        l.getObject().addAll(objects);
                    }
                    ba.raiseEventFromDifferentThread(getObject(), null, 0, EventName.toLowerCase(BA.cul) + "_donefind", 
                            true,
                            new Object[] {e == null, l, TaskId});
                }
            });
        }
        /**
         * Counts the number of objects matching the query.
         *DoneCount event will be raised when the operation completes.
         */
        public void Count(final BA ba, final String EventName, final int TaskId) {
            getObject().countInBackground(new CountCallback() {
                @Override
                public void done(int count, ParseException e) {
                    setLastException(ba, e);
                    ba.raiseEventFromDifferentThread(getObject(), null, 0, EventName.toLowerCase(BA.cul) + "_donecount", 
                            true,
                            new Object[] {e == null, count, TaskId});
                }
            });
        }
        /**
         * Sets the query order by.
         */
        public void OrderBy (String Key, boolean Ascending) {
            if (Ascending)
                getObject().orderByAscending(Key);
            else
                getObject().orderByDescending(Key);
        }
        /**
         * Adds a condition to the query.
         */
        public ParseQueryWrapper WhereEqualTo(String Key, Object Value) {
            getObject().whereEqualTo(Key, Value);
            return this;
        }
        /**
         * Adds a condition to the query.
         */
        public ParseQueryWrapper WhereGreaterThan(String Key, Object Value) {
            getObject().whereGreaterThan(Key, Value);
            return this;
        }
        /**
         * Adds a condition to the query.
         */
        public ParseQueryWrapper WhereLessThan(String Key, Object Value) {
            getObject().whereLessThan(Key, Value);
            return this;
        }
        /**
         * Adds a condition to the query.
         */
        public ParseQueryWrapper WhereNotEqualTo(String Key, Object Value) {
            getObject().whereNotEqualTo(Key, Value);
            return this;
        }
        /**
         * Limits the number of results. Pass -1 to retrieve all items.
         */
        public void setLimit(int v) {
            getObject().setLimit(v);
        }
        
        /**
         * Adds a condition to the query.
         */
        public ParseQueryWrapper WhereNear(String Key, ParseGeoPoint Value) {
            getObject().whereNear(Key, Value);
            return this;
        }
        
        /**
         *  Add a proximity based constraint for finding objects with key point values near the point given and within the maximum distance given.
         */
        public ParseQueryWrapper whereWithinKilometers(String key, ParseGeoPoint point, double maxDistance)  {
           getObject().whereWithinKilometers(key, point, maxDistance);
           return this;
        }
        
        /**
         * Add a proximity based constraint for finding objects with key point values near the point given and within the maximum distance given.
         */
        public ParseQueryWrapper whereWithinMiles(String key, ParseGeoPoint point, double maxDistance)  {
           getObject().whereWithinMiles(key, point, maxDistance) ;
           return this;
        }
        
        /**
         * Add a proximity based constraint for finding objects with key point values near the point given and within the maximum distance given.
         */
        public ParseQueryWrapper whereWithinRadians(String key, ParseGeoPoint point, double maxDistance)  {
           getObject().whereWithinRadians(key, point, maxDistance);
           return this;
        }
       
        
    }
    
    /**
     *     
     */
    @Version(1.0f)
    @Events(values={
            "DoneSave (Success As Boolean)",
            "DoneDelete (Success As Boolean)",
            "DoneRefresh (Success As Boolean)"
            })
    @ShortName("ParseGeoPoint")
    public class ParseGeoPointWrapper extends AbsObjectWrapper<ParseGeoPoint>{
        /**
         * Initializes the object and sets  long and latitude
         */
        public void Initialize(double latitude, double longitude) {
            setObject(new ParseGeoPoint(latitude, longitude));
        }
        
        /**
         * Initializes the object and sets  long and latitude = 0
         */
        public void Initialize2() {
            setObject(new ParseGeoPoint());
        }
      
        public void setLatitude(double latitude) {
            getObject().setLatitude(latitude);
        }
        public void setLongitude(double longitude) {
            getObject().setLongitude(longitude);
        }
        public double getLatitude() {
           return getObject().getLatitude();
        }
        public double getLongitude() {
           return getObject().getLongitude();
        }
    }  
    
    
    
}

Could you please take a look on it on how to parse the locations?

Geo Queries

Now that you have a bunch of objects with spatial coordinates, it would be nice to find out which objects are closest to a point. This can be done by adding another restriction to ParseQuery using whereNear. Getting a list of ten places that are closest to a user may look something like:

ParseGeoPoint userLocation = (ParseGeoPoint) userObject.get("location");
ParseQuery query = new ParseQuery("PlaceObject");
query.whereNear("location", userLocation);
query.setLimit(10);
ArrayList<ParseObject> nearPlaces = query.find();
At this point nearPlaces will be an array of objects ordered by distance (nearest to farthest) from userLocation.

To limit the results using distance, check out whereWithinKilometers, whereWithinMiles, and whereWithinRadians.

Thank you very much.
That would be really much appreciated.

Tomas
 

XverhelstX

Well-Known Member
Licensed User
Longtime User
Hey Erel,

GeoQueries is a top priority for my app and I cannot work on it furthur as I did the most basics now.

I added ParseGeoPoints and those works now, the only problem is the parsing.
I cannot seem to find a way on how to parse the latitude and longitude from a found object.

Here's my code:

B4X:
package com.rootsoft.parse;

import java.util.List;

import anywheresoftware.b4a.AbsObjectWrapper;
import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.Events;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;

import com.parse.CountCallback;
import com.parse.DeleteCallback;
import com.parse.FindCallback;
import com.parse.GetCallback;
import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseGeoPoint;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.RefreshCallback;
import com.parse.SaveCallback;

/**
 *     
 */
@Version(1.0f)
@Events(values={
        "DoneSave (Success As Boolean)",
        "DoneDelete (Success As Boolean)",
        "DoneRefresh (Success As Boolean)"
        })
@ShortName("ParseObject")
public class ParseObjectWrapper extends AbsObjectWrapper<ParseObject>{
    /**
     * Initializes the object and sets the class name.
     */
    public void Initialize(String ClassName) {
        setObject(new ParseObject(ClassName));
    }
    public boolean ContainsKey(String Key) {
        return getObject().containsKey(Key);
    }
    public void Put(String Key, Object Value) {
        getObject().put(Key, Value);
    }
    public String GetString(String Key) {
        return getObject().getString(Key);
    }
    public double GetDouble(String Key) {
        return getObject().getDouble(Key);
    }
    public long GetLong(String Key) {
        return getObject().getLong(Key);
    }
    public boolean GetBoolean(String Key) {
        return getObject().getBoolean(Key);
    }
    public int GetInt(String Key) {
        return getObject().getInt(Key);
    }
    public long getCreatedAt() {
        return getObject().getCreatedAt().getTime();
    }
    public long getUpdatedAt() {
        return getObject().getUpdatedAt().getTime();
    }
    public String getObjectId() {
        return getObject().getObjectId();
    }
    /**
     * Saves the object on the server.
     *DoneSave event will be raised when saving completes.
     */
    public void Save(final BA ba, final String EventName) {
        if (EventName.length() == 0) {
            getObject().saveInBackground();
        }
        else {
            getObject().saveInBackground(new SaveCallback() {
    
                @Override
                public void done(ParseException e) {
                    setLastException(ba, e);
                    ba.raiseEventFromDifferentThread(getObject(), null, 0, EventName.toLowerCase(BA.cul) + "_donesave", 
                        true,
                        new Object[] {e == null});
                }
                
            });
        }
    }
    /**
     * Deletes the object from the server.
     *DoneDelete event will be raised when saving completes.
     */
    public void Delete(final BA ba, final String EventName) {
        if (EventName.length() == 0) {
            getObject().deleteInBackground();
        }
        else {
            getObject().deleteInBackground(new DeleteCallback() {

                @Override
                public void done(ParseException e) {
                    setLastException(ba, e);
                    ba.raiseEventFromDifferentThread(getObject(), null, 0, EventName.toLowerCase(BA.cul) + "_donedelete", 
                        true,
                        new Object[] {e == null});
                }
                
            });
        }
    }
    /**
     * Refreshes the object by reading it from the server.
     *DoneRefresh event will be raised when the operation completes.
     */
    public void Refresh(final BA ba, final String EventName) {
        getObject().refreshInBackground(new RefreshCallback() {

            @Override
            public void done(ParseObject object, ParseException e) {
                setLastException(ba, e);
                ba.raiseEventFromDifferentThread(getObject(), null, 0, EventName.toLowerCase(BA.cul) + "_donerefresh", 
                    true,
                    new Object[] {e == null});
            }
            
        });
    }
    static void setLastException(BA ba, Exception e) {
        if (e != null) {
            BA b = ba;
            if (ba.processBA != null)
                b = ba.processBA;
            b.setLastException(e);
            e.printStackTrace();
        }
    }
    
    @ShortName("Parse")
    @Permissions(values = {"android.permission.INTERNET"})
    public static class ParseWrapper {
        /**
         * Initializes the Parse library.
         */
        public static void Initialize(String ApplicationId, String ClientId) {
            Parse.initialize(BA.applicationContext, ApplicationId, ClientId);
        }
    }
    
    @ShortName("ParseQuery")
    @Events(values={
            "DoneGet (Success As Boolean, PO As ParseObject, TaskId As Int)",
            "DoneFind (Success As Boolean, ListOfPO As List, TaskId As Int)",
            "DoneCount (Success As Boolean, Count As Int, TaskId As Int)"})
    public static class ParseQueryWrapper extends AbsObjectWrapper<ParseQuery> {
        /**
         * Initializes the object and sets the class name.
         */
        public void Initialize(String ClassName) {
            setObject(new ParseQuery(ClassName));
        }
        /**
         * Gets an object based on its ObjectId.
         *DoneGet event will be raised when the operation completes.
         */
        public void GetById(final BA ba, final String EventName, final String ObjectId, final int TaskId) {
            getObject().getInBackground(ObjectId, new GetCallback() {

                @Override
                public void done(ParseObject object, ParseException e) {
                    setLastException(ba, e);
                    ba.raiseEventFromDifferentThread(getObject(), null, 0, EventName.toLowerCase(BA.cul) + "_doneget",
                            true,
                            new Object[] {e == null, object, TaskId});
                }
                
            });
        }
        /**
         * Finds all objects matching the query.
         *DoneFind event will be raised when the operation completes.
         */
        public void Find(final BA ba, final String EventName, final int TaskId) {
            getObject().findInBackground( new FindCallback() {
                @Override
                public void done(List<ParseObject> objects, ParseException e) {
                    setLastException(ba, e);
                    anywheresoftware.b4a.objects.collections.List l = new anywheresoftware.b4a.objects.collections.List();
                    if (objects != null) {
                        l.Initialize();
                        l.getObject().addAll(objects);
                    }
                    ba.raiseEventFromDifferentThread(getObject(), null, 0, EventName.toLowerCase(BA.cul) + "_donefind", 
                            true,
                            new Object[] {e == null, l, TaskId});
                }
            });
        }
        

        /**
         * Counts the number of objects matching the query.
         *DoneCount event will be raised when the operation completes.
         */
        public void Count(final BA ba, final String EventName, final int TaskId) {
            getObject().countInBackground(new CountCallback() {
                @Override
                public void done(int count, ParseException e) {
                    setLastException(ba, e);
                    ba.raiseEventFromDifferentThread(getObject(), null, 0, EventName.toLowerCase(BA.cul) + "_donecount", 
                            true,
                            new Object[] {e == null, count, TaskId});
                }
            });
        }
        /**
         * Sets the query order by.
         */
        public void OrderBy (String Key, boolean Ascending) {
            if (Ascending)
                getObject().orderByAscending(Key);
            else
                getObject().orderByDescending(Key);
        }
        /**
         * Adds a condition to the query.
         */
        public ParseQueryWrapper WhereEqualTo(String Key, Object Value) {
            getObject().whereEqualTo(Key, Value);
            return this;
        }
        /**
         * Adds a condition to the query.
         */
        public ParseQueryWrapper WhereGreaterThan(String Key, Object Value) {
            getObject().whereGreaterThan(Key, Value);
            return this;
        }
        /**
         * Adds a condition to the query.
         */
        public ParseQueryWrapper WhereLessThan(String Key, Object Value) {
            getObject().whereLessThan(Key, Value);
            return this;
        }
        /**
         * Adds a condition to the query.
         */
        public ParseQueryWrapper WhereNotEqualTo(String Key, Object Value) {
            getObject().whereNotEqualTo(Key, Value);
            return this;
        }
        /**
         * Limits the number of results. Pass -1 to retrieve all items.
         */
        public void setLimit(int v) {
            getObject().setLimit(v);
        }
        
        /**
         * Adds a condition to the query.
         */
        public ParseQueryWrapper WhereNear(String Key, Object Value) {
            getObject().whereNear(Key, (ParseGeoPoint) Value);
            return this;
        }
        
        /**
         *  Add a proximity based constraint for finding objects with key point values near the point given and within the maximum distance given.
         */
        public ParseQueryWrapper whereWithinKilometers(String key, Object point, double maxDistance)  {
           getObject().whereWithinKilometers(key, (ParseGeoPoint) point, maxDistance);
           return this;
        }
        
        /**
         * Add a proximity based constraint for finding objects with key point values near the point given and within the maximum distance given.
         */
        public ParseQueryWrapper whereWithinMiles(String key, Object point, double maxDistance)  {
           getObject().whereWithinMiles(key, (ParseGeoPoint) point, maxDistance) ;
           return this;
        }
        
        /**
         * Add a proximity based constraint for finding objects with key point values near the point given and within the maximum distance given.
         */
        public ParseQueryWrapper whereWithinRadians(String key, Object point, double maxDistance)  {
           getObject().whereWithinRadians(key, (ParseGeoPoint) point, maxDistance);
           return this;
        }
       
        
    }
    

    @ShortName("ParseGeoPoint")
    public class ParseGeoPointWrapper extends AbsObjectWrapper<ParseGeoPoint>{
        /**
         * Initializes the object and sets  long and latitude
         */
        public void Initialize(double latitude, double longitude) {
            setObject(new ParseGeoPoint(latitude, longitude));
        }
        
        /**
         * Initializes the object and sets  long and latitude = 0
         */
        public void Initialize2() {
            setObject(new ParseGeoPoint());
        }
      
        public void setLatitude(double latitude) {
            getObject().setLatitude(latitude);
        }
        public void setLongitude(double longitude) {
            getObject().setLongitude(longitude);
        }
        public double getLatitude() {
           return getObject().getLatitude();
        }
        public double getLongitude() {
           return getObject().getLongitude();
        }
    }  
    
    
    
}

I know you are busy with the next version of B4A but I really hope you can help me. (to put me on some trails and /or provide me some code).


Tomas
 
Last edited:

vb1992

Well-Known Member
Licensed User
Longtime User
Looks like

DeleteItems_DoneFind (Success As Boolean, ListOfPO As List, TaskId As Int)

Bombs out (app crashes without a trace)
after it finds 100 records from a

query.Find("DeleteItems", 1)

Erel can you do a test with 200 records?





B4X:
Sub DeleteItems_DoneFind (Success As Boolean, ListOfPO As List, TaskId As Int)
    
   Msgbox ("DoneFind001","")
   
 

   
    
   If Success = False Then
        Log("Error: " & LastException.Message)
        ToastMessageShow("Error: " & LastException.Message, True)
    Else
        
      Dim aa As Int
          
   Msgbox ("DoneFind002","")
   
        For i = 0 To ListOfPO.Size - 1
      
      aa = aa + 1 
            Log(aa)
   
            Dim po As ParseObject
            po = ListOfPO.Get(i)
            
         If po.GetString("UniqID") = "test1234" Then 
         
            'po.Delete("delete")

         End If
         
            ProgressDialogShow("Waiting for response.")
        Next
        
    End If
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
I'm getting the following error when adding the items:
java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3@418804e0 rejected from java.util.concurrent.ThreadPoolExecutor@4181ce40[Running, pool size = 128, active threads = 128, queued tasks = 10, completed tasks = 0]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1967)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:782)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1303)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:564)
at android.os.AsyncTask.execute(AsyncTask.java:511)
at com.parse.ParseObject.saveInBackground(ParseObject.java:563)
at anywheresoftware.b4a.objects.ParseObjectWrapper.Save(ParseObjectWrapper.java:80)
at test.parse.main._additems_click(main.java:264)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:113)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:97)
at test.parse.main$B4AMenuItemsClickListener.onMenuItemClick(main.java:117)
at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:144)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874)
at com.android.internal.view.menu.IconMenuView.invokeItem(IconMenuView.java:468)
at com.android.internal.view.menu.IconMenuItemView.performClick(IconMenuItemView.java:126)
at android.view.View$PerformClick.run(View.java:13983)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4340)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3@418804e0 rejected from java.util.concurrent.ThreadPoolExecutor@4181ce40[Running, pool size = 128, active threads = 128, queued tasks = 10, completed tasks = 0]

This error happens because you are doing too many background tasks at once.
You will need to limit the number of background tasks to less than 128 (total).
 

XverhelstX

Well-Known Member
Licensed User
Longtime User
Mhmm, Guess i'll have to wait :s

Meanwhile I also added ParseFile:
This lets you upload a file to the Parse Cloud.

B4X:
    @ShortName("ParseFile")
    public static class ParseFileWrapper extends AbsObjectWrapper<ParseFile>{
        /**
         * Initializes the object and sets the byte data.
         */
        public void Initialize(byte[] data) {
            setObject(new ParseFile(data));
        }
        
        /**
         * Initializes the object and sets the byte data and a file name
         */
        public void Initialize2(String fileName,byte[] data) {
            setObject(new ParseFile(fileName,data));
        }
        /**
         *  Synchronously gets the data for this object.
         * @return
         * @throws ParseException
         */
        public byte[] getData() throws ParseException {
           return getObject().getData();
        }
        
        /**
         * The filename. 
         * Before save is called, this is just the filename given by the user (if any). 
         * After save is called, that name gets prefixed with a unique identifier.
         * @return
         */
        public String getName() {
           return getObject().getName();
        }
        
        /**
         * This returns the url of the file. 
         * It's only available after you save or after you get the file from a ParseObject.
         * @return
         */
        public String getUrl() {
           return getObject().getUrl();
        }
        
        /**
         * Saves the file to the Parse cloud synchronously.
         * @throws ParseException
         */
        public void save(final BA ba, final String EventName) throws ParseException {
           getObject().save();
           ba.raiseEventFromDifferentThread(getObject(), null, 0, EventName.toLowerCase(BA.cul) + "_filesave", true, new Object[] {true});
        }
        
        /**
         * Returns the contents of the file in a byte array.
         * @param Directory
         * @param Filename
         * @return
         * @throws IOException
         */
       public byte[] BytesFromFile(String Directory, String Filename) throws IOException {
          
          File file = new File(Directory, Filename);
          
           InputStream is = new FileInputStream(file);

           // Get the size of the file
           long length = file.length();

           // You cannot create an array using a long type.
           // It needs to be an int type.
           // Before converting to an int type, check
           // to ensure that file is not larger than Integer.MAX_VALUE.
           if (length > Integer.MAX_VALUE) {
               // File is too large
           }

           // Create the byte array to hold the data
           byte[] bytes = new byte[(int)length];

           // Read in the bytes
           int offset = 0;
           int numRead = 0;
           while (offset < bytes.length
                  && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
               offset += numRead;
           }

           // Ensure all the bytes have been read in
           if (offset < bytes.length) {
               throw new IOException("Could not completely read file "+file.getName());
           }

           // Close the input stream and return bytes
           is.close();
           return bytes;
       }
    }

Less coding for Erel then ;)
I also provided a quick way to read a file into bytes.

Tomas
 

sellnet

New Member
Licensed User
Longtime User
Latest status of Parse library

Is their a version of this library that is newer than 0.9 as that's all I have been able to find to download?

Is there a version that includes teh code written by Tomas to upload a file?

Thanks.
 
Top