FragViewActivity中的v4.app.Fragment中的MapView

时间:2014-10-17 11:50:36

标签: android android-fragments android-mapview

我尝试在FragmentActivity(称为CustomerTabs)中的android.support.v4.app.Fragment中显示MapView。 我已根据入门文档完成了这些步骤 https://developers.google.com/maps/documentation/android/start#get_an_android_certificate_and_the_google_maps_api_key

的AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<uses-feature
    android:glEsVersion="0x00020000"
    android:required="true"/>

<permission
    android:name="com.example.permission.MAPS_RECEIVE"
    android:protectionLevel="signature"/>
<uses-permission android:name="com.example.permission.MAPS_RECEIVE"/>

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

    <meta-data android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />

    <meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value="xyz"/>

    <activity
        android:name=".view.CustomerTabs"
        android:screenOrientation="portrait"
        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="x.y.view.Login_"
        android:screenOrientation="portrait">
    </activity>
    <activity android:name="x.y.view.Registration_"
        android:screenOrientation="portrait">
    </activity>
    <activity
        android:name="x.y.view.OwnerTabs"
        android:screenOrientation="portrait"
        android:label="@string/title_activity_owner_tab" >
    </activity>
</application>

CustomerTabs.java

public class CustomerTabs extends FragmentActivity {
final String TAG = this.getClass().getSimpleName();

TabHost mTabHost;

//tab identifier as keys
HashMap<String, Stack<Fragment>> mStacks;
String mCurrentTab;
Context context = this;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.tabs);

    mStacks = new HashMap<String, Stack<Fragment>>();
    mStacks.put(Constants.TAB_A, new Stack<Fragment>());
    mStacks.put(Constants.TAB_B, new Stack<Fragment>());
    mStacks.put(Constants.TAB_C, new Stack<Fragment>());

    mTabHost = (TabHost) findViewById(android.R.id.tabhost);
    mTabHost.setOnTabChangedListener(listener);
    mTabHost.setup();

    initializeTabs();
}


void initializeTabs() {
    /* Setup your tab icons and content views.. Nothing special in this.. */
    TabHost.TabSpec spec = mTabHost.newTabSpec(Constants.TAB_A);



    spec.setContent(new TabHost.TabContentFactory() {
        public View createTabContent(String tag) {
            return findViewById(R.id.realtabcontent);
        }
    });
    spec.setIndicator("start");

    mTabHost.addTab(spec);


    spec = mTabHost.newTabSpec(Constants.TAB_B);
    spec.setContent(new TabHost.TabContentFactory() {
        public View createTabContent(String tag) {
            return findViewById(R.id.realtabcontent);
        }
    });


    spec.setIndicator("map");

    mTabHost.addTab(spec);

    spec = mTabHost.newTabSpec(Constants.TAB_C);
    spec.setContent(new TabHost.TabContentFactory() {
        public View createTabContent(String tag) {
            return findViewById(R.id.realtabcontent);
        }
    });
    spec.setIndicator("news");

    mTabHost.addTab(spec);



    setCurrentTab(0);

}

TabHost.OnTabChangeListener listener = new TabHost.OnTabChangeListener() {
    public void onTabChanged(String tabId) {
        /* Set current tab.. */
        mCurrentTab = tabId;
        Log.v(TAG,tabId);

        if (mStacks.get(tabId).size() == 0) {
            if (tabId.equals(Constants.TAB_A)) {
            Start start = Start_.builder().build();
            pushFragments(tabId, start, true);

            } else if (tabId.equals(Constants.TAB_B)) {
                Map map = Map_.builder().build();
                pushFragments(tabId, map, true);

            } else if (tabId.equals(Constants.TAB_C)) {
                News news = News_.builder().build();
                pushFragments(tabId, news, true);

            }
        } else {
            /*
             * We are switching tabs, and target tab is already has atleast
             * one fragment. No need of animation, no need of stack pushing.
             * Just show the target fragment
             */
            Log.v(TAG, "tabId " + tabId);

            pushFragments(tabId, mStacks.get(tabId).lastElement(),
                        false);
        }
    }
};

public void pushFragments(String tag, Fragment fragment,
                           boolean shouldAdd) {
    if (shouldAdd)
        mStacks.get(tag).push(fragment);
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction ft = manager.beginTransaction();
    ft.replace(R.id.realtabcontent, fragment);
    ft.commit();
}

public void popFragments() {
    Fragment fragment = mStacks.get(mCurrentTab).elementAt(
            mStacks.get(mCurrentTab).size() - 2);
    mStacks.get(mCurrentTab).pop();
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction ft = manager.beginTransaction();
    ft.replace(R.id.realtabcontent, fragment);
    ft.commit();
}

public void setCurrentTab(int val) {
    mTabHost.setCurrentTab(val);
}

tabs.xml

<TabHost
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0"/>

        <FrameLayout
            android:id="@+android:id/realtabcontent"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>

        <TabWidget
            android:id="@android:id/tabs"
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"/>

    </LinearLayout>
</TabHost>

map.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<com.google.android.gms.maps.MapView android:id="@+id/mapview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />

Map.java

@EFragment
public class Map extends SupportMapFragment{
final String TAG = this.getClass().getSimpleName();

MapView mapView;
GoogleMap mMap;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.map, container, false);

    // Gets the MapView from the XML layout and creates it
    mapView = (MapView) v.findViewById(R.id.mapview);
    mapView.onCreate(savedInstanceState);

    // Gets to GoogleMap from the MapView and does initialization stuff
    mMap = mapView.getMap();
    mMap.getUiSettings().setMyLocationButtonEnabled(false);
    mMap.setMyLocationEnabled(true);

    // Needs to call MapsInitializer before doing any CameraUpdateFactory calls
    try {
        MapsInitializer.initialize(this.getActivity());
    } catch (Exception e) {
        e.printStackTrace();
    }

    // Updates the location and zoom of the MapView
    CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(50, 8.2711111), 10);
    mMap.animateCamera(cameraUpdate);

    return v;
}

build.greadle

dependencies {
apt "org.androidannotations:androidannotations:3.0+"
compile files('libs/androidannotations-3.0.1.jar')
compile files('libs/androidannotations-api-3.0.1.jar')
compile 'com.android.support:support-v4:20.0.0'
compile 'com.google.android.gms:play-services:5.2.08'
compile 'com.android.support:appcompat-v7:20.0.0'
compile files('libs/Parse-1.7.0.jar')

}

我不知道为什么会出现以下异常:

java.lang.NullPointerException
at com.google.maps.api.android.lib6.c.u.b(Unknown Source)
at com.google.android.gms.maps.internal.u.onTransact(SourceFile:115)
at android.os.Binder.transact(Binder.java:326)
at com.google.android.gms.maps.internal.IMapFragmentDelegate$a$a.onResume(Unknown Source)
at com.google.android.gms.maps.SupportMapFragment$a.onResume(Unknown Source)
at com.google.android.gms.dynamic.a$7.b(Unknown Source)
at com.google.android.gms.dynamic.a.a(Unknown Source)
at com.google.android.gms.dynamic.a.onResume(Unknown Source)
at com.google.android.gms.maps.SupportMapFragment.onResume(Unknown Source)
at x.y.view.Map.onResume(Map.java:66)
at android.support.v4.app.Fragment.performResume(Fragment.java:1547)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:978)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
at  android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1484)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:450)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4898)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:0)

我自己解决了。

主要的错误是我在AndroidStudio中签署我的应用程序,例如build / generate signed apk并使用此SHA1创建了一个客户端密钥(通过控制台从keeytool获取)。

据我了解,我必须签署位于.android文件夹的 debug.keystore 文件。 使用以下命令行,您可以在调试模式下对应用程序进行签名。

keytool -list -v -keystore debug.keystore (pass: android)

生成的SHA1在api控制台上创建一个新的客户端密钥。

我的代码在app.greadle和android-tag

中使用以下行
buildTypes {
    release {
        runProguard true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug {

        jniDebugBuild false
        renderscriptDebugBuild false
    }
}

当我使用包含TabHost的FragmentActivity时,我将framelayout替换为SupportMapFragment。

SupportMapFragment mapFragment = new Map();
pushFragments(tabId, mapFragment, true); 

我的SupportMapFragment看起来像这样:

public class Map extends SupportMapFragment{
final String TAG = this.getClass().getSimpleName();

GoogleMap mapView;

@Override
public void onCreate(Bundle arg0) {
    super.onCreate(arg0);
}

@Override
public View onCreateView(LayoutInflater mInflater, ViewGroup arg1,
                         Bundle arg2) {
    return super.onCreateView(mInflater, arg1, arg2);
}

@Override
public void onInflate(Activity arg0, AttributeSet arg1, Bundle arg2) {
    super.onInflate(arg0, arg1, arg2);
}

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

    mapView = getMap();
    MarkerOptions markerOptions = new MarkerOptions();
    markerOptions.draggable(true);
    markerOptions.position(new LatLng(23.231251f, 71.648437f));
    markerOptions.icon(BitmapDescriptorFactory.defaultMarker());
    mapView.addMarker(markerOptions);
}