2017-03-09 31 views
0

因此,我试图将Google Map视图实现为片段,然后在其上显示用户的当前位置。我之前做了类似的事情,但它是在一个Activity而不是Fragment上。由于我现在使用导航抽屉,因此我正在使用片段来显示我的地图。我可以将地图显示出来,但它不会在当前位置显示用户的针脚。在片段内的Google Map API中显示用户的当前位置

我实现了同样的事情在一个单一的活动,它的工作原理,该代码如下所示:http://pastebin.com/8WTRZ1CR

这里是我当前的代码的外观:

MainActivity:

public class MainActivity extends AppCompatActivity 
     implements NavigationView.OnNavigationItemSelectedListener,OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { 

    //declared as global so we have access to it 
    NavigationView navigationView = null; 
    Toolbar toolbar = null; 

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

     //Set the fragment initially 
     MainFragment fragment = new MainFragment(); 
     android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
     fragmentTransaction.replace(R.id.fragment_container, fragment); 
     fragmentTransaction.commit(); 

     toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
     fab.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) 
         .setAction("Action", null).show(); 
      } 
     }); 

     DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 
     ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
       this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); 
     drawer.setDrawerListener(toggle); 
     toggle.syncState(); 

     navigationView = (NavigationView) findViewById(R.id.nav_view); 
     navigationView.setNavigationItemSelectedListener(this); 
    } 

    @Override 
    public void onBackPressed() { 
     DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 
     if (drawer.isDrawerOpen(GravityCompat.START)) { 
      drawer.closeDrawer(GravityCompat.START); 
     } else { 
      super.onBackPressed(); 
     } 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_information) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    @SuppressWarnings("StatementWithEmptyBody") 
    @Override 
    public boolean onNavigationItemSelected(MenuItem item) { 
     // Handle navigation view item clicks here. 
     int id = item.getItemId(); 

     if (id == R.id.nav_main) { 
      // Redirect to main fragment 
      MainFragment fragment = new MainFragment(); 
      android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
      fragmentTransaction.replace(R.id.fragment_container, fragment); 
      fragmentTransaction.commit(); 
     } else if (id == R.id.nav_history) { 
      // Redirect to history fragment 
      HistoryFragment fragment = new HistoryFragment(); 
      android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
      fragmentTransaction.replace(R.id.fragment_container, fragment); 
      fragmentTransaction.commit(); 
     } else if (id == R.id.nav_garage_info) { 
      // Redirect to garage info fragment 
      GarageInfoFragment fragment = new GarageInfoFragment(); 
      android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
      fragmentTransaction.replace(R.id.fragment_container, fragment); 
      fragmentTransaction.commit(); 
     } else if (id == R.id.nav_settings) { 
      // Redirect to garage info fragment 
      SettingsFragment fragment = new SettingsFragment(); 
      android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
      fragmentTransaction.replace(R.id.fragment_container, fragment); 
      fragmentTransaction.commit(); 
     } 

     DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 
     drawer.closeDrawer(GravityCompat.START); 
     return true; 
    } 

    @Override 
    public void onConnected(@Nullable Bundle bundle) { 

    } 

    @Override 
    public void onConnectionSuspended(int i) { 

    } 

    @Override 
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 

    } 

    @Override 
    public void onLocationChanged(Location location) { 

    } 

    @Override 
    public void onMapReady(GoogleMap googleMap) { 

    } 
} 

MainFragment:

public class MainFragment extends Fragment implements OnMapReadyCallback,  GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,  LocationListener { 
GoogleMap mGoogleMap; 
MapView mMapView; 
View mView; 
GoogleApiClient mGoogleApiClient; 
Location mLastLocation; 
Marker mCurrLocationMarker; 
LocationRequest mLocationRequest; 
Context fragment_context; 

public MainFragment() { 
    // Required empty public constructor 
} 

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

} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    // Inflate the layout for this fragment by using global mView 
    mView = inflater.inflate(R.layout.fragment_main, container, false); 
    fragment_context = container.getContext(); 
    return mView; 
} 

@Override 
public void onViewCreated(View view, Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 

    //Create map view and bind to layout 
    mMapView = (MapView) mView.findViewById(R.id.map); 
    if(mMapView != null) { 
     mMapView.onCreate(null); 
     mMapView.onResume(); 
     mMapView.getMapAsync(this); 
    } 
} 

@Override 
public void onMapReady(GoogleMap googleMap) { 
    MapsInitializer.initialize(getContext()); 
    mGoogleMap = googleMap; 
    mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 

    //Test information 
    /* 
    googleMap.addMarker(new MarkerOptions().position(new LatLng(40.689247, -74.044502)).title("Statue of Liberty").snippet("Test pin")); 
    CameraPosition Liberty = CameraPosition.builder().target(new LatLng(40.689247, -74.044502)).zoom(18).bearing(0).tilt(0).build(); 
    googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(Liberty)); 
    */ 

    //Initialize Google Play Services 
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
     if (ContextCompat.checkSelfPermission(getActivity(), 
       android.Manifest.permission.ACCESS_FINE_LOCATION) 
       == PackageManager.PERMISSION_GRANTED) { 
      buildGoogleApiClient(); 
      mGoogleMap.setMyLocationEnabled(true); 
     } 
    } 
    else { 
     buildGoogleApiClient(); 
     mGoogleMap.setMyLocationEnabled(true); 
    } 
} 

protected synchronized void buildGoogleApiClient() { 
    mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) 
      .addConnectionCallbacks(this) //cast so it works with fragment 
      .addOnConnectionFailedListener(this) //cast so it works with fragment 
      .addApi(LocationServices.API) 
      .build(); 
    mGoogleApiClient.connect(); 
} 

@Override 
public void onConnected(Bundle bundle) { 

    mLocationRequest = new LocationRequest(); 
    mLocationRequest.setInterval(1000); 
    mLocationRequest.setFastestInterval(1000); 
    mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 
    if (ContextCompat.checkSelfPermission(fragment_context, 
      android.Manifest.permission.ACCESS_FINE_LOCATION) 
      == PackageManager.PERMISSION_GRANTED) { 
     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
    } 
} 

@Override 
public void onConnectionSuspended(int i) { 

} 

@Override 
public void onLocationChanged(Location location) { 

    mLastLocation = location; 
    if (mCurrLocationMarker != null) { 
     mCurrLocationMarker.remove(); 
    } 

    //Place current location marker on map 
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); 
    MarkerOptions markerOptions = new MarkerOptions(); 
    markerOptions.position(latLng); 
    markerOptions.title("Current Position"); 
    markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE)); 
    mCurrLocationMarker = mGoogleMap.addMarker(markerOptions); 

    //moving the map 
    mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); 
    mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(11)); 

    //stop location updates 
    if (mGoogleApiClient != null) { 
     LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
    } 
} 

@Override 
public void onConnectionFailed(ConnectionResult connectionResult) { 

} 

public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99; 
public boolean checkLocationPermission(){ 
    if (ContextCompat.checkSelfPermission(fragment_context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 

     // Asking user if explanation is needed 
     if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), 
       android.Manifest.permission.ACCESS_FINE_LOCATION)) { 

      // Show an explanation to the user *asynchronously* -- don't block 
      // this thread waiting for the user's response! After the user 
      // sees the explanation, try again to request the permission. 

      //Prompt the user once explanation has been shown 
      ActivityCompat.requestPermissions(getActivity(), 
        new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 
        MY_PERMISSIONS_REQUEST_LOCATION); 


     } else { 
      // No explanation needed, we can request the permission. 
      ActivityCompat.requestPermissions(getActivity(), 
        new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 
        MY_PERMISSIONS_REQUEST_LOCATION); 
     } 
     return false; 
    } else { 
     return true; 
    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { 
    switch (requestCode) { 
     case MY_PERMISSIONS_REQUEST_LOCATION: { 
      // If request is cancelled, the result arrays are empty. 
      if (grantResults.length > 0 
        && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

       // permission was granted. Do the 
       // contacts-related task you need to do. 
       if (ContextCompat.checkSelfPermission(fragment_context, 
         android.Manifest.permission.ACCESS_FINE_LOCATION) 
         == PackageManager.PERMISSION_GRANTED) { 

        if (mGoogleApiClient == null) { 
         buildGoogleApiClient(); 
        } 
        mGoogleMap.setMyLocationEnabled(true); 
       } 

      } else { 

       // Permission denied, Disable the functionality that depends on this permission. 
       Toast.makeText(getActivity(), "permission denied", Toast.LENGTH_LONG).show(); 
      } 
      return; 
     } 

     // other 'case' lines to check for other permissions this app might request. 
     // You can add here other case statements according to your requirement. 
    } 
} 

} 

清单:

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

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
     <activity 
      android:name=".MainActivity" 
      android:label="@string/app_name" 
      android:theme="@style/AppTheme.NoActionBar"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

     <!--Maps Android Key--> 
     <meta-data 
      android:name="com.google.android.geo.API_KEY" 
      android:value="@string/google_maps_api_key" /> 
     <!--Maps Android Key--> 
    </application> 

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

fragment_main.xml看起来是这样的:

<FrameLayout 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="com.hallnguyenrahimeen.findmycar.MainFragment"> 

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

</FrameLayout> 

当应用程序打开时,它显示了实际上不显示用户所在位置的默认地图。

enter image description here

我在做什么错?

+0

请您添加r menifest –

+0

@RjzSatvara将它添加到主帖子中。 – FlameDra

+0

检查第一个GPS是否在 –

回答

1

试试这个

SupportMapFragment mapFragment = (SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.map); 
mapFragment.getMapAsync(this); 

而不是

mMapView = (MapView) mView.findViewById(R.id.map); 
+0

您是否希望我使用mapFragment删除mMapView的每个实例?我应该如何使用mMapView将mapFragment声明为全局的,然后在onViewCreated中初始化?当我尝试在onViewCreated中声明它时,我得到一个NullPointer异常 – FlameDra

+0

是的,将所有MapView替换为SupportMapFragment。 你可以在onCreateView里初始化这个。 –

+0

我声明它并按照你在onCreateView中的要求初始化它,并且getMapAsync得到一个NullPointerException。 – FlameDra

0

//你的XML

<fragment xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/map" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:name="com.google.android.gms.maps.SupportMapFragment"/> 

// Java代码

SupportMapFragment mapFragment ; 
if (Build.VERSION.SDK_INT < 21) { 
       mapFragment = ((SupportMapFragment) getActivity() 
         .getSupportFragmentManager().findFragmentById(R.id.map)); 
      } else { 
       mapFragment = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)); 
      } 
+0

你的意思是在我的框架布局?我在主文章中添加了我的fragment_main.xml文件。 – FlameDra

+0

正是.. !!!!!!! –

+0

我改变了我的fragment_main.xml看起来像这样:http://pastebin.com/QAsEFDd8 我得到一行错误Build.VERSION.SDK_INT <21它说“21”是一个意外的标记。 – FlameDra

相关问题