我想在地图上画一条折线
进口com.google.android.gms.maps.model.Polyline;进口com.google.android.gms.maps.model.PolylineOptions;
导入java.util。ArrayList;导入java.util.List;
公共类 MainActivity extends AppCompatActivity 实现了 OnMapReadyCallback, SeekBar.OnSeekBarChangeListener { //Initialise variables
GoogleMap gMap;
SeekBar seekWidth, seekBlue, seekGreen, seekRed;
Button btClear, btDraw;
Polyline polyline = null;
List<LatLng> latLngList = new ArrayList<>();
List<Marker> markerList = new ArrayList<>();
PolylineOptions polylineOptions = null;
int red = 0, green= 0, blue=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Assign variable
seekWidth = findViewById(R.id.seek_width);
seekRed = findViewById(R.id.seek_red);
seekGreen = findViewById(R.id.seek_green);
seekBlue = findViewById(R.id.seek_blue);
btDraw=findViewById(R.id.bt_draw);
btClear=findViewById(R.id.bt_clear);
/*Initialise SupportMapFragment
SupportMapFragment supportMapFragment = (SupportMapFragment)getSupportFragmentManager()
.findFragmentById(R.id.google_map);
supportMapFragment.getMapAsync(this);
btDraw.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Draw Polyline on Map
if (polyline!=null) polyline.remove();
//Create PolylineOptions
PolylineOptions polylineOptions = new PolylineOptions()
.addAll(latLngList).clickable(true);
polyline = gMap.addPolyline(polylineOptions);
setWidth();
}
});*/
//Initialise SupportMapFragment
SupportMapFragment supportMapFragment = (SupportMapFragment)getSupportFragmentManager()
.findFragmentById(R.id.google_map);
supportMapFragment.getMapAsync(this);
btDraw.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Draw Polyline on Map
if (polyline!=null) polyline.remove();
if(polylineOptions!=null){
//Create PolylineOptions
polyline = gMap.addPolyline(polylineOptions);
setWidth();
}
}
});
btClear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Clear All
if (polyline!=null) polyline.remove();
for(Marker marker: markerList) marker.remove();
latLngList.clear();
markerList.clear();
seekWidth.setProgress(3);
seekBlue.setProgress(0);
seekGreen.setProgress(0);
seekRed.setProgress(0);
}
});
seekRed.setOnSeekBarChangeListener(this);
seekGreen.setOnSeekBarChangeListener(this);
seekBlue.setOnSeekBarChangeListener(this);
}
private void setWidth() {
seekWidth.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
//Get Seekbar Progress
int width = seekWidth.getProgress();
if (polyline != null) {
//Set Polyline Width
polyline.setWidth(width);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
/*@Override
public void onMapReady(GoogleMap googleMap) {
/*gMap= googleMap;
gMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
//Create MarkerOptions
MarkerOptions markerOptions = new MarkerOptions().position(latLng);
//Create Marker
Marker marker = gMap.addMarker(markerOptions);
//Add Latlng and Marker
latLngList.add(latLng);
markerList.add(marker);
}
});
}*/
public void onMapReady(GoogleMap googleMap) {
gMap= googleMap;
gMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
//Create MarkerOptions
MarkerOptions markerOptions = new MarkerOptions().position(latLng);
//Create Marker
Marker marker = gMap.addMarker(markerOptions);
//Add Latlng and Marker
latLngList.add(latLng);
markerList.add(marker);
polylineOptions = new PolylineOptions().addAll(latLngList).clickable(true);
}
});
}
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
html" target="_blank">switch (seekBar.getId()){
case R.id.seek_red:
red = i;
break;
case R.id.seek_green:
green = i;
break;
case R.id.seek_blue:
blue= i;
break;
}
if(polyline !=null){
//Set Polyline Color
polyline.setColor(Color.rgb(red,green,blue));
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
误差如下:
2019-11-29 13:39:40.39120694-20694/com.example。poly E/AndroidRuntime:致命异常:主进程:com.example。poly,PID:20694 java.lang.NullPointerException:尝试调用虚拟方法'void com.google.android.gms.maps.model.Polyline'。在android.widget.ProgressBar.setProgressInternal(ProgressBar.java:1447)的android.Widgets.Progress中,在com.example.poly.MainActivity.onProgressChanged(mainActivitive.java:149)的空对象引用上使用“setColor(int)”,在android.widgetandroid.widget.AbsSeekBar.trackTouchEvent(AbsSeekBar.java:850)位于android.widget.AbsSeekBar.onTouchEvent(absseebar.java:760)位于android.view.view.view.dispatchTouchEvent(view.java:9943)位于android.view.ViewGroup.DispatchedTouchevent(ViewGroup.java:2669)位于andro.view.view.ViewGroup.Dispatch TransformedToucheven(ViewGroup.java:2358)(ViewGroup.java:2669)在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2358)在android.view.view.Group.dispatchTransformedTouchEvent(view.java:2669),在android.view.ViewGroup.Dispatch触摸Event(ViewGroup.java:2358),在android.view.ViewGroup.DispatchedTouchEnd(view.java:269),在android.view.ViewGroup.ViewGroup.dispatchTouchEvent(ViewGroup.java:2358)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2669)在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2358)在android.view.ViewGroup.DispatchtransformedTouCheEvent(view.java:2669),android.view.ViewGroup.DispatchedTouchevent(ViewGroup.java:2358),在android.view.ViewGroup.ViewGroupandroid.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:411)的android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2358)和android.app.Activity.Dispatch.TouchEvent的android.Interior.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1810)的androidx.appcompat.view.WindowCallbackWrapper.DispatcherEvent(WindowCallBackWrappers.java:69)的Dispatchtouch事件(Activity.java:3061)在android.view.ViewRootImpl$viewPostimInputStage.ProcessPointEvent(ViewRootImpl.java:4434)在android.view.view.dispatchPointerEvent(view.java:10163)在android.view.ViewRootImpl$viewsPostimInputstage.ProcesserEvent(DecorView.java:373)在android.view.ViewRootImpl$ViewPostimInputTage.onProcess(viewroot.java:4302)在andro.view.viewrotImpl$InputStage.交付(ViewRootImpl.java:3849)android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImp.java:3902)在android.view.ViewRootImpr$InputStageforward(ViewRootImpl.java:3868)在android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3995)在android.view.ViewRootImpl$InputStage.apply(viewRootImpr.java:3876)在Android.view.vieRootImpl$.java:4052应用android.view.ViewRootImpl$InputStage.deliver(ViewRootImpr.java:3849)在android.view.ViewRootImp$InputStageOnDelivertonExt(ViewRootImpl.java:3902)在android.view.ViewRootImpl$InputStage.forward(ViewRootCompl.java:3868)在android.;view.ViewRootImpl$InputStage.apply(ViewRootInfl.java:3876)在android。view.ViewRootImplandroid.view.ViewRootImpl.DeliveryInputEvent(ViewRootImp.java:6210)在android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6184)在android.view.ViewRootImpl.enqueueInputEvent在android.view.ViewRootimp.java:6145在android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent事件(ViewRootIncl.java:6313)在android.;view.InputEventReciper.DispatchInputEventRecependerandroid.view.InputEventReceiver。android.view.InputEventReceiver.ConsumedBatchedInputEvents(本机方法)在android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:6284)在android.view.ViewRootImpl$ConsumedbatchedInputRunnable.run(ViewRootImpl.java:6336)
这实际上可能是一个临时的修复或永久的,取决于为什么折线仍然为空的根本原因,但下面应该修复您的崩溃。
注意:我使用注释来解释下面代码的各个方面。
.
首先是更改下面的片段:
if(polyline!=null) /*Note that without the curly brace, the if statement will only be applied to the immediate code below, so in your case, polyline is still also null here as the if statement only applies to the comment which will be ignored by the compiler. */
//Set Polyline Width
polyline.setWidth(width);
到下面:
if(polyline!=null){ /*you should try and always use your opening and closing brace for readability. */
//Set Polyline Width
polyline.setWidth(width);
}
第二,你的车祸的主要原因是什么:
//Set Polyline Color
polyline.setColor(Color.rgb(red,green,blue)); /* you for got to place a check here which is why you get the crash because as at here, *polyline* is still null for some reasons. */
因此,将上面的代码段更改为下面的代码段:
if(polyline !=null){
//Set Polyline Color
polyline.setColor(Color.rgb(red,green,blue));
}
除此之外,正如@cricket_007所指出的:
就像您有<code>Polyline,Polyline=null
中,还添加以下内容:PolylineOptions:PolylineOptions=null
然后修改您的
支持地图碎片,
如下所示:
//Initialise SupportMapFragment
SupportMapFragment supportMapFragment = (SupportMapFragment)getSupportFragmentManager()
.findFragmentById(R.id.google_map);
supportMapFragment.getMapAsync(this);
btDraw.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Draw Polyline on Map
if (polyline!=null) polyline.remove();
if(polylineOptions!=null){
//Create PolylineOptions
polyline = gMap.addPolyline(polylineOptions);
setWidth();
}
}
});
然后这里:
@Override
public void onMapReady(GoogleMap googleMap) {
gMap= googleMap;
gMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
//Create MarkerOptions
MarkerOptions markerOptions = new MarkerOptions().position(latLng);
//Create Marker
Marker marker = gMap.addMarker(markerOptions);
//Add Latlng and Marker
latLngList.add(latLng);
markerList.add(marker);
polylineOptions = new PolylineOptions().addAll(latLngList).clickable(true);
}
});
}
由于您是Android的新手,如果您发现很难找到上述代码在代码中的位置,请简单复制例如
polyline.setColor(Color.rgb(red,green,blue));
然后导航到AndroidStudio中的编辑并导航到查找,请将其粘贴到那里以帮助您找到代码的确切位置。祝你好运编码。
...
新答案:
下面是完整的java类,包括所有需要的导入,只需复制和替换,因为它的包名称相同,其他一切都相同。
package com.example.poly;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
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.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;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, SeekBar.OnSeekBarChangeListener {
//Initialise variables
GoogleMap gMap;
SeekBar seekWidth, seekBlue, seekGreen, seekRed;
Button btClear, btDraw;
List<LatLng> latLngList = new ArrayList<>();
List<Marker> markerList = new ArrayList<>();
int red = 0, green= 0, blue=0;
Polyline polyline = null;
PolylineOptions polylineOptions = null;
private static int PERMISSION_LOCATION_STATE = 1001; //hopefully no other permission code conflict with this in the future, so watch out.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Assign variable
seekWidth = findViewById(R.id.seek_width);
seekRed = findViewById(R.id.seek_red);
seekGreen = findViewById(R.id.seek_green);
seekBlue = findViewById(R.id.seek_blue);
btDraw=findViewById(R.id.bt_draw);
btClear=findViewById(R.id.bt_clear);
/* We decide to put our function inside a runner that runs on UI thread to at least try to
* load the page before prompting users to allow location access, this will delay the prompt by 2 seconds.
* Note: it's actually not compulsory, so you can remove it either way, it will work.
* */
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mapPermissionCheck();
}
}, 2000);
btDraw.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Draw Polyline on Map
if (polyline!=null) polyline.remove();
if(polylineOptions!=null){
//Create PolylineOptions
polyline = gMap.addPolyline(polylineOptions);
setWidth();
}
}
});
btClear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Clear All
if (polyline!=null) polyline.remove();
for(Marker marker: markerList) marker.remove();
latLngList.clear();
markerList.clear();
seekWidth.setProgress(3);
seekBlue.setProgress(0);
seekGreen.setProgress(0);
seekRed.setProgress(0);
}
});
seekRed.setOnSeekBarChangeListener(this);
seekGreen.setOnSeekBarChangeListener(this);
seekBlue.setOnSeekBarChangeListener(this);
}
private void initSupportFragment() {
SupportMapFragment supportMapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.google_map);
if(supportMapFragment!=null){
supportMapFragment.getMapAsync(this);
}
}
private void mapPermissionCheck() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Initialise SupportMapFragment when we're sure permission is granted to access location, else Map will not be ready and mapReady() will never be called.
initSupportFragment();
}else{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_LOCATION_STATE);
}
}
private void setWidth() {
seekWidth.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
//Get Seekbar Progress
int width = seekWidth.getProgress();
if (polyline != null) {
//Set Polyline Width
polyline.setWidth(width);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
@Override
public void onMapReady(GoogleMap googleMap) {
gMap= googleMap;
gMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
//Create MarkerOptions
MarkerOptions markerOptions = new MarkerOptions().position(latLng);
//Create Marker
Marker marker = gMap.addMarker(markerOptions);
//Add Latlng and Marker
latLngList.add(latLng);
markerList.add(marker);
polylineOptions = new PolylineOptions().addAll(latLngList).clickable(true);
}
});
}
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
switch (seekBar.getId()){
case R.id.seek_red:
red = i;
break;
case R.id.seek_green:
green = i;
break;
case R.id.seek_blue:
blue= i;
break;
}
if(polyline !=null){
//Set Polyline Color
polyline.setColor(Color.rgb(red,green,blue));
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
/*
* Right below here is a permission callback method that get called when ever an action is taken on a permission prompt request
* So, if a user declined or accept, we can check and decide what to do next, in this case, we will try enforce the user to
* give us location access in case they declined at first since we can't do much without the permission.
* */
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PERMISSION_LOCATION_STATE) { // remember PERMISSION_LOCATION_STATE? check above on how we parse it.
if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
new AlertDialog.Builder(this)
.setTitle("Location Permission Needed")
.setMessage("Daniel Poly App Need Your Location Permission To Proceed.")
.setCancelable(false)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
mapPermissionCheck();
}
})
.show();
}else{ //Meaning permission finally granted....hurray!!!
initSupportFragment();
}
}
}
}
总之,你错过的是许可。有关详细信息,请阅读此内容。
我被代码卡住了,无法继续。模拟器崩溃,堆栈指向第47行。请帮助初学者! 堆栈错误: 致命的例外:主java。lang.NumberFormatException:无效的int:“t”在java中。整型。invalidInt(Integer.java:138)
问题内容: 我有以下代码: 在模拟器中工作正常。但是当我在手机上尝试时,它崩溃了。这是控制台: 这行: NSNumberFormatter()。numberFromString(display.text!)! 返回nil,这导致应用程序崩溃,导致无法打开可选包装。我真的不知道怎么了 我正在关注iTunes U中的一些教程。 任何帮助,将不胜感激。 问题答案: 尝试: 因为默认情况下使用设备区域设置
第一个屏幕上传权和工作正常(Toast和所有其他设置和参数),直到我尝试保存结果并通过相同的按钮打开新屏幕。按下按钮会使我手机中的应用程序崩溃,而不会打开第二个屏幕。然而,在模拟器中,一切正常。 这是主要的活动: 这是相关的XML: 这是第二个活动: 这是第二个XML: 这是日志猫错误: 致命异常:主< br >进程:com . example . rach mani . mythematix _
几周前我开始使用Android Studio。我在一个具有正常登录屏幕的应用程序上工作过,在模拟器上一切正常。但如果我尝试在我的三星Galaxy S7 Edge(Android 7.0)上运行该应用程序,该应用程序会立即崩溃。 我已经用API 23模拟了Nexus 5,当我用API 24模拟的Pixel尝试时,模拟器也会崩溃。所以我想问题取决于Android版本? Logcat(我把我正在使用的所
问题内容: 背景 我想在Jenkins上的不同模拟器上运行我的Android Instrumented测试。假设我有100个测试和4个仿真器,我想在每个仿真器上运行25个测试。 我在Jenkins Pipeline的并行处理中为4个模拟器执行 会产生其他命令,以便为运行已测试的测试设置环境。 当环境准备就绪时,它将执行,这将开始在模拟器上运行测试。 我不想对所有并行调用都运行这些过程(在这种情况下