0

ForeignCollection次のクラスでOrmlite を使用しようとすると問題が発生します。Run & Waypoint クラスに正しく注釈が付けられていると思います。(Run には WayPoint のコレクションがあります)。ただし、WayPoints にアクセスしようとすると (3 番目のコードの抜粋を参照)、CloseableIteratorを呼び出すと null が返されますhasNext()。エミュレーターでこれをテストするときは、最初に Run 用に多数の WayPoint を生成して保存します。次に、Run のインスタンスを介してこれらの WayPoint にアクセスしようとします。ここであまり多くのコードをダンプせずに全体像を完成させるために、ForeignCollection<WayPoint>オブジェクトは呼び出しによって Contender コンストラクターに渡されます。

run.getWayPoints();

WayPoint を作成して保存する方法は次のとおりです:: - GPSLocation.onLocationChanged() が起動し、状態が GPS_STATE_RUNNING の場合、createWayPoint() が呼び出されます。これにより、WayPoint がインスタンス化され、lng/lat 値が設定され、関連付けられた Run インスタンスへのハンドルが設定されます。この時点ではまだ db に保存されていません。GPSLocation.updateWayPointWithElapsedTime() でコールバックする別のクラスにインテントが送信され、WayPoint が最終的にデータベースに格納されます。実行が完了すると、外部クラスは、Run インスタンスを格納する storeRun() を呼び出します。関連付けられている Run インスタンス自体がまだ保存されていないときに WayPoint を保存することが問題の一部であるかどうか疑問に思い始めています。

** 注:: クラスは、質問に関連するセクションを表示するためにカットダウンされているため、コンパイルされません。

@DatabaseTable
public class Run {

    @DatabaseField(generatedId=true)
    private int id;

    @DatabaseField(foreign=true,foreignAutoRefresh=true)
    private Route route;

    @ForeignCollectionField
    private ForeignCollection<WayPoint> wayPoints; 

    @DatabaseField
    private Date date;

    @DatabaseField
    private long time;

    public ForeignCollection<WayPoint> getWayPoints() {
        return wayPoints;
    }
}

@DatabaseTable
public class WayPoint {

    @DatabaseField(generatedId=true)
    private int id;

    @DatabaseField
    private int latitude;

    @DatabaseField
    private int longitude;

    @DatabaseField
    private int time; // offset 

    @DatabaseField(foreign=true,foreignAutoRefresh=true) 
    private Run run;
}    

public class Contender implements Comparable<Contender> {

    private int accumulatedDistance;
    private int interpolatedDistance;
    private WayPoint startPoint;
    CloseableIterator itr;
    private int id;
    WayPoint previous;
    WayPoint next;

    public Contender(ForeignCollection<WayPoint> wayPoints, WayPoint startPoint, int id) {

        this.startPoint = startPoint;
        this.id = id;
        itr = wayPoints.closeableIterator();

        if(itr.hasNext()) { 
            next = (WayPoint)itr.next();
        }
        else {
            Log.e("@@@", "no way points");
        }

        Log.i("@@@", "wayPoints size is " + wayPoints.size()); 
    }
}


public class GPSLocation extends Service implements LocationListener {
    private Run run;
    private WayPoint  wayPoint;
    private int distanceTravelled;

    @Override
        public void onCreate() {
            locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
            Criteria criteria = new Criteria();
            provider = locationManager.getBestProvider(criteria, false);
            startLocationUpdates = new ArrayList<Location>();

            Log.i(LOGTAG, "GPSLocation Service Running...");
        }

        public void startRunning() {

            setState(GPS_STATE_RUNNING);
            startTime = System.currentTimeMillis();
            run = new Run();
            run.setRoute(route);
            run.setDate(new Date());
        }

        public void storeRun(long elapsedTime) {

            // if first run and end point not set then set end point
            run.setTime(elapsedTime);
            route.addToCumulativeDistance(distanceTravelled);
            DatabaseManager.getInstance().storeRun(run);
            DatabaseManager.getInstance().updateRoute(route);

            resetGlobalState();
        }

        public void onLocationChanged(Location location) {

            previousLocation = currentLocation;
            currentLocation = location;

            Intent i = null; 
            boolean startActivity = true;

            switch(state)
            {
                case GPS_STATE_SETTING_START_LOCATION:
                    startLocationUpdates.add(location);

                    if(startLocationAccepted())
                    {
                        i = new Intent(this, AddRoute.class);
                        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        i.setAction("acquired");
                    }
                    else
                    {
                        startActivity = false; // waiting for more location data
                    }
                    break;

                case GPS_STATE_READY:
                    if(!atLocation(ROUTE_START, location, ROUTE_DELIMITER_REQUIRED_PROXIMITY))
                    {
                        setState(GPS_STATE_AWAITING_ARRIVAL_AT_START_LOCATION);
                        i = new Intent(this, Running.class);
                        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        i.setAction("proximity_update");
                    }
                    break;

                case GPS_STATE_AWAITING_ARRIVAL_AT_START_LOCATION:
                    i = new Intent(this, Running.class);
                    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                    if(atLocation(ROUTE_START, location, ROUTE_DELIMITER_REQUIRED_PROXIMITY))
                    {
                        setState(GPS_STATE_READY);
                        i.setAction("ready");
                    }
                    else
                    {
                        i.setAction("proximity_update");
                    }
                    break;

                case GPS_STATE_RUNNING:
                    createWayPoint(location);
                    i = new Intent(this, Running.class);
                    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                    if(atLocation(ROUTE_END, location, ROUTE_DELIMITER_REQUIRED_PROXIMITY) 
                            && (distanceTravelled > ROUTE_DELIMITER_REQUIRED_PROXIMITY))
                    {
                        i.setAction("at_end");
                    }
                    else
                    {
                        i.setAction("update");
                    }

                    distanceTravelled += currentLocation.distanceTo(previousLocation);  
                    i.putExtra("distanceTravelled", distanceTravelled);
                    setState(GPS_STATE_RUNNING_UPDATE);
                    break;

                default:
                    // error
            }
        }

        private void createWayPoint(Location location) {

            wayPoint = new WayPoint();
            wayPoint.setLatitude(LocationMath.degreesToMicroDegrees(location.getLatitude()));
            wayPoint.setLongitude(LocationMath.degreesToMicroDegrees(location.getLongitude()));
            wayPoint.setRun(run);
        }

        /*
         * Now we have the elapsed time from the Running Activity, we can store this WayPoint
         */
        public void updateWayPointWithElapsedTime(long elapsedTime) {

            // TODO::check the time value is correct
            wayPoint.setTimeOffset((int)elapsedTime);
            DatabaseManager.getInstance().storeWayPoint(wayPoint);
            setState(GPS_STATE_RUNNING); 
        }
    }

DatabaseManager からの抜粋 -->

public void storeWayPoint(WayPoint point) {
        try {
            getHelper().getWayPointDao().create(point);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

public void storeRun(Run run) {
    try {
        getHelper().getRunDao().create(run);
    } catch (SQLException e) {
        e.printStackTrace();
    }
}
4

1 に答える 1

1

Chris さんが投稿したコードに問題はありません。WayPointしたがって、あなたが思っているように s を挿入していないと思われます。それらがデータベースにあることを確認しましたか? WayPointDAO を直接使用してクエリを試しましたか?

// what does this return?
List<WayPoint> wayPoints = wayPointDao.queryForAll();

まず、Run 用に多数の WayPoint を生成して保存します

また、の作成を行う前にRun、フィールドをRunテーブルに挿入し、それぞれに設定したことを確認してください。あなたは次のようなことをしているはずです:WayPoint WayPoint

Run run1 = new Run(...);
runDao.create(run1);
...
WayPoint wayPoint1 = new WayPoint(...);
wayPoint1.setRun(run1);
wayPointDao.create(wayPoint1);
...

挿入できる別の方法は、外部コレクション自体を使用することです。

// create a foreign collection we can add to
run.wayPoints = runDao.getEmptyForeignCollection("wayPoints");
// now if you add something to the collection, it gets created in the DAO as well
run.wayPoints.add(wayPoint1);

WayPoint質問を編集して、 s をデータベースに挿入するために使用したコードを表示していただければ、回答を編集して詳細情報を提供します。

于 2012-05-07T13:05:28.547 に答える