1

詳細:

私は次のことを行う必要があるサービスを持っています:-パラメータとして50メートルを使用してGPS位置を常にリッスンし(正常に動作します)、サーバーに送信します-60秒ごとに、GPS位置が読み取られなかった場合は、ネットワークのリッスンを開始します場所を特定してサーバーに送信します

これは奇妙に聞こえるかもしれませんが、これはプロジェクトの要件です。そのため、ユーザーは常にGPSを使用して追跡されています。彼が停止したとき、GPSがロックされていないとき、または建物の中にいるときは、60秒ごとにネットワーク位置のクイック読み取りを開始し、この位置をサーバーに送信します。サービスはメインアプリと同じスレッドを使用するため、各サーバーの更新は独自のスレッドで行われます。また、もう1つの重要な点は、各ロケーション読み取りを次々に送信する必要があるためです。たとえば、ユーザーが運転していて複数の読み取りが行われた場合、前の読み取りが送信された後に、それぞれがサーバーに送信される必要があります。そのため、スレッドを送信でき、スレッドが次々に実行されるため、ScheduledExecutorServiceを使用することにしました。

コードは次のとおりです。

private ScheduledExecutorService scheduleTaskExecutor;
Handler locationHandler = new Handler();
private Location lastNetworkLocation;

@Override
    public void onStartCommand() {
        scheduleTaskExecutor = Executors.newSingleThreadScheduledExecutor();

        //prepare to execute Network reading every 60 seconds
        scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                    initNetworkReadings();

                    //usually a network location read is done almost instantly
                    //however after 5 seconds I check if a location has been read by the Network listener inside the locationRunnable
                    locationHandler.postDelayed(locationRunnable, 5000);
                } 

            }
        }, 60, 60, TimeUnit.SECONDS);

        locationRunnable = new Runnable() {
            @Override
            public void run() {
                    if (lastNetworkLocation !=null){
                         //send location to the server if valid
                    }
            lastNetworkLocation = null;
            }
        }
    }

    private void initNetworkReadings() {
        locationManager.removeUpdates(locationListenerNetwork);
        try {
            isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        } catch (Exception ex) {
        }

        if (isGpsEnabled) {
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
        }
    }

    LocationListener locationListenerNetwork = new LocationListener() {
    @Override
    public void onLocationChanged(Location location) {
        lastNetworkLocation = location;
        // stop listening for Network locations
        locationManager.removeUpdates(locationListenerNetwork);
    }
    ...
    }

GPSの位置を読み取るたびに、次のようにスレッドキューに追加します。

scheduleTaskExecutor.submit(new Runnable() {
        @Override
        public void run() {
            updateLocationOnServer(readLocation);
        }
    });

onLocationChanged()私が抱えている問題は、上記のコードのようにRunnableで使用すると、ネットワークロケーションリスナーが呼び出されないことです。しかし、サービス開始を追加すると、すぐinitNetworkReadings()に解雇されます。onLocationChanged()したがって、scheduleAtFixedRateで使用されることと関係があると思います。何が問題だと思いますか?ワークフローの考え方に悪い点はありますか?

4

2 に答える 2

1

scheduleAtFixedRate()の代わりにハンドラーとランナブルを使用して繰り返しを設定しようとするとどうなりますか?

Handler h = new Handler();
Runnable run = new Runnable(){
    //Do your repeititive work here!
    h.postDelayed(run, 60 * 1000);
};
h.post(run);
于 2012-11-28T14:31:04.727 に答える
0

同じ問題ですが、場所を検出するバックグラウンドサービスがあります。ネットワークが利用可能な場合はネットワークを使用し、そうでない場合はgpsを使用します。

多くのスマートフォン(nexus s 4.1、galaxy nexus 4.2、galaxy note)でうまく機能しますが、Galaxy s3 jb(4.1)では、ネットワークの場所がどの場所でも上昇することはありません。

GPSの場所と同じコードで、問題なく動作します。

于 2012-11-30T11:34:01.770 に答える