【发布时间】:2021-08-24 03:59:56
【问题描述】:
gradle的时候没有报错。当它安装在虚拟机上时,程序无法运行并显示以下错误。这是代码。这是 Android 开发。
MainActivity.java
package com.example.app;
import java.util.List;
import android.annotation.SuppressLint;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.content.Intent;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import com.esri.arcgisruntime.data.ArcGISFeature;
import com.esri.arcgisruntime.data.FeatureEditResult;
import com.esri.arcgisruntime.loadable.LoadStatus;
import com.esri.arcgisruntime.mapping.Basemap;
import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.layers.ArcGISTiledLayer;
import com.esri.arcgisruntime.data.ServiceFeatureTable;
import com.esri.arcgisruntime.layers.FeatureLayer;
import com.esri.arcgisruntime.mapping.ArcGISMap;
import com.esri.arcgisruntime.mapping.GeoElement;
import com.esri.arcgisruntime.mapping.Viewpoint;
import com.esri.arcgisruntime.mapping.view.Callout;
import com.esri.arcgisruntime.mapping.view.DefaultMapViewOnTouchListener;
import com.esri.arcgisruntime.mapping.view.IdentifyLayerResult;
import com.esri.arcgisruntime.mapping.view.MapView;
import com.google.android.material.snackbar.Snackbar;
import android.app.ProgressDialog;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private MapView mMapView;
private Callout mCallout;
private ArcGISFeature mSelectedArcGISFeature;
private static final String TAG = MainActivity.class.getSimpleName();
private android.graphics.Point mClickPoint;
private Snackbar mSnackbarSuccess;
private Snackbar mSnackbarFailure;
private String mSelectedArcGISFeatureAttributeValue;
private boolean mFeatureUpdated;
private View mCoordinatorLayout;
private ProgressDialog mProgressDialog;
private ServiceFeatureTable mServiceFeatureTable;
private FeatureLayer mFeatureLayer;
@SuppressLint("ClickableViewAccessibility")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMapView = findViewById(R.id.mapView);
String url = "http://map.geoq.cn/arcgis/rest/services/ChinaOnlineCommunity/MapServer";
ArcGISTiledLayer arcGISTiledLayer = new ArcGISTiledLayer(url);
Basemap basemap = new Basemap(arcGISTiledLayer);
ArcGISMap arcGISMap = new ArcGISMap(basemap);
mCallout = mMapView.getCallout();
ServiceFeatureTable mServiceFeatureTable = new ServiceFeatureTable("http://192.168.1.103:6080/arcgis/rest/services/huda1/MapServer/0");
FeatureLayer featureLayer = new FeatureLayer(mServiceFeatureTable);
arcGISMap.getOperationalLayers().add(featureLayer);
mFeatureLayer.setOpacity(0.8f);*/
mMapView.setMap(arcGISMap);
mMapView.setViewpoint(new Viewpoint(30.577421, 114.331955, 10000));
//set an on touch listener to listen for click events
// set an on touch listener to listen for click events
mMapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this, mMapView) {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// get the point that was clicked and convert it to a point in map coordinates
mClickPoint = new android.graphics.Point((int) e.getX(), (int) e.getY());
// clear any previous selection
mFeatureLayer.clearSelection();
mSelectedArcGISFeature = null;
mCallout.dismiss();
// identify the GeoElements in the given layer
final ListenableFuture<IdentifyLayerResult> identifyFuture = mMapView
.identifyLayerAsync(mFeatureLayer, mClickPoint, 5, false, 1);
// add done loading listener to fire when the selection returns
identifyFuture.addDoneListener(() -> {
try {
// call get on the future to get the result
IdentifyLayerResult layerResult = identifyFuture.get();
List<GeoElement> resultGeoElements = layerResult.getElements();
if (!resultGeoElements.isEmpty()) {
if (resultGeoElements.get(0) instanceof ArcGISFeature) {
mSelectedArcGISFeature = (ArcGISFeature) resultGeoElements.get(0);
// highlight the selected feature
mFeatureLayer.selectFeature(mSelectedArcGISFeature);
// show callout with the value for the attribute "typdamage" of the selected feature
mSelectedArcGISFeatureAttributeValue = (String) mSelectedArcGISFeature.getAttributes()
.get("typdamage");
showCallout(mSelectedArcGISFeatureAttributeValue);
Toast.makeText(MainActivity.this, "Tap on the info button to change attribute value",
Toast.LENGTH_SHORT).show();
}
} else {
// none of the features on the map were selected
mCallout.dismiss();
}
} catch (Exception e1) {
Log.e(TAG, "Select feature failed: " + e1.getMessage());
}
});
return super.onSingleTapConfirmed(e);
}
});
mSnackbarSuccess = Snackbar
.make(mCoordinatorLayout, "Feature successfully updated", Snackbar.LENGTH_LONG)
.setAction("UNDO", view -> {
String snackBarText = updateAttributes(mSelectedArcGISFeatureAttributeValue) ?
"Feature is restored!" :
"Feature restore failed!";
Snackbar snackbar1 = Snackbar.make(mCoordinatorLayout, snackBarText, Snackbar.LENGTH_SHORT);
snackbar1.show();
});
mSnackbarFailure = Snackbar.make(mCoordinatorLayout, "Feature update failed", Snackbar.LENGTH_LONG);
}
/**
* Function to read the result from newly created activity
*/
@Override
protected void onActivityResult(int requestCode,
int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == 100) {
// display progress dialog while updating attribute callout
mProgressDialog.show();
updateAttributes(data.getStringExtra("typdamage"));
}
}
/**
* Applies changes to the feature, Service Feature Table, and server.
*/
private boolean updateAttributes(final String typeDamage) {
// load the selected feature
mSelectedArcGISFeature.loadAsync();
// update the selected feature
mSelectedArcGISFeature.addDoneLoadingListener(() -> {
if (mSelectedArcGISFeature.getLoadStatus() == LoadStatus.FAILED_TO_LOAD) {
Log.e(TAG, "Error while loading feature");
}
// update the Attributes map with the new selected value for "typdamage"
mSelectedArcGISFeature.getAttributes().put("typdamage", typeDamage);
try {
// update feature in the feature table
ListenableFuture<Void> mapViewResult = mServiceFeatureTable.updateFeatureAsync(mSelectedArcGISFeature);
/*mServiceFeatureTable.updateFeatureAsync(mSelectedArcGISFeature).addDoneListener(new Runnable() {*/
mapViewResult.addDoneListener(() -> {
// apply change to the server
final ListenableFuture<List<FeatureEditResult>> serverResult = mServiceFeatureTable.applyEditsAsync();
serverResult.addDoneListener(() -> {
try {
// check if server result successful
List<FeatureEditResult> edits = serverResult.get();
if (!edits.isEmpty()) {
if (!edits.get(0).hasCompletedWithErrors()) {
Log.e(TAG, "Feature successfully updated");
mSnackbarSuccess.show();
mFeatureUpdated = true;
}
} else {
Log.e(TAG, "The attribute type was not changed");
mSnackbarFailure.show();
mFeatureUpdated = false;
}
if (mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
// display the callout with the updated value
showCallout((String) mSelectedArcGISFeature.getAttributes().get("typdamage"));
}
} catch (Exception e) {
Log.e(TAG, "applying changes to the server failed: " + e.getMessage());
}
});
});
} catch (Exception e) {
Log.e(TAG, "updating feature in the feature table failed: " + e.getMessage());
}
});
return mFeatureUpdated;
}
/**
* Displays Callout
*
* @param title the text to show in the Callout
*/
private void showCallout(String title) {
// create a text view for the callout
RelativeLayout calloutLayout = new RelativeLayout(getApplicationContext());
TextView calloutContent = new TextView(getApplicationContext());
calloutContent.setId(R.id.textview);
calloutContent.setTextColor(Color.BLACK);
calloutContent.setTextSize(18);
calloutContent.setPadding(0, 10, 10, 0);
calloutContent.setText(title);
RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
relativeParams.addRule(RelativeLayout.RIGHT_OF, calloutContent.getId());
// create image view for the callout
ImageView imageView = new ImageView(getApplicationContext());
imageView
.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_info_outline_black_18dp));
imageView.setLayoutParams(relativeParams);
imageView.setOnClickListener(new ImageViewOnclickListener());
calloutLayout.addView(calloutContent);
calloutLayout.addView(imageView);
mCallout.setGeoElement(mSelectedArcGISFeature, null);
mCallout.setContent(calloutLayout);
mCallout.show();
}
@Override
protected void onPause() {
mMapView.pause();
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
mMapView.resume();
}
@Override
protected void onDestroy() {
mMapView.dispose();
super.onDestroy();
}
/**
* Defines the listener for the ImageView clicks
*/
private class ImageViewOnclickListener implements View.OnClickListener {
@Override public void onClick(View v) {
Intent myIntent = new Intent(MainActivity.this, DamageTypesListActivity.class);
startActivityForResult(myIntent, 100);
}
}
}
DamageTypesListActivity.java
package com.example.app;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
/**
* Displays the Damage type options in a ListView.
*/
public class DamageTypesListActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.damage_types_listview);
final String[] damageTypes = getResources().getStringArray(R.array.damage_types);
ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(new ArrayAdapter<>(this, R.layout.damage_types, damageTypes));
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent myIntent = new Intent();
myIntent.putExtra("typdamage", damageTypes[position]); //Optional parameters
setResult(100, myIntent);
finish();
}
});
}
@Override
public void onBackPressed() {
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app">
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.DisplayAMapJava">
<activity
android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".DamageTypesListActivity"
android:label="@string/select_damage_Type">
</activity>
</application>
</manifest>
字符串.xml
<resources>
<string name="app_name">Display a map java</string>
<string name="select_damage_Type">"Select new damage type"</string>
<!-- Progress dialog messages -->
<string name="progress_title">Updating attribute type</string>
<string name="progress_message">Please wait…</string>
<!-- Sample Strings -->
<string name="sample_service_url">https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer/0</string>
<string-array name="damage_types">
<item>Destroyed</item>
<item>Major</item>
<item>Minor</item>
<item>Affected</item>
<item>Inaccessible</item>
</string-array>
</resources>
下面是logcat消息
AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.app, PID: 21571
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.app/com.example.app.MainActivity}: java.lang.IllegalArgumentException: No suitable parent found from the given view. Please provide a valid view.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.IllegalArgumentException: No suitable parent found from the given view. Please provide a valid view.
at com.google.android.material.snackbar.Snackbar.make(Snackbar.java:158)
at com.example.app.MainActivity.onCreate(MainActivity.java:137)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
【问题讨论】:
-
您在使用
SnackBar之前没有初始化mCoordinatorLayout视图 -
如何操作?请说的具体点。谢谢。我看过上面的文章,和他的问题不一样。
标签: java android android-snackbar