我能够将位置(字符串地址)+消息发送到我的服务器;但是,我的应用程序在将数据发送到服务器后崩溃了。我使用Volley库发出POST请求。有人可以帮我解决这个问题吗?
首先,我获取地址和地址列表。
public class MainActivity extends AppCompatActivity {
//Declare LocationManager and LocationListener
LocationManager locationManager;
LocationListener locationListener;
String address = "Unable to get the address!";
EditText Message;
AlertDialog.Builder builder;
String server_url ="https://schoolserver-tand089.c9users.io/Report.php";
//Process when users give the permission
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Start the location service
startListening();
}
}
//Checking permission granted method
public void startListening() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
}
}
//Update location method. 1 variable location
public void updatedLocationInfo(Location location) {
Log.i ("Location", location.toString());
//Cast the textViews
TextView latTextView = (TextView) findViewById(R.id.txtLat);
TextView lonTextView = (TextView) findViewById(R.id.txtLong);
TextView altTextView = (TextView) findViewById(R.id.txtAltitude);
TextView accTextView = (TextView) findViewById(R.id.txtAccuracy);
//get the string from location
latTextView.setText("Latitude: " + location.getLatitude());
lonTextView.setText("Longitude: " + location.getLongitude());
altTextView.setText("Altitude: " + location.getAltitude());
accTextView.setText("Accuracy: " + location.getAccuracy());
//Create Geocoder object to Get the address
Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
//Using try/catch to prevent the app from crashing when failing to get Addresses
try {
//Declare the error string
//String address = "Unable to get the address!";
List<Address> listAddresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
//Check if the address is valid
if (listAddresses != null && listAddresses.size() > 0) {
//Set address to empty string again when we know it is working
address = "Address: \n";
// Log.i("Address", listAddresses.get(0).toString());
//check for every item in the list Addresses is valid
if (listAddresses.get(0).getSubThoroughfare() != null) {
address += listAddresses.get(0).getSubThoroughfare() + " ";
}
//Street name
if (listAddresses.get(0).getThoroughfare() != null) {
address += listAddresses.get(0).getThoroughfare() + "\n";
}
//City name
if (listAddresses.get(0).getLocality() != null) {
address += listAddresses.get(0).getLocality() + "\n";
}
//Zip code
if (listAddresses.get(0).getPostalCode() != null) {
address += listAddresses.get(0).getPostalCode() + "\n";
}
//Country name
if (listAddresses.get(0).getCountryName() != null) {
address += listAddresses.get(0).getCountryName() + "\n";
}
TextView addressTextView = (TextView) findViewById(R.id.txtAddress);
//set the address into the text View
addressTextView.setText(address);
//Log.i("Address", address.toString());
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//set up locationManager and locationListener above and cast them into their type
//Using built-in location service
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
//Get the location when it changes
@Override
public void onLocationChanged(Location location) {
//call the updated location above
updatedLocationInfo(location);
}
//
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
//Check for the version of SDK
if (Build.VERSION.SDK_INT < 23) {
startListening();
} else {
// above 23 we need to check for permission
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//ask for permission. Number 1 is just a request queue.
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}
//we have permission
else {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
//Get the last location from the built-in GPS
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//In case location does not have lastknownlocation, we call the updatedLocation method above
if (location != null) {
updatedLocationInfo(location);
}
}
}
}
接下来,当用户点击按钮时,我使用onClick方法向服务器发送地址和消息。
// using onClick
public void bntTap (View bnt) {
Message = (EditText) findViewById(R.id.message);
//Hide virtual keyboard after click the button
InputMethodManager inputManager = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
final String message;
message = Message.getText().toString();
if (message.equals("")) {
builder.setTitle("Unable to report");
//Creating a AlertDialog to display errors
AlertDialog alertDialog = builder.create();
alertDialog.setMessage("Please Enter All Required Fields*");
alertDialog.show();
} else {
//Post request
StringRequest stringRequest = new StringRequest(Request.Method.POST, server_url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
//get response form server to check if it is successfully submitted
builder.setTitle("Server Response");
builder.setMessage("Congratulation" + " " + response);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Message.setText("");
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, "Error!!!", Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
//send data to mySQL server
//the keys must be same as field names in mySQL server
// get the list of the address
params.put("LOCATION", address);
params.put("MESSAGES", message);
return params;
}
};
MySingleton.getInstance(MainActivity.this).addTorequestqueue(stringRequest);
//Log.i("Address", address.toString());
}
}
所有数据都成功发送到服务器,但应用程序崩溃了。
更新:崩溃时的logcat logcat when crashing
答案 0 :(得分:0)
您收到NPE
,因为您忘记定义builder
。您只在代码中将其声明为
AlertDialog.Builder builder;
请将构建器定义为
builder = new AlertDialog.Builder(MainActivity.this);
在onCreate()
。