0

我的 android 应用程序有一个奇怪的问题。我实现了地图,我得到了应该完成的 api-key,将它插入到我的应用程序中......当我通过 Eclipse 直接在手机上启动应用程序时,它可以工作。当我将应用程序导出到 apk 并将其传递给朋友以便在其他手机上进行测试时,地图永远不会显示并且应用程序崩溃,因为 mapController 为 null:

07-24 14:52:07.425: E/AndroidRuntime(4107): FATAL EXCEPTION: main
07-24 14:52:07.425: E/AndroidRuntime(4107): java.lang.NullPointerException
07-24 14:52:07.425: E/AndroidRuntime(4107):     at com.google.android.maps.MapController.animateTo(MapController.java:232)
07-24 14:52:07.425: E/AndroidRuntime(4107):     at com.google.android.maps.MapController.animateTo(MapController.java:203)
07-24 14:52:07.425: E/AndroidRuntime(4107):     at com.emaborsa.cablePark.activities.MainActivity$5.onItemClick(MainActivity.java:492)
07-24 14:52:07.425: E/AndroidRuntime(4107):     at com.emaborsa.cablePark.popUpMenu.MapPopupMenu$1.onClick(MapPopupMenu.java:163)
07-24 14:52:07.425: E/AndroidRuntime(4107):     at android.view.View.performClick(View.java:4084)
07-24 14:52:07.425: E/AndroidRuntime(4107):     at android.view.View$PerformClick.run(View.java:16966)
07-24 14:52:07.425: E/AndroidRuntime(4107):     at android.os.Handler.handleCallback(Handler.java:615)
07-24 14:52:07.425: E/AndroidRuntime(4107):     at android.os.Handler.dispatchMessage(Handler.java:92)
07-24 14:52:07.425: E/AndroidRuntime(4107):     at android.os.Looper.loop(Looper.java:137)
07-24 14:52:07.425: E/AndroidRuntime(4107):     at android.app.ActivityThread.main(ActivityThread.java:4745)
07-24 14:52:07.425: E/AndroidRuntime(4107):     at java.lang.reflect.Method.invokeNative(Native Method)
07-24 14:52:07.425: E/AndroidRuntime(4107):     at java.lang.reflect.Method.invoke(Method.java:511)
07-24 14:52:07.425: E/AndroidRuntime(4107):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
07-24 14:52:07.425: E/AndroidRuntime(4107):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
07-24 14:52:07.425: E/AndroidRuntime(4107):     at dalvik.system.NativeStart.main(Native Method)

编码:

public class MainActivity extends MapActivity {



/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.e("Log", "onCreate()");

    this.application = (CableParkApplication) getApplication();
    database = new DatabaseManager(getApplicationContext());

    if (getWindowManager().getDefaultDisplay().getRotation() == VERTICAL) {
        setContentView(R.layout.main_v);
    } else {
        setContentView(R.layout.main_h);
    }

    if (savedInstanceState != null) {
        this.currentView = savedInstanceState.getInt(CURRENT_VIEW);
        this.mapType = savedInstanceState.getBoolean(MAP_TYPE);
        this.country = savedInstanceState.getString(COUNTRY);
        showMapMenu((LinearLayout) ((ImageView) mapViewContainer.findViewById(R.id.map_menu_open)).getParent());
    }

    initViews();

    myLocationOverlay = new MyLocationOverlay(getApplicationContext(), mapView);
    mapView.getOverlays().add(myLocationOverlay);
    mapHandler = new MapHandler(this, mapView);
    mapHandler.initMap(mapType);
    addListeners();

    showActualFrame();

}

protected void initViews() {
    // initializes main view
    mainView = (LinearLayout) findViewById(R.id.mainView);
    LinearLayout main_view_vertical = (LinearLayout) getLayoutInflater().inflate(R.layout.mainview_v, null);
    mainView.addView(main_view_vertical);

    // initializes search view
    searchMainView = (LinearLayout) findViewById(R.id.searchView);
    LinearLayout search_view_vertical = (LinearLayout) getLayoutInflater().inflate(R.layout.searchview_v, null);
    searchMainView.addView(search_view_vertical);
    searchTextCountry = (TextView) findViewById(R.id.selectCountry);
    selectCountryFlag = (ImageView) searchMainView.findViewById(R.id.selectCountryFlag);
    searchEditTextKey = (EditText) findViewById(R.id.searchEditTextKey);
    searchTextView = (TextView) findViewById(R.id.searchTextView);
    searchButton = (LinearLayout) findViewById(R.id.searchButton);

    if (country != null && !country.equals("")) {
        searchTextCountry.setText(country);
        String flag = country.toLowerCase().replace(" ", "");
        int resId = getResources().getIdentifier(flag, "drawable", CableParkApplication.PACKAGE);
        selectCountryFlag.setImageResource(resId);
    }

    // initializes diary view
    diaryMainView = (LinearLayout) findViewById(R.id.diaryView);
    LinearLayout diary_view_vertical = (LinearLayout) getLayoutInflater().inflate(R.layout.diaryview_v, null);
    diaryMainView.addView(diary_view_vertical);

    // initializes map(container) view
    mapViewContainer = (LinearLayout) findViewById(R.id.mapViewContainer);
    LinearLayout map_view_container_vertical = (LinearLayout) getLayoutInflater().inflate(R.layout.mapviewcontainer_v, null);
    mapViewContainer.addView(map_view_container_vertical);
    mapView = (MapView) findViewById(R.id.mapView);

    if (!application.isLoaded()) {
        application.setLoaded(true);
        Animation myFadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.fadein);
        myFadeInAnimation.setAnimationListener(new SplashAnimation(MainActivity.this, getWindowManager().getDefaultDisplay()
                .getRotation()));
        mainView.startAnimation(myFadeInAnimation);
    } else {
        findViewById(R.id.buttonsLayout).setVisibility(View.VISIBLE);
        findViewById(R.id.id).setVisibility(View.INVISIBLE);
    }

    // initializes bottom buttons
    searchImageLayout = (LinearLayout) findViewById(R.id.searchImageLayout);
    mapImageLayout = ((LinearLayout) findViewById(R.id.mapImageLayout));
    diaryImageLayout = ((LinearLayout) findViewById(R.id.diaryImageLayout));

}

private void addListeners() {

    searchButton.setOnTouchListener(new View.OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                searchButton.setBackgroundResource(R.drawable.singlebuttondown);
                searchTextView.setTextColor(Color.YELLOW);
                return true;
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                searchButton.setBackgroundResource(R.drawable.singlebutton);
                searchTextView.setTextColor(getResources().getColor(R.color.gray));
                if (doSearch()) {
                    showSearchResult();
                    hideSoftPad();
                    showMap(null);
                } else {
                    showNoResultDialog();
                }
                return true;
            }
            return false;
        }
    });

    searchEditTextKey.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            if (searchEditTextKey.getText().toString().equals("....?")) {
                searchEditTextKey.setText("");
            }
        }
    });

    searchEditTextKey.setOnEditorActionListener(new TextView.OnEditorActionListener() {

        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                if (doSearch()) {
                    showSearchResult();
                    hideSoftPad();
                    showMap(null);
                } else {
                    showNoResultDialog();
                }
                return true;
            }
            return false;
        }
    });

}

protected void showActualFrame() {

    switch (currentView) {
    case SEARCH:
        showSearch(searchMainView);
        break;
    case MAP:
        showMap(mapView);
        break;
    case DIARY:
        showDiary(diaryMainView);
        break;
    default:
        showFrame(mainView);
    }
}

@Override
protected void onResume() {
    Log.e("Log", "onResume()");
    broadcastReceiver = new MessageReceiver();
    IntentFilter inFilter = new IntentFilter();
    inFilter.addAction(CableParkApplication.CANCEL);
    inFilter.addAction(CableParkApplication.COUNTRY);
    inFilter.addAction(CableParkApplication.SINGLE_PARK);
    registerReceiver(broadcastReceiver, inFilter);
    super.onResume();
    myLocationOverlay.enableMyLocation();
    myLocationOverlay.enableCompass();
};

@Override
protected void onPause() {
    unregisterReceiver(broadcastReceiver);
    this.zoomLevel = mapView.getZoomLevel();
    this.mapCenter = mapView.getMapCenter();
    super.onPause();
    myLocationOverlay.disableMyLocation();
    myLocationOverlay.disableCompass();
    Log.e("Log", "onPause()");
}

// customized the onBackButton
@Override
public void onBackPressed() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Leave?").setCancelable(false).setMessage("Close the application?").setCancelable(true)
            .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    finish();
                }
            }).setNegativeButton("No", null);
    AlertDialog dialog = builder.create();
    dialog.show();
}

@Override
protected boolean isRouteDisplayed() {
    return false;
}

public void showSearch(View v) {
    mapView.removeAllViews();
    currentView = SEARCH;
    searchEditTextKey.setText("");
    setBackground(searchImageLayout);
    showFrame(searchMainView);
}

public void showMap(View v) {
    currentView = MAP;
    setBackground(mapImageLayout);
    showFrame(mapViewContainer);
    mapView.setVisibility(View.VISIBLE);
}

public void showDiary(View v) {
    mapView.removeAllViews();
    currentView = DIARY;
    setBackground(diaryImageLayout);
    showFrame(diaryMainView);
}

protected void showFrame(View view) {
    mainView.setVisibility(View.INVISIBLE);
    mapView.setVisibility(View.INVISIBLE);
    mapViewContainer.setVisibility(View.INVISIBLE);
    diaryMainView.setVisibility(View.INVISIBLE);
    searchMainView.setVisibility(View.INVISIBLE);
    view.setVisibility(View.VISIBLE);
}

protected void setBackground(LinearLayout layout) {
    searchImageLayout.setBackgroundResource(R.drawable.buttons);
    mapImageLayout.setBackgroundResource(R.drawable.buttons);
    diaryImageLayout.setBackgroundResource(R.drawable.buttons);
    layout.setBackgroundResource(R.drawable.buttonsdown);
}


private boolean doSearch() {
    String key = searchEditTextKey.getText().toString();
    String country = (String) searchTextCountry.getText();
    database.connectForReading();
    Vector<Park> parks = database.getParks(country, key);
    database.disconnect();
    application.setParkSearch(parks);
    return parks.size() > 0;
}

private void showSearchResult() {
    Vector<Park> parks = application.getParkSearch();
    mapHandler.drawGeopoints(parks);
    CenterGeoPointCalculator cgpc = new CenterGeoPointCalculator(parks);
    cgpc.calc();
    mapHandler.centerMap(cgpc, getWindowManager().getDefaultDisplay().getRotation());
    mapView.getController().animateTo(cgpc.getCenterPoint());

}

public void showCountriesDialog(View v) {
    searchTextCountry.setTextColor(Color.YELLOW);
    CountriesAdapter adapter = new CountriesAdapter(MainActivity.this, application.getCountries());
    dialog = new CountriesDialog(MainActivity.this, adapter);
    dialog.show();

}

public void showNoResultDialog() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage("No parks found.\nTry another country or another search key.").setCancelable(false)
            .setNegativeButton("OK", null);
    AlertDialog alert = builder.create();
    alert.show();
}

private class MessageReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action.equals(CableParkApplication.COUNTRY)) {
            country = intent.getStringExtra("country");
            searchTextCountry.setText(country);
            String flag = country.toLowerCase().replace(" ", "");
            int resId = context.getResources().getIdentifier(flag, "drawable", CableParkApplication.PACKAGE);
            selectCountryFlag.setImageResource(resId);
            searchTextCountry.setTextColor(Color.WHITE);
            dialog.dismiss();

        } else if (action.equals(CableParkApplication.COUNTRY)) {
            searchTextCountry.setTextColor(Color.WHITE);
            dialog.dismiss();

        } else if (action.equals(CableParkApplication.SINGLE_PARK)) {
            int parkId = intent.getIntExtra("park", -1);
            if (parkId > 0) {
                mapView.removeAllViews();
                Intent i = new Intent(context, SinglePark.class);
                i.putExtra("park", parkId);
                startActivity(i);
            }

        }
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    Log.e("Log", "onSaveInstanceState()");
    super.onSaveInstanceState(outState);
    if (popupMenu != null) {
        popupMenu.dismiss();
    }
    outState.putInt(CURRENT_VIEW, currentView);
    outState.putBoolean(MAP_TYPE, mapType);
    outState.putString(COUNTRY, (String) searchTextCountry.getText());
}

public void showMapMenu(View v) {
    mapView.removeAllViews();
    popupMenu = new MapPopupMenu(this);

    final ImageView mapMenuOpen = (ImageView) v.findViewById(R.id.map_menu_open);
    mapMenuOpen.setImageResource(R.drawable.menu_close);

    Drawable image = getResources().getDrawable(R.drawable.location);
    if (mapView.getZoomLevel() < 5
            || (myLocationOverlay.isMyLocationEnabled() && !mapHandler.isMyLocationVisible(application.getCurrentLocation()))) {
        MenuEntry myLocation = new MenuEntry(ID_MOVE_TO_ME, "Show", image);
        popupMenu.addActionItem(myLocation);

    } else if (myLocationOverlay.isMyLocationEnabled()) {
        MenuEntry hideLocation = new MenuEntry(ID_DISABLE_LOC, "Hide", image);
        popupMenu.addActionItem(hideLocation);

    } else {
        MenuEntry showLocation = new MenuEntry(ID_ENABLE_LOC, "Show", image);
        popupMenu.addActionItem(showLocation);
    }

    image = getResources().getDrawable(R.drawable.compass);
    if (myLocationOverlay.isCompassEnabled()) {
        MenuEntry hideCompass = new MenuEntry(ID_DISABLE_COMP, "Hide", image);
        popupMenu.addActionItem(hideCompass);

    } else {
        MenuEntry showCompass = new MenuEntry(ID_ENABLE_COMP, "Show", image);
        popupMenu.addActionItem(showCompass);

    }

    image = getResources().getDrawable(R.drawable.map_menu);
    if (mapHandler.getShownMap() == MapHandler.SATELLITE) {
        MenuEntry showMap = new MenuEntry(ID_SHOW_MAP, "Map", image);
        popupMenu.addActionItem(showMap);

    } else {
        MenuEntry showTraffic = new MenuEntry(ID_SHOW_TRAFFIC, "Hybrid", image);
        popupMenu.addActionItem(showTraffic);

    }

    popupMenu.setAnimStyle(MapPopupMenu.ANIM_GROW_FROM_RIGHT);

    // Set listener for action item clicked
    popupMenu.setOnActionItemClickListener(new MapPopupMenu.OnActionItemClickListener() {

        public void onItemClick(MapPopupMenu source, int pos, int actionId) {
            switch (actionId) {
            case ID_DISABLE_COMP:
                myLocationOverlay.disableCompass();
                break;

            case ID_ENABLE_COMP:
                myLocationOverlay.enableCompass();
                break;

            case ID_DISABLE_LOC:
                myLocationOverlay.disableMyLocation();
                break;

            case ID_ENABLE_LOC:
                myLocationOverlay.enableMyLocation();
                mapView.getController().animateTo(application.getCurrentLocation());//line 492 controller seems to be null...
                break;

            case ID_SHOW_MAP:
                mapType = mapHandler.showMap(MapHandler.MAP);
                break;

            case ID_SHOW_TRAFFIC:
                mapType = mapHandler.showMap(MapHandler.SATELLITE);
                break;

            case ID_MOVE_TO_ME:
                myLocationOverlay.enableMyLocation();
                mapView.getController().animateTo(application.getCurrentLocation());
                mapView.getController().setZoom(MapHandler.MYLOCATION_ZOOM);
                break;
            }
            mapMenuOpen.setImageResource(R.drawable.menu_open);

        }
    });

    popupMenu.setOnDismissListener(new MapPopupMenu.OnDismissListener() {

        public void onDismiss() {
            mapMenuOpen.setImageResource(R.drawable.menu_open);
        }
    });

    popupMenu.show(v, mapMenuOpen);
}

private void hideSoftPad() {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(searchEditTextKey.getWindowToken(), 0);
}


@Override
protected void onRestart() {
    mapView.getController().setZoom(zoomLevel);
    mapView.getController().setCenter(mapCenter);
    Log.e("Log", "onRestart()");
    super.onRestart();
}

}

我的 getCurrentLocation() 方法:

public GeoPoint getCurrentLocation() {

    // Get the location manager
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    // Define the criteria how to select the locatioin provider -> use
    // default
    Criteria criteria = new Criteria();
    String provider = locationManager.getBestProvider(criteria, false);
    Location location = locationManager.getLastKnownLocation(provider);

    // Initialize the location fields
    if (location != null) {
        int lat = (int) (location.getLatitude() * 1E6);
        int lng = (int) (location.getLongitude() * 1E6);
        return new GeoPoint(lat, lng);
    } else {
        return null;
    }
}

...如果该方法返回 null,我理解异常。但是它怎么会在我的手机上返回一些东西,而在所有其他手机上返回 null 呢?

4

3 回答 3

2

“因为 mapController 在 null”——不,不是。您可以通过阅读堆栈跟踪来判断这一点。如果你MapControllernull,你不可能animateTo()MapController. animateTo()的是某物。null

最有可能null抱怨animateTo()的是传入的参数值,application.getCurrentLocation().

于 2012-07-28T12:16:50.657 回答
0

要在您导出签名 APK的设备上显示地图,您需要使用release key生成MAP API密钥。

仔细阅读教程

于 2012-07-28T11:12:22.043 回答
0

[1]首先,在 MainActivity 中将您的应用程序声明为 Global

public class MainActivity extends MapActivity {

    public Application application;  // <---------- DECLARE IT HERE

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {

[2]然后将所有其他需要的对象声明为 Global

[3]然后将检查条件放在第 492 行,它为哪个对象提供 NullPointerException 作为

If(null == mapView)
    System.out.println("mapView NULL");
If(null == application)
    System.out.println("application NULL");

[4]对 Null Found Object 进行必要的更改。

于 2012-07-28T12:02:57.667 回答