I've created an application in which, when I click a button, it gives me my gps coordinates. In the simulator it works with no problem, but when I've tried it on a mobile phone a had the next 2 scenarios: when I had the GPS activated, nothing happened, and when i didn't had the GPS connected, it said "Gps Disabled"
Here is my code so far:
This is the .java file: (Saver.java):
package com.example.lifesaver;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class Saver extends Activity {
Button b;
Location newLocation = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_saver);
b = (Button) findViewById(R.id.button1);
// We use LocationManager class to obtain GPS locations
LocationManager mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
b.setOnClickListener(new OnClickListener(){
public void onClick(View v)
{
if (newLocation != null) {
String Text = "Current location is: " + "Latitud = "
+ newLocation.getLatitude() + "Longitud = "
+ newLocation.getLongitude();
Toast.makeText(getApplicationContext(), Text,
Toast.LENGTH_SHORT).show();
}
}
});
}
//MyLocationListener class
public class MyLocationListener implements LocationListener
{
public void onLocationChanged(Location loc)
{
newLocation = loc;
}
public void onProviderDisabled(String provider)
{
Toast.makeText(getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT).show();
}
public void onProviderEnabled(String provider)
{
Toast.makeText(getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
}
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}
}
And the .xml file(activity_saver.xml):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".Saver" >
<Button
android:id="#+id/button1"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="#drawable/circle"
android:onClick="onClick"/>
</RelativeLayout>
Also, i've added this in the AndroidManifest.xml file:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">
</uses-permission>
Are you trying to turn on GPS programmatically ?
It won't work above versions 4.0. You have to turn it on manually.
Use my code :-
Android - How to get the user current location every time based on sim Network
You have to wait for the GPS to get a fix. onLocationChanged may not be triggered for several minutes from a cold start. If you are inside a building you may never get a fix. There is no such facility as 'get my position via GPS immediately'.
Related
So I did a bluetooth scanner app in android studio and I want to store data in a csv. the problem is that I want to remove the button and the app to keep scanning and write in csv. Right now it scans automatically but I have to press the button in order to create and write in csv. Can you help me with implementing a method for automatically writing? I tried using the btn.setPressed(true) and btn.performClick() but it didn't work. Here is MainActivity and activity_xm. The manifest has all permissions and in gradle.app has minSDK 28 AND targetSDK 32.
package com.example.blutut;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
Bluetooth bluetooth = new Bluetooth();
private BluetoothAdapter BTAdapter = BluetoothAdapter.getDefaultAdapter();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
Button btn = findViewById(R.id.btnDetect);
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
int rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
String name = device.getName();
TextView txt = findViewById(R.id.textView);
txt.setText(txt.getText() + name + " => " + rssi + "dBm\n");
String entry = "\n" + String.format("%d", rssi);
try {
File path = new File("/storage/emulated/0/Download");
File file = new File(path + "/bluetooth.csv");
FileOutputStream f = new FileOutputStream(file, true);
try {
f.write(entry.getBytes());
f.flush();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
};
public void btnClick(View view) {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
BTAdapter.startDiscovery();
return;
}
}
}
/// activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="#+id/btnDetect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="btnClick"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btnDetect" />
I am training coding on android studio, I am coding an activity that use bluetooth. I am able to enable/disable the bluetooth. but I am in trouble while I am trying to discover devices. The bluetooth doesn't find any device it seems that the ACTION_fOUND never trigger..
The code has no error, and the application runs well.
I found out that the permission ACCESS_COARSE_LOCATION is not granted. It may cause the error ?
Does anyone can tell how to grant the permission ?
I followed the following tutorial :
https://developer.android.com/guide/topics/connectivity/bluetooth
Here is my code..
package com.example.kartouche;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;
public class BluetoothActivity extends AppCompatActivity {
/** Declaration des variables privés
* - p_bluetoothAdapter : représente le bluetooth de l'appareil
* - p_acces_btn_bluetooth : représente le bouton logique d'activation et désactivation du bluetooth de l'appareil
* -
* -- */
private BluetoothAdapter p_bluetoothAdapter;
private Button p_access_btn_bluetooth;
private Button p_btn_discover_device;
private ListView p_list_device;
int MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 1;
private static final int REQUEST_ENABLE_BT = 0;
private static final int REQUEST_DISCOVER_BT = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth);
p_access_btn_bluetooth = (Button) findViewById(R.id.btn_access_bluetooth);
p_btn_discover_device = (Button) findViewById(R.id.btn_discover_device);
p_list_device = (ListView) findViewById(R.id.lv_list_devices);
/** ETAPE 1
* Implementation Bluetooth qui objective le bluetooth de l'appareil. -- */
p_bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (p_bluetoothAdapter == null)
{Toast.makeText(getApplicationContext(), "Bluetooth non disponible sur cette appareil",Toast.LENGTH_SHORT).show();}
if (getApplicationContext().checkSelfPermission("android.permission.ACCESS_COARSE_LOCATION") == PackageManager.PERMISSION_GRANTED)
{
Log.e("[MESSAGE]","ACCES_COARSE_LOCATION GRANTED");
}
else
{
Log.e("[MESSAGE]","ACCES_COARSE_LOCATION NOT GRANTED");
}
/** Textualisation du bouton p_acces_btn_bluetooth*/
if(!p_bluetoothAdapter.isEnabled())
{p_access_btn_bluetooth.setText("ACTIVER BLUETOOTH");}
else
{p_access_btn_bluetooth.setText("DESACTIVER BLUETOOTH");}
/** ETAPE 2
* Vérification de l'etat d'activation de l'appareil, Si le bluetooth n'est pas activé alors nous l'activons (resp) et changeons le texte du bouton -- */
p_access_btn_bluetooth.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Button btn_logique_text = (Button) p_access_btn_bluetooth;
String buttonText = btn_logique_text.getText().toString();
if (!p_bluetoothAdapter.isEnabled())
{
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
p_access_btn_bluetooth.setText("DESACTIVER BLUETOOTH");
}
else
{
p_bluetoothAdapter.disable();
p_access_btn_bluetooth.setText("ACTIVER BLUETOOTH");
}
}
});
/**
* ETAPE 3
* Analyse des appareils à proximité. -- */
p_btn_discover_device.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(!p_bluetoothAdapter.isEnabled())
{Toast.makeText(getApplicationContext(), "Le bluetooth doit être activé pour effectuer l'analyse", Toast.LENGTH_SHORT).show();}
else
{
p_bluetoothAdapter.startDiscovery();
Toast.makeText(getApplicationContext(),"début d'analyse ...", Toast.LENGTH_SHORT).show();
}
}
});
// Register for broadcasts when a device is discovered.
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(receiver, filter);
}//OnCreate
// Create a BroadcastReceiver for ACTION_FOUND.
private final BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
List<String> p_device_bluetooth = new ArrayList<String>();
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(BluetoothActivity.this,android.R.layout.simple_list_item_1,p_device_bluetooth );
p_list_device.setAdapter(arrayAdapter);
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
Log.e("[MESSAGE]","Device enfin trouvé..");
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
p_device_bluetooth.add(deviceName);
arrayAdapter.notifyDataSetChanged();
}
}
};// BroadcastReceiver
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}//onDestroy
#Override
public void onBackPressed(){
startActivity(new Intent(getApplicationContext(), MainActivity.class));
finish();
}//OnBackPressed
}
Here is the xml file:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BluetoothActivity">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="#+id/btn_access_bluetooth"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="0dp" />
<Button
android:id="#+id/btn_access_bluetooth"
android:layout_width="345dp"
android:layout_height="40dp"
android:text=""
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/btn_discover_device"
android:layout_width="345dp"
android:layout_height="40dp"
android:text="Analyse bluetooth a proximite"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.492"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.584" />
</androidx.constraintlayout.widget.ConstraintLayout>
here is the manifest xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.kartouche">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
It looks like you checked for the permission, however, did not ask the user to grant the permission. I would recommend following this developer documentation on this.
Hence, instead of just printing the logs, you might have to prompt the dialog to the user to grant your app the permissions that you need.
if (ContextCompat.checkSelfPermission(
CONTEXT, Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED) {
Log.e("[MESSAGE]","ACCES_COARSE_LOCATION GRANTED");
else {
// You can directly ask for the permission.
// The registered ActivityResultCallback gets the result of this request.
requestPermissionLauncher.launch(
Manifest.permission.ACCESS_COARSE_LOCATION);
Log.e("[MESSAGE]","ACCES_COARSE_LOCATION NOT GRANTED");
}
And you have to override the onRequestPermissionsResult in your activity/fragment where you are asking for that.
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission is granted. Continue the action or workflow
// in your app.
} else {
// Explain to the user that the feature is unavailable because
// the features requires a permission that the user has denied.
// At the same time, respect the user's decision. Don't link to
// system settings in an effort to convince the user to change
// their decision.
}
return;
}
}
}
I have been struggling to fix this issue, but nothing I have found online has worked. I have gotten an unrestricted key for my project, but the map will still not display correctly. The status that is returned is considered OK, but nothing displays. I have also made sure to enable both APIs for that key. Below are some pictures showing what it looks like followed by my code. If I need to include any other code just comment on what you need. I'm also using the Google Direction Library found here https://github.com/akexorcist/Android-GoogleDirectionLibrary
After the button is clicked, it goes to the correct area, but everything is grey so I believe there is a problem with my google maps.
Dependencies
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.android.support:design:24.2.1'
compile 'com.android.support:recyclerview-v7:24.2.1'
compile 'com.akexorcist:googledirectionlibrary:1.0.5'
testCompile 'junit:junit:4.12'
}
XML Fragment
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_directions"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="<did not show my package>.Directions">
<fragment
android:id="#+id/map_fragment"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="<did not show my package>.MapsActivity" />
<Button
android:id="#+id/get_directions_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Get Directions" />
</RelativeLayout>
Directions.java
import android.graphics.Color;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.akexorcist.googledirection.DirectionCallback;
import com.akexorcist.googledirection.GoogleDirection;
import com.akexorcist.googledirection.constant.TransportMode;
import com.akexorcist.googledirection.model.Direction;
import com.akexorcist.googledirection.model.Route;
import com.akexorcist.googledirection.util.DirectionConverter;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.ArrayList;
public class Directions extends AppCompatActivity implements OnMapReadyCallback,
View.OnClickListener, DirectionCallback
{
private GoogleMap googleMap;
private LatLng origin = new LatLng(29.572813, -97.984900);
private LatLng destination;
private Button get_directions_btn;
private String serverKey = "<server key not shown>";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_directions);
// origin = new LatLng(29.572813, -97.984900);
Bundle bundle = getIntent().getExtras();
double destLatitude = bundle.getDouble("latitude");
double destLongitude = bundle.getDouble("longitude");
Log.d("Latitude", "Latitude is: " + destLatitude);
Log.d("Longitude", "Longitude is:" + destLongitude);
destination = new LatLng(destLatitude, destLongitude);
get_directions_btn = (Button) findViewById(R.id.get_directions_btn);
get_directions_btn.setOnClickListener(this);
((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map_fragment)).getMapAsync(this);
}
public void onMapReady(GoogleMap googleMap) {
this.googleMap = googleMap;
}
public void onClick(View v) {
int id = v.getId();
if (id == R.id.get_directions_btn) {
requestDirection();
}
}
public void requestDirection() {
Log.d("RequestOrigin", "Origin inside request: " + origin);
Log.d("RequestDestination", "Destination inside request: " + destination);
Snackbar.make(get_directions_btn, "Direction Requesting...", Snackbar.LENGTH_SHORT).show();
GoogleDirection.withServerKey(serverKey)
.from(origin)
.to(destination)
.transportMode(TransportMode.DRIVING)
.execute(this);
}
public void onDirectionSuccess(Direction direction, String rawBody) {
Log.d("Status","Direction Status is:" +direction.getStatus());
Snackbar.make(get_directions_btn, "Success with status : " + direction.getStatus(), Snackbar.LENGTH_SHORT).show();
if (direction.isOK()) {
Route route = direction.getRouteList().get(0);
Log.d("Route ", "Route is: " + route);
Log.d("Origin Marker", "Origin Marker: " + origin);
Log.d("Destination Marker", "Destination Marker: " + destination);
googleMap.addMarker(new MarkerOptions().position(origin));
googleMap.addMarker(new MarkerOptions().position(destination));
ArrayList<LatLng> directionPositionList = route.getLegList().get(0).getDirectionPoint();
googleMap.addPolyline(DirectionConverter.createPolyline(this, directionPositionList, 5, Color.RED));
setCameraWithCoordinationBounds(route);
get_directions_btn.setVisibility(View.GONE);
}
else{
Log.d("Status","Direction Status is:" +direction.getStatus());
Snackbar.make(get_directions_btn, direction.getStatus(), Snackbar.LENGTH_SHORT).show();
}
}
public void onDirectionFailure(Throwable t) {
Snackbar.make(get_directions_btn, t.getMessage(), Snackbar.LENGTH_SHORT).show();
}
private void setCameraWithCoordinationBounds(Route route) {
LatLng southwest = route.getBound().getSouthwestCoordination().getCoordination();
LatLng northeast = route.getBound().getNortheastCoordination().getCoordination();
LatLngBounds bounds = new LatLngBounds(southwest, northeast);
googleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100));
}
}
Manifest meta data
<meta-data android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key"/>
Manifest Permissions
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.READ_PROFILE"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
Anyway you can try to apply custom style to Google Map. For map style JSON preparing you can use Styling Wizard and save JSON file with style description (e.g. map_style.json) into res/raw folder. And than apply custom style in onMapReady() callback:
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
private GoogleMap mGoogleMap;
private MapFragment mapFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map_fragment);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
try {
// Customise the styling of the base map using a JSON object defined
// in a raw resource file.
boolean success = mGoogleMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this, R.raw.map_style));
if (!success) {
Log.e(TAG, "Style parsing failed.");
}
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Can't find style. Error: ", e);
}
}
}
Hi I posted a question concerning the same topic a while ago, after following your advices I can feel that I'm getting closed to solving my problem. The App does is now crashing as I click on the button with the following error message in the monitor:
FATAL EXCEPTION: main
Process: com.example.apple.myapp1, PID: 10081
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.example.apple.myapp1.MainActivity$1.onClick(MainActivity.java:62)
MainActivity.java
package com.example.apple.myapp1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Locale;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;
public class MainActivity extends Activity {
double lats, lons;
Geocoder geocoder;
double lat = lats;
double lon = lons;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnGetLocation = (Button) findViewById(R.id.button1);
btnGetLocation.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ProgressDialog mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setMessage("Fetching location...");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressDialog.show();
geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(lat, lon, 1);
} catch (IOException e) {
e.printStackTrace();
}
if (addresses != null) {
String address = addresses.get(0).getAddressLine(0);
String city = addresses.get(0).getLocality();
String state = addresses.get(0).getAdminArea();
String country = addresses.get(0).getCountryName();
String postalCode = addresses.get(0).getPostalCode();
String knownName = addresses.get(0).getFeatureName();
mProgressDialog.dismiss();
TextView cellText = (TextView) findViewById(R.id.cellText);
cellText.setText(address);
} else {
mProgressDialog.dismiss();
TextView cellText = (TextView) findViewById(R.id.cellText);
cellText.setText("Error");
}
}
});
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Please click the button below to get your location" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me" />
<TextView
android:id="#+id/cellText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:id="#+id/lacationText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />
</LinearLayout>
in the condition if (addresses != null) { } you should also check for the length of the addresses, since there might be 0.
if (addresses != null && addresses.size() > 0) {
String address = addresses.get(0).getAddressLine(0);
String city = addresses.get(0).getLocality();
String state = addresses.get(0).getAdminArea();
String country = addresses.get(0).getCountryName();
String postalCode = addresses.get(0).getPostalCode();
String knownName = addresses.get(0).getFeatureName();
mProgressDialog.dismiss();
TextView cellText = (TextView) findViewById(R.id.cellText);
cellText.setText(address);
} else {
mProgressDialog.dismiss();
TextView cellText = (TextView) findViewById(R.id.cellText);
cellText.setText("Error");
}
if it wasn't able to find at least one address you should consider showing the user an empty state.
It also seems like you forgot to initialize your latitude and longitude before calling addresses = geocoder.getFromLocation(lat, lon, 1);
To properly initialize this, do the following:
Location location = intent.getParcelableExtra(__YOUR_PACKAGE_NAME__ + ".LOCATION_DATA_EXTRA");
lat = location.getLatitude();
lon = location.getLongitude();
If you need any more help check out this page from android. It should hold all information you need.
EDIT:
I kind of assumed you we're further in the process, but it seems you have only tried to get the location of a latLong position, which you have never obtained. To achieve obtaining the address you will have to have the user's lcoation first.
Again, the page mentioned above should explain everything you need to obtain the location, but make sure of the following:
1. Have the permission to access the user's location (for Android 6+ use Runtime permissions)
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.gms.location.sample.locationupdates" >
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
</manifest>
2. Get an instance of the GoogleApi and ave your activity implement some callbacks
For the Callbacks
public class YourActivity extends AppCompatActivity implements
ConnectionCallbacks, OnConnectionFailedListener
Then in your OnCreate() create an instance of GoogleApiClient.
protected GoogleApiClient mGoogleApiClient;
public void onCreate(Bundle savedInstanceState) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
3. Obtain the location from the GoogleApiClient
Do this by implementing the callbacks properly.
/**
* Represents a geographical location.
*/
protected Location mLastLocation;
#Override
public void onConnected(Bundle connectionHint) {
// Gets the best and most recent location currently available, which may be null
// in rare cases when a location is not available.
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
// Determine whether a Geocoder is available.
if (!Geocoder.isPresent()) {
Toast.makeText(this, "no geocoder available", Toast.LENGTH_LONG).show();
return;
}
}
}
4. Now obtain the lat long and try to obtain the address as attempted before.
lat = mLastLocation.getLatitude();
lon = mLastLocation.getLongitude();
geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(lat, lon, 1);
} catch (IOException e) {
e.printStackTrace();
}
This should be enough to obtain the actual adress of the device and ask the geocoder for the addresses. I altered the example a bit to simplify for this question. Google's example handles fetching the address a bit more clean. Note that you will also have to disconnect the GoogleApi when stopping your activity and such. Again I recommend reading the entire Tutorial page. You can find en example of their implementation on this page on GitHub
I have seen many posts regarding this problem, but none of them offered a solution for me.
I am trying to get the user position through the GPS (or, ultimately, any other valid provider). But I am always getting null locations. I do get a map, and can set an arbitrary location, is the providers that don't work.
I have my MAPS key properly set (also checked that it was the right one), all necessary permissions set (android.permission.INTERNET, android.permission.ACCESS_COARSE_LOCATION, android.permission.ACCESS_FINE_LOCATION) and in fact, all seemed to be working just fine yesterday!
I tried getting all possible providers with this code:
List<String> providers = locManager.getAllProviders();
for (String provider : providers) {
printProvider(provider);
}
Which shows all providers (4, in my case) are DummyLocationProviders.
I am trying to run my app on the phone, not the emulator (although I also tried with the emulator, with GPS enabled, to no avail).
This is the code I am using to fetch the location (which, again, worked just fine yesterday):
//Get criteria
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
//Get best provider
String bestProvider = locManager.getBestProvider(criteria, false);
printProvider(bestProvider);
//get the current location (last known location) from the location manager
Location location = locManager.getLastKnownLocation(bestProvider);
//if location found display as a toast the current latitude and longitude
if (location != null) {
Toast.makeText(this, "Current location:\nLatitude: " + location.getLatitude() + "\n" + "Longitude: " + location.getLongitude(), Toast.LENGTH_LONG).show();
point = new GeoPoint((int) (location.getLatitude()*1E6),(int)(location.getLongitude() *1E6));
controller.animateTo(point);
} else {
Toast.makeText(this, "Cannot fetch current location!", Toast.LENGTH_LONG).show();
}
My manifest file:
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="10" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".activities.MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-library android:name="com.google.android.maps" />
<activity
android:name=".activities.GoogleMapsActivity"
android:label="#string/title_activity_maps" >
</activity>
<activity
android:name=".activities.MyMapsActivity"
android:label="#string/title_activity_maps" >
</activity>
</application>
</manifest>
Try this code :
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import android.content.Context;
import android.graphics.Canvas;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.Toast;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
public class MyMapsActivity extends MapActivity
{
MapView mapView;
MapController mapController;
LocationManager locationManager;
LocationListener locationListener;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mapView = (MapView) findViewById(R.id.mapView);
// enable Street view by default
mapView.setStreetView(true);
// enable to show Satellite view
// mapView.setSatellite(true);
// enable to show Traffic on map
// mapView.setTraffic(true);
mapView.setBuiltInZoomControls(true);
mapController = mapView.getController();
mapController.setZoom(5);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new GPSLocationListener();
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0, locationListener);
Touchy t = new Touchy();
List<Overlay> overlayList = mapView.getOverlays();
overlayList.add(t);
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
class Touchy extends Overlay
{
public boolean onTap(GeoPoint point, MapView mapView)
{
Context contexto = mapView.getContext();
String msg = "Latitude : " + point.getLatitudeE6()/1E6 + " - " + "Longitude : " + point.getLongitudeE6()/1E6;
Toast toast = Toast.makeText(contexto, msg, Toast.LENGTH_SHORT);
toast.show();
return true;
}
}
private class GPSLocationListener implements LocationListener
{
public void onLocationChanged(Location location)
{
if (location != null)
{
GeoPoint point = new GeoPoint((int) (location.getLatitude() * 1E6),(int) (location.getLongitude() * 1E6));
Toast.makeText(getBaseContext(),"Latitude: " + location.getLatitude() + " Longitude: " + location.getLongitude(),
Toast.LENGTH_SHORT).show();
mapController.animateTo(point);
mapController.setZoom(5);
mapView.invalidate();
}
if (location != null)
{
GeoPoint point=null;
String address = ConvertPointToLocation(point);
Toast.makeText(getBaseContext(), address, Toast.LENGTH_SHORT).show();
}
}
public String ConvertPointToLocation(GeoPoint point) {
String address = "";
Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
try {
List<Address> addresses = geoCoder.getFromLocation(point.getLatitudeE6() / 1E6,
point.getLongitudeE6() / 1E6, 1);
if (addresses.size() > 0) {
for (int index = 0;
index < addresses.get(0).getMaxAddressLineIndex(); index++)
address += addresses.get(0).getAddressLine(index) + " ";
}
}
catch (IOException e) {
e.printStackTrace();
}
return address;
}
}
Layout Coding :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.google.android.maps.MapView
android:id="#+id/mapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:enabled="true"
android:clickable="true"
android:apiKey="Your MAP API Key"/>
<LinearLayout android:id="#+id/zoom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
Link for getting own API key process :
http://sanathnandasiri.blogspot.in/2011/04/obtaining-google-maps-api-key-for.html
//get the current location (last known location) from the location manager
Location location = locManager.getLastKnownLocation(bestProvider);
use this instead of above line
location = locManager.getLastKnownLocation(bestProvider);
locManager.requestLocationUpdates(bestProvider,0, 0, locationListener);
location = locManager.getLastKnownLocation(bestProvider);
locManager.requestLocationUpdates(bestProvider,0, 0, locationListener);
First time location is null , so set your current location is last location .