如何在棉花糖中首次启动应用程序时获取位置访问权限

Posted

技术标签:

【中文标题】如何在棉花糖中首次启动应用程序时获取位置访问权限【英文标题】:How to get location access when starting the app for the first time in marshmallow 【发布时间】:2016-10-29 10:18:55 【问题描述】:

我正在创建一个应用程序。当我安装应用程序然后打开它并允许位置访问权限但只显示地图时,我没有获得当前位置。重新打开应用程序后,当前位置显示。使用以下代码-

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

    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;

    LatLng latLng;
    GoogleMap mMap;
    SupportMapFragment mFragment;
    Marker CurrentMarker;

    private static final int PERMISSION_REQUEST_CODE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar 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();
            
        );

        mFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mFragment.getMapAsync(this);

       // Button request_permission = (Button)findViewById(R.id.request_permission);

        //request_permission.setOnClickListener(this);

        if (!checkPermission()) 

            requestPermission();

         else 

            Toast.makeText(this,"Permission already granted.",Toast.LENGTH_SHORT).show();

        


    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.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_settings) 
            return true;
        

        return super.onOptionsItemSelected(item);
    


    @Override
    public void onMapReady(GoogleMap googleMap) 
        mMap = googleMap;
        //final int LOCATION_PERMISSION_REQUEST_CODE = 100;
       // ActivityCompat.requestPermissions(this, new String[]android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION,
              //  LOCATION_PERMISSION_REQUEST_CODE);
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 

           return;
        
        mMap.setMyLocationEnabled(true);
        buildGoogleApiClient();
        mGoogleApiClient.connect();

    

    private void buildGoogleApiClient() 

        // TODO Auto-generated method stub
        Toast.makeText(this, "buildGoogleApiClient", Toast.LENGTH_SHORT).show();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    

    @Override
    public void onConnected(Bundle bundle) 


        Toast.makeText(this, "Onconnection", Toast.LENGTH_SHORT).show();
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 

            return;
        
        Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if(mLastLocation != null)
            latLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
            MarkerOptions markerOptions = new MarkerOptions();
            markerOptions.position(latLng);
            markerOptions.title("Current Location");
            markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
            CurrentMarker = mMap.addMarker(markerOptions);
        
        mLocationRequest = new LocationRequest();
        //mLocationRequest.setInterval(5000);
       // mLocationRequest.setFastestInterval(3000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);

    

    @Override
    public void onConnectionSuspended(int i) 
        Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show();

    

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) 
        Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show();

    

    @Override
    public void onLocationChanged(Location location) 

        if (CurrentMarker != null)
            CurrentMarker.remove();
        
        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));
        CurrentMarker = mMap.addMarker(markerOptions);
        Toast.makeText(this,"Location changed",Toast.LENGTH_SHORT).show();

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

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

    


    private boolean checkPermission()
        int result = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
        if (result == PackageManager.PERMISSION_GRANTED)

            return true;

         else 

            return false;

        
    

    private void requestPermission()

        if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.ACCESS_FINE_LOCATION))

            Toast.makeText(this,"GPS permission allows us to access location data. Please allow in App Settings for additional functionality.",Toast.LENGTH_LONG).show();

         else 

            ActivityCompat.requestPermissions(this,new String[]Manifest.permission.ACCESS_FINE_LOCATION,PERMISSION_REQUEST_CODE);
        
    

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) 
        switch (requestCode) 
            case PERMISSION_REQUEST_CODE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) 



                 else 



                
                break;
        
    

请告诉我安装时如何获取位置,然后第一次打开它。使用我的源代码。

谢谢

【问题讨论】:

现在请告诉我如何解决它 【参考方案1】:

在棉花糖中,除非用户允许在运行时对应用程序进行位置访问,否则您无法获取位置。 作为用户许可位置权限重新启动您的活动

  Intent intent= new Intent(MainActivity.this,MainActivity.class);
    startActivity(intent);
    finish();

【讨论】:

ok ...当我安装应用程序然后打开并允许用户权限但不显示位置。重新打开显示的应用位置。 在 onRequestPermissionResult 中授予权限时。重新开始您的活动。用户第一次许可时只会执行一次 你给定的代码我应该把我的源代码放在哪里 @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) switch (requestCode) case PERMISSION_REQUEST_CODE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) Intent intent= new Intent(MainActivity.this,MainActivity.class);开始活动(意图);结束(); 其他 休息; 【参考方案2】:

为什么第一次没有显示:因为你授权后没有处理。

为什么你第二次出现:因为你之前已经授予了权限。

 @Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) 
    switch (requestCode) 
        case PERMISSION_REQUEST_CODE:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) 

            // TRY GETTING THE LOCATION HERE ON FIRST TIME (AFTER GRANTING)
             Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
             else 
            break;
    

【讨论】:

在授予权限对话框YES后,将调用onRequestPermissionsResult方法。这意味着您可以调用 getLastLocation 或进行位置请求更新。看看我的答案中的评论位置。 我没有得到...请用我的源代码告诉我 java.lang.RuntimeException: 传递结果失败 ResultInfowho=@android:requestPermissions:, request=1, result=-1, data=Intent act=android.content.pm.action. REQUEST_PERMISSIONS(有附加功能) 到活动 com.test/com.test.MainActivity:java.lang.IllegalArgumentException:需要 GoogleApiClient 参数。在 android.app.ActivityThread.deliverResults(ActivityThread.java:4013)---得到这个错误 你没有通过 mGoogleApiClient 吗? 好像你有设计问题。日志说需要 GoogleApiClient。您正在传递 mGoogleApiClient,但此时它尚未初始化。

以上是关于如何在棉花糖中首次启动应用程序时获取位置访问权限的主要内容,如果未能解决你的问题,请参考以下文章

仅在模拟器 iPhone6 中首次启动时出现位置权限问题 - XCode 9.4.1

在棉花糖中获取蓝牙本地mac地址

小程序中首次获取位置权限失败后,主动引导用户授权方案

在棉花糖中获取前台应用程序的 packageName 延迟 3 秒

清除棉花糖中所有应用程序的缓存?

检测棉花糖中的吐司