I am trying to use Google Map in an Android app for the first time.
For that I found a couple of tutorials and documents on the net to get started.
I already have an API key that I got from Google.
Here is the kind of code I have:
package me.myapp
import ....
class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
private lateinit var mMap: GoogleMap
private lateinit var binding: ActivityMapsBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMapsBinding.inflate(layoutInflater)
setContentView(binding.root)
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
val mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
}
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
// Add a marker in Sydney and move the camera
val sydney = LatLng(-34.0, 151.0)
mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
}
}
I can launch the app I made, but something is not what I expected:
When installed and launched on my device the app appears with the name MapsActivity instead of the usual name I give (MyApp). I don't know if this is important, but I just wonder why that is.
After it is launched, I see a grey display with the Google mark at the bottom left, but no other contents. I expected to see some map of Sidney appear.
I hope someone reading this will have some relevant feedback to provide.
Thanks in advance.
......... addition .........
Here is how the AndroidManifest.xml file looks like, in case that may be useful:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="me.myapp">
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.MyApp"
tools:targetApi="31">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${MAPS_API_KEY}" />
<activity
android:name=".MapsActivity"
android:exported="true"
android:label="#string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
The app screenshot is:
Please Provide your Google Map Api Key
Create google api key enter link description here
Enter the Key you got in the value field
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="pasteApiKey" />
To change the name of your application you need to open the Manifest file and change the string label inside the application and activity tag :
<application
android:label="MyApp"
<activity
android:label="MyApp"
</activity>
</application>
To access location you need to add these permissions in the Manifest file as well:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
And make sure to request the use of location when launching your app
This decomuntation tells how to do it :
Request location in android apps
Related
I have a Unity activity embedded as a fragment inside of my Android app. Everything works fine, except that after the fragment runs, the resolution of the app is funny. And it stays that way even after restarting. I have to make a change to the AndroidManifest and then reinstall in order to get the resolution right again.
Here is a piece of the manifest from the Android app.
<application
android:name=".App"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:extractNativeLibs="true"
android:theme="#style/AppTheme"
android:usesCleartextTraffic="true">
<activity android:name=".FragmentActivity"
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:windowSoftInputMode="adjustNothing">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Here is the entire AndroidManifest from unityLibrary that I imported into the app.
<?xml version="1.0" encoding="utf-8"?>
<!-- GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" xmlns:tools="http://schemas.android.com/tools">
<application>
<activity android:name="com.unity3d.player.UnityPlayerActivity" android:theme="#style/UnityThemeSelector" android:screenOrientation="fullSensor" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" android:hardwareAccelerated="false">
<!--<intent-filter>-->
<!--<action android:name="android.intent.action.MAIN" />-->
<!--<category android:name="android.intent.category.DEFAULT" />-->
<!--</intent-filter>-->
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
<meta-data android:name="android.notch_support" android:value="true" />
</activity>
<meta-data android:name="unity.splash-mode" android:value="0" />
<meta-data android:name="unity.splash-enable" android:value="True" />
<meta-data android:name="notch.config" android:value="portrait|landscape" />
<meta-data android:name="unity.build-id" android:value="f6e555a5-44fc-47be-9a81-b3809caa8f74" />
</application>
<uses-feature android:glEsVersion="0x00030000" />
<uses-feature android:name="android.hardware.vulkan.version" android:required="false" />
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
<uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
<uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
</manifest>
Here's the activity that holds the fragment.
class FragmentActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_fragment)
}
}
Here's the fragment itself.
class UnityFragment : Fragment() {
protected var mUnityPlayer: UnityPlayer? = null
var frameLayoutForUnity: FrameLayout? = null
fun UnityFragment() {}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mUnityPlayer = UnityPlayer(activity)
val view = inflater.inflate(R.layout.fragment_unity, container, false)
frameLayoutForUnity =
view.findViewById<View>(R.id.frameLayoutForUnity) as FrameLayout
frameLayoutForUnity!!.addView(
mUnityPlayer!!.view,
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT
)
mUnityPlayer!!.requestFocus()
mUnityPlayer!!.windowFocusChanged(true)
return view
}
override fun onDestroy() {
mUnityPlayer!!.quit()
super.onDestroy()
}
override fun onPause() {
super.onPause()
mUnityPlayer!!.pause()
}
override fun onResume() {
super.onResume()
mUnityPlayer!!.resume()
}
}
And here's R.layout.fragment_unity.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/frameLayoutForUnity"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".UnityFragment"/>
The layout for FragmentActivity is just a single fragment inside of a constraintlayout.
I hope someone can point me in the right direction because I really don't understand how screen resolution works or what controls it. But based on the appearance of layouts in the rest of the app, it feels like that's what it's related to.
I found a solution, but it's not super enlightening. What I mean is that I found a way to make the symptom stop.
For reasons I can't explain, if I set hardwareAccelerated to true inside of my app Manifest WHILE ALSO turning notchsupport to false inside the unityLibrary Manifest then my custom views stop drawing their canvases weird.
I know this seems like rain dancing or using a dowsing rod, but it works and I can revisit later to make an implementation that I understand.
Some notes: My gut feeling is that I'm letting the unity manifest talk over my app manifest and somehow turn off hardwareAccelerated, since that would explain the canvases being drawn differently. But suppressing hardwareAccelerated turning off inside the unity manifest and also forcing it as enabled in the app manifest are not enough by themselves to stop the symptom. The only thing that stops the symptom is doing all of that and also turning off notch_support. Maybe somewhere notch_support interacts with hardwareAccelerated. But I think it's more likely that there's a third factor causing all this and this random confluence of settings affects that factor happenstantially.
Edit: It's been a long time since I asked this question. But I see that it's gotten some interest recently from someone likely experiencing the same problem. I never figured out what the problem was. It sort of just happened intermittently and eventually stopped. But for the benefit of posterity I would like to say that visually detecting a change in resolution in any situation and for any cause points to a failure to accommodate different screens and is probably why the question got downvoted.
So if you're experiencing this problem too, the first place you should probably look is whether you're using px instead of dp in your custom drawn canvases. A lot of the canvas draw methods default to px and you have to normalize to dp yourself.
Also use percentages to size things out inside of ConstraintLayouts.
Ive been trying to use Google Awareness API (Fence API) and I can register every other kind of fence - headphones, walking- and my broadcast reciever that handles callbacks from fence state changes is working but keep getting com.google.android.gms.common.api.ApiException: 7503 when registering a location fence
Looked for similar posts on stack overflow and made sure I didnt turn off my phones location - below is the code Ive been trying to use for location fence types only
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.location_try_dos">
<!-- Needed For Awarness - Fence API -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<receiver
android:name=".FenceReciever"
android:enabled="true"
android:exported="false"></receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.awareness.API_KEY"
android:value="MYKEY" />
</application>
</manifest>
MainActivity.kt
override fun onStart() {
super.onStart()
Timber.i("onStart Called")
//there was two optations for manifest
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED){
Toast.makeText(this,
"Have Permissions Needed",
Toast.LENGTH_LONG).show()
val locationFence:AwarenessFence = LocationFence.entering(37.4220,-122.0841, 1609.0)
Awareness.getFenceClient(this).updateFences(FenceUpdateRequest.Builder()
.addFence(FENCE_KEY, locationFence,
PendingIntent.getBroadcast(
this,
FENCE_INTENT_ID,
Intent(this,FenceReciever::class.java),
PendingIntent.FLAG_UPDATE_CURRENT))
.build())
.addOnSuccessListener { Log.i("FENCE API", "Fence was successfully registered.") }
.addOnFailureListener { e -> Log.e("FENCE API", "Fence could not be registered: $e") }
}
}
In case anyone gets this problem too.
Have android 10 api 29 on physical device
If your testing on a phone/emulator thats on android 29 - you need to add the permission
ACCESS_BACKGROUND_LOCATION to the manifest and allow the app to get your location all the time
If your testing on api 30 - you only need "allow while app is in use" to get location fences to register correctly
lass MapsActivity : AppCompatActivity(), OnMapReadyCallback {
private lateinit var mMap: GoogleMap
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_maps)
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
val mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
val permissionx= arrayOf(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION)
ActivityCompat.requestPermissions(this, permissionx,0)
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
// Add a marker in Sydney and move the camera
val sydney = LatLng(-34.0, 151.0)
mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
}
}
ı set there the permıssıon code because i want to check if program goes there and the program never goes there and want permıssion ı tried it with Toast too but program never open this
Xml of main activity for map fragment
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="259dp"
tools:context="com.example.siparis.MapsActivity" />
I entered key Correctly i m sure.
Here is my manifest for the program.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.siparis">
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<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"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.NoActionBar">
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
<activity
android:name=".MapsActivity"
android:label="#string/title_activity_maps"></activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Only error in Logcat is that :
2020-03-06 16:52:50.323 20804-20804/? E/example.sipari: Unknown bits
set in runtime_flags: 0x8000
Please check this:
https://developer.android.com/reference/android/Manifest.permission#ACCESS_BACKGROUND_LOCATION
Allows an app to access location in the background. If you're requesting this permission, you must also request either ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION. Requesting this permission by itself doesn't give you location access.
I think you are missing permissions. Please also request before using.
You should call mMap.onResume() inside onMapReady()
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
// Add a marker in Sydney and move the camera
val sydney = LatLng(-34.0, 151.0)
mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
//map is the mapview in the layout
(map as SupportMapFragment).onResume() //this line is very necessary
}
I am not a programmer but am doing a very basic android development app through work.
I have managed to set up all the config keys in order to get a google map screen in my app up and running. However, when I click to open the map screen it shows a blank map (only showing a google logo at the bottom of my screen).
I have looked at questions from people here with similar issue, so I suspect I need to add certain permissions in my android manifest and also play a bit with my java code? So really hoping someone would be able to look into my code and point me to the right direction (kind of baby steps...)
Thanks
Android Manifest xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.learn5things">
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".LocationActivity" />
<activity android:name=".CultureActivity" />
<activity android:name=".FoodActivity" />
<activity android:name=".FootballActivity" />
<activity android:name=".CarnavalActivity" />
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
<activity
android:name=".MapsActivity"
android:label="#string/title_activity_maps"></activity>
</application>
</manifest>
Activity maps (XML)
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.learn5things.MapsActivity" />
Maps Activity (java file)
package com.example.android.learn5things;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
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.MarkerOptions;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Brazil and move the camera
LatLng brazil = new LatLng(-8.892710, -56.098682);
mMap.addMarker(new MarkerOptions().position(brazil).title("Marker in Brazil"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(brazil));
}
}
You have to clarify Google Play Services version in your manifest.xml file under application tag:
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
Also, I think your google maps api key should be referenced as:
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="#string/google_maps_key" />
Also, make sure you put your actual Google Maps Key in your strings file!
Hope it helped.
Source
I am trying to setup a basic Google Maps application for Android 2.3.3. I tried developing in Eclipse, NetBeans and IntelliJ IDEA just to name it. After failing too many times I am back to basic. Please help me with my API v1.
Currently my maps shows blank (emulator and my real device). This is my code (I tried every possible permission tag by the way):
I am signing the application with the default debug key and even when I sign it in release I still get the blank map.
All I want is to see a real map.
(By the way I am not sure if the format of the text here is right so in a nutshell I just copied the code 1-1 from here mapview v1 sample)
The manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hellogooglemaps"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8"/>
<application android:label="#string/app_name">
<uses-library android:name="com.google.android.maps"/>
<activity android:name="MyActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
The activity layout
<com.google.android.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:apiKey="BLA_BLA_BLA_GOT_A_KEY"
/>
The activity
package com.example.hellogooglemaps;
import android.os.Bundle;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
public class MyActivity extends MapActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MapView mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
}
If you are using MD5 for default.keystore.
Then go to Windows>show view>other>Emulator control
and send the click the send button from Emulator control(C ordinates in Decimal)
Then again run your application Map should appear with some default US location.
For getting Map in Device you need to create MD5 from your Application keystore not the default keystore.
Thanks.
The code looks fine for Google Map API V1. So there must be some problem with your key. for what I know if it's a new generated key then Google doesn't provide keys for Google Map API V1, so it must be a key for Google Map API V2 and that's the reason it doesn't work.
Please try map V2,
Use the correct map key after generating, along with the below considerations:
Internet permission. 2 . Turn on Google map for Android V2 in the developer console. 3 . Use appropriate tags in manifest, for example
below:
<application android:label="#string/app_name" android:icon="#drawable/ic_launcher">
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="xxx"/>
<activity android:name="MyActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</application>