2017-03-06 14 views
1

TabLayoutを実装することができました。タブの1つにGoogleマップの断片があります。ユーザーの場所にアクセスする権限を求めて、現在の場所にマーカーを配置したいと考えています。現時点では、ダイアログボックスが表示されず、理由がわかりません。誰でも助けてくれますか?TabLayoutを使ってViewPagerでGoogleマップのフラグメント内の現在の位置を取得する方法

public class MapsFragment extends Fragment implements OnMapReadyCallback{ 

    GoogleMap mGoogleMap; 
    MapView mMapView; 
    View mView; 
    LocationManager locationManager; 
    static final int REQUEST_LOCATION = 1; 

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

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

    @Override 
    public void onViewCreated(View view, Bundle savedInstanceState){ 
     super.onViewCreated(view, savedInstanceState); 
     mMapView = (MapView) mView.findViewById(R.id.googleMap); 
     if(mMapView != null){ 
      mMapView.onCreate(null); 
      mMapView.onResume(); 
      mMapView.getMapAsync(this); 

     } 
    } 

    @Override 
    public void onMapReady(GoogleMap googleMap) { 
     mGoogleMap = googleMap; 
     googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 
     //Initialize Google PLay Services 
     if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ 
      if(ContextCompat.checkSelfPermission(getContext(), 
        Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){ 
       //Location Permission is gratned 
       MapsInitializer.initialize(getContext()); 
       mGoogleMap.setMyLocationEnabled(true); 
      } 
     } 
     googleMap.addMarker(new MarkerOptions().position(new LatLng(36.652527, -121.797277)).title("CSUMB")); 
     CameraPosition CSUMB = CameraPosition.builder().target(new LatLng(36.6538, -121.797277)).zoom(16).bearing(0).tilt(45).build(); 
     googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(CSUMB)); 
    } 

    void getLocation(){ 
     locationManager = (LocationManager)getActivity() 
       .getSystemService(Context.LOCATION_SERVICE); 
     getLocation(); 
     if(ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) 
       != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), 
       Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED){ 

     }else{ 
      Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
      if(location!= null){ 
       double latti = location.getLatitude(); 
       double longi = location.getLongitude(); 
       Toast.makeText(getActivity(),"Location is " + String.valueOf(latti) + ", " + String.valueOf(longi),Toast.LENGTH_LONG); 
       Log.e("Maps Fragment", "Location is: " + String.valueOf(latti) + ", " + String.valueOf(longi)); 
      } 
      else{ 
       Log.e("Maps fragment", "Unable to find current location."); 
      } 
     } 
    } 
    @Override 
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
     super.onRequestPermissionsResult(requestCode, permissions, grantResults); 

     switch (requestCode) { 
      case REQUEST_LOCATION: 
       getLocation(); 
       break; 
     } 
    } 
    @Override 
    public void onResume() { 
     super.onResume(); 
     mMapView.onResume(); 
    } 

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

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

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

答えて

1

これは私のother answer hereに非常に近い、しかし、その答えはTabLayoutでViewPagerを使用してそれを行う方法を説明していません。

最初に、これを別の回答とは別に設定する部分は、instantiateItem()オーバーライドを使用して、FragmentPagerAdapterで現在のFragmentへの参照を保持する必要があります。

また、ここでは、ユーザの許可要求応答をフラグメントにルーティングするために、アクティビティにonRequestPermissionsResult()メソッドが必要であることに注意してください。本質的に同じコードを使用して、マップフラグメントに対して

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:fitsSystemWindows="true" 
    tools:context=".MainActivity"> 

    <android.support.design.widget.AppBarLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:theme="@style/AppTheme.AppBarOverlay" 
     android:elevation="6dp"> 

     <android.support.v7.widget.Toolbar 
      android:id="@+id/toolbar" 
      android:layout_width="match_parent" 
      android:layout_height="?attr/actionBarSize" 
      android:background="?attr/colorPrimary" 
      android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 
      app:popupTheme="@style/ThemeOverlay.AppCompat.Light" 
      android:elevation="0dp" /> 

     <android.support.design.widget.TabLayout 
      android:id="@+id/tab_layout" 
      app:tabMode="fixed" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_below="@+id/toolbar" 
      android:background="?attr/colorPrimary" 
      android:elevation="0dp" 
      app:tabTextColor="#d3d3d3" 
      app:tabSelectedTextColor="#ffffff" 
      app:tabIndicatorColor="#ff00ff" 
      android:minHeight="?attr/actionBarSize" 
      /> 

    </android.support.design.widget.AppBarLayout> 

    <android.support.v4.view.ViewPager 
     android:id="@+id/viewpager" 
     android:layout_width="match_parent" 
     android:layout_height="fill_parent" 
     app:layout_behavior="@string/appbar_scrolling_view_behavior" 
     /> 

</android.support.design.widget.CoordinatorLayout> 

custom_tab.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
    <TextView 
     android:id="@+id/custom_text" 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     android:background="?attr/selectableItemBackground" 
     android:gravity="center" 
     android:textSize="16dip" 
     android:textColor="#ffffff" 
     android:maxLines="1" 
     /> 
</LinearLayout> 

public class MainActivity extends AppCompatActivity { 

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

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

     // Get the ViewPager and set it's PagerAdapter so that it can display items 
     viewPager = (ViewPager) findViewById(R.id.viewpager); 
     pagerAdapter = new PagerAdapter(getSupportFragmentManager(), MainActivity.this); 
     viewPager.setAdapter(pagerAdapter); 

     // Give the TabLayout the ViewPager 
     TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout); 
     tabLayout.setupWithViewPager(viewPager); 

     // Iterate over all tabs and set the custom view 
     for (int i = 0; i < tabLayout.getTabCount(); i++) { 
      TabLayout.Tab tab = tabLayout.getTabAt(i); 
      tab.setCustomView(pagerAdapter.getTabView(i)); 
     } 
    } 

    class PagerAdapter extends FragmentPagerAdapter { 

     String tabTitles[] = new String[] { "Tab One", "Tab Two", "Tab Three", }; 
     public Fragment[] fragments = new Fragment[tabTitles.length]; 
     Context context; 

     public PagerAdapter(FragmentManager fm, Context context) { 
      super(fm); 
      this.context = context; 
     } 

     @Override 
     public int getCount() { 
      return tabTitles.length; 
     } 

     @Override 
     public Fragment getItem(int position) { 

      switch (position) { 
       case 0: 
        return new MapFragment(); 
       case 1: 
        return new BlankFragment(); 
       case 2: 
        return new BlankFragment(); 
      } 

      return null; 
     } 

     @Override 
     public CharSequence getPageTitle(int position) { 
      // Generate title based on item position 
      return tabTitles[position]; 
     } 

     public View getTabView(int position) { 
      View tab = LayoutInflater.from(MainActivity.this).inflate(R.layout.custom_tab, null); 
      TextView tv = (TextView) tab.findViewById(R.id.custom_text); 
      tv.setText(tabTitles[position]); 
      return tab; 
     } 

     //This populates your Fragment reference array: 
     @Override 
     public Object instantiateItem(ViewGroup container, int position) { 
      Fragment createdFragment = (Fragment) super.instantiateItem(container, position); 
      fragments[position] = createdFragment; 
      return createdFragment; 
     } 
    } 

    @Override 
    public void onRequestPermissionsResult(int requestCode, 
              String permissions[], int[] grantResults) { 
     if (requestCode == MapFragment.MY_PERMISSIONS_REQUEST_LOCATION){ 
      MapFragment mapFragment = (MapFragment) pagerAdapter.fragments[0]; 
      if (mapFragment != null) { 
       mapFragment.onRequestPermissionsResult(requestCode, permissions, grantResults); 
      } 
     } 
     else { 
      super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
     } 
    } 
} 

がactivity_main.xml:ここ

は、完全な活性のコードでありますもう1つの答え:

public class MapFragment extends SupportMapFragment 
     implements OnMapReadyCallback, 
     GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener, 
     LocationListener { 

    GoogleMap mGoogleMap; 
    LocationRequest mLocationRequest; 
    GoogleApiClient mGoogleApiClient; 
    Location mLastLocation; 
    Marker mCurrLocationMarker; 

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

     setUpMapIfNeeded(); 
    } 

    private void setUpMapIfNeeded() { 

     if (mGoogleMap == null) { 
      getMapAsync(this); 
     } 
    } 
    @Override 
    public void onPause() { 
     super.onPause(); 

     //stop location updates when Activity is no longer active 
     if (mGoogleApiClient != null) { 
      LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
     } 
    } 

    @Override 
    public void onMapReady(GoogleMap googleMap) 
    { 
     mGoogleMap=googleMap; 
     mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); 

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

    protected synchronized void buildGoogleApiClient() { 
     mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .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(getActivity(), 
       Manifest.permission.ACCESS_FINE_LOCATION) 
       == PackageManager.PERMISSION_GRANTED) { 
      LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
     } 
    } 

    @Override 
    public void onConnectionSuspended(int i) {} 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) {} 

    @Override 
    public void onLocationChanged(Location location) 
    { 
     mLastLocation = location; 
     if (mCurrLocationMarker != null) { 
      mCurrLocationMarker.remove(); 
     } 

     //Place current location marker 
     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_MAGENTA)); 
     mCurrLocationMarker = mGoogleMap.addMarker(markerOptions); 

     //move map camera 
     mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); 
     mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(11)); 

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

    public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99; 
    private void checkLocationPermission() { 
     if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) 
       != PackageManager.PERMISSION_GRANTED) { 

      // Should we show an explanation? 
      if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), 
        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. 
       new AlertDialog.Builder(getActivity()) 
         .setTitle("Location Permission Needed") 
         .setMessage("This app needs the Location permission, please accept to use location functionality") 
         .setPositiveButton("OK", new DialogInterface.OnClickListener() { 
          @Override 
          public void onClick(DialogInterface dialogInterface, int i) { 
           //Prompt the user once explanation has been shown 
           ActivityCompat.requestPermissions(getActivity(), 
             new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
             MY_PERMISSIONS_REQUEST_LOCATION); 
          } 
         }) 
         .create() 
         .show(); 


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

    @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, yay! Do the 
        // location-related task you need to do. 
        if (ContextCompat.checkSelfPermission(getActivity(), 
          Manifest.permission.ACCESS_FINE_LOCATION) 
          == PackageManager.PERMISSION_GRANTED) { 

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

       } else { 

        // permission denied, boo! 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 
     } 
    } 

} 

結果

まず、場所の許可プロンプト:

enter image description here

:ユーザーは、ユーザーの現在位置を表示し、実行時に許可を受け入れた後

enter image description here

+0

なぜ断片参照が必要なのか説明できますか配列? – TheLearner

+0

@TheLearnerこれは、 'mapFragment.onRequestPermissionsResult()'を呼び出して、ユーザの権限の選択肢をアクティビティからフラグメントに渡すために必要です。 ViewPagerは、ユーザーがスワイプする間に必要に応じてフラグメントを作成して再作成し、デフォルトでは現在のフラグメントと両サイドのフラグメントを有効に保ちます。だから、現在生きているFragmentsへの参照を取得するためには、 'instantiateItem()'オーバーライドが必要です。 –

+0

その説明をありがとうございます。私は何らかの理由でエラーが発生しています:PagerAdapter.getTabView(int) 'nullのオブジェクト参照で android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2947) – TheLearner

関連する問題