如何接收GPS位置和膨胀片段MapView以编程方式添加标记与SyncAdapter



嗯,在阅读了这个网站上的许多例子和许多帖子之后,我解决了一些问题,最后我设法让片段响应和我的syncAdapter工作。但是在这些天尝试了很多东西之后,我仍然看不到地图。我只有一个空白的屏幕。我试过一些方法,但对我来说都不起作用。我遇到了瓶颈,我需要继续我的项目。谁能指导我怎么做这件事?我真的很感激。我只是想请你们注意我所有的元素,因为我一直在兜圈子,当我试图改变一些东西时,其他的东西很好地工作了。

这个应用程序有,你看到下面:一个位置请求(主活动)同步的变化,并返回GPS纬度和纬度。之后,它带来了片段,一旦在那里,我首先同步数据使用GPS纬度和长度发送这些数据存储在数据库中与原理图。syncAdapter使用GPS的时间和长度传递到Yelp(据我所知)异步调用。

供参考,我用过这样的帖子,但它不适合我。

当我导入android.support.v4.app时,我很小心。或者简单地导入android.app.xxx,因为它会弄乱其他东西。这条路现在正在运行,没有中断,但我还看不见地图。

我试过了:
(与结果,重复id, Nullpointer)几个帖子说使用getChildFragmentManager,使用onDestroyView,使用类SupportMapFragment,但没有工作。
这些帖子:一,二,三,四

阅读这些帖子后,我调整了代码如下错误"NullPointerException在SupportMapFragment"。我也尝试过简单的MapFragment,但没有。


我不知道该怎么感谢你才好。
欢呼


调整如下:(必须将minSdkVersion更改为17)


在片段

 @Override
    public void onDestroyView()
    {
        super.onDestroyView();
        Fragment fragment = (getActivity().getSupportFragmentManager().findFragmentById(R.id.thismap));
        FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
        ft.remove(fragment);
        ft.commit();
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        //getLoaderManager().initLoader(CURSOR_LOADER_ID, null, this);

                SupportMapFragment mapFragment = (SupportMapFragment) this.getChildFragmentManager()
                .findFragmentById(R.id.thismap);
        mapFragment.getMapAsync(this);
return null;
}

尝试了这个yelp_google_map.xml(片段单独,没有其他)

<fragment android:id="@+id/thismap"
          android:name="com.google.android.gms.maps.SupportMapFragment"
          xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:map="http://schemas.android.com/apk/res-auto"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          tools:context="mem.edu.joshua.MapsActivity"/>




整个应用程序没有上述调整
Gradle

apply plugin: 'com.android.application'
apply plugin: 'android-apt'
//apply plugin: 'com.google.gms.google-services'
android {
    compileSdkVersion 24
    buildToolsVersion "24.0.0"
    defaultConfig {
        applicationId "mem.edu.joshua"
        minSdkVersion 16
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }
    dexOptions {
        preDexLibraries = false
        javaMaxHeapSize "4g"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    buildTypes.each {
        it.buildConfigField 'String', 'YELP_CONSUMER_KEY', YelpConsumerKey
        it.buildConfigField 'String', 'YELP_CONSUMER_SECRET', YelpConsumerSecret
        it.buildConfigField 'String', 'YELP_TOKEN', YelpToken
        it.buildConfigField 'String', 'YELP_TOKEN_SECRET', YelpTokenSecret
    }
}
repositories {
    mavenCentral()
}
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    apt 'net.simonvt.schematic:schematic-compiler:0.6.3'
    compile 'net.simonvt.schematic:schematic:0.6.3'
    compile 'com.android.support:appcompat-v7:24.1.1'
    compile 'com.google.firebase:firebase-ads:9.0.2'
    //compile 'com.google.android.gms:play-services-maps:9.2.1'
    compile 'com.google.android.gms:play-services-maps:9.0.2'
    compile 'com.google.android.gms:play-services-location:9.0.2'
    compile 'com.yelp.clientlib:yelp-android:2.0.0'
    compile 'org.scribe:scribe:1.3.7'
    //compile 'com.google.android.gms:play-services:9.2.1'
}
清单

<?xml version="1.0" encoding="utf-8"?>
<manifest package="mem.edu.joshua"
          xmlns:android="http://schemas.android.com/apk/res/android">
    <!--
         The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
         Google Maps Android API v2, but you must specify either coarse or fine
         location permissions for the 'MyLocation' functionality. 
    -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat">
        <uses-library android:name="com.google.android.maps"/>
        <!--
             The API key for Google Maps-based APIs is defined as a string resource.
             (See the file "res/values/google_maps_api.xml").
             Note that the API key is linked to the encryption key used to sign the APK.
             You need a different API key for each encryption key, including the release key that is used to
             sign the APK for publishing.
             You can define the keys for the debug and release targets in src/debug/ and src/release/. 
        -->
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key"/>
        <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=".MapsActivity"-->
            <!--android:label="@string/app_name">-->
            <!--<meta-data-->
                <!--android:name="android.support.PARENT_ACTIVITY"-->
                <!--android:value="mem.edu.joshua.MainActivity"/>-->
            <!--<intent-filter>-->
                <!--<action android:name="android.intent.action.MAIN"/>-->
                <!--<category android:name="android.intent.category.LAUNCHER"/>-->
            <!--</intent-filter>-->
        <!--</activity>-->
        <!-- android:accountType="com.clashtoolkit.clashtoolkit" -->
        <service android:name=".sync.AuthenticatorService">
            <intent-filter>
                <action android:name="android.accounts.AccountAuthenticator"/>
            </intent-filter>
            <meta-data
                android:name="android.accounts.AccountAuthenticator"
                android:resource="@xml/authenticator"/>
        </service>
        <!-- The SyncAdapter service -->
        <!-- android:allowParallelSyncs="true" -->
        <service
            android:name=".sync.SyncService"
            android:exported="true">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/syncadapter"/>
        </service>
        <provider
            android:name=".data.generated.QuoteProvider"
            android:authorities="mem.edu.joshua.data.QuoteProvider"
            android:exported="false"/>
    </application>
</manifest>
在mainActivity.java

@Override
    public void onConnected(@Nullable Bundle bundle) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(60000);

        try {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest, (LocationListener) this);
            if (mLocationRequest != null) {
                Log.e(LOG_TAG, "google working");

//                FragmentManager manager = getSupportFragmentManager();
//                FragmentTransaction transaction = manager.beginTransaction();
//                SupportMapFragment fragment = new SupportMapFragment();
//                transaction.add(R.id.mapView, fragment);
//                transaction.commit();
                LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
                Criteria criteria = new Criteria();
                String provider = service.getBestProvider(criteria, false);
                Location location = service.getLastKnownLocation(provider);

                coord.setLon(location.getLongitude());
                coord.setLat(location.getLatitude());
                sPref.saveCoordBody("lat", coord.getLat());
                sPref.saveCoordBody("lon", coord.getLon());
                    getSupportFragmentManager()
                            .beginTransaction()
                            .add(R.id.container, new MapsActivity(), MapsActivity.LOG_TAG)
                            .disallowAddToBackStack()
                            .commit();

            }
        }catch  (SecurityException e) {
            Log.e(LOG_TAG, e.getMessage(), e);
            e.printStackTrace();
        }

    }

在MapsActivity.java (Fragment -> import android.support.v4.app.FragmentActivity;)

public class MapsActivity extends Fragment implements OnMapReadyCallback, LoaderManager.LoaderCallbacks<Cursor> {
GoogleApiClient.ConnectionCallbacks,
        public static final String LOG_TAG = MapsActivity.class.getSimpleName();
    private static final int CURSOR_LOADER_ID = 0;
    private Context mContext;

    private MapCursor mMapCursor;
    protected Location mLastLocation;
    private Cursor initQueryCursor;
    private GetSet coord;
    private AppPreferences sPref;
    private LatLng home;
    private GoogleMap mMap;
    MapView mMapView;
    private GoogleMap googleMap;
        private static final String FRAGMENT_LISTS =
                "net.simonvt.schematic.samples.ui.SampleActivity.LISTS";


    public MapsActivity() {
    }

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

        sPref = new AppPreferences(getActivity());
        SyncAdapter.syncImmediately(getActivity(),
                sPref.getCoordBody("lat"),
                sPref.getCoordBody("lon"));
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        //getLoaderManager().initLoader(CURSOR_LOADER_ID, null, this);

        View v = inflater.inflate(R.layout.yelp_google_map, container,
                false);

        mMapView = (MapView) v.findViewById(R.id.mapView);
        mMapView.onCreate(savedInstanceState);
        mMapView.onResume();
        mMapView.getMapAsync(this);
        return v;
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        return new CursorLoader(getActivity(), QuoteProvider.Quotes.CONTENT_URI,
                new String[]{ QuoteColumns._ID, QuoteColumns.DISPLAY_ADDRESS, QuoteColumns.DISPLAY_PHONE,
                        QuoteColumns.RATING, QuoteColumns.URL, QuoteColumns.POSTAL_CODE, QuoteColumns.ID_BUSINESS_NAME,
                        QuoteColumns.LATITUDE,
                        QuoteColumns.LOGITUDE},
                null,
                null,
                null);
    }
    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        if (loader != null) {
            //     mMapCursor.swapCursor(data);
            initQueryCursor = data;
        }
    }
    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
    }

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

    @Override
    public void onMapReady(GoogleMap googleMap) {
        LatLngBounds.Builder builder = new LatLngBounds.Builder();
        mMap = googleMap;
        initQueryCursor = getContext().getContentResolver().query(QuoteProvider.Quotes.CONTENT_URI,
                new String[]{QuoteColumns.LATITUDE, QuoteColumns.LOGITUDE, QuoteColumns.ID_BUSINESS_NAME}, null,
                null, null);

        if (initQueryCursor != null) {
            DatabaseUtils.dumpCursor(initQueryCursor);
            initQueryCursor.moveToFirst();
            for (int i = 0; i < initQueryCursor.getCount(); i++) {
                home = new LatLng(Double.valueOf(initQueryCursor.getString(initQueryCursor.getColumnIndex("latitude"))),
                        Double.valueOf(initQueryCursor.getString(initQueryCursor.getColumnIndex("longitude"))));
                mMap.addMarker(new MarkerOptions().position(home).
                        title(initQueryCursor.getString(initQueryCursor.getColumnIndex("id_bussines_name"))));
                initQueryCursor.moveToNext();
                builder.include(home);
            }
            if(home!=null) {
                mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 91, 91, 42));
            }
        }
    }
}
我yelp_google_map.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <!--<include-->
        <!--android:id="@+id/map_toolbar"-->
        <!--layout="@layout/app_bar" />-->

    <LinearLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <com.google.android.gms.maps.MapView
            android:id="@+id/mapView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            class="com.google.android.gms.maps.MapFragment" />
        <!--was SupportMapFragment-->
    </LinearLayout>
</LinearLayout>

在绝望的尝试之后,我找到了Mrigank在这里给出的类似线程的解决方案我相信在我的代码调整后,即使它是膨胀的父容器是空的。

所以我的yelp_google_map.xml是这样的

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context="mem.edu.joshua.MapsActivity"
                android:background="#009688">

    <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.SupportMapFragment" />
</RelativeLayout>

我去掉了@Override public void onDestroyView部分

onCreateView保持如下


高级变量:private SupportMapFragment sMap;
private FragmentManager fm;
private GoogleMap mMap;

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        getLoaderManager().initLoader(CURSOR_LOADER_ID, null, this);
        View v = inflater.inflate(R.layout.yelp_google_map, container, false);
        fm=getChildFragmentManager();
        sMap = ((SupportMapFragment) fm.findFragmentById(R.id.map));
        mMap = sMap.getMap();

        initQueryCursor = getActivity().getContentResolver().query(QuoteProvider.Quotes.CONTENT_URI,
                new String[]{QuoteColumns.LATITUDE, QuoteColumns.LOGITUDE, QuoteColumns.ID_BUSINESS_NAME}, null,
                null, null);
        LatLngBounds.Builder builder = new LatLngBounds.Builder();
        if (initQueryCursor != null) {
            DatabaseUtils.dumpCursor(initQueryCursor);
            initQueryCursor.moveToFirst();
            for (int i = 0; i < initQueryCursor.getCount(); i++) {
                home = new LatLng(Double.valueOf(initQueryCursor.getString(initQueryCursor.getColumnIndex("latitude"))),
                        Double.valueOf(initQueryCursor.getString(initQueryCursor.getColumnIndex("longitude"))));
                mMap.addMarker(new MarkerOptions().position(home).
                        title(initQueryCursor.getString(initQueryCursor.getColumnIndex("id_bussines_name"))));
                initQueryCursor.moveToNext();
                builder.include(home);
            }
            if(home!=null) {
                mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 91, 91, 42));
            }
        }
        return v;
    }

将所有这些添加到同一个Fragment java文件

 @Override
        public void onResume() {
            super.onResume();
            sMap.onResume();
        }
        @Override
        public void onPause() {
            super.onPause();
            sMap.onPause();
        }
        @Override
        public void onDestroy() {
            super.onDestroy();
            sMap.onDestroy();
        }
        @Override
        public void onLowMemory() {
            super.onLowMemory();
            sMap.onLowMemory();
        }

最后在mainActivity.java

            getSupportFragmentManager()
                    .beginTransaction()
                    .add(R.id.map, new MapsActivity(), MapsActivity.LOG_TAG)
                    .disallowAddToBackStack()
                    .commitAllowingStateLoss();

希望这能帮助到一些人。这对我来说是一场噩梦。

最新更新