Hey, die Emulatoren sind im Moment ein Mysterium, habe alle möglichen Images mit GoogleAPI getestet, zu Anfang meines Projektes hat auch alles funktioniert. Irgendwann hats nimmer funktioniert. God knows why. Hatte überlegt Studio mal neu zu installieren, aber im Moment läuft alles auf dem Handy, never change a running system ;).
Beiträge von hypnotoad
-
-
werwer
-
Update:
habe ein paar kleine Schritte in die richtige Richtung gemacht. Die Permissionrequests lassen sich erstmal umgehen. Das Problem kommt später. Im Moment steht die Map soweit, zeigt die Position des Nutzers an und Polylines zu weiteren zufälligen Positionen sind erstmal grob vorbereitet.
Code
Alles anzeigenpackage com.who.is; import android.location.Location; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationServices; 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.BitmapDescriptorFactory; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.gms.maps.model.Polyline; import com.google.android.gms.maps.model.PolylineOptions; public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, GoogleMap.OnMyLocationButtonClickListener{ LocationRequest mLocationRequest; GoogleApiClient mGoogleApiClient; LatLng latLng; GoogleMap mGoogleMap; SupportMapFragment mFragment; boolean connectedSchalter = true; Marker currLocationMarker; // TODO: 17.07.2016 polylines private static final LatLng MELBOURNE = new LatLng(-37.81319, 144.96298); private static final LatLng ADELAIDE = new LatLng(-34.92873, 138.59995); private static final LatLng PERTH = new LatLng(-31.95285, 115.85734); // TODO: 17.07.2016 polylines @Override protected void onCreate(Bundle savedInstanceState) { Log.i("TAG", "onCreate wurde aufgerufen"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps); mFragment=(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); mFragment.getMapAsync(this); } @Override public void onMapReady(GoogleMap gMap) { Log.i("TAG", "onMapReady wurde aufgerufen"); Toast.makeText(this,"onMapReady",Toast.LENGTH_SHORT).show(); // Das Kartenfragment ist bereit und kann eingestellt werden mGoogleMap = gMap; mGoogleMap.setMyLocationEnabled(true); buildGoogleApiClient(); mGoogleApiClient.connect(); } protected synchronized void buildGoogleApiClient() { Log.i("TAG", "buildGoogleApiClient wurde aufgerufen"); Toast.makeText(this,"buildGoogleApiClient",Toast.LENGTH_SHORT).show(); mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); } @Override public void onConnected(Bundle bundle) { Log.i("TAG", "onConnected wurde aufgerufen"); Toast.makeText(this,"onConnected",Toast.LENGTH_SHORT).show(); Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient); if (mLastLocation != null) { //place marker at current position //mGoogleMap.clear(); latLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude()); MarkerOptions markerOptions = new MarkerOptions(); markerOptions.position(latLng); markerOptions.title("ICKE"); markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)); currLocationMarker = mGoogleMap.addMarker(markerOptions); } mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(1000); //1 sekunde mLocationRequest.setFastestInterval(1000); //1 sekunde mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); // TODO: 14.07.2016 soll nur einmal aufgerufen werden if (connectedSchalter) { CameraPosition cameraPosition = new CameraPosition.Builder() .target(latLng).zoom(15.5f).bearing(300).tilt(50).build(); mGoogleMap.animateCamera(CameraUpdateFactory .newCameraPosition(cameraPosition)); connectedSchalter = false; } // Fertig!!!! // TODO: 17.07.2016 polylines mGoogleMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker")); mGoogleMap.addMarker(new MarkerOptions().position(MELBOURNE).title("Marker")); mGoogleMap.addMarker(new MarkerOptions().position(ADELAIDE).title("Marker")); mGoogleMap.addMarker(new MarkerOptions().position(PERTH).title("Marker")); mGoogleMap.addPolyline((new PolylineOptions()) .add(MELBOURNE, ADELAIDE, PERTH, latLng)); // TODO: 17.07.2016 polylines soweit so schlecht } @Override public void onConnectionSuspended(int i) { Log.i("TAG", "onConnectionSuspended wurde aufgerufen"); Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show(); } @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.i("TAG", "onConnectionFailed wurde aufgerufen"); Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show(); } @Override public void onLocationChanged(Location location) { Log.i("TAG", "onLocationChanged wurde aufgerufen"); Toast.makeText(this,"onLocationChanged",Toast.LENGTH_SHORT).show(); // falls es bereits einen Marker gibt, wird er entfernt if (currLocationMarker != null) { currLocationMarker.remove(); } // dieser Block generiert den Marker an meiner Position latLng = new LatLng(location.getLatitude(), location.getLongitude()); MarkerOptions markerOptions = new MarkerOptions(); markerOptions.position(latLng); markerOptions.title("Current Position"); markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)); currLocationMarker = mGoogleMap.addMarker(markerOptions); Toast.makeText(this,"Location Changed",Toast.LENGTH_SHORT).show(); } @Override public boolean onMyLocationButtonClick() { Log.i("TAG", "onMyLocationButtonClick wurde aufgerufen"); Toast.makeText(this,"onMyLocationButtonClick",Toast.LENGTH_SHORT).show(); // dieser Block zentriert die kamera auf der Position des Nutzers CameraPosition cameraPosition = new CameraPosition.Builder() .target(latLng).zoom(15.5f).bearing(300).tilt(50).build(); mGoogleMap.animateCamera(CameraUpdateFactory .newCameraPosition(cameraPosition)); return false; } } //stuff: //mGoogleMap.clear(); //mLocationRequest.setSmallestDisplacement(0.1F); //1/10 meter // hier wird die Camera auf meiner Position zentriert, genau wie in onmylocationbuttonclick /** CameraPosition cameraPosition = new CameraPosition.Builder() .target(latLng).zoom(15.5f).bearing(300).tilt(50).build(); mGoogleMap.animateCamera(CameraUpdateFactory .newCameraPosition(cameraPosition)); */
Nächste Aufgabe:
Die Position eines Nutzers an einen anderen senden. Noch nicht sicher, welche Technik da zu verwenden sinnvoll wäre, mir fallen Cellbroadcasts, Wlan, Le Interwebs, oder auch bestehende Netzwerke wie twitter, whatsapp oder Pokemon ein. Denke auch hier, ist der richtige Weg, erstmal eine einfach Variante zu implementieren. Wenn alles soweit läuft, kann man sich nach einer besseren Variante umsehen. -
Gradle: Project:
Code
Alles anzeigen// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.1.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }
Gradle: Modul:
Code
Alles anzeigenapply plugin: 'com.android.application' android { compileSdkVersion 24 buildToolsVersion "24" defaultConfig { applicationId "com.hypnotoad.mapapp" minSdkVersion 23 targetSdkVersion 24 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } productFlavors { } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:24.0.0' compile 'com.google.android.gms:play-services:9.2.0' compile 'com.google.android.gms:play-services-ads:9.2.0' compile 'com.google.android.gms:play-services-auth:9.0.2' compile 'com.google.android.gms:play-services-gcm:9.0.2' }
Manifest:
Code
Alles anzeigen<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.hypnotoad.mapapp"> <!-- 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"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <!-- 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>
Wenn ich den LocationManager und die Requestabfrage raus nehmen funktioniert eigentlich alles. Soweit ich das beurteilen kann, sollten diese Teile eigentlich funktionieren.
Halp! -
Mapfragment:
Code
Alles anzeigenpackage com.who.is; import android.location.Location; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationServices; 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.BitmapDescriptorFactory; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.gms.maps.model.Polyline; import com.google.android.gms.maps.model.PolylineOptions; public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, GoogleMap.OnMyLocationButtonClickListener{ LocationRequest mLocationRequest; GoogleApiClient mGoogleApiClient; LatLng latLng; GoogleMap mGoogleMap; SupportMapFragment mFragment; boolean connectedSchalter = true; Marker currLocationMarker; // TODO: 17.07.2016 polylines private static final LatLng MELBOURNE = new LatLng(-37.81319, 144.96298); private static final LatLng ADELAIDE = new LatLng(-34.92873, 138.59995); private static final LatLng PERTH = new LatLng(-31.95285, 115.85734); // TODO: 17.07.2016 polylines @Override protected void onCreate(Bundle savedInstanceState) { Log.i("TAG", "onCreate wurde aufgerufen"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps); mFragment=(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); mFragment.getMapAsync(this); } @Override public void onMapReady(GoogleMap gMap) { Log.i("TAG", "onMapReady wurde aufgerufen"); Toast.makeText(this,"onMapReady",Toast.LENGTH_SHORT).show(); // Das Kartenfragment ist bereit und kann eingestellt werden mGoogleMap = gMap; mGoogleMap.setMyLocationEnabled(true); buildGoogleApiClient(); mGoogleApiClient.connect(); } protected synchronized void buildGoogleApiClient() { Log.i("TAG", "buildGoogleApiClient wurde aufgerufen"); Toast.makeText(this,"buildGoogleApiClient",Toast.LENGTH_SHORT).show(); mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); } @Override public void onConnected(Bundle bundle) { Log.i("TAG", "onConnected wurde aufgerufen"); Toast.makeText(this,"onConnected",Toast.LENGTH_SHORT).show(); Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient); if (mLastLocation != null) { //place marker at current position //mGoogleMap.clear(); latLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude()); MarkerOptions markerOptions = new MarkerOptions(); markerOptions.position(latLng); markerOptions.title("ICKE"); markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)); currLocationMarker = mGoogleMap.addMarker(markerOptions); } mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(1000); //1 sekunde mLocationRequest.setFastestInterval(1000); //1 sekunde mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); // TODO: 14.07.2016 soll nur einmal aufgerufen werden if (connectedSchalter) { CameraPosition cameraPosition = new CameraPosition.Builder() .target(latLng).zoom(15.5f).bearing(300).tilt(50).build(); mGoogleMap.animateCamera(CameraUpdateFactory .newCameraPosition(cameraPosition)); connectedSchalter = false; } // Fertig!!!! // TODO: 17.07.2016 polylines mGoogleMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker")); mGoogleMap.addMarker(new MarkerOptions().position(MELBOURNE).title("Marker")); mGoogleMap.addMarker(new MarkerOptions().position(ADELAIDE).title("Marker")); mGoogleMap.addMarker(new MarkerOptions().position(PERTH).title("Marker")); mGoogleMap.addPolyline((new PolylineOptions()) .add(MELBOURNE, ADELAIDE, PERTH, latLng)); // TODO: 17.07.2016 polylines soweit so schlecht } @Override public void onConnectionSuspended(int i) { Log.i("TAG", "onConnectionSuspended wurde aufgerufen"); Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show(); } @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.i("TAG", "onConnectionFailed wurde aufgerufen"); Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show(); } @Override public void onLocationChanged(Location location) { Log.i("TAG", "onLocationChanged wurde aufgerufen"); Toast.makeText(this,"onLocationChanged",Toast.LENGTH_SHORT).show(); // falls es bereits einen Marker gibt, wird er entfernt if (currLocationMarker != null) { currLocationMarker.remove(); } // dieser Block generiert den Marker an meiner Position latLng = new LatLng(location.getLatitude(), location.getLongitude()); MarkerOptions markerOptions = new MarkerOptions(); markerOptions.position(latLng); markerOptions.title("Current Position"); markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)); currLocationMarker = mGoogleMap.addMarker(markerOptions); Toast.makeText(this,"Location Changed",Toast.LENGTH_SHORT).show(); } @Override public boolean onMyLocationButtonClick() { Log.i("TAG", "onMyLocationButtonClick wurde aufgerufen"); Toast.makeText(this,"onMyLocationButtonClick",Toast.LENGTH_SHORT).show(); // dieser Block zentriert die kamera auf der Position des Nutzers CameraPosition cameraPosition = new CameraPosition.Builder() .target(latLng).zoom(15.5f).bearing(300).tilt(50).build(); mGoogleMap.animateCamera(CameraUpdateFactory .newCameraPosition(cameraPosition)); return false; } }
-
Spoiler: der Code hier ist nicht mehr aktuell, siehe unten!
Servus miteinander,
Habe vor kurzem mal wieder angefangen mich an meiner Projektidee zu versuchen. Auch wenn das finale Produkt etwas umfangreicher (für meine Maßstäbe) sein soll, ist die momentane Variante recht simpel und die Beschreibung wird sich hier immer am aktuellen Zustand orientieren:
Es gibt eine main activity die kaum mehr als ein Platzhalter ist und einen button enthält, der zum nächsten screen, einem mapfragment führt.
Das mapfragment, soll nun vor allem ein paar fixe marker anzeigen.todo: im Moment versuche ich meine map zu überreden, die aktuelle Location als marker an zu zeigen.
probleme: Die app startet zunächst problemlos und die mainactivity mit dem button lädt. Wenn man diesen drückt, kommt die Fehlermeldung: Map won`t run unless u update Google Play Services und einem Button: "update".
wenn man auf update klickt, schmiert das Programm leider ab.Main:
Code
Alles anzeigenpackage com.hypnotoad.mapapp; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { Log.i("TAG", "Scope onCreate MainActivity wurde aufgerufen"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void showMapButton (View view){ Log.i("TAG", "showMapButton MainActivity onCreate wurde aufgerufen"); Intent mapintent = new Intent(this, MapsActivity.class); startActivity(mapintent); } }
-
Hallo Allerseits,
Habe einen neuen Anlauf gestartet eine alte Idee in die Tat um zu setzen.
Beim umsetzen tuen sich wie immer unüberwindbare Hindernisse auf. Aus einer Main Activity möchte ich mit einem Button zu einem Mapfragment kommen.
Habe also erst eine Blank Activity erstellt und einen Button eingefügt:OkButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.activity_maps_recieve);
}
});Die Aufgerufene Map sieht so aus:
private GoogleMap mMap;@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps_recieve);
// 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 Sydney and move the camera
LatLng sydney = new LatLng(-34, 151);
Marker Sydney = mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));Die Map wird soweit auch erst einmal aufgerufen, nur fehlt der Marker und der Zoom findet ebenfalls nicht statt.
Der Code ist im Grunde der unverändert durch Android Studio erstellt. Wenn man ein neues Projekt erstellt, mit einem Mapfragment, als main Activity,
funktioniert die Marker Darstellung auch problemlos.Werde irgendetwas grundsätzlich falsch verstanden haben, nur was?
Müssen die Steuerbefehle in der Main activity aufgerufen werden? Würde dies nicht dem Prinzip, eine View, eine Activity widersprechen? Meh, werde mal versuchen, alles in einer main Activity unter zu bringen. Nehme an ein Inflater wäre da das richtige Instrument. Auch wenn es net sehr elegant aussieht. Zumal beides am Ende lediglich ein Teil einer grösseren Architektur sein soll.
Hm, neue Idee, vielleicht lässt sich das eleganter lösen, wenn man den Map-Teil als eigenständiges Modul deklariert? Mal nachforschen, wie des mit den Modulen funktioniert.
Problem gelöst. Ein guter alter Intent führte zum Erfolg. Frage mich allerdings wozu SetContentView gut sein soll, wenn man am Ende doch wieder Intents braucht:
public void showMapButton (View view){
Intent mapintent = new Intent(this, MapsActivity.class);
startActivity(mapintent);
}