it-swarm.com.ru

Ошибка вызова виртуального метода 'double Android.location.Location.getLatitude ()' для ссылки на пустой объект

Все, что я пытаюсь сделать, это позволить пользователю получить список мест, которые ему нравятся. Например, если ввод был больницей, мое приложение открыло бы карты Google со строкой поиска «Больница». Но, как предлагается в документации, использование геокода, такого как geo:0,0?q=hospital uri, показывает все больницы рядом с координатами 0 широты и 0 долготы. Поэтому, когда я попытался сначала получить координаты пользователей, используя следующий код.

Places Decoder.Java

package com.kkze.Mappy;

import Android.app.Activity;
import Android.app.AlertDialog;
import Android.content.Context;
import Android.content.DialogInterface;
import Android.content.Intent;
import Android.location.Criteria;
import Android.location.Location;
import Android.location.LocationManager;
import Android.net.Uri;
import Android.os.Build;
import Android.os.Bundle;
import Android.provider.Settings;
import Android.text.TextUtils;
import Android.util.Log;
import Android.widget.Toast;

public class PlacesDecoder extends Activity {
Intent intentThatCalled;
public double latitude;
public double longitude;
public LocationManager locationManager;
public Criteria criteria;
public String bestProvider;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    intentThatCalled = getIntent();
    String voice2text = intentThatCalled.getStringExtra("v2txt");
    getLocation(voice2text);
}
public static boolean isLocationEnabled(Context context)
{
    int locationMode = 0;
    String locationProviders;
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat)
    {
        try
        {
            locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }
        return locationMode != Settings.Secure.LOCATION_MODE_OFF;
    }
    else
    {
        locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
        return !TextUtils.isEmpty(locationProviders);
    }
}

public void getLocation(String voice2txt) {
    locationManager = (LocationManager)  this.getSystemService(Context.LOCATION_SERVICE);
    criteria = new Criteria();
    bestProvider = String.valueOf(locationManager.getBestProvider(criteria, true)).toString();
    Location location = locationManager.getLastKnownLocation(bestProvider);
    if (isLocationEnabled(PlacesDecoder.this)) {
            Log.e("TAG", "GPS is on");
            latitude = location.getLatitude();
            longitude = location.getLongitude();
            Toast.makeText(PlacesDecoder.this, "latitude:" + latitude + " longitude:" + longitude, Toast.LENGTH_SHORT).show();
            searchNearestPlace(voice2txt);

        }
    else
    {
        AlertDialog.Builder notifyLocationServices = new AlertDialog.Builder(PlacesDecoder.this);
        notifyLocationServices.setTitle("Switch on Location Services");
        notifyLocationServices.setMessage("Location Services must be turned on to complete this action. Also please take note that if on a very weak network connection,  such as 'E' Mobile Data or 'Very weak Wifi-Connections' it may take even 15 mins to load. If on a very weak network connection as stated above, location returned to application may be null or nothing and cause the application to crash.");
        notifyLocationServices.setPositiveButton("Ok, Open Settings", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent openLocationSettings = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                PlacesDecoder.this.startActivity(openLocationSettings);
                finish();
            }
        });
        notifyLocationServices.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                finish();
            }
        });
        notifyLocationServices.show();
    }
}

public void searchNearestPlace(String v2txt) {
    Log.e("TAG", "Started");
    v2txt = v2txt.toLowerCase();
    String[] placesS = {"accounting", "airport", "aquarium", "atm", "attraction", "bakery", "bakeries", "bank", "bar", "cafe", "campground", "casino", "cemetery", "cemeteries", "church", "courthouse", "dentist", "doctor", "electrician", "embassy", "embassies", "establishment", "finance", "florist", "food", "grocery", "groceries", "supermarket", "gym", "health", "hospital", "laundry", "laundries", "lawyer", "library", "libraries", "locksmith", "lodging", "mosque", "museum", "Painter", "park", "parking", "pharmacy", "pharmacies", "physiotherapist", "plumber", "police", "restaurant", "school", "spa", "stadium", "storage", "store", "synagog", "synagogue", "university", "universities", "Zoo"};
    String[] placesM = {"amusement park", "animal care", "animal care", "animal hospital", "art gallery", "art galleries", "beauty salon", "bicycle store", "book store", "bowling alley", "bus station", "car dealer", "car rental", "car repair", "car wash", "city hall", "clothing store", "convenience store", "department store", "electronics store", "electronic store", "fire station", "funeral home", "furniture store", "gas station", "general contractor", "hair care", "hardware store", "hindu temple", "home good store", "homes good store", "home goods store", "homes goods store", "insurance agency", "insurance agencies", "jewelry store", "liquor store", "local government office", "meal delivery", "meal deliveries", "meal takeaway", "movie rental", "movie theater", "moving company", "moving companies", "night club", "pet store", "place of worship", "places of worship", "post office", "real estate agency", "real estate agencies", "roofing contractor", "rv park", "shoe store", "shopping mall", "subway station", "taxi stand", "train station", "travel agency", "travel agencies", "veterinary care"};
    int index;
    for (int i = 0; i <= placesM.length - 1; i++) {
        Log.e("TAG", "forM");
        if (v2txt.contains(placesM[i])) {
            Log.e("TAG", "sensedM?!");
            index = i;
            Uri gmmIntentUri = Uri.parse("geo:" + latitude + "," + longitude + "?q=" + placesM[index]);
            Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
            mapIntent.setPackage("com.google.Android.apps.maps");
            startActivity(mapIntent);
            finish();
        }
    }
    for (int i = 0; i <= placesS.length - 1; i++) {
        Log.e("TAG", "forS");
        if (v2txt.contains(placesS[i])) {
            Log.e("TAG", "sensedS?!");
            index = i;
            Uri gmmIntentUri = Uri.parse("geo:" + latitude + "," + longitude + "?q=" + placesS[index]);
            Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
            mapIntent.setPackage("com.google.Android.apps.maps");
            startActivity(mapIntent);
            finish();
        }
    }
}
}

Проблема в том, что всегда и всегда местоположение возвращает ноль. И я точно знаю, что другое приложение Jarvis легко выполняет эту задачу, пока локация включена, а если нет, просто просит пользователя. Но при одинаковых условиях мое приложение всегда вылетает. 

Что я сделал: 

  1. Потратил день и ночь, пытаясь решить эту проблему.
  2. Просматривал многочисленные страницы по теме.
  3. Пробовал разные свои коды.

И это все еще происходит. Я новичок в Android ... и, пожалуйста, помогите мне. Нет ли способа решить мою проблему? даже подумал, что другому приложению как-то удается это сделать.

Это мой LogCat.

Process: com.kkze.Mappy, PID: 6742
Java.lang.RuntimeException: Unable to start activity ComponentInfo{com.kkze.Mappy/com.kkze.Mappy.PlacesDecoder}: Java.lang.NullPointerException: Attempt to invoke virtual method 'double Android.location.Location.getLatitude()' on a null object reference
        at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2658)
        at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2723)
        at Android.app.ActivityThread.access$900(ActivityThread.Java:172)
        at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1422)
        at Android.os.Handler.dispatchMessage(Handler.Java:102)
        at Android.os.Looper.loop(Looper.Java:145)
        at Android.app.ActivityThread.main(ActivityThread.Java:5832)
        at Java.lang.reflect.Method.invoke(Native Method)
        at Java.lang.reflect.Method.invoke(Method.Java:372)
        at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:1399)
        at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:1194)
 Caused by: Java.lang.NullPointerException: Attempt to invoke virtual method 'double Android.location.Location.getLatitude()' on a null object reference
        at com.kkze.Mappy.PlacesDecoder.getLocation(PlacesDecoder.Java:62)
        at com.kkze.Mappy.PlacesDecoder.onCreate(PlacesDecoder.Java:32)
        at Android.app.Activity.performCreate(Activity.Java:6221)
        at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1119)
        at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2611)
at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2723)
at Android.app.ActivityThread.access$900(ActivityThread.Java:172)
at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1422)
at Android.os.Handler.dispatchMessage(Handler.Java:102)
at Android.os.Looper.loop(Looper.Java:145)
at Android.app.ActivityThread.main(ActivityThread.Java:5832)
at Java.lang.reflect.Method.invoke(Native Method)
at Java.lang.reflect.Method.invoke(Method.Java:372)
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:1399)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:1194)

Также проверка местоположения! = Null требует разрешения ACCESS_FINE_LOCATION, которое портит мое приложение, заставляя его всегда возвращаться как нулевое.

8
KISHORE_ZE

Как упоминал Джон Скит в комментариях, метод getLastKnownLocation() может и будет возвращать ноль. Основная проблема заключается в том, что он не запрашивает у ОС запрос на новую блокировку местоположения, а просто проверяет, было ли последнее известное местоположение из запроса местоположения какого-либо другого приложения. Если ни одно другое приложение недавно не сделало запрос местоположения, то вы получите нулевое местоположение, возвращенное вам.

Единственный способ гарантировать, что вы действительно получите местоположение, это запросить его, и это делается с помощью вызова requestLocationUpdates() .

Местоположение, переданное в метод обратного вызова onLocationChanged(), не будет нулевым, поскольку обратный вызов происходит только при успешной блокировке местоположения.

Просто отметим, что все время, пока ваше приложение регистрируется для получения обновлений местоположения, оно будет вызывать дополнительную разрядку батареи, поэтому обязательно отмените регистрацию обновлений местоположения как можно скорее. Здесь, похоже, вы можете отменить регистрацию, как только появится первое местоположение.

Кроме того, вы можете захотеть показать диалоговое окно хода выполнения в этом действии, пока оно ожидает блокировки местоположения, чтобы дать пользователю некоторую обратную связь о том, что приложение ожидает чего-то.

Вот общая структура того, как должен выглядеть ваш код:

public class MainActivity extends Activity
        implements LocationListener {

    Intent intentThatCalled;
    public double latitude;
    public double longitude;
    public LocationManager locationManager;
    public Criteria criteria;
    public String bestProvider;

    String voice2text; //added

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        intentThatCalled = getIntent();
        voice2text = intentThatCalled.getStringExtra("v2txt");
        getLocation();
    }

    public static boolean isLocationEnabled(Context context)
    {
       //...............
        return true;
    }

    protected void getLocation() {
        if (isLocationEnabled(MainActivity.this)) {
            locationManager = (LocationManager)  this.getSystemService(Context.LOCATION_SERVICE);
            criteria = new Criteria();
            bestProvider = String.valueOf(locationManager.getBestProvider(criteria, true)).toString();

            //You can still do this if you like, you might get lucky:
            Location location = locationManager.getLastKnownLocation(bestProvider);
            if (location != null) {
                Log.e("TAG", "GPS is on");
                latitude = location.getLatitude();
                longitude = location.getLongitude();
                Toast.makeText(MainActivity.this, "latitude:" + latitude + " longitude:" + longitude, Toast.LENGTH_SHORT).show();
                searchNearestPlace(voice2text);
            }
            else{
                //This is what you need:
                locationManager.requestLocationUpdates(bestProvider, 1000, 0, this);
            }
        }
        else
        {
            //Prompt user to enable location....
            //.................
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        locationManager.removeUpdates(this);

    }

    @Override
    public void onLocationChanged(Location location) {
        //Hey, a non null location! Sweet!

        //remove location callback:
        locationManager.removeUpdates(this);

        //open the map:
        latitude = location.getLatitude();
        longitude = location.getLongitude();
        Toast.makeText(MainActivity.this, "latitude:" + latitude + " longitude:" + longitude, Toast.LENGTH_SHORT).show();
        searchNearestPlace(voice2text);
    }

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

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    public void searchNearestPlace(String v2txt) {
        //.....
    }
}
17
Daniel Nugent

Измените это в вашем методе getLocation

if (isLocationEnabled(PlacesDecoder.this) && location != null) {
 ...
}
1
Stas Parshin

вы написали коды, которые получают ваше текущее местоположение (latlng), и эта ошибка из-за того, что ваш GPS (местоположение) на вашем реальном устройстве Android не включается . Я включил его, и он работает для меня. надеюсь быть полезным

0
Mosayeb Masoumi

вот еще один способ сделать это в соответствии с вашей концепцией расположения предохранителей. Я использовал это и был для меня успешным mFusedLocationClient = LocationServices.getFusedLocationProviderClient (this);

является ли декларация плавленым местом

 @SuppressWarnings( {"MissingPermission"})
private void enableLocationComponent() {
    System.out.println("on map click is here in permission///////////////");
    // Check if permissions are enabled and if not request
    if (PermissionsManager.areLocationPermissionsGranted(this)) {

        // Activate the MapboxMap LocationComponent to show user location
        // Adding in LocationComponentOptions is also an optional parameter
        LocationComponent locationComponent = mapboxMap.getLocationComponent();
        locationComponent.activateLocationComponent(this);
        locationComponent.setLocationComponentEnabled(true);
        // Set the component's camera mode
        locationComponent.setCameraMode(CameraMode.TRACKING);

        mFusedLocationClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        originLocation=location;
                        // Got last known location. In some rare situations this can be null.
                        if (location != null) {
                            originLocation=location;
                            System.out.println(" permission granted location is in iff ++///////////////"+location);
                        }
                    }
                });

        //originLocation = locationComponent.getLastKnownLocation();
        System.out.println("Origin location is that//////////"+originLocation);


    } else {


        permissionsManager = new PermissionsManager(this);
        permissionsManager.requestLocationPermissions(this);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
    Toast.makeText(this, "granted", Toast.LENGTH_LONG).show();
}

@Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
    Toast.makeText(this, R.string.user_location_permission_explanation, Toast.LENGTH_LONG).show();
}

@Override
public void onPermissionResult(boolean granted) {
    if (granted) {
        enableLocationComponent();
    } else {
        Toast.makeText(this, R.string.user_location_permission_not_granted, Toast.LENGTH_LONG).show();``
        finish();
    }
}
0
Qasim

Исключение из-за нулевого указателя возникает из-за того, что ваше приложение не запрашивает текущее местоположение, оно использует последнее найденное местоположение и просто проверяет, включено ли ваше местоположение, и запускает любое другое приложение, которое использует ваше текущее местоположение. После этого просто попробуйте запустить свой проект снова. Надеюсь, это решит вашу проблему.

0
Yash Patel