Android MapView v2黑屏

时间:2013-07-11 21:31:31

标签: android android-mapview

我一直在尝试实现android的MapView v2。除了这个bug之外,我还能正常工作。

这是我从头开始加载应用程序时的样子... enter image description here

如您所见,那里没有问题。

现在,当我按下“主页”按钮并尝试从“最近的应用程序”窗口访问应用程序时,我得到: enter image description here

并保持这种状态,直到我解雇该应用并从头开始重新加载。

以下是我的一些代码。

Layout.xml

<LinearLayout
    android:id="@+id/maps_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment android:id="@+id/map"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:name="com.google.android.gms.maps.SupportMapFragment"
              android:layout_marginBottom="100dip"
              android:layout_marginLeft="10dip"
              android:layout_marginRight="10dip"
              android:layout_marginTop="100dip"/>

</LinearLayout>

活动:

public class MyActivity extends BaseActivity {

private GoogleMap mMaps;
private LinearLayout mMapsContainer;

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.my_layout);

    mMapsContainer = (LinearLayout) findViewById(R.id.maps_container);

    mMaps =((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();

}

@Override
public void onPause() {
    super.onPause();
}

@Override
public void onResume() {
    super.onResume();

    if (mMaps == null) {
        mMaps = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
    }

    getSupportFragmentManager().findFragmentById(R.id.map).onResume();
}

}

BaseActivity:

public abstract class BaseActivity extends FragmentActivity implements
    LocationListener,
    GooglePlayServicesClient.ConnectionCallbacks,
    GooglePlayServicesClient.OnConnectionFailedListener {


// A request to connect to Location Services
private LocationRequest mLocationRequest;

// Stores the current instantiation of the location client in this object
private LocationClient mLocationClient;

// Handle to SharedPreferences for this app
SharedPreferences mPrefs;

// Handle to a SharedPreferences editor
SharedPreferences.Editor mEditor;

boolean mUpdatesRequested = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Create a new global location parameters object
    mLocationRequest = LocationRequest.create();
    mLocationRequest.setInterval(LocationUtils.UPDATE_INTERVAL_IN_MILLISECONDS);

    // Use high accuracy
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    // Set the interval ceiling to one minute
    mLocationRequest.setFastestInterval(LocationUtils.FAST_INTERVAL_CEILING_IN_MILLISECONDS);

    // Note that location updates are off until the user turns them on
    mUpdatesRequested = false;

    // Open Shared Preferences
    mPrefs = getSharedPreferences(LocationUtils.SHARED_PREFERENCES, Context.MODE_PRIVATE);

    // Get an editor
    mEditor = mPrefs.edit();

    /*
     * Create a new location client, using the enclosing class to
     * handle callbacks.
     */
    mLocationClient = new LocationClient(this, this, this);

}


@Override
public void onStop() {

    // If the client is connected
    if (mLocationClient.isConnected()) {
        stopPeriodicUpdates();
    }

    // After disconnect() is called, the client is considered "dead".
    mLocationClient.disconnect();

    super.onStop();
}

@Override
public void onPause() {

    // Save the current setting for updates
    mEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED, mUpdatesRequested);
    mEditor.commit();

    super.onPause();
}


@Override
public void onStart() {

    super.onStart();

    /*
     * Connect the client. Don't re-start any requests here;
     * instead, wait for onResume()
     */
    mLocationClient.connect();

}


@Override
public void onResume() {
    super.onResume();

    // If the app already has a setting for getting location updates, get it
    if (mPrefs.contains(LocationUtils.KEY_UPDATES_REQUESTED)) {
        mUpdatesRequested = mPrefs.getBoolean(LocationUtils.KEY_UPDATES_REQUESTED, false);

        // Otherwise, turn off location updates until requested
    } else {
        mEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED, false);
        mEditor.commit();
    }

}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {

    // Choose what to do based on the request code
    switch (requestCode) {

        // If the request code matches the code sent in onConnectionFailed
        case LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST :

            switch (resultCode) {
                // If Google Play services resolved the problem
                case Activity.RESULT_OK:


                    break;

                // If any other result was returned by Google Play services
                default:
                    // Log the result


                    break;
            }

            // If any other request code was received
        default:
            // Report that this Activity received an unknown requestCode
            Log.d(LocationUtils.APPTAG,
                    getString(R.string.unknown_activity_request_code, requestCode));

            break;
    }
}


private boolean servicesConnected() {

    // Check that Google Play services is available
    int resultCode =
            GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

    // If Google Play services is available
    if (ConnectionResult.SUCCESS == resultCode) {
        // In debug mode, log the status
        Log.d(LocationUtils.APPTAG, getString(R.string.play_services_available));

        // Continue
        return true;
        // Google Play services was not available for some reason
    } else {
        // Display an error dialog
        Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode, this, 0);
        if (dialog != null) {
            ErrorDialogFragment errorFragment = new ErrorDialogFragment();
            errorFragment.setDialog(dialog);
           // errorFragment.show(getSupportFragmentManager(), LocationUtils.APPTAG);
        }
        return false;
    }
}

public void getAddress(View v) {


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD && !Geocoder.isPresent()) {
        // No geocoder is present. Issue an error message
        Toast.makeText(this, R.string.no_geocoder_available, Toast.LENGTH_LONG).show();
        return;
    }

    if (servicesConnected()) {

        // Get the current location
        Location currentLocation = mLocationClient.getLastLocation();


        // Start the background task
        (new GetAddressTask(this)).execute(currentLocation);
    }
}


public void startUpdates(View v) {
    mUpdatesRequested = true;

    if (servicesConnected()) {
        startPeriodicUpdates();
    }
}


public void stopUpdates(View v) {
    mUpdatesRequested = false;

    if (servicesConnected()) {
        stopPeriodicUpdates();
    }
}

@Override
public void onConnected(Bundle bundle) {
    if (mUpdatesRequested) {
        startPeriodicUpdates();
    }

    EventBus.getDefault().post(new EventMessage().new LocationServicesConnected());
}


@Override
public void onDisconnected() {
}


@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

    if (connectionResult.hasResolution()) {
        try {

            // Start an Activity that tries to resolve the error
            connectionResult.startResolutionForResult(
                    this,
                    LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);


        } catch (IntentSender.SendIntentException e) {
            e.printStackTrace();
        }
    } else {

        // If no resolution is available, display a dialog to the user with the error.
        showErrorDialog(connectionResult.getErrorCode());
    }
}

@Override
public void onLocationChanged(Location location) {
    EventBus.getDefault().post(new EventMessage().new LocationChangedEvent(location));
}


private void startPeriodicUpdates() {
    mLocationClient.requestLocationUpdates(mLocationRequest, this);
}


private void stopPeriodicUpdates() {
    mLocationClient.removeLocationUpdates(this);
}


protected class GetAddressTask extends AsyncTask<Location, Void, String> {

    // Store the context passed to the AsyncTask when the system instantiates it.
    Context localContext;

    // Constructor called by the system to instantiate the task
    public GetAddressTask(Context context) {

        // Required by the semantics of AsyncTask
        super();

        // Set a Context for the background task
        localContext = context;
    }


    @Override
    protected String doInBackground(Location... params) {

        Geocoder geocoder = new Geocoder(localContext, Locale.getDefault());

        // Get the current location from the input parameter list
        Location location = params[0];

        // Create a list to contain the result address
        List<Address> addresses = null;

        // Try to get an address for the current location. Catch IO or network problems.
        try {

            /*
             * Call the synchronous getFromLocation() method with the latitude and
             * longitude of the current location. Return at most 1 address.
             */
            addresses = geocoder.getFromLocation(location.getLatitude(),
                    location.getLongitude(), 1
            );

            // Catch network or other I/O problems.
        } catch (IOException exception1) {

            // Log an error and return an error message
            Log.e(LocationUtils.APPTAG, getString(R.string.IO_Exception_getFromLocation));

            // print the stack trace
            exception1.printStackTrace();

            // Return an error message
            return (getString(R.string.IO_Exception_getFromLocation));

            // Catch incorrect latitude or longitude values
        } catch (IllegalArgumentException exception2) {

            // Construct a message containing the invalid arguments
            String errorString = getString(
                    R.string.illegal_argument_exception,
                    location.getLatitude(),
                    location.getLongitude()
            );
            // Log the error and print the stack trace
            Log.e(LocationUtils.APPTAG, errorString);
            exception2.printStackTrace();

            //
            return errorString;
        }
        // If the reverse geocode returned an address
        if (addresses != null && addresses.size() > 0) {

            // Get the first address
            Address address = addresses.get(0);

            // Format the first line of address
            String addressText = getString(R.string.address_output_string,

                    // If there's a street address, add it
                    address.getMaxAddressLineIndex() > 0 ?
                            address.getAddressLine(0) : "",

                    // Locality is usually a city
                    address.getLocality(),

                    // The country of the address
                    address.getCountryName()
            );

            // Return the text
            return addressText;

            // If there aren't any addresses, post a message
        } else {
            return getString(R.string.no_address_found);
        }
    }

    /**
     * A method that's called once doInBackground() completes. Set the text of the
     * UI element that displays the address. This method runs on the UI thread.
     */
    @Override
    protected void onPostExecute(String address) {
    }
}

/**
 * Show a dialog returned by Google Play services for the
 * connection error code
 *
 * @param errorCode An error code returned from onConnectionFailed
 */
private void showErrorDialog(int errorCode) {

    // Get the error dialog from Google Play services
    Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
            errorCode,
            this,
            LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);

    // If Google Play services can provide an error dialog
    if (errorDialog != null) {

        // Create a new DialogFragment in which to show the error dialog
        ErrorDialogFragment errorFragment = new ErrorDialogFragment();

        // Set the dialog in the DialogFragment
        errorFragment.setDialog(errorDialog);

        // Show the error dialog in the DialogFragment
       // errorFragment.show(getSupportFragmentManager(), LocationUtils.APPTAG);
    }
}

/**
 * Define a DialogFragment to display the error dialog generated in
 * showErrorDialog.
 */
public static class ErrorDialogFragment extends DialogFragment {

    // Global field to contain the error dialog
    private Dialog mDialog;

    /**
     * Default constructor. Sets the dialog field to null
     */
    public ErrorDialogFragment() {
        super();
        mDialog = null;
    }

    /**
     * Set the dialog to display
     *
     * @param dialog An error dialog
     */
    public void setDialog(Dialog dialog) {
        mDialog = dialog;
    }

    /*
     * This method must return a Dialog to the DialogFragment.
     */
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return mDialog;
    }
}

}

2 个答案:

答案 0 :(得分:3)

我在文件manifest.xml上禁用硬件加速,我的应用程序在第二次加载时不再显示黑色地图。我在模拟器中尝试。

<application android:hardwareAccelerated="false">
 ...
</application

来自这篇文章:http://developer.android.com/guide/topics/graphics/hardware-accel.html

答案 1 :(得分:0)

有点晚了但是,我发现WebViews(甚至在其他片段上)有时会“崩溃”GL引擎或导致MapView中出现黑屏的东西。我在LogCat中找到了这个:

09-30 10:58:17.765: E/libEGL(29805): call to OpenGL ES API with no current context (logged once per thread)
09-30 10:58:17.765: W/Adreno200-EGL(29805): <qeglDrvAPI_eglSwapBuffers:3421>: EGL_BAD_CONTEXT
09-30 10:58:17.765: W/HardwareRenderer(29805): EGL error: EGL_BAD_CONTEXT
09-30 10:58:17.775: W/HardwareRenderer(29805): Mountain View, we've had a problem here.

切换回软件渲染。 要在分离WebView时修复此问题,我在片段中调用destroy函数:

@Override
public void onDestroyView() {
    if (webView != null) {
        webView.destroy();
        webView = null;
    }
    super.onDestroyView();
}

也许它会给你一个解决这个问题的方向。