我目前有一个可用的Google地图屏幕,我正在尝试添加其他功能。
在地图上点击,我想打开一个新活动来创建一个新标记。当我点击创建时,我想回到地图上。
我遇到的问题是运行时错误,通过谷歌搜索我发现我需要以某种方式销毁先前的地图片段以重新实现另一个。这是我正在努力解决的问题:如何销毁地图片段或在创建时重新加载地图片段?
代码:
public class MapsMain extends FragmentActivity implements
OnMapReadyCallback,
GoogleMap.OnMapLongClickListener,
GoogleMap.OnMapClickListener,
GoogleMap.OnMarkerClickListener {
//Initializing variables
private GoogleMap myMap;
boolean locationPermissionGranted;
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
private FusedLocationProviderClient mFusedLocationProviderClient;
private Location mLastKnownLocation;
private static final int DEFAULT_ZOOM = 15;
private static final String TAG = MapsMain.class.getSimpleName();
private final LatLng mDefaultLocation = new LatLng(-33.8523341, 151.2106085);
private AlertDialog.Builder userPrompt;
private AlertDialog.Builder markerInfo;
private String titleInput;
private String descInput;
private ArrayList<MapItem> markerArray = new ArrayList<>();
private MapItem tryMarker;
private MapItem putMarker;
private Button button;
private TextView myTextView;
private ImageView mainImage;
private TextView instructionTextView;
private TextView functionTextView;
private Button cameraButton;
private EditText titleEdit;
private EditText descriptionEdit;
private Button scenicButton;
private Button shadyButton;
private Button coveredButton;
private Button workButton;
private Button createButton;
private Button cancelButton;
public static final String PREFS_NAME = "MyPrefsFile";
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;
static final int REQUEST_IMAGE_CAPTURE = 1;
ImageView mImageView;
private int markerCounter = 0;
String tempImg = "";
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps_main);
editor = getApplicationContext().getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit();
mainImage = findViewById(R.id.imageView1); //accessing image
button = findViewById(R.id.button); //accessing button
myTextView = findViewById(R.id.TitleText); //accessing caption
instructionTextView = findViewById(R.id.instructionText);
functionTextView = findViewById(R.id.functionsText);
button.setOnClickListener((v) -> {
setContentView(R.layout.map_fragment);
// Grab SupportMapFragment and async data call when it's ready
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
});
}
@Override
public void onMapReady(GoogleMap googleMap) {
myMap = googleMap;
//pull shared preferences HERE
//Turn on My Location layer then get user location
getLocationPermission();
updateLocationUI();
getDeviceLocation();
myMap.setOnMapClickListener(this);
myMap.setOnMapLongClickListener(this);
myMap.setOnMarkerClickListener(this);
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
mImageView = (ImageView) findViewById(R.id.sampleImg);
mImageView.setImageBitmap(imageBitmap);
tempImg = encodeToBase64(imageBitmap);
}
}
//Defining MapItem Object
public class MapItem {
String title = "";
String description = "";
LatLng coords;
String base64Img;
String additionalInfo;
//constructor 1, temporary, ideally only use the second constructor in the future
public MapItem(LatLng coords) {
this.coords = coords;
}
//second constructor, after button issue, can get worked out.
public LatLng getCoords() {
return this.coords;
}
public void setTitle(String t) {
this.title = t;
}
public String getTitle() {
return this.title;
}
public void setDescription(String d) {
this.description = d;
}
public String getDescription() {
return this.description;
}
public void setIsShady() {
this.additionalInfo = this.additionalInfo + "\n This bench is shady!";
}
public void setIsScenic() {
this.additionalInfo = this.additionalInfo + "\n This bench is scenic!";
}
public void setIsCovered() {
this.additionalInfo = this.additionalInfo + " \n Safe from the elements";
}
public void setWorkBench() {
this.additionalInfo = this.additionalInfo + "\n Good place to do work";
}
public void setAdditionalInfo() {
this.description = this.description + this.additionalInfo;
}
public void setBase64Img(String s) {
this.base64Img = s;
}
public String getBase64Img() {
return this.base64Img;
}
}
public void populateMap() {
if (markerArray.size() == 0) {
int tempCounter = 0;
while (true) {
}
}
for (MapItem g: markerArray) {
myMap.addMarker(new MarkerOptions().position(g.coords));
}
}
private void getLocationPermission() {
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
locationPermissionGranted = true;
} else {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
locationPermissionGranted = false;
switch (requestCode) {
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
locationPermissionGranted = true;
}
}
updateLocationUI();
}
private void updateLocationUI() {
if (myMap == null) {
return;
}
try {
if (locationPermissionGranted) {
myMap.setMyLocationEnabled(true);
myMap.getUiSettings().setMyLocationButtonEnabled(true);
} else {
myMap.setMyLocationEnabled(false);
myMap.getUiSettings().setMyLocationButtonEnabled(false);
//Google Maps API documentation says this line is necessary
//but variable type not specified
//myLastKnownLocation = null;
}
}
catch (SecurityException e) {
Log.e("Exception: %s", e.getMessage());
}
}
private void getDeviceLocation() {
//this function gets most recent device location, which is rare when location != available
try {
if (locationPermissionGranted) {
//android error suggestion is handled already, suppress.
@SuppressLint("MissingPermission") Task locationResult = mFusedLocationProviderClient.getLastLocation();
locationResult.addOnCompleteListener(this, new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
if (task.isSuccessful()) {
//set map camera to current position
mLastKnownLocation = (Location) task.getResult();
myMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(mLastKnownLocation.getLatitude(), mLastKnownLocation.getLongitude()), DEFAULT_ZOOM
));
}
else {
Log.d(TAG, "No current location. Set default");
Log.d(TAG, "Exception: %s", task.getException());
myMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM));
myMap.getUiSettings().setMyLocationButtonEnabled(false);
}
}
});
}
}
catch(SecurityException e) {
Log.e("Exception: %s", e.getMessage());
}
}
@Override
public void onMapClick(LatLng point) {
//on click this creates new marker using MapItem's base constructor, to get coordinate data into the AlertDialog UI
setContentView(R.layout.relative_create_popup);
createMarker(point);
//calls user prompt method
//promptUser();
}
public static String encodeToBase64(Bitmap image) {
Bitmap myImage = image;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
myImage.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] b = baos.toByteArray();
String imageEncoded = Base64.encodeToString(b, Base64.DEFAULT);
return imageEncoded;
}
public static Bitmap decodeBase64(String input) {
byte[] decodedByte = Base64.decode(input, 0);
return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
}
这是产生错误的部分:当我调用createMarker时,我会拉出用户可以将文本放入的字段。当我为提交按钮设置onClickListener()
时,应用程序崩溃了。
public void createMarker(LatLng coords) {
String tempTitle;
String tempDescription;
MapItem tempMapItem = new MapItem(coords);
cameraButton = (Button) findViewById(R.id.cameraButton);
titleEdit = (EditText) findViewById(R.id.titleEdit);
descriptionEdit = (EditText) findViewById(R.id.descriptionEdit);
scenicButton = (Button) findViewById(R.id.scenicButton);
shadyButton = (Button) findViewById(R.id.shadyButton);
coveredButton = (Button) findViewById(R.id.coveredButton);
workButton = (Button) findViewById(R.id.workButton);
createButton = (Button) findViewById(R.id.createButton);
cancelButton = (Button) findViewById(R.id.cancelButton);
cameraButton.setOnClickListener((camera) -> {
dispatchTakePictureIntent();
tempMapItem.setBase64Img(tempImg);
});
tempMapItem.setTitle(titleEdit.getText().toString());
tempMapItem.setDescription(descriptionEdit.getText().toString());
scenicButton.setOnClickListener((scenic) -> {
tempMapItem.setIsScenic();
scenicButton.setBackgroundColor(Color.BLUE);
});
shadyButton.setOnClickListener((shady) -> {
tempMapItem.setIsShady();
shadyButton.setBackgroundColor(Color.BLUE);
});
coveredButton.setOnClickListener((covered) -> {
tempMapItem.setIsCovered();
coveredButton.setBackgroundColor(Color.BLUE);
});
workButton.setOnClickListener((work) -> {
tempMapItem.setWorkBench();
workButton.setBackgroundColor(Color.BLUE);
});
createButton.setOnClickListener((create) -> {
//tempMapItem.setAdditionalInfo();
//markerArray.add(tempMapItem);
//editor.putString("title"+markerCounter, tempMapItem.getTitle());
//editor.putString("description"+markerCounter, tempMapItem.getDescription());
//editor.putFloat("latitude"+markerCounter, (float) coords.latitude);
//editor.putFloat("longitude"+markerCounter, (float) coords.longitude);
//editor.putString("image"+markerCounter, tempMapItem.getBase64Img());
//populateMap();
setContentView(R.layout.map_fragment);
// Grab SupportMapFragment and async data call when it's ready
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
});
}
更多代码
@Override
public void onMapLongClick(LatLng point) {
//For testing; long click clears map, next marker input will re-populate fully!
createMarker(point);
myMap.clear();
dispatchTakePictureIntent();
}
@Override
public boolean onMarkerClick(Marker marker) {
setContentView(R.layout.view_popup);
String tempTitle ="";
String tempDescription = "";
for (MapItem g: markerArray) {
double lat1 = g.getCoords().latitude;
double long1= g.getCoords().longitude;
double lat2 = marker.getPosition().latitude;
double long2 = marker.getPosition().longitude;
double threshold = .0005;
if ((Math.abs(lat1-lat2) < threshold) && (Math.abs(long1-long2) < threshold)) {
tempTitle = g.getTitle();
tempDescription = g.getDescription();
}
}
//markerZoom(marker, tempTitle, tempDescription);
return false;
}
}
// XML:create_popup
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_blue_light"
>
<Button
android:id="@+id/cameraButton"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:text="Access the camera" />
<TextView
android:id="@+id/textView"
android:layout_width="100dp"
android:layout_height="30dp"
android:layout_alignLeft="@+id/cameraButton"
android:layout_alignStart="@+id/cameraButton"
android:layout_below="@+id/cameraButton"
android:layout_gravity="center"
android:layout_marginTop="19dp"
android:text="Bench Name: "
android:textColor="@android:color/white"
android:textSize="15dp" />
<EditText
android:id="@+id/titleEdit"
android:layout_width="300dp"
android:layout_height="50dp"
android:layout_below="@+id/textView"
android:layout_centerHorizontal="true"
android:layout_gravity="center" />
<TextView
android:layout_width="130dp"
android:layout_height="30dp"
android:layout_below="@+id/titleEdit"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:layout_marginTop="11dp"
android:text="Bench Description: "
android:textColor="@android:color/white"
android:textSize="15dp"
android:id="@+id/textView2" />
<EditText
android:id="@+id/descriptionEdit"
android:layout_width="300dp"
android:layout_height="50dp"
android:layout_alignLeft="@+id/titleEdit"
android:layout_alignStart="@+id/titleEdit"
android:layout_below="@+id/textView2"
android:layout_gravity="center"
android:visibility="visible" />
<TextView
android:id="@+id/textView3"
android:layout_width="175dp"
android:layout_height="50dp"
android:layout_below="@+id/descriptionEdit"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:layout_marginTop="11dp"
android:text="Press the buttons below to add tags to your bench:"
android:textColor="@android:color/white"
android:textSize="15dp" />
<Button
android:id="@+id/scenicButton"
android:layout_width="175dp"
android:layout_height="50dp"
android:layout_alignLeft="@+id/coveredButton"
android:layout_alignStart="@+id/coveredButton"
android:layout_below="@+id/textView3"
android:layout_gravity="center"
android:text="Scenic" />
<Button
android:id="@+id/shadyButton"
android:layout_width="175dp"
android:layout_height="50dp"
android:layout_alignBaseline="@+id/scenicButton"
android:layout_alignBottom="@+id/scenicButton"
android:layout_gravity="center"
android:layout_toEndOf="@+id/scenicButton"
android:layout_toRightOf="@+id/scenicButton"
android:text="Shady" />
<Button
android:id="@+id/coveredButton"
android:layout_width="175dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/scenicButton"
android:layout_gravity="center"
android:layout_marginLeft="14dp"
android:layout_marginStart="14dp"
android:text="Covered" />
<Button
android:id="@+id/workButton"
android:layout_width="175dp"
android:layout_height="50dp"
android:layout_below="@+id/shadyButton"
android:layout_gravity="center"
android:layout_toEndOf="@+id/coveredButton"
android:layout_toRightOf="@+id/coveredButton"
android:text="Good Work Station" />
<Button
android:id="@+id/createButton"
android:layout_width="175dp"
android:layout_height="50dp"
android:layout_alignLeft="@+id/workButton"
android:layout_alignParentBottom="true"
android:layout_alignStart="@+id/workButton"
android:layout_gravity="right"
android:layout_marginBottom="25dp"
android:layout_weight="0"
android:text="Create"
android:visibility="visible" />
<Button
android:id="@+id/cancelButton"
android:layout_width="175dp"
android:layout_height="50dp"
android:layout_alignBaseline="@+id/createButton"
android:layout_alignBottom="@+id/createButton"
android:layout_gravity="left"
android:layout_toLeftOf="@+id/createButton"
android:layout_toStartOf="@+id/createButton"
android:layout_weight="0"
android:text="Cancel"
/>
</RelativeLayout>
XML地图片段:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
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.mylab_final.cisc181.finalproject.MapsMain" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/sampleImg"
android:visibility="invisible"
/>
</RelativeLayout>
logcat的:
12-04 08:04:12.429 26140-26140/com.mylab_final.cisc181.finalproject E/Zygote: v2
12-04 08:04:12.430 26140-26140/com.mylab_final.cisc181.finalproject E/Zygote: accessInfo : 0
12-04 08:04:47.422 26140-26140/com.mylab_final.cisc181.finalproject E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mylab_final.cisc181.finalproject, PID: 26140
android.util.SuperNotCalledException: Activity {com.mylab_final.cisc181.finalproject/com.mylab_final.cisc181.finalproject.MapsMain} did not call through to super.onDestroy()
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4575)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4609)
at android.app.ActivityThread.-wrap7(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1692)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(
ZygoteInit.java:1410)