0

Google Maps APIをTabLayoutに組み込むことはできましたが、2つの問題があります。 1つは、アプリがすぐにユーザーの場所を尋ね、許可が与えられた場合は新しい更新された場所が表示されないということです。 誰か助けてくれますか?TabLayout TabLayout内で権限を要求した後にユーザーの場所を更新しない

MainActivity

public class MainActivity extends AppCompatActivity 
     implements NavigationView.OnNavigationItemSelectedListener{ 

    private Toolbar toolbar; 
    private TabLayout tabLayout; 
    private ViewPager viewPager; 
    private PagerAdapter pagerAdapter; 
    private DrawerLayout drawerLayout; 
    //private ViewPagerAdapter viewPagerAdapter; 
    private String[] pageTitle = {"myPlanner", "News", "Parking"}; 
    private String studyRooms = "http://library2.csumb.edu/mrbs/mobilenow.php"; 

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


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

     //create default navigation drawer toggle 
     ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, 
       R.string.navigation_drawer_open, R.string.navigation_drawer_close); 
     drawerLayout.addDrawerListener(toggle); 
     toggle.syncState(); 


     tabLayout = (TabLayout) findViewById(R.id.tab_layout); 
     tabLayout.setupWithViewPager(viewPager); 
     for (int i = 0; i < 3; i++) { 
      //TabLayout.Tab tab = tabLayout.getTabAt(i); 
      //tab.setCustomView(pagerAdapter.getTabView(i)); 
      tabLayout.addTab(tabLayout.newTab().setText(pageTitle[i])); 
     } 

     //set gravity for tab bar 
     tabLayout.setTabGravity(TabLayout.GRAVITY_FILL); 
     //handling navigation view item event 
     NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); 
     assert navigationView != null; 
     navigationView.setNavigationItemSelectedListener(this); 

     viewPager = (ViewPager)findViewById(R.id.view_pager); 
     pagerAdapter = new PagerAdapter(getSupportFragmentManager(), MainActivity.this); 
     viewPager.setAdapter(pagerAdapter); 


     //setting Tab layout (number of Tabs = number of ViewPager pages) 
     viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); 
     viewPager.setOffscreenPageLimit(3); 
     tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager)); 

    } 

    class PagerAdapter extends FragmentPagerAdapter{ 

     String tabTitles[] = new String[]{"myPlanner", "News", "Parking"}; 
     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 myPlanner(); 
       case 1: 
        return new News(); 
       case 2: 
        return new MapsFragment(); 
      } 
      return null; 
     } 

     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; 
     } 


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

     @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 == MapsFragment.MY_PERMISSIONS_REQUEST_LOCATION){ 
      MapsFragment mapFragment = (MapsFragment) pagerAdapter.fragments[2]; 
      if(mapFragment != null){ 
       mapFragment.onRequestPermissionsResult(requestCode,permissions,grantResults); 
      } 
     } 
     else{ 
      super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
     } 
    } 



    /* 
    Method for the navigation Drawer that takes in the id from the navigation drawer 
    and based on the view, an action will be performed. 
    */ 
    @Override 
    public boolean onNavigationItemSelected(MenuItem item) { 
     int id = item.getItemId(); 

     if (id == R.id.DinningCommonsItem) { 
      viewPager.setCurrentItem(0); 
     } else if (id == R.id.LibraryStudyRooms) { 
      Uri uri = Uri.parse(studyRooms); 
      Intent intent = new Intent(Intent.ACTION_VIEW, uri); 
      startActivity(intent); 
      // viewPager.setCurrentItem(1); 
     } else if (id == R.id.MapYourRoute) { 
      viewPager.setCurrentItem(2); 
     } else if (id == R.id.CampusPD) { 
      Intent i = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + "18316550268")); 
      i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
      startActivity(i); 

     } else if (id == R.id.close) { 
      finish(); 
     } 
     drawerLayout.closeDrawer(GravityCompat.START); 
     return true; 
    } 

    @Override 
    public void onBackPressed() { 
     assert drawerLayout != null; 
     if (drawerLayout.isDrawerOpen(GravityCompat.START)) { 
      drawerLayout.closeDrawer(GravityCompat.START); 
     } else { 
      super.onBackPressed(); 
     } 
    } 

} 

MapsFragment

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

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

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

    @Override 
    public void onResume() { 
     super.onResume(); 
     Log.d("MapsFragment", "Inside onResume"); 
     setUpMapIfNeeded(); 
    } 

    private void setUpMapIfNeeded() { 
     Log.d("MapsFragment", "Inside setUpMapIfNeeded"); 

     if (mGoogleMap == null) { 
      getMapAsync(this); 
     } 
    } 

    //This method gets called when the activity's view is obstructed. 
    @Override 
    public void onPause() { 
     super.onPause(); 
     Log.d("MapsFragment", "Inside onPause"); 

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

    //Call back method for when map is ready to be used. 
    @Override 
    public void onMapReady(GoogleMap googleMap){ 
     Log.d("MapsFragment", "Inside onMapReady"); 

     mGoogleMap = googleMap; 
     mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 

     //Initialize Google Play Services 
     if(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); 
     } 
    } 


    private void buildGoogleApiClient() { 
     Log.d("MapsFragment", "Inside buildGoogleApiClient"); 

     mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API) 
       .build(); 
     mGoogleApiClient.connect(); 
    } 

    //After calling connect(), this method will be invoked asynch when the 
    //connect request has successfully completed. 
    @Override 
    public void onConnected(@Nullable Bundle bundle) { 
     Log.d("MapsFragment", "Inside onConnected"); 

     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(@NonNull ConnectionResult connectionResult) { 

    } 

    @Override 
    public void onLocationChanged(Location location) { 
     Log.d("MapsFragment", "Inside onLocationChanged"); 

     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.zoomBy(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() { 
     Log.d("MapsFragment", "Inside 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 *asyncly* -- dont 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 dialog, int i) { 
           //prompt the user once the 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){ 
     Log.d("MapsFragment", "Inside onRequestPermissionsResult"); 

     switch (requestCode){ 
      case MY_PERMISSIONS_REQUEST_LOCATION:{ 
       //If request is cancelled, the results arrays are empty 
       if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){ 
        //Permission was granted 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{ 
        //permissions were denied. Disable the functionality that depends onthis permission 
        Toast.makeText(getActivity(), "Permission denied",Toast.LENGTH_LONG).show(); 
       } 
       return; 
      }//Other case lines to check for other permissions this app might request 
     } 

    } 

答えて

1

それが正常に動作している、このクラスを試してみてください。

public class MapsFragmentDemo extends com.google.android.gms.maps.MapFragment implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, 
    GoogleApiClient.OnConnectionFailedListener, LocationListener { 


private static final int REQUEST_LOCATION = 1; 
private final int REQUEST_CHECK_SETTINGS = 300; 
GoogleMap mGoogleMap; 
LocationRequest mLocationRequest; 
GoogleApiClient mGoogleApiClient; 
Location mLastLocation; 
Marker mCurrLocationMarker; 
boolean isFragmentVisible = false; 
private LocationSettingsRequest.Builder builder; 
private PendingResult<LocationSettingsResult> result; 

@Override 
public void setUserVisibleHint(boolean isVisibleToUser) { 
    super.setUserVisibleHint(isVisibleToUser); 
    if (isVisibleToUser) { 
     isFragmentVisible = true; 
     Log.d("MapsFragment", "Inside Visible"); 
     getMapAsync(this); 
     createLocationRequest(); 
     buildGoogleApiClient(); 

    } 
} 


protected void createLocationRequest() { 
    mLocationRequest = new LocationRequest(); 
    mLocationRequest.setInterval(1000); 
    mLocationRequest.setFastestInterval(1000); 
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    mLocationRequest.setSmallestDisplacement(.5f); 

} 


@Override 
public void onResume() { 
    super.onResume(); 
    Log.d("MapsFragment", "Inside onResume"); 
    if (isFragmentVisible) { 
     Log.d("MapsFragment", "Inside onResume true"); 
     if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) { 
      if (checkAccessPermission()) 
       startLocationUpdates(); 

      else 
       askForPermission(); 
     } 
    } 
} 

@Override 
public void onPause() { 
    super.onPause(); 
    Log.d("MapsFragment", "Inside onPause"); 
    stopLocationUpdates(); 
} 

@Override 
public void onStop() { 
    super.onStop(); 
    Log.d("MapsFragment", "onStop fired .............."); 
    if (mGoogleApiClient != null && !mGoogleApiClient.isConnected()) 
     mGoogleApiClient.disconnect(); 

} 

protected void stopLocationUpdates() { 
    if (mGoogleApiClient != null) 
     LocationServices.FusedLocationApi.removeLocationUpdates(
       mGoogleApiClient, this); 
} 

protected void startLocationUpdates() { 
    if (mGoogleApiClient != null) { 

     accessLocation(); 
    } 
} 

private boolean checkAccessPermission() { 
    return (ContextCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) 
      == PackageManager.PERMISSION_GRANTED); 
} 

@SuppressWarnings("MissingPermission") 
private void accessLocation() { 
    LocationServices.FusedLocationApi.requestLocationUpdates(
      mGoogleApiClient, mLocationRequest, this); 
    if (mGoogleMap != null) 
     mGoogleMap.setMyLocationEnabled(true); 
} 

private void askForPermission() { 
    // Should we show an explanation? 
    if (android.support.v4.app.ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), 
      android.Manifest.permission.ACCESS_FINE_LOCATION)) { 
     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 dialog, int i) { 
         //prompt the user once the explanation has been shown 
         FragmentCompat.requestPermissions(MapsFragmentDemo.this, 
           new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 
           REQUEST_LOCATION); 
        } 
       }) 
       .create() 
       .show(); 
    } else 
     FragmentCompat.requestPermissions(MapsFragmentDemo.this, 
       new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 
       REQUEST_LOCATION); 
} 


//Call back method for when map is ready to be used. 
@Override 
public void onMapReady(GoogleMap googleMap) { 
    Log.d("MapsFragment", "Inside onMapReady"); 

    mGoogleMap = googleMap; 
    mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 


} 

private void buildGoogleApiClient() { 
    Log.d("MapsFragment", "Inside buildGoogleApiClient"); 

    mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) 
      .addConnectionCallbacks(this) 
      .addOnConnectionFailedListener(this) 
      .addApi(LocationServices.API) 
      .build(); 
    mGoogleApiClient.connect(); 
} 


@Override 
public void onConnected(@Nullable Bundle bundle) { 
    Log.d("MapsFragment", "Inside onConnected"); 

    builder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest); 
    result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build()); 
    result.setResultCallback(new ResultCallback<LocationSettingsResult>() { 
     @Override 
     public void onResult(LocationSettingsResult result) { 
      final Status status = result.getStatus(); 
      final LocationSettingsStates mState = result.getLocationSettingsStates(); 
      switch (status.getStatusCode()) { 
       case LocationSettingsStatusCodes.SUCCESS: 
        if (!checkAccessPermission()) { 

         askForPermission(); 

        } else 
         startLocationUpdates(); 
        break; 
       case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: 
        try { 
         status.startResolutionForResult(getActivity(), REQUEST_CHECK_SETTINGS); 
        } catch (IntentSender.SendIntentException e) { 
        } 
        break; 
       case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE: 
        break; 
      } 
     } 
    }); 


} 

public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    switch (requestCode) { 
     case REQUEST_CHECK_SETTINGS: 
      switch (resultCode) { 
       case Activity.RESULT_OK: 
        if (!checkAccessPermission()) { 

         askForPermission(); 

        } else 
         startLocationUpdates(); 
        break; 
       case Activity.RESULT_CANCELED: 

        break; 
      } 
      break; 
    } 
} 

@Override 
public void onConnectionSuspended(int i) { 

} 

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

} 

@Override 
public void onLocationChanged(Location location) { 
    mGoogleMap.clear(); 
    Log.d("MapsFragment", "Inside onLocationChanged"); 
    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)); 
    Marker currLocationMarker = mGoogleMap.addMarker(markerOptions); 


    CameraPosition cameraPosition = new CameraPosition.Builder() 
      .target(latLng).zoom(14).build(); 


    mGoogleMap.animateCamera(CameraUpdateFactory 
      .newCameraPosition(cameraPosition)); 

    //Optionally, stop location updates if only current location is needed 
    if (mGoogleApiClient != null) { 
     stopLocationUpdates(); 
    } 

} 

@Override 
public void onRequestPermissionsResult(int requestCode, String permissions[] 
     , int[] grantResults) { 
    Log.d("MapsFragment", "Inside onRequestPermissionsResult"); 

    switch (requestCode) { 
     case REQUEST_LOCATION: { 
      //If request is cancelled, the results arrays are empty 
      if (grantResults.length > 0 
        && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       // permission was granted 
       accessLocation(); 
      } else { 
       // permission was denied 
       Toast.makeText(getActivity(), "Permission denied", Toast.LENGTH_LONG).show(); 
      } 
      return; 
     }//Other case lines to check for other permissions this app might request 
    } 

} 

}

+0

こんにちは、私は疑問を持っている:なぜ我々はのaccessLocationメソッド内@SuppressedWarningsラインが必要なのでしょうか? – TheLearner

+0

また、FragmentCompatを使用しているときにエラーが発生する – TheLearner

+0

Android lintは場所の許可を確認するために偽陽性の警告を表示しますが、アクセス許可を確認した後に呼び出すため、 'accessLocation()'メソッド内で別途確認する必要はありません。そこで私は '@ SuppressedWarning'を使用しています。これを確認してください[リンク](http://stackoverflow.com/questions/37642254/false-positive-lint-permission-error-even-after-asking-for-permission-at-runtime) –

関連する問題