অ্যান্ড্রয়েডে ব্যবহারকারীর অবস্থান পাওয়ার ভাল উপায়


211

সমস্যাটি:

ASAP এবং একই সময়ে ব্যাটারি সংরক্ষণের দ্বার মধ্যে ব্যবহারকারীর বর্তমান অবস্থান প্রাপ্ত করা Get

সমস্যাটি কেন সমস্যা:

প্রথমে, অ্যান্ড্রয়েডের দুটি সরবরাহকারী রয়েছে; নেটওয়ার্ক এবং জিপিএস কখনও কখনও নেটওয়ার্ক ভাল এবং কখনও কখনও জিপিএস ভাল হয়।

"আরও ভাল" দ্বারা আমি গতি বনাম যথার্থতা অনুপাত বলতে চাইছি।
আমি যদি প্রায় তাত্ক্ষণিকভাবে এবং জিপিএস চালু না করে লোকেশনটি পেতে পারি তবে আমি কয়েক মিটার নির্ভুলতার জন্য ত্যাগ করতে ইচ্ছুক।

দ্বিতীয়ত, আপনি যদি অবস্থানের পরিবর্তনের জন্য আপডেটের জন্য অনুরোধ করেন তবে বর্তমান অবস্থানটি স্থিতিশীল থাকলে কিছুই প্রেরণ করা হয় না।

গুগলের এখানে "সেরা" অবস্থান নির্ধারণের একটি উদাহরণ রয়েছে: http://developer.android.com/guide/topics/location/obtaining-user-location.html# সর্বোত্তমতা
তবে আমি মনে করি এটি এর মতো ঠিক যতটা উচিত তার কাছাকাছি নেই no /হতে পারে.

আমি গুগল ধরণের কারণ কেন গুগল কোনও অবস্থানের জন্য সাধারণীকরণকারী এপিআই না করে, বিকাশকারীকে সেই অবস্থানটি কোথায় সেদিকে খেয়াল রাখতে হবে না, আপনাকে কেবল কী চান তা নির্দিষ্ট করা উচিত এবং ফোনটি আপনার জন্য বেছে নেওয়া উচিত।

আমার যেটির সাহায্য দরকার:

"উত্তম" অবস্থান নির্ধারণ করার জন্য আমাকে একটি ভাল উপায় খুঁজে বের করতে হবে, যদিও কিছু তাত্পর্যপূর্ণ বা সম্ভবত কোনও তৃতীয় পক্ষের লাইব্রেরির মাধ্যমে।

এর অর্থ এই নয় যে সেরা সরবরাহকারী নির্ধারণ করুন!
আমি সম্ভবত সমস্ত সরবরাহকারী ব্যবহার করব এবং তাদের মধ্যে সেরাটি বেছে নেব।

অ্যাপ্লিকেশনটির পটভূমি:

অ্যাপ্লিকেশনটি একটি নির্দিষ্ট বিরতিতে ব্যবহারকারীর অবস্থান সংগ্রহ করবে (প্রতি 10 মিনিট বা তার পরে বলা যাক) এবং এটি একটি সার্ভারে প্রেরণ করবে।
অ্যাপ্লিকেশনটিতে যথাসম্ভব ব্যাটারি সংরক্ষণ করা উচিত এবং অবস্থানটির এক্স (50-100?) মিটার নির্ভুলতা থাকা উচিত।

লক্ষ্যটি হ'ল পরবর্তী সময়ে কোনও মানচিত্রে ব্যবহারকারীর পথ চক্রান্ত করতে সক্ষম হব তাই এর জন্য আমার পর্যাপ্ত যথার্থতা প্রয়োজন।

বিবিধ:

কাঙ্ক্ষিত এবং স্বীকৃত যথাযথতার জন্য যুক্তিসঙ্গত মানগুলি কী বলে আপনি মনে করেন?
আমি গ্রহণযোগ্য হিসাবে 100 মিটার এবং পছন্দসই হিসাবে 30 মি ব্যবহার করছি, এটি কি অনেক বেশি জিজ্ঞাসা করার?
আমি পরে কোনও মানচিত্রে ব্যবহারকারীর পথ চক্রান্ত করতে সক্ষম হতে চাই।
পছন্দসই জন্য 100 মিটার এবং 500 মিটার গ্রহণযোগ্যতর কি?

এছাড়াও, এই মুহুর্তে আমার কাছে অবস্থানের আপডেটের জন্য সর্বাধিক seconds০ সেকেন্ডের জন্য জিপিএস রয়েছে, আপনি যদি বাড়ির অভ্যন্তরে সম্ভবত 200 মিটার নির্ভুলতা নিয়ে থাকেন তবে কোনও অবস্থান পাওয়া কি খুব কম?


এটি আমার বর্তমান কোড, যে কোনও প্রতিক্রিয়ার প্রশংসা করা হয়েছে (ত্রুটি যাচাইয়ের অভাব বাদে যা টোডো):

protected void runTask() {
    final LocationManager locationManager = (LocationManager) context
            .getSystemService(Context.LOCATION_SERVICE);
    updateBestLocation(locationManager
            .getLastKnownLocation(LocationManager.GPS_PROVIDER));
    updateBestLocation(locationManager
            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER));
    if (getLocationQuality(bestLocation) != LocationQuality.GOOD) {
        Looper.prepare();
        setLooper(Looper.myLooper());
        // Define a listener that responds to location updates
        LocationListener locationListener = new LocationListener() {

            public void onLocationChanged(Location location) {
                updateBestLocation(location);
                if (getLocationQuality(bestLocation) != LocationQuality.GOOD)
                    return;
                // We're done
                Looper l = getLooper();
                if (l != null) l.quit();
            }

            public void onProviderEnabled(String provider) {}

            public void onProviderDisabled(String provider) {}

            public void onStatusChanged(String provider, int status,
                    Bundle extras) {
                // TODO Auto-generated method stub
                Log.i("LocationCollector", "Fail");
                Looper l = getLooper();
                if (l != null) l.quit();
            }
        };
        // Register the listener with the Location Manager to receive
        // location updates
        locationManager.requestLocationUpdates(
                LocationManager.GPS_PROVIDER, 1000, 1, locationListener,
                Looper.myLooper());
        locationManager.requestLocationUpdates(
                LocationManager.NETWORK_PROVIDER, 1000, 1,
                locationListener, Looper.myLooper());
        Timer t = new Timer();
        t.schedule(new TimerTask() {

            @Override
            public void run() {
                Looper l = getLooper();
                if (l != null) l.quit();
                // Log.i("LocationCollector",
                // "Stopping collector due to timeout");
            }
        }, MAX_POLLING_TIME);
        Looper.loop();
        t.cancel();
        locationManager.removeUpdates(locationListener);
        setLooper(null);
    }
    if (getLocationQuality(bestLocation) != LocationQuality.BAD) 
        sendUpdate(locationToString(bestLocation));
    else Log.w("LocationCollector", "Failed to get a location");
}

private enum LocationQuality {
    BAD, ACCEPTED, GOOD;

    public String toString() {
        if (this == GOOD) return "Good";
        else if (this == ACCEPTED) return "Accepted";
        else return "Bad";
    }
}

private LocationQuality getLocationQuality(Location location) {
    if (location == null) return LocationQuality.BAD;
    if (!location.hasAccuracy()) return LocationQuality.BAD;
    long currentTime = System.currentTimeMillis();
    if (currentTime - location.getTime() < MAX_AGE
            && location.getAccuracy() <= GOOD_ACCURACY)
        return LocationQuality.GOOD;
    if (location.getAccuracy() <= ACCEPTED_ACCURACY)
        return LocationQuality.ACCEPTED;
    return LocationQuality.BAD;
}

private synchronized void updateBestLocation(Location location) {
    bestLocation = getBestLocation(location, bestLocation);
}

// Pretty much an unmodified version of googles example
protected Location getBestLocation(Location location,
        Location currentBestLocation) {
    if (currentBestLocation == null) {
        // A new location is always better than no location
        return location;
    }
    if (location == null) return currentBestLocation;
    // Check whether the new location fix is newer or older
    long timeDelta = location.getTime() - currentBestLocation.getTime();
    boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
    boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
    boolean isNewer = timeDelta > 0;
    // If it's been more than two minutes since the current location, use
    // the new location
    // because the user has likely moved
    if (isSignificantlyNewer) {
        return location;
        // If the new location is more than two minutes older, it must be
        // worse
    } else if (isSignificantlyOlder) {
        return currentBestLocation;
    }
    // Check whether the new location fix is more or less accurate
    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation
            .getAccuracy());
    boolean isLessAccurate = accuracyDelta > 0;
    boolean isMoreAccurate = accuracyDelta < 0;
    boolean isSignificantlyLessAccurate = accuracyDelta > 200;
    // Check if the old and new location are from the same provider
    boolean isFromSameProvider = isSameProvider(location.getProvider(),
            currentBestLocation.getProvider());
    // Determine location quality using a combination of timeliness and
    // accuracy
    if (isMoreAccurate) {
        return location;
    } else if (isNewer && !isLessAccurate) {
        return location;
    } else if (isNewer && !isSignificantlyLessAccurate
            && isFromSameProvider) {
        return location;
    }
    return bestLocation;
}

/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
    if (provider1 == null) {
        return provider2 == null;
    }
    return provider1.equals(provider2);
}

7
সত্যিই দেরিতে চিমিং করা, তবে সম্প্রতি আইও 2013 তে ঘোষিত "ফিউজড লোকেশন প্রোভাইডার" দেখে মনে হচ্ছে এটি আপনার বেশিরভাগ প্রয়োজনকে সম্বোধন করে - developer.android.com/google/play-services/location.html
ম্যাট

getBestLocation () হওয়া শেষ লাইনটি হওয়া উচিত নয়: কারেন্টবেস্টলকেশনটি ফিরিয়ে দিন; ফেরতের পরিবর্তে সেরা লোকেশন;?
গ্যাভ্রিয়েল

উত্তর:


164

দেখে মনে হচ্ছে আমরা একই অ্যাপ্লিকেশনটির কোডিং করছি ;-)
এখানে আমার বর্তমান বাস্তবায়ন। আমি এখনও আমার জিপিএস আপলোডার অ্যাপ্লিকেশনটির বিটা পরীক্ষার পর্যায়ে আছি, সুতরাং অনেকগুলি সম্ভাব্য উন্নতি হতে পারে। তবে এটি এখন পর্যন্ত বেশ ভালভাবে কাজ করছে বলে মনে হচ্ছে।

/**
 * try to get the 'best' location selected from all providers
 */
private Location getBestLocation() {
    Location gpslocation = getLocationByProvider(LocationManager.GPS_PROVIDER);
    Location networkLocation =
            getLocationByProvider(LocationManager.NETWORK_PROVIDER);
    // if we have only one location available, the choice is easy
    if (gpslocation == null) {
        Log.d(TAG, "No GPS Location available.");
        return networkLocation;
    }
    if (networkLocation == null) {
        Log.d(TAG, "No Network Location available");
        return gpslocation;
    }
    // a locationupdate is considered 'old' if its older than the configured
    // update interval. this means, we didn't get a
    // update from this provider since the last check
    long old = System.currentTimeMillis() - getGPSCheckMilliSecsFromPrefs();
    boolean gpsIsOld = (gpslocation.getTime() < old);
    boolean networkIsOld = (networkLocation.getTime() < old);
    // gps is current and available, gps is better than network
    if (!gpsIsOld) {
        Log.d(TAG, "Returning current GPS Location");
        return gpslocation;
    }
    // gps is old, we can't trust it. use network location
    if (!networkIsOld) {
        Log.d(TAG, "GPS is old, Network is current, returning network");
        return networkLocation;
    }
    // both are old return the newer of those two
    if (gpslocation.getTime() > networkLocation.getTime()) {
        Log.d(TAG, "Both are old, returning gps(newer)");
        return gpslocation;
    } else {
        Log.d(TAG, "Both are old, returning network(newer)");
        return networkLocation;
    }
}

/**
 * get the last known location from a specific provider (network/gps)
 */
private Location getLocationByProvider(String provider) {
    Location location = null;
    if (!isProviderSupported(provider)) {
        return null;
    }
    LocationManager locationManager = (LocationManager) getApplicationContext()
            .getSystemService(Context.LOCATION_SERVICE);
    try {
        if (locationManager.isProviderEnabled(provider)) {
            location = locationManager.getLastKnownLocation(provider);
        }
    } catch (IllegalArgumentException e) {
        Log.d(TAG, "Cannot acces Provider " + provider);
    }
    return location;
}

সম্পাদনা করুন: এখানে অংশটি যা অবস্থান সরবরাহকারীদের থেকে পর্যায়ক্রমিক আপডেটগুলির জন্য অনুরোধ করে:

public void startRecording() {
    gpsTimer.cancel();
    gpsTimer = new Timer();
    long checkInterval = getGPSCheckMilliSecsFromPrefs();
    long minDistance = getMinDistanceFromPrefs();
    // receive updates
    LocationManager locationManager = (LocationManager) getApplicationContext()
            .getSystemService(Context.LOCATION_SERVICE);
    for (String s : locationManager.getAllProviders()) {
        locationManager.requestLocationUpdates(s, checkInterval,
                minDistance, new LocationListener() {

                    @Override
                    public void onStatusChanged(String provider,
                            int status, Bundle extras) {}

                    @Override
                    public void onProviderEnabled(String provider) {}

                    @Override
                    public void onProviderDisabled(String provider) {}

                    @Override
                    public void onLocationChanged(Location location) {
                        // if this is a gps location, we can use it
                        if (location.getProvider().equals(
                                LocationManager.GPS_PROVIDER)) {
                            doLocationUpdate(location, true);
                        }
                    }
                });
        // //Toast.makeText(this, "GPS Service STARTED",
        // Toast.LENGTH_LONG).show();
        gps_recorder_running = true;
    }
    // start the gps receiver thread
    gpsTimer.scheduleAtFixedRate(new TimerTask() {

        @Override
        public void run() {
            Location location = getBestLocation();
            doLocationUpdate(location, false);
        }
    }, 0, checkInterval);
}

public void doLocationUpdate(Location l, boolean force) {
    long minDistance = getMinDistanceFromPrefs();
    Log.d(TAG, "update received:" + l);
    if (l == null) {
        Log.d(TAG, "Empty location");
        if (force)
            Toast.makeText(this, "Current location not available",
                    Toast.LENGTH_SHORT).show();
        return;
    }
    if (lastLocation != null) {
        float distance = l.distanceTo(lastLocation);
        Log.d(TAG, "Distance to last: " + distance);
        if (l.distanceTo(lastLocation) < minDistance && !force) {
            Log.d(TAG, "Position didn't change");
            return;
        }
        if (l.getAccuracy() >= lastLocation.getAccuracy()
                && l.distanceTo(lastLocation) < l.getAccuracy() && !force) {
            Log.d(TAG,
                    "Accuracy got worse and we are still "
                      + "within the accuracy range.. Not updating");
            return;
        }
        if (l.getTime() <= lastprovidertimestamp && !force) {
            Log.d(TAG, "Timestamp not never than last");
            return;
        }
    }
    // upload/store your location here
}

বিবেচনা করার বিষয়গুলি:

  • জিপিএস আপডেটগুলি খুব ঘন ঘন অনুরোধ করবেন না, এটি ব্যাটারি শক্তি চালিত করে। আমি বর্তমানে আমার অ্যাপ্লিকেশনটির জন্য 30 মিনিট ডিফল্ট হিসাবে ব্যবহার করি।

  • 'সর্বশেষ জ্ঞাত স্থানে সর্বনিম্ন দূরত্ব' চেক যোগ করুন। এটি ছাড়া, আপনার পয়েন্টগুলি যখন "জিপ্পিং" করবে যখন জিপিএস উপলব্ধ নেই এবং অবস্থানটি সেল টাওয়ারগুলি থেকে ত্রিভুজ করা হচ্ছে ang অথবা আপনি জানতে পারেন যে নতুন অবস্থানটি সর্বশেষ জ্ঞাত অবস্থান থেকে নির্ভুলতার মানের বাইরে।


2
আপনি আসলে কোনও নতুন অবস্থান পাবেন না, আপনি কেবল পূর্ববর্তী আপডেটগুলি থেকে এমন অবস্থানগুলি ব্যবহার করেন। আমি মনে করি যে এই কোডটি আসলে এমন শ্রোতা যুক্ত করে যা সময়ে সময়ে জিপিএস চালু করে লোকেশন আপডেট করে।
নিক্লাস এ।

2
দুঃখিত, আমি ভেবেছিলাম যে আপনি কেবল সেই অংশে আগ্রহী ছিলেন যা সমস্ত উপলব্ধ অবস্থান থেকে সেরাটি নির্বাচন করে। আমি উপরের কোডটি যুক্ত করেছি যা এগুলিও অনুরোধ করে। যদি কোনও নতুন জিপিএস অবস্থান প্রাপ্ত হয়, এটি এখনই সঞ্চিত / আপলোড করা হবে। যদি আমি কোনও নেটওয়ার্ক লোকেশন আপডেট পাই তবে আমি এটিকে রেফারেন্সের জন্য সঞ্চয় করি এবং 'আশা' যে পরবর্তী অবস্থানের চেক না হওয়া পর্যন্ত আমি একটি জিপিএস আপডেট গ্রহণ করব।
গ্রিফিয়াস

2
আমার একটি স্টপ রেকর্ডিং () পদ্ধতিও ছিল যা টাইমার বাতিল করেছিল। অবশেষে আমি টাইমার থেকে একটি নির্ধারিত ট্র্যাডপুলএক্সেকিউটারে স্যুইচ করেছি, সুতরাং স্টপ রেকর্ডিং এখন মূলত এক্সিকিউটার.শুটডাউন () কে কল করে এবং সমস্ত অবস্থান আপডেট শ্রোতাদের ডি-রেজিস্টার করে
গ্রিফিয়াস

1
আমার স্ক্যাম অনুসারে, স্টপ রেকর্ডিং কেবলমাত্র gpsTimer.cancel () নামে পরিচিত এবং gps_recorder_running = মিথ্যা সেট করে, তাই আপনার ক্ষেত্রে যেমন শ্রোতাদের ততক্ষণ কোনও ক্লিনআপ নেই। বর্তমান কোডটি সমস্ত সক্রিয় শ্রোতাদের একটি ভেক্টরে নজর রাখে, 1.5 বছর আগে আমি যখন এই উত্তরটি লিখেছিলাম তখন আমার কাছে এটি ছিল না।
গ্রিফিয়াস

1
এটি ইতিমধ্যে গিথুবে রয়েছে তবে আমি নিশ্চিত নই যে এটি আজকাল জিপিএস স্টাফ করার সবচেয়ে ভাল উপায়। আফাইক আমার এই কোডটি লেখার পর থেকে তারা অবস্থানের API এ অনেক উন্নতি করেছে।
গ্রিফিউস

33

আপনার অ্যাপ্লিকেশনের জন্য সঠিক অবস্থান প্রদানকারী নির্বাচন করতে, আপনি মানদণ্ডের বস্তুগুলি ব্যবহার করতে পারেন :

Criteria myCriteria = new Criteria();
myCriteria.setAccuracy(Criteria.ACCURACY_HIGH);
myCriteria.setPowerRequirement(Criteria.POWER_LOW);
// let Android select the right location provider for you
String myProvider = locationManager.getBestProvider(myCriteria, true); 

// finally require updates at -at least- the desired rate
long minTimeMillis = 600000; // 600,000 milliseconds make 10 minutes
locationManager.requestLocationUpdates(myProvider,minTimeMillis,0,locationListener); 

আর্গুমেন্টগুলি কীভাবে বিবেচনায় নেওয়া হয় সে সম্পর্কে আরও তথ্যের জন্য অনুরোধের জন্য ডকুমেন্টেশন পড়ুন

বিজ্ঞপ্তির ফ্রিকোয়েন্সি মিনিটাইম এবং মিনিটস্ট্যান্স পরামিতিগুলি ব্যবহার করে নিয়ন্ত্রণ করা যেতে পারে। যদি মিনিটটাইম 0 এর চেয়ে বেশি হয় তবে লোকেশনম্যানেজার পাওয়ার সংরক্ষণের জন্য লোকেশন আপডেটের মধ্যে মিনিটাইম মিলিসেকেন্ডের জন্য সম্ভাব্যভাবে বিশ্রাম নিতে পারে। যদি মিনিডেস্ট্যান্স 0 এর চেয়ে বেশি হয়, তবে ডিভাইসটি মিনিডাস্টেন্স মিটারের সাথে চালিত হলেই কোনও অবস্থান সম্প্রচারিত হবে। যত তাড়াতাড়ি সম্ভব বিজ্ঞপ্তিগুলি পেতে, উভয় পরামিতি 0 তে সেট করুন।

আরও চিন্তা

  • সাথে অবস্থানের বস্তুর সঠিকতা নজর রাখতে পারেন Location.getAccuracy () , যা মিটারে অবস্থানের আনুমানিক নির্ভুলতা প্রদান করে।
  • দ্য Criteria.ACCURACY_HIGHনির্ণায়ক 100 নিচে আপনি ত্রুটি দিতে হবে, যেমন জিপিএস যাবে, যা ভাল হিসাবে নয়, কিন্তু আপনার চাহিদা মেলে।
  • আপনার নিজের অবস্থান সরবরাহকারীর স্থিতিও নিরীক্ষণ করতে হবে এবং যদি ব্যবহারকারী কর্তৃক এটি অনুপলব্ধ বা অক্ষম হয়ে যায় তবে অন্য সরবরাহকারীর কাছে স্যুইচ করতে হবে।
  • প্যাসিভ প্রদানকারী এছাড়াও আবেদন এই ধরনের একটি ভাল ম্যাচ হতে পারে: ধারণা যখনই অন্য অ্যাপ্লিকেশন এবং সম্প্রচার Systemwide দ্বারা অনুরোধ করা হয় আপডেটেড অবস্থান ব্যবহার করা হয়।

আমি এটি সন্ধান করেছি Criteriaতবে কি যদি সর্বশেষতম নেটওয়ার্কের অবস্থানটি দুর্দান্ত হয় (এটি ওয়াইফাইয়ের মাধ্যমে জানা থাকতে পারে) এবং এটি পেতে কোনও সময় বা ব্যাটারি লাগে না (getLastK ज्ञিত), তবে মানদণ্ডটি সম্ভবত এটিকে অবহেলা করবে এবং পরিবর্তে জিপিএসটি ফিরিয়ে আনবে। আমি বিশ্বাস করতে পারি না গুগল বিকাশকারীদের পক্ষে এটি কঠিন করে তুলেছে।
নিক্লাস এ।

মানদণ্ডটি ব্যবহারের শীর্ষে, আপনি নির্বাচিত সরবরাহকারীর মাধ্যমে প্রেরিত প্রতিটি অবস্থানের আপডেটে, জিপিএস সরবরাহকারীর জন্য সর্বশেষ জ্ঞানের অবস্থানটি পরীক্ষা করে দেখতে পারেন এবং এটি (যথার্থতা এবং তারিখ) আপনার বর্তমান অবস্থানের সাথে তুলনা করতে পারেন। তবে এটি আপনার স্পেসিফিকেশন থেকে প্রয়োজনীয়তার চেয়ে আমার কাছে সুন্দর মনে হয়েছে; যদি কখনও কখনও আরও ভাল নির্ভুলতা অর্জন করা হয় তবে তা কি আপনার ব্যবহারকারীদের পক্ষে কার্যকর হবে?
স্টাফনে

এটাই আমি এখন করছি, সমস্যাটি হ'ল আমি জানার জন্য একটি হার্ড সময় পেয়েছি যদি শেষ জানা যথেষ্ট ভাল হয়। আমি আরও যোগ করতে পারি যে আমাকে নিজেকে একজন সরবরাহকারীর মধ্যে সীমাবদ্ধ করতে হবে না, আমি যত বেশি দ্রুত ততই লক পেতে পারি use
নিক্লাস এ

মনে রাখবেন যে PASSIVE_PROVIDER এর জন্য API স্তর 8 বা ততোধিক প্রয়োজন।
এডুয়ার্ডো

@ স্টাফেন সম্পাদনার জন্য দুঃখিত। এটি যত্ন নেবেন না। আপনার পোস্টটি সঠিক। আমি সম্পাদনাটি ত্রুটির জন্য করেছি। দুঃখিত। শুভেচ্ছা।
গাউচো

10

প্রথম দুটি বিষয় উত্তর :

  • এটি সক্ষম থাকলে এবং চারপাশে কোনও ঘন প্রাচীর না থাকলে জিপিএস সর্বদা আপনাকে আরও সুনির্দিষ্ট অবস্থান দেয় ।

  • যদি অবস্থানটি পরিবর্তন না হয়, তবে আপনি getLastK জ্ঞানত লোকেশন (স্ট্রিং) কল করতে পারেন এবং অবিলম্বে অবস্থানটি পুনরুদ্ধার করতে পারেন ।

বিকল্প পদ্ধতির ব্যবহার :

আপনি সেল আইডি ব্যবহারে বা পার্শ্ববর্তী সমস্ত সেল ব্যবহার করার চেষ্টা করতে পারেন

TelephonyManager mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
GsmCellLocation loc = (GsmCellLocation) mTelephonyManager.getCellLocation(); 
Log.d ("CID", Integer.toString(loc.getCid()));
Log.d ("LAC", Integer.toString(loc.getLac()));
// or 
List<NeighboringCellInfo> list = mTelephonyManager.getNeighboringCellInfo ();
for (NeighboringCellInfo cell : list) {
    Log.d ("CID", Integer.toString(cell.getCid()));
    Log.d ("LAC", Integer.toString(cell.getLac()));
}

আপনি বেশ কয়েকটি উন্মুক্ত ডাটাবেসগুলির মাধ্যমে ঘরের অবস্থানটি উল্লেখ করতে পারেন (যেমন, http://www.location-api.com/ বা http://opencellid.org/ )


কৌশলটি হ'ল লোকেশনটি পড়ার সময় টাওয়ার আইডির তালিকাটি পড়া। তারপরে, পরবর্তী ক্যোয়ারিতে (আপনার অ্যাপ্লিকেশনটিতে 10 মিনিট) আবার সেগুলি পড়ুন। যদি কমপক্ষে কিছু টাওয়ার একই থাকে তবে এটি ব্যবহার করা নিরাপদ getLastKnownLocation(String)। যদি তারা না হয় তবে অপেক্ষা করুন onLocationChanged()। এটি অবস্থানের জন্য কোনও তৃতীয় পক্ষের ডাটাবেসের প্রয়োজনীয়তা এড়ায়। আপনি এই পদ্ধতির চেষ্টা করতে পারেন ।


হ্যাঁ, তবে আমি যদি শেষ জ্ঞাত স্থানটি সত্যিই খারাপ হয় তবে আমার সমস্যা হয়। আমার কাছে দুটি অবস্থানের মধ্যে সবচেয়ে ভাল সিদ্ধান্ত নেওয়ার দরকার need
নিক্লাস এ।

আপনি টাওয়ারগুলির তথ্য সংরক্ষণ করতে পারেন এবং সেই টাওয়ারগুলি পরিবর্তন হয়েছে কিনা তা পরীক্ষা করতে পারেন। যদি তারা তা করে থাকে, তবে কোনও নতুন অবস্থানের জন্য অপেক্ষা করুন, যদি না হয় (বা যদি কিছু পরিবর্তিত হয়) তবে এটি পুনরায় ব্যবহার করুন। এইভাবে আপনি টাওয়ারের অবস্থানগুলিকে একটি ডাটাবেসের সাথে তুলনা করা এড়ান।
আলেয়াদাম

টাওয়ার ব্যবহার করা আমার কাছে বড় ওভারকিলের মতো বলে মনে হচ্ছে, যদিও ভাল ধারণা।
নিক্লাস এ।

@ নিক্লাস কোড এর চেয়ে জটিল আর কিছু পায় না। তবে আপনার অ্যান্ড্রয়েডের দরকার হবে an
আলেয়াদাম

হ্যাঁ, তবে তৃতীয় পক্ষের পরিষেবাটি আমাকে এখনও ব্যবহার করতে হবে এবং লোকেশন ডেটার উপর কখন টাওয়ার তথ্য ব্যবহার করতে হবে তা ঠিক করার একটি উপায়ও আমার দরকার, এটি কেবল জটিলতার অতিরিক্ত স্তর যুক্ত করে।
নিক্লাস এ

9

এটি আমার সমাধান যা মোটামুটি ভালভাবে কাজ করে:

private Location bestLocation = null;
private Looper looper;
private boolean networkEnabled = false, gpsEnabled = false;

private synchronized void setLooper(Looper looper) {
    this.looper = looper;
}

private synchronized void stopLooper() {
    if (looper == null) return;
    looper.quit();
}

@Override
protected void runTask() {
    final LocationManager locationManager = (LocationManager) service
            .getSystemService(Context.LOCATION_SERVICE);
    final SharedPreferences prefs = getPreferences();
    final int maxPollingTime = Integer.parseInt(prefs.getString(
            POLLING_KEY, "0"));
    final int desiredAccuracy = Integer.parseInt(prefs.getString(
            DESIRED_KEY, "0"));
    final int acceptedAccuracy = Integer.parseInt(prefs.getString(
            ACCEPTED_KEY, "0"));
    final int maxAge = Integer.parseInt(prefs.getString(AGE_KEY, "0"));
    final String whichProvider = prefs.getString(PROVIDER_KEY, "any");
    final boolean canUseGps = whichProvider.equals("gps")
            || whichProvider.equals("any");
    final boolean canUseNetwork = whichProvider.equals("network")
            || whichProvider.equals("any");
    if (canUseNetwork)
        networkEnabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    if (canUseGps)
        gpsEnabled = locationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER);
    // If any provider is enabled now and we displayed a notification clear it.
    if (gpsEnabled || networkEnabled) removeErrorNotification();
    if (gpsEnabled)
        updateBestLocation(locationManager
                .getLastKnownLocation(LocationManager.GPS_PROVIDER));
    if (networkEnabled)
        updateBestLocation(locationManager
                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER));
    if (desiredAccuracy == 0
            || getLocationQuality(desiredAccuracy, acceptedAccuracy,
                    maxAge, bestLocation) != LocationQuality.GOOD) {
        // Define a listener that responds to location updates
        LocationListener locationListener = new LocationListener() {

            public void onLocationChanged(Location location) {
                updateBestLocation(location);
                if (desiredAccuracy != 0
                        && getLocationQuality(desiredAccuracy,
                                acceptedAccuracy, maxAge, bestLocation)
                                == LocationQuality.GOOD)
                    stopLooper();
            }

            public void onProviderEnabled(String provider) {
                if (isSameProvider(provider,
                        LocationManager.NETWORK_PROVIDER))networkEnabled =true;
                else if (isSameProvider(provider,
                        LocationManager.GPS_PROVIDER)) gpsEnabled = true;
                // The user has enabled a location, remove any error
                // notification
                if (canUseGps && gpsEnabled || canUseNetwork
                        && networkEnabled) removeErrorNotification();
            }

            public void onProviderDisabled(String provider) {
                if (isSameProvider(provider,
                        LocationManager.NETWORK_PROVIDER))networkEnabled=false;
                else if (isSameProvider(provider,
                        LocationManager.GPS_PROVIDER)) gpsEnabled = false;
                if (!gpsEnabled && !networkEnabled) {
                    showErrorNotification();
                    stopLooper();
                }
            }

            public void onStatusChanged(String provider, int status,
                    Bundle extras) {
                Log.i(LOG_TAG, "Provider " + provider + " statusChanged");
                if (isSameProvider(provider,
                        LocationManager.NETWORK_PROVIDER)) networkEnabled = 
                        status == LocationProvider.AVAILABLE
                        || status == LocationProvider.TEMPORARILY_UNAVAILABLE;
                else if (isSameProvider(provider,
                        LocationManager.GPS_PROVIDER))
                    gpsEnabled = status == LocationProvider.AVAILABLE
                      || status == LocationProvider.TEMPORARILY_UNAVAILABLE;
                // None of them are available, stop listening
                if (!networkEnabled && !gpsEnabled) {
                    showErrorNotification();
                    stopLooper();
                }
                // The user has enabled a location, remove any error
                // notification
                else if (canUseGps && gpsEnabled || canUseNetwork
                        && networkEnabled) removeErrorNotification();
            }
        };
        if (networkEnabled || gpsEnabled) {
            Looper.prepare();
            setLooper(Looper.myLooper());
            // Register the listener with the Location Manager to receive
            // location updates
            if (canUseGps)
                locationManager.requestLocationUpdates(
                        LocationManager.GPS_PROVIDER, 1000, 1,
                        locationListener, Looper.myLooper());
            if (canUseNetwork)
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER, 1000, 1,
                        locationListener, Looper.myLooper());
            Timer t = new Timer();
            t.schedule(new TimerTask() {

                @Override
                public void run() {
                    stopLooper();
                }
            }, maxPollingTime * 1000);
            Looper.loop();
            t.cancel();
            setLooper(null);
            locationManager.removeUpdates(locationListener);
        } else // No provider is enabled, show a notification
        showErrorNotification();
    }
    if (getLocationQuality(desiredAccuracy, acceptedAccuracy, maxAge,
            bestLocation) != LocationQuality.BAD) {
        sendUpdate(new Event(EVENT_TYPE, locationToString(desiredAccuracy,
                acceptedAccuracy, maxAge, bestLocation)));
    } else Log.w(LOG_TAG, "LocationCollector failed to get a location");
}

private synchronized void showErrorNotification() {
    if (notifId != 0) return;
    ServiceHandler handler = service.getHandler();
    NotificationInfo ni = NotificationInfo.createSingleNotification(
            R.string.locationcollector_notif_ticker,
            R.string.locationcollector_notif_title,
            R.string.locationcollector_notif_text,
            android.R.drawable.stat_notify_error);
    Intent intent = new Intent(
            android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
    ni.pendingIntent = PendingIntent.getActivity(service, 0, intent,
            PendingIntent.FLAG_UPDATE_CURRENT);
    Message msg = handler.obtainMessage(ServiceHandler.SHOW_NOTIFICATION);
    msg.obj = ni;
    handler.sendMessage(msg);
    notifId = ni.id;
}

private void removeErrorNotification() {
    if (notifId == 0) return;
    ServiceHandler handler = service.getHandler();
    if (handler != null) {
        Message msg = handler.obtainMessage(
                ServiceHandler.CLEAR_NOTIFICATION, notifId, 0);
        handler.sendMessage(msg);
        notifId = 0;
    }
}

@Override
public void interrupt() {
    stopLooper();
    super.interrupt();
}

private String locationToString(int desiredAccuracy, int acceptedAccuracy,
        int maxAge, Location location) {
    StringBuilder sb = new StringBuilder();
    sb.append(String.format(
            "qual=%s time=%d prov=%s acc=%.1f lat=%f long=%f",
            getLocationQuality(desiredAccuracy, acceptedAccuracy, maxAge,
                    location), location.getTime() / 1000, // Millis to
                                                            // seconds
            location.getProvider(), location.getAccuracy(), location
                    .getLatitude(), location.getLongitude()));
    if (location.hasAltitude())
        sb.append(String.format(" alt=%.1f", location.getAltitude()));
    if (location.hasBearing())
        sb.append(String.format(" bearing=%.2f", location.getBearing()));
    return sb.toString();
}

private enum LocationQuality {
    BAD, ACCEPTED, GOOD;

    public String toString() {
        if (this == GOOD) return "Good";
        else if (this == ACCEPTED) return "Accepted";
        else return "Bad";
    }
}

private LocationQuality getLocationQuality(int desiredAccuracy,
        int acceptedAccuracy, int maxAge, Location location) {
    if (location == null) return LocationQuality.BAD;
    if (!location.hasAccuracy()) return LocationQuality.BAD;
    long currentTime = System.currentTimeMillis();
    if (currentTime - location.getTime() < maxAge * 1000
            && location.getAccuracy() <= desiredAccuracy)
        return LocationQuality.GOOD;
    if (acceptedAccuracy == -1
            || location.getAccuracy() <= acceptedAccuracy)
        return LocationQuality.ACCEPTED;
    return LocationQuality.BAD;
}

private synchronized void updateBestLocation(Location location) {
    bestLocation = getBestLocation(location, bestLocation);
}

protected Location getBestLocation(Location location,
        Location currentBestLocation) {
    if (currentBestLocation == null) {
        // A new location is always better than no location
        return location;
    }
    if (location == null) return currentBestLocation;
    // Check whether the new location fix is newer or older
    long timeDelta = location.getTime() - currentBestLocation.getTime();
    boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
    boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
    boolean isNewer = timeDelta > 0;
    // If it's been more than two minutes since the current location, use
    // the new location
    // because the user has likely moved
    if (isSignificantlyNewer) {
        return location;
        // If the new location is more than two minutes older, it must be
        // worse
    } else if (isSignificantlyOlder) {
        return currentBestLocation;
    }
    // Check whether the new location fix is more or less accurate
    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation
            .getAccuracy());
    boolean isLessAccurate = accuracyDelta > 0;
    boolean isMoreAccurate = accuracyDelta < 0;
    boolean isSignificantlyLessAccurate = accuracyDelta > 200;
    // Check if the old and new location are from the same provider
    boolean isFromSameProvider = isSameProvider(location.getProvider(),
            currentBestLocation.getProvider());
    // Determine location quality using a combination of timeliness and
    // accuracy
    if (isMoreAccurate) {
        return location;
    } else if (isNewer && !isLessAccurate) {
        return location;
    } else if (isNewer && !isSignificantlyLessAccurate
            && isFromSameProvider) {
        return location;
    }
    return bestLocation;
}

/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
    if (provider1 == null) return provider2 == null;
    return provider1.equals(provider2);
}

হাই নিক্লাস আমার একই সমীকরণ রয়েছে তাই আমি যে কোনও উপায়ে আপনার সাথে যোগাযোগ করতে পারলাম .. আপনি যদি আমাদের সহায়তা করতে পারেন তবে আমি আপনাকে ধন্যবাদ জানাব ..
স্কুল বয়

আপনি পুরো কোড পোস্ট করতে পারেন? ধন্যবাদ, সত্যই প্রশংসিত
রোদি

যে কোড সব। প্রকল্পে আমার আর অ্যাক্সেস নেই।
নিক্লাস এ

1
আপনি এই প্রকল্পটির কোড "অ্যান্ড্রয়েড-প্রিপিস-লোকেশন" নিয়েছেন বলে মনে হয় এবং এটি এখনও জীবিত। লোকেরা এখানে কীভাবে কাজ করে তা দেখতে পায় কোডডোড.এফ
অ্যান্ড্রয়েড- প্রোটিটস

7

অবস্থানের নির্ভুলতা বেশিরভাগ ব্যবহৃত অবস্থান সরবরাহকারীর উপর নির্ভর করে:

  1. জিপিএস - আপনি কয়েক মিটার নির্ভুলতা পাবেন (ধরে নিবেন আপনার জিপিএস অভ্যর্থনা রয়েছে)
  2. ওয়াইফাই - আপনি কয়েকশ মিটার নির্ভুলতা পাবেন
  3. সেল নেটওয়ার্ক - আপনাকে খুব ভুল ফলাফল দেবে (আমি 4 কিলোমিটারের বিচ্যুতি দেখেছি ...)

যদি আপনি এটির যথার্থতা খুঁজছেন তবে জিপিএস হ'ল একমাত্র বিকল্প।

আমি এটা সম্পর্কে একটি খুব তথ্যপূর্ণ নিবন্ধ পড়েছি এখানে

জিপিএস সময়সীমা হিসাবে - 60 সেকেন্ডের পর্যাপ্ত হওয়া উচিত, এবং বেশিরভাগ ক্ষেত্রে এমনকি খুব বেশি much আমি মনে করি 30 সেকেন্ড ঠিক আছে এবং কখনও কখনও 5 সেকেন্ডেরও কম ...

আপনার যদি কেবল একটি একক অবস্থানের প্রয়োজন হয় তবে আমি আপনাকে পরামর্শ দিচ্ছি যে আপনার onLocationChangedপদ্ধতিতে, আপনি একবার আপডেট পাওয়ার পরে আপনি শ্রোতার তালিকাভুক্ত করবেন এবং জিপিএসের অপ্রয়োজনীয় ব্যবহার এড়াতে পারবেন।


আমি আমার অবস্থান যেখানে পাই সেখান থেকে আমি সত্যিই যত্নশীল নই, আমি আমাকে কোনও সরবরাহকারীর মধ্যে সীমাবদ্ধ রাখতে চাই না
নিক্লাস এ

আপনি ডিভাইসে উপলভ্য সমস্ত অবস্থান সরবরাহকারীর নিবন্ধন করতে পারেন (আপনি লোকেশনম্যানেজার.জেটপ্রভাইডার ()) থেকে সমস্ত সরবরাহকারীর তালিকা পেতে পারেন, তবে আপনি যদি সঠিক সমাধানের সন্ধান করছেন তবে বেশিরভাগ ক্ষেত্রে নেটওয়ার্ক সরবরাহকারী আপনার পক্ষে কার্যকর হবে না।
মুজিকান্ত

হ্যাঁ, তবে এটি সরবরাহকারীদের মধ্যে চয়ন সম্পর্কে কোনও প্রশ্ন নয়, এটি সাধারণত সেরা অবস্থান পাওয়ার বিষয়ে একটি প্রশ্ন (সাধারণত একাধিক সরবরাহকারী জড়িত থাকা সত্ত্বেও)
নিক্লাস এ

4

বর্তমানে আমি ব্যবহার করছি যেহেতু এটি আমার অ্যাপ্লিকেশনটির জন্য অবস্থান এবং দূরত্ব গণনা করার জন্য নির্ভরযোগ্য ...... আমি এটি আমার ট্যাক্সি অ্যাপ্লিকেশনের জন্য ব্যবহার করছি।

গুগল বিকাশকারী জিপিএস সেন্সর, ম্যাগনেটমিটার, অ্যাক্সিলোমিটারের সাথে ফাইশন বা সেল অবস্থান ব্যবহার করে অবস্থান নির্ণয় বা অনুমান করতে ফিউশন এপিআই ব্যবহার করুন। এটি সঠিকভাবে ভবনের অভ্যন্তরে অবস্থান আপডেটগুলিও দিতে সক্ষম। বিস্তারিত জানার জন্য https://developers.google.com/android/references/com/google/android/gms/location/FusedLocationProviderApi লিঙ্কটি পেতে পান

import android.app.Activity;
import android.location.Location;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;


public class MainActivity extends Activity implements LocationListener,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {

    private static final long ONE_MIN = 500;
    private static final long TWO_MIN = 500;
    private static final long FIVE_MIN = 500;
    private static final long POLLING_FREQ = 1000 * 20;
    private static final long FASTEST_UPDATE_FREQ = 1000 * 5;
    private static final float MIN_ACCURACY = 1.0f;
    private static final float MIN_LAST_READ_ACCURACY = 1;

    private LocationRequest mLocationRequest;
    private Location mBestReading;
TextView tv;
    private GoogleApiClient mGoogleApiClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (!servicesAvailable()) {
            finish();
        }

        setContentView(R.layout.activity_main);
tv= (TextView) findViewById(R.id.tv1);
        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(POLLING_FREQ);
        mLocationRequest.setFastestInterval(FASTEST_UPDATE_FREQ);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();


        if (mGoogleApiClient != null) {
            mGoogleApiClient.connect();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        if (mGoogleApiClient != null) {
            mGoogleApiClient.connect();
        }
    }

    @Override
    protected void onPause() {d
        super.onPause();

        if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
    }


        tv.setText(location + "");
        // Determine whether new location is better than current best
        // estimate
        if (null == mBestReading || location.getAccuracy() < mBestReading.getAccuracy()) {
            mBestReading = location;


            if (mBestReading.getAccuracy() < MIN_ACCURACY) {
                LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
            }
        }
    }

    @Override
    public void onConnected(Bundle dataBundle) {
        // Get first reading. Get additional location updates if necessary
        if (servicesAvailable()) {

            // Get best last location measurement meeting criteria
            mBestReading = bestLastKnownLocation(MIN_LAST_READ_ACCURACY, FIVE_MIN);

            if (null == mBestReading
                    || mBestReading.getAccuracy() > MIN_LAST_READ_ACCURACY
                    || mBestReading.getTime() < System.currentTimeMillis() - TWO_MIN) {

                LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);

               //Schedule a runnable to unregister location listeners

                    @Override
                    public void run() {
                        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, MainActivity.this);

                    }

                }, ONE_MIN, TimeUnit.MILLISECONDS);

            }

        }
    }

    @Override
    public void onConnectionSuspended(int i) {

    }


    private Location bestLastKnownLocation(float minAccuracy, long minTime) {
        Location bestResult = null;
        float bestAccuracy = Float.MAX_VALUE;
        long bestTime = Long.MIN_VALUE;

        // Get the best most recent location currently available
        Location mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        //tv.setText(mCurrentLocation+"");
        if (mCurrentLocation != null) {
            float accuracy = mCurrentLocation.getAccuracy();
            long time = mCurrentLocation.getTime();

            if (accuracy < bestAccuracy) {
                bestResult = mCurrentLocation;
                bestAccuracy = accuracy;
                bestTime = time;
            }
        }

        // Return best reading or null
        if (bestAccuracy > minAccuracy || bestTime < minTime) {
            return null;
        }
        else {
            return bestResult;
        }
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    private boolean servicesAvailable() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

        if (ConnectionResult.SUCCESS == resultCode) {
            return true;
        }
        else {
            GooglePlayServicesUtil.getErrorDialog(resultCode, this, 0).show();
            return false;
        }
    }
}

2

আমি গুগল দ্বারা প্রস্তাবিত সর্বশেষ অবস্থানের টানানোর পদ্ধতিগুলি ব্যবহার করে (ফিউজডলোকেশনপ্রোভাইডারক্লায়েন্ট ব্যবহার করে) একটি আপডেট (বিগত বছর) উত্তরের জন্য ইন্টারনেটকে স্কলার করেছি। আমি অবশেষে এই অবতরণ:

https://github.com/googlesamples/android-play-location/tree/master/LocationUpdates

আমি একটি নতুন প্রকল্প তৈরি করেছি এবং এই কোডটির বেশিরভাগটিতে অনুলিপি করেছি। গম্ভীর গর্জন। এটা কাজ করে। এবং আমি মনে করি কোনও অবচয় রেখা ছাড়াই।

এছাড়াও, সিমুলেটরটি কোনও জিপিএসের অবস্থান পেয়েছে বলে মনে হচ্ছে না, যা আমি জানি। লগতে এটির প্রতিবেদন হিসাবে এটি পাওয়া যায়: "সমস্ত অবস্থানের সেটিংস সন্তুষ্ট" "

এবং পরিশেষে, আপনি জানতে চেয়েছিলেন (আমি করেছি), আপনার যদি গুগল বিকাশকারী কনসোল থেকে গুগল ম্যাপস এপিআই কী প্রয়োজন হয় না, আপনি যদি চান তবে জিপিএসের অবস্থান।

এছাড়াও তাদের টিউটোরিয়াল দরকারী। তবে আমি একটি পুরো পৃষ্ঠার টিউটোরিয়াল / কোড উদাহরণ এবং এটি চেয়েছিলাম। তাদের টিউটোরিয়াল স্ট্যাকগুলি তবে বিভ্রান্তিকর যখন আপনি এটিতে নতুন হন কারণ আপনি পূর্ববর্তী পৃষ্ঠাগুলি থেকে কী টুকরোগুলি প্রয়োজন তা জানেন না।

https://developer.android.com/training/location/index.html

এবং অবশেষে, এই জাতীয় জিনিসগুলি মনে রাখবেন:

আমাকে কেবল মূলঅ্যাক্টিভিটি.জভা পরিবর্তন করতে হবে না। আমাকে স্ট্রিংস.এক্সএমএল, অ্যান্ড্রয়েডম্যানিফিসিট.এক্সএমএল এবং সঠিক বিল্ড.gradle সংশোধন করতে হয়েছিল। এবং আপনার ক্রিয়াকলাপ_মেন.এক্সএমএল (তবে সেই অংশটি আমার পক্ষে সহজ ছিল)।

আমার এইগুলির মতো নির্ভরতা যুক্ত করার দরকার ছিল: বাস্তবায়ন 'com.google.android.gms: play-পরিষেবাদি-অবস্থান: 11.8.0' এবং গুগল প্লে পরিষেবাদি অন্তর্ভুক্ত করতে আমার অ্যান্ড্রয়েড স্টুডিও এসডিকে এর সেটিংস আপডেট করুন update (ফাইল সেটিংস উপস্থিতি সিস্টেম সেটিংস অ্যান্ড্রয়েড এসডিকে এসডিকে সরঞ্জামগুলি গুগল প্লে পরিষেবাদি পরীক্ষা করুন)।

আপডেট: অ্যান্ড্রয়েড সিমুলেটরটি একটি অবস্থান এবং অবস্থান পরিবর্তন ইভেন্টগুলি (যখন আমি সিমের সেটিংসে মান পরিবর্তন করেছি) পেয়েছিল বলে মনে হয়েছিল। তবে আমার সেরা এবং প্রথম ফলাফলগুলি একটি আসল ডিভাইসে ছিল। সুতরাং প্রকৃত ডিভাইসগুলিতে এটি পরীক্ষা করা সম্ভবত সবচেয়ে সহজ।


1

কোডটির অবস্থান পাওয়ার জন্য সম্প্রতি রিফ্যাক্টর করে কিছু ভাল ধারণা শিখুন এবং শেষ পর্যন্ত তুলনামূলকভাবে নিখুঁত গ্রন্থাগার এবং ডেমো অর্জন করেছেন।

@ গ্রিফিয়াসের উত্তর ভাল

    //request all valid provider(network/gps)
private boolean requestAllProviderUpdates() {
    checkRuntimeEnvironment();
    checkPermission();

    if (isRequesting) {
        EasyLog.d("Request location update is busy");
        return false;
    }


    long minTime = getCheckTimeInterval();
    float minDistance = getCheckMinDistance();

    if (mMapLocationListeners == null) {
        mMapLocationListeners = new HashMap<>();
    }

    mValidProviders = getValidProviders();
    if (mValidProviders == null || mValidProviders.isEmpty()) {
        throw new IllegalArgumentException("Not available provider.");
    }

    for (String provider : mValidProviders) {
        LocationListener locationListener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                if (location == null) {
                    EasyLog.e("LocationListener callback location is null.");
                    return;
                }
                printf(location);
                mLastProviderTimestamp = location.getTime();

                if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) {
                    finishResult(location);
                } else {
                    doLocationResult(location);
                }

                removeProvider(location.getProvider());
                if (isEmptyValidProviders()) {
                    requestTimeoutMsgInit();
                    removeUpdates();
                }
            }

            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {
            }

            @Override
            public void onProviderEnabled(String provider) {
            }

            @Override
            public void onProviderDisabled(String provider) {
            }
        };
        getLocationManager().requestLocationUpdates(provider, minTime, minDistance, locationListener);
        mMapLocationListeners.put(provider, locationListener);
        EasyLog.d("Location request %s provider update.", provider);
    }
    isRequesting = true;
    return true;
}

//remove request update
public void removeUpdates() {
    checkRuntimeEnvironment();

    LocationManager locationManager = getLocationManager();
    if (mMapLocationListeners != null) {
        Set<String> keys = mMapLocationListeners.keySet();
        for (String key : keys) {
            LocationListener locationListener = mMapLocationListeners.get(key);
            if (locationListener != null) {
                locationManager.removeUpdates(locationListener);
                EasyLog.d("Remove location update, provider is " + key);
            }
        }
        mMapLocationListeners.clear();
        isRequesting = false;
    }
}

//Compared with the last successful position, to determine whether you need to filter
private boolean isNeedFilter(Location location) {
    checkLocation(location);

    if (mLastLocation != null) {
        float distance = location.distanceTo(mLastLocation);
        if (distance < getCheckMinDistance()) {
            return true;
        }
        if (location.getAccuracy() >= mLastLocation.getAccuracy()
                && distance < location.getAccuracy()) {
            return true;
        }
        if (location.getTime() <= mLastProviderTimestamp) {
            return true;
        }
    }
    return false;
}

private void doLocationResult(Location location) {
    checkLocation(location);

    if (isNeedFilter(location)) {
        EasyLog.d("location need to filtered out, timestamp is " + location.getTime());
        finishResult(mLastLocation);
    } else {
        finishResult(location);
    }
}

//Return to the finished position
private void finishResult(Location location) {
    checkLocation(location);

    double latitude = location.getLatitude();
    double longitude = location.getLongitude();
    float accuracy = location.getAccuracy();
    long time = location.getTime();
    String provider = location.getProvider();

    if (mLocationResultListeners != null && !mLocationResultListeners.isEmpty()) {
        String format = "Location result:<%f, %f> Accuracy:%f Time:%d Provider:%s";
        EasyLog.i(String.format(format, latitude, longitude, accuracy, time, provider));

        mLastLocation = location;
        synchronized (this) {
            Iterator<LocationResultListener> iterator =  mLocationResultListeners.iterator();
            while (iterator.hasNext()) {
                LocationResultListener listener = iterator.next();
                if (listener != null) {
                    listener.onResult(location);
                }
                iterator.remove();
            }
        }
    }
}

সম্পূর্ণ বাস্তবায়ন: https://github.com/bingerz/FastLocation/blob/master/fastlocationlib/src/main/java/cn/bingerz/fastlocation/FastLocation.java

১. গ্রিফিউস সমাধান সমাধানের জন্য ধন্যবাদ, আমিও সম্পূর্ণ কোডটি ভাগ করে নিই।

2. অবস্থানটি সম্পূর্ণ করার জন্য প্রতিটি অনুরোধ, আপডেটগুলি অপসারণ করা ভাল, অন্যথায় ফোনের স্থিতি দণ্ড সর্বদা অবস্থানের আইকনটি প্রদর্শন করবে


0

আমার অভিজ্ঞতায়, জিপিএস ফিক্স না পাওয়া পর্যন্ত আমি সবচেয়ে ভালভাবে বেড়াতে পেরেছি। আমি অন্যান্য অবস্থান সরবরাহকারীদের সম্পর্কে খুব বেশি জানি না, তবে আমি জানি যে জিপিএসের জন্য কয়েকটি কৌশল রয়েছে যা ঘেটো নির্ভুলতার পরিমাপের জন্য কিছুটা দিতে পারে। উচ্চতা প্রায়শই একটি চিহ্ন, তাই আপনি হাস্যকর মানগুলি পরীক্ষা করতে পারেন। অ্যান্ড্রয়েড লোকেশন ফিক্সগুলিতে নির্ভুলতার পরিমাপ রয়েছে। এছাড়াও যদি আপনি ব্যবহৃত উপগ্রহের সংখ্যা দেখতে পান তবে এটি নির্ভুলতাও নির্দেশ করতে পারে।

নির্ভুলতার আরও ভাল ধারণা পাওয়ার একটি আকর্ষণীয় উপায় হ'ল 10 সেকেন্ডের জন্য ~ 1 / সেকেন্ডের মতো খুব দ্রুত সমাধানের সেট জিজ্ঞাসা করা এবং তারপরে এক বা দুই মিনিটের জন্য ঘুমানো। আমি যে কথা বলেছিলাম তাতে বিশ্বাস করা হয়েছে যে কিছু অ্যান্ড্রয়েড ডিভাইস যেভাবেই এটি করবে। তারপরে আপনি আউটলিয়ারদের আগাছা ছড়িয়ে দেবেন (আমি এখানে কলমান ফিল্টারটি উল্লেখ করেছি) এবং একটি একক সংশোধন করার জন্য একধরণের কেন্দ্রিক কৌশল ব্যবহার করি।

স্পষ্টতই আপনি এখানে যে গভীরতা পাবেন তার উপর নির্ভর করে আপনার প্রয়োজনীয়তা কতটা শক্ত। সেরা অবস্থানটি সম্ভব হওয়ার জন্য যদি আপনার বিশেষভাবে কঠোর প্রয়োজনীয়তা থাকে তবে আমি মনে করি আপনি দেখতে পাবেন যে জিপিএস এবং নেটওয়ার্কের অবস্থান আপেল এবং কমলার মতো। এছাড়াও জিপিএস ডিভাইস থেকে ডিভাইসে বন্যভাবে পৃথক হতে পারে।


ঠিক আছে, এটি গুরুত্বপূর্ণ যে এটি খুব ভাল নয়, ঠিক এটিই যে মানচিত্রে প্লট করা যথেষ্ট ভাল এবং এটি ব্যাকগ্রাউন্ড টাস্ক হওয়ায় আমি ব্যাটারিটি ড্রেন না।
নিক্লাস এ।

-3

স্কাইহুক (http://www.skyhookwireless.com/) এর একটি অবস্থান সরবরাহকারী রয়েছে যা গুগল যে স্ট্যান্ডার্ড সরবরাহ করে তার চেয়ে অনেক দ্রুত। এটি আপনি যা খুঁজছেন তা হতে পারে। আমি তাদের সাথে অনুমোদিত নই।


সত্যই আকর্ষণীয়, তারা কেবলমাত্র ওয়াইফাই ব্যবহার করছে বলে মনে হচ্ছে যা খুব সুন্দর তবে আমার যখনই আশেপাশে কোনও ওয়াইফাই বা 3 জি / 2 জি সংযোগ নেই তখন এটি কাজ করা দরকার যাতে এটি বিমূর্তির আরও একটি স্তর যুক্ত করে। ভাল ধরা যদিও।
নিক্লাস এ।

1
স্কাইহুক ওয়াইফাই, জিপিএস এবং সেল টাওয়ারগুলির সংমিশ্রণ ব্যবহার করে appears প্রযুক্তিগত তথ্যের জন্য স্কাইহুকওয়্যারলেস.com/howitworks দেখুন । তারা ইদানীং বেশ কয়েকটি ডিজাইনের জয় অর্জন করেছে, উদাহরণস্বরূপ ম্যাপকোয়েস্ট, টুইড্রয়েড, শপস্যাভি এবং সোনি এনজিপি। নোট করুন যে তাদের এসডিকে ডাউনলোড এবং চেষ্টা করা নিখরচায় মনে হচ্ছে তবে আপনার অ্যাপে এটি বিতরণের লাইসেন্স সম্পর্কে আপনাকে তাদের সাথে যোগাযোগ করতে হবে। দুর্ভাগ্যক্রমে তারা তাদের ওয়েবসাইটে দামের তালিকা দেয় না।
এড বার্নেট

আচ্ছা বুঝলাম. ঠিক আছে, যদি এটি বাণিজ্যিকভাবে ব্যবহারের জন্য নিখরচায় না হয় তবে আমি ভয় করি যে আমি এটি ব্যবহার করতে পারি না।
নিক্লাস এ।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.