Обратное геокодирование, внезапно возвращающее значение null через несколько дней в Android

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

ГлавнаяАктивность

public class Main2Activity extends AppCompatActivity {

private static final String TAG = MainActivity.class.getSimpleName();

private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;

private static final String ADDRESS_REQUESTED_KEY = "address-request-pending";
private static final String LOCATION_ADDRESS_KEY = "location-address";

/**
 * Provides access to the Fused Location Provider API.
 */
private FusedLocationProviderClient mFusedLocationClient;

/**
 * Represents a geographical location.
 */
private Location mLastLocation;

/**
 * Tracks whether the user has requested an address. Becomes true when the user requests an
 * address and false when the address (or an error message) is delivered.
 */
private boolean mAddressRequested;

/**
 * The formatted location address.
 */
private String mAddressOutput;

/**
 * Receiver registered with this activity to get the response from FetchAddressIntentService.
 */
private AddressResultReceiver mResultReceiver;

/**
 * Displays the location address.
 */

private TextView selectManually;
private TextView mLocationAddressTextView;

/**
 * Visible while the address is being fetched.
 */
private ProgressBar mProgressBar;

/**
 * Kicks off the request to fetch an address when pressed.
 */

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.location_fetch);

    mResultReceiver = new AddressResultReceiver(new Handler());

    mProgressBar = findViewById(R.id.progress_bar2);
    selectManually= findViewById(R.id.select_manually);

    // Set defaults, then update using values stored in the Bundle.
    mAddressRequested = false;
    mAddressOutput = "";
    updateValuesFromBundle(savedInstanceState);

    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);

    if (!checkPermissions()) {
        requestPermissions();
    } else {
        getAddress();
    }

}

@Override
public void onStart() {
    super.onStart();

    updateUIWidgets();
}



/**
 * Updates fields based on data stored in the bundle.
 */
private void updateValuesFromBundle(Bundle savedInstanceState) {
    if (savedInstanceState != null) {
        // Check savedInstanceState to see if the address was previously requested.
        if (savedInstanceState.keySet().contains(ADDRESS_REQUESTED_KEY)) {
            mAddressRequested = savedInstanceState.getBoolean(ADDRESS_REQUESTED_KEY);
        }
        // Check savedInstanceState to see if the location address string was previously found
        // and stored in the Bundle. If it was found, display the address string in the UI.
        if (savedInstanceState.keySet().contains(LOCATION_ADDRESS_KEY)) {
            mAddressOutput = savedInstanceState.getString(LOCATION_ADDRESS_KEY);
            Intent intent = new Intent(getBaseContext(), LocationShow.class);
            intent.putExtra("addressOutput", mAddressOutput);
            startActivity(intent);
        }
    }
}

/**
 * Runs when user clicks the Fetch Address button.

/**
 * Creates an intent, adds location data to it as an extra, and starts the intent service for
 * fetching an address.
 */
private void startIntentService() {
    // Create an intent for passing to the intent service responsible for fetching the address.
    Intent intent = new Intent(this, FetchAddressIntentService.class);

    // Pass the result receiver as an extra to the service.
    intent.putExtra(Constants.RECEIVER, mResultReceiver);

    // Pass the location data as an extra to the service.
    intent.putExtra(Constants.LOCATION_DATA_EXTRA, mLastLocation);

    // Start the service. If the service isn't already running, it is instantiated and started
    // (creating a process for it if needed); if it is running then it remains running. The
    // service kills itself automatically once all intents are processed.
    startService(intent);
}

/**
 * Gets the address for the last known location.
 */
@SuppressWarnings("MissingPermission")
private void getAddress() {
    mFusedLocationClient.getLastLocation()
            .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    if (location == null) {
                        Log.w(TAG, "onSuccess:null");
                        mAddressRequested=false;
                        updateUIWidgets();
                        return;
                    }

                    mLastLocation = location;

                    // Determine whether a Geocoder is available.
                    if (!Geocoder.isPresent()) {
                        showSnackbar(getString(R.string.no_geocoder_available));
                        mAddressRequested=false;
                        updateUIWidgets();
                        return;
                    }

                    // If the user pressed the fetch address button before we had the location,
                    // this will be set to true indicating that we should kick off the intent
                    // service after fetching the location.
                    mAddressRequested=true;
                    if (mAddressRequested) {
                        startIntentService();
                        return;
                    }
                    updateUIWidgets();
                }
            })
            .addOnFailureListener(this, new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Log.w(TAG, "getLastLocation:onFailure", e);
                    mAddressRequested=false;
                    updateUIWidgets();
                }
            });
}

/**
 * Updates the address in the UI.
 */

/**
 * Toggles the visibility of the progress bar. Enables or disables the Fetch Address button.
 */
private void updateUIWidgets() {
    mAddressRequested=true;
    if (mAddressRequested) {
        mProgressBar.setVisibility(ProgressBar.VISIBLE);
        selectManually.setVisibility(TextView.GONE);
    } else {
        mProgressBar.setVisibility(ProgressBar.GONE);
        selectManually.setVisibility(TextView.VISIBLE);
    }
}

/**
 * Shows a toast with the given text.
 */
private void showToast(String text) {
    Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save whether the address has been requested.
    savedInstanceState.putBoolean(ADDRESS_REQUESTED_KEY, mAddressRequested);

    // Save the address string.
    savedInstanceState.putString(LOCATION_ADDRESS_KEY, mAddressOutput);
    super.onSaveInstanceState(savedInstanceState);
}

/**
 * Receiver for data sent from FetchAddressIntentService.
 */
private class AddressResultReceiver extends ResultReceiver {
    AddressResultReceiver(Handler handler) {
        super(handler);
    }

    /**
     * Receives data sent from FetchAddressIntentService and updates the UI in MainActivity.
     */
    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {

        // Display the address string or an error message sent from the intent service.
        mAddressOutput = resultData.getString(Constants.RESULT_DATA_KEY);
        Intent intent = new Intent(getBaseContext(), LocationShow.class);
        intent.putExtra("addressOutput", mAddressOutput);
        startActivity(intent);

        // Show a toast message if an address was found.
        if (resultCode == Constants.SUCCESS_RESULT) {
            showToast(getString(R.string.address_found));

        }

        // Reset. Enable the Fetch Address button and stop showing the progress bar.

    }
}

/**
 * Shows a {@link Snackbar} using {@code text}.
 *
 * @param text The Snackbar text.
 */
private void showSnackbar(final String text) {
    View container = findViewById(android.R.id.content);
    if (container != null) {
        Snackbar.make(container, text, Snackbar.LENGTH_LONG).show();
    }
}

/**
 * Shows a {@link Snackbar}.
 *
 * @param mainTextStringId The id for the string resource for the Snackbar text.
 * @param actionStringId   The text of the action item.
 * @param listener         The listener associated with the Snackbar action.
 */
private void showSnackbar(final int mainTextStringId, final int actionStringId,
                          View.OnClickListener listener) {
    Snackbar.make(findViewById(android.R.id.content),
            getString(mainTextStringId),
            Snackbar.LENGTH_INDEFINITE)
            .setAction(getString(actionStringId), listener).show();
}

/**
 * Return the current state of the permissions needed.
 */
private boolean checkPermissions() {
    int permissionState = ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION);
    return permissionState == PackageManager.PERMISSION_GRANTED;
}

private void requestPermissions() {
    boolean shouldProvideRationale =
            ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION);

    // Provide an additional rationale to the user. This would happen if the user denied the
    // request previously, but didn't check the "Don't ask again" checkbox.
    if (shouldProvideRationale) {
        Log.i(TAG, "Displaying permission rationale to provide additional context.");

        showSnackbar(R.string.permission_rationale, android.R.string.ok,
                new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        // Request permission
                        ActivityCompat.requestPermissions(Main2Activity.this,
                                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                REQUEST_PERMISSIONS_REQUEST_CODE);
                    }
                });

    } else {
        Log.i(TAG, "Requesting permission");
        // Request permission. It's possible this can be auto answered if device policy
        // sets the permission in a given state or the user denied the permission
        // previously and checked "Never ask again".
        ActivityCompat.requestPermissions(Main2Activity.this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                REQUEST_PERMISSIONS_REQUEST_CODE);
    }
}

/**
 * Callback received when a permissions request has been completed.
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    Log.i(TAG, "onRequestPermissionResult");
    if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
        if (grantResults.length <= 0) {
            // If user interaction was interrupted, the permission request is cancelled and you
            // receive empty arrays.
            Log.i(TAG, "User interaction was cancelled.");
        } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // Permission granted.
            getAddress();
        } else {
            // Permission denied.

            // Notify the user via a SnackBar that they have rejected a core permission for the
            // app, which makes the Activity useless. In a real app, core permissions would
            // typically be best requested during a welcome-screen flow.

            // Additionally, it is important to remember that a permission might have been
            // rejected without asking the user for permission (device policy or "Never ask
            // again" prompts). Therefore, a user interface affordance is typically implemented
            // when permissions are denied. Otherwise, your app could appear unresponsive to
            // touches or interactions which have required permissions.
            showSnackbar(R.string.permission_denied_explanation, R.string.settings,
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            // Build intent that displays the App settings screen.
                            Intent intent = new Intent();
                            intent.setAction(
                                    Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                            Uri uri = Uri.fromParts("package",
                                    BuildConfig.APPLICATION_ID, null);
                            intent.setData(uri);
                            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            startActivity(intent);
                        }
                    });
        }
    }
}

}

FetchAddressIntentService

public class FetchAddressIntentService extends IntentService {
private static final String TAG = "FetchAddressIS";

/**
 * The receiver where results are forwarded from this service.
 */
private ResultReceiver mReceiver;

/**
 * This constructor is required, and calls the super IntentService(String)
 * constructor with the name for a worker thread.
 */
public FetchAddressIntentService() {
    // Use the TAG to name the worker thread.
    super(TAG);
}

/**
 * Tries to get the location address using a Geocoder. If successful, sends an address to a
 * result receiver. If unsuccessful, sends an error message instead.
 * Note: We define a {@link ResultReceiver} in * MainActivity to process content
 * sent from this service.
 *
 * This service calls this method from the default worker thread with the intent that started
 * the service. When this method returns, the service automatically stops.
 */
@Override
protected void onHandleIntent(Intent intent) {
    String errorMessage = "";

    mReceiver = intent.getParcelableExtra(Constants.RECEIVER);

    // Check if receiver was properly registered.
    if (mReceiver == null) {
        Log.wtf(TAG, "No receiver received. There is nowhere to send the results.");
        return;
    }

    // Get the location passed to this service through an extra.
    Location location = intent.getParcelableExtra(Constants.LOCATION_DATA_EXTRA);

    // Make sure that the location data was really sent over through an extra. If it wasn't,
    // send an error error message and return.
    if (location == null) {
        errorMessage = "no location data provided";
        Log.wtf(TAG, errorMessage);
        deliverResultToReceiver(Constants.FAILURE_RESULT, errorMessage);
        return;
    }

    // Errors could still arise from using the Geocoder (for example, if there is no
    // connectivity, or if the Geocoder is given illegal location data). Or, the Geocoder may
    // simply not have an address for a location. In all these cases, we communicate with the
    // receiver using a resultCode indicating failure. If an address is found, we use a
    // resultCode indicating success.

    // The Geocoder used in this sample. The Geocoder's responses are localized for the given
    // Locale, which represents a specific geographical or linguistic region. Locales are used
    // to alter the presentation of information such as numbers or dates to suit the conventions
    // in the region they describe.
    Geocoder geocoder = new Geocoder(this, Locale.getDefault());

    // Address found using the Geocoder.
    List<Address> addresses = null;

    try {
        // Using getFromLocation() returns an array of Addresses for the area immediately
        // surroungetString(R.string.invalid_lat_long_used)ding the given latitude and longitude. The results are a best guess and are
        // not guaranteed to be accurate.
        addresses = geocoder.getFromLocation(
                location.getLatitude(),
                location.getLongitude(),
                // In this sample, we get just a single address.
                1);
    } catch (IOException ioException) {
        // Catch network or other I/O problems.
        errorMessage = "service not available";
        Log.e(TAG, errorMessage, ioException);
    } catch (IllegalArgumentException illegalArgumentException) {
        // Catch invalid latitude or longitude values.
        errorMessage ="invalid lat and  long" ;
        Log.e(TAG, errorMessage + ". " +
                "Latitude = " + location.getLatitude() +
                ", Longitude = " + location.getLongitude(), illegalArgumentException);
    }

    // Handle case where no address was found.
    if (addresses == null || addresses.size()  == 0) {
        if (errorMessage.isEmpty()) {
            errorMessage = "no address found";
            Log.e(TAG, errorMessage);
        }
        deliverResultToReceiver(Constants.FAILURE_RESULT, errorMessage);
    } else {
        Address address = addresses.get(0);
        ArrayList<String> addressFragments = new ArrayList<>();

        // Fetch the address lines using {@code getAddressLine},
        // join them, and send them to the thread. The {@link android.location.address}
        // class provides other options for fetching address details that you may prefer
        // to use. Here are some examples:
        // getLocality() ("Mountain View", for example)
        // getAdminArea() ("CA", for example)
        // getPostalCode() ("94043", for example)
        // getCountryCode() ("US", for example)
        // getCountryName() ("United States", for example)
        for(int i = 0; i <= address.getMaxAddressLineIndex(); i++) {
            addressFragments.add(address.getSubLocality());
        }
        Log.i(TAG, "address found");
        deliverResultToReceiver(Constants.SUCCESS_RESULT,
                TextUtils.join(System.getProperty("line.separator"), addressFragments));
    }
}

/**
 * Sends a resultCode and message to the receiver.
 */
private void deliverResultToReceiver(int resultCode, String message) {
    Bundle bundle = new Bundle();
    bundle.putString(Constants.RESULT_DATA_KEY, message);
    mReceiver.send(resultCode, bundle);
}

}

LocationShow

public class LocationShow extends AppCompatActivity {

TextView t1;
String output,output2;
private static final String ADDRESS_REQUESTED_KEY = "address-request-pending";
private static final String LOCATION_ADDRESS_KEY = "location-address";
String mAddressOutput;

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

    t1=findViewById(R.id.place2);

    output = getIntent().getStringExtra("addressOutput");
    output2 = getIntent().getStringExtra("addressOutput2");

    showAddress(output2);
}

private void showAddress(String place) {

    t1.setText(place);
}

}

Константы

final class Constants {
static final int SUCCESS_RESULT = 0;

static final int FAILURE_RESULT = 1;

private static final String PACKAGE_NAME =
        "com.google.android.gms.location.sample.locationaddress";

static final String RECEIVER = PACKAGE_NAME + ".RECEIVER";

static final String RESULT_DATA_KEY = PACKAGE_NAME + ".RESULT_DATA_KEY";

static final String LOCATION_DATA_EXTRA = PACKAGE_NAME + ".LOCATION_DATA_EXTRA";

}

Это вывод журнала

07-16 23:36:43.553 16544-16544/? E/android.os.Debug: failed to load memtrack module: -2

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

Google только что внес большие изменения в свои картографические API. Без какого-либо вывода журнала трудно сказать, что может происходить, но если вы не вносили изменений в код, я бы проверил вашу учетную запись, связанную с вашим ключом сопоставления, и посмотрел, нужно ли вам добавить кредитную карту в учетную запись. Подробнее здесь: https://developers.google.com/maps/billing/important-updates


person Scof Lj    schedule 16.07.2018    source источник


Ответы (1)


Я включил биллинг, а также получил бесплатные кредиты, как и в правилах API, но все равно безрезультатно.

person saswanb    schedule 16.07.2018
comment
07-16 23:36:43.948 16555-16555/? E/memtrack: не удалось загрузить модуль memtrack (нет такого файла или каталога) 07-16 23:36:43.948 16555-16555/? E/android.os.Debug: не удалось загрузить модуль memtrack: -2 07-16 23:36:44.440 16566-16566/? E/memtrack: не удалось загрузить модуль memtrack (нет такого файла или каталога) 07-16 23:36:44.440 16566-16566/? E/android.os.Debug: не удалось загрузить модуль memtrack: -2 07-16 23:36:44.935 16577-16577/? E/memtrack: не удалось загрузить модуль memtrack (нет такого файла или каталога) 07-16 23:36:44.935 16577-16577/? E/android.os.Debug: не удалось загрузить модуль memtrack: -2 07-16 23:36:45.641 16588-16588/? E/memtrack: не удалось загрузить модуль memtrack (нет такого файла или каталога) 07-16 23:36:45.641 16588-16588/? E/android.os.Debug: не удалось загрузить модуль memtrack: -2 07-16 23:36:46.052 16599-16599/? E/memtrack: не удалось загрузить модуль memtrack (нет такого файла или каталога) 07-16 23:36:46.052 16599-16599/? E/android.os.Debug: не удалось загрузить модуль памяти: -2 07-16 23:36:46.241 16608-16612/? E/art: Не удалось отправить ответ отладчику: Broken pipe 07-16 23:36:46.772 1322-1322/? E/installd: не удалось открыть каталог /data/app/vmdl1055021888.tmp: такого файла или каталога нет 07-16 23:36:46.952 1990-13324/com.google.android.gms.persistent E/NetworkScheduler: предоставлено нераспознанное действие : android.intent.action.PACKAGE_REMOVED 07-16 23:36:47.363 16660-16660/? E/memtrack: не удалось загрузить модуль memtrack (нет такого файла или каталога) 07-16 23:36:47.363 16660-16660/? E/android.os.Debug: не удалось загрузить модуль memtrack: -2 07-16 23:36:47.682 2016-2281/com.android.launcher3 E/Surface: getSlotFromBufferLocked: неизвестный буфер: 0x7f4388d4cc80 07-16 23:36: 47,724 16699-16699/? E/dex2oat: не удалось создать файл овса: /data/dalvik-cache/x86_64/data@[email protected]@[email protected]: разрешение отклонено 07-16 23:36: 47,936 16717-16717/? E/dex2oat: не удалось создать файл овса: /data/dalvik-cache/x86_64/data@[email protected]@[email protected]: разрешение отклонено 07-16 23:36: 47,995 16722-16722/? E/dex2oat: не удалось создать файл овса: /data/dalvik-cache/x86_64/data@[email protected]@[email protected]: разрешение отклонено 07-16 23:36: 48.044 16725-16725/? E/dex2oat: не удалось создать файл овса: /data/dalvik-cache/x86_64/data@[email protected]@[email protected]: разрешение отклонено 07-16 23:36: 48.079 16728-16728/? E/dex2oat: не удалось создать файл овса: /data/dalvik-cache/x86_64/data@[email protected]@[email protected]: разрешение отклонено 07-16 23:36: 48. 122 16732-16732/? E/dex2oat: не удалось создать файл овса: /data/dalvik-cache/x86_64/data@[email protected]@[email protected]: разрешение отклонено 07-16 23:36: 48.149 16736-16736/? E/dex2oat: не удалось создать файл овса: /data/dalvik-cache/x86_64/data@[email protected]@[email protected]: разрешение отклонено 07-16 23:36: 48.185 16739-16739/? E/dex2oat: не удалось создать файл овса: /data/dalvik-cache/x86_64/data@[email protected]@[email protected]: разрешение отклонено 07-16 23:36: 48.219 16743-16743/? E/dex2oat: не удалось создать файл овса: /data/dalvik-cache/x86_64/data@[email protected]@[email protected]: разрешение отклонено 07-16 23:36: 48.249 16629-16729/? E/ActivityThread: не удалось найти информацию о провайдере для com.google.android.partnersetup.rlzappprovider 07-16 23:36:48.259 16746-16746/? E/dex2oat: не удалось создать файл овса: /data/dalvik-cache/x86_64/data@[email protected]@[email protected]: разрешение отклонено 07-16 23:36: 48.299 16750-16750/? E/dex2oat: не удалось создать файл овса: /data/dalvik-cache/x86_64/data@[email protected]@[email protected]: разрешение отклонено 07-16 23:36: 48.817 1226-1269/? E/SurfaceFlinger: ro.sf.lcd_density должен быть определен как свойство сборки. - person Scof Lj; 16.07.2018