API上的权限问题23

时间:2015-11-28 15:16:26

标签: android

在我的应用的活动(MapsActivity)中,会显示一个地图供用户选择他想要的地方。我使用的是ACCES_FINE_LOCATIONACCES_COARSE_LOCATION权限。

我创建了PermissioUtils class来验证MapsActivity class中的权限。

访问MapsActicity时,应用会以FATAL EXCEPTION

结束

logcat错误

11-28 13:18:50.053 12496-12496/luizugliano.com.br.lugaresfavoritos E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                 Process: luizugliano.com.br.lugaresfavoritos, PID: 12496
                                                                                 java.lang.RuntimeException: Unable to start activity ComponentInfo{luizugliano.com.br.lugaresfavoritos/luizugliano.com.br.lugaresfavoritos.MapsActivity}: java.lang.IllegalArgumentException: invalid provider: null
                                                                                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
                                                                                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                                                                     at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                                                                     at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                     at android.os.Looper.loop(Looper.java:148)
                                                                                     at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                                                  Caused by: java.lang.IllegalArgumentException: invalid provider: null
                                                                                     at android.location.LocationManager.checkProvider(LocationManager.java:1704)
                                                                                     at android.location.LocationManager.requestLocationUpdates(LocationManager.java:459)
                                                                                     at luizugliano.com.br.lugaresfavoritos.MapsActivity.setUpMap(MapsActivity.java:205)
                                                                                     at luizugliano.com.br.lugaresfavoritos.MapsActivity.setUpMapIfNeeded(MapsActivity.java:171)
                                                                                     at luizugliano.com.br.lugaresfavoritos.MapsActivity.onCreate(MapsActivity.java:104)
                                                                                     at android.app.Activity.performCreate(Activity.java:6237)
                                                                                     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
                                                                                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                                                                                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
                                                                                     at android.app.ActivityThread.-wrap11(ActivityThread.java) 
                                                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
                                                                                     at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                     at android.os.Looper.loop(Looper.java:148) 
                                                                                     at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                                                     at java.lang.reflect.Method.invoke(Native Method) 
                                                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

PermissionUtils类

public class PermissionUtils {

/**
 * Solicita as permissões
 */
public static boolean validate(Activity activity, int requestCode, String... permissions) {
    List<String> list = new ArrayList<String>();
    for (String permission : permissions) {
        // Valida permissão
        boolean ok = ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED;
        if (! ok ) {
            list.add(permission);
        }
    }
    if (list.isEmpty()) {
        // Tudo ok, retorna true
        return true;
    }

    // Lista de permissões que falta acesso.
    String[] newPermissions = new String[list.size()];
    list.toArray(newPermissions);

    // Solicita permissão
    ActivityCompat.requestPermissions(activity, newPermissions, 1);

    return false;
}
}

MapsActivity类

public class MapsActivity extends AppCompatActivity implements GoogleMap.OnMapLongClickListener, LocationListener {

private GoogleMap mMap;
int location = -1;

LocationManager locationManager;
String provider;
/**
 * ATTENTION: This was auto-generated to implement the App Indexing API.
 * See https://g.co/AppIndexing/AndroidStudio for more information.
 */
private GoogleApiClient client;

@Override
public void onMapLongClick(LatLng point) {

    Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());

    String label = new Date().toString();

    try {
        List<Address> listAddresses = geocoder.getFromLocation(point.latitude, point.longitude, 1);

        if (listAddresses != null && listAddresses.size() > 0) {

            label = listAddresses.get(0).getAddressLine(0);

        }


    } catch (IOException e) {
        e.printStackTrace();
    }

    MainActivity.places.add(label);
    MainActivity.arrayAdapter.notifyDataSetChanged();
    MainActivity.locations.add(point);

    mMap.addMarker(new MarkerOptions()
            .position(point)
            .title(label)
            .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
}

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

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

    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    provider = locationManager.getBestProvider(new Criteria(), false);

    ActionBar actionBar = getActionBar();
    if (actionBar != null) {
        actionBar.setDisplayHomeAsUpEnabled(true);
    }


    Intent i = getIntent();
    location = i.getIntExtra("locationInfo", -1);


    setUpMapIfNeeded();

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();

    // Solicita as permissões
    String[] permissoes = new String[]{
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION,
    };
    PermissionUtils.validate(this, 0, permissoes);
}

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

    setUpMapIfNeeded();

    if (location == -1 || location == 0) {

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(MapsActivity.this,Manifest.permission.ACCESS_FINE_LOCATION) && (ActivityCompat.shouldShowRequestPermissionRationale(MapsActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION))) {
                // Caso o usuário tenha negado a permissão anteriormente, e não tenha marcado o check "nunca mais mostre este alerta"
                // Podemos mostrar um alerta explicando para o usuário porque a permissão é importante.
            } else {
                // Solicita a permissão
                ActivityCompat.requestPermissions(MapsActivity.this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},0);
                ActivityCompat.requestPermissions(MapsActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},0);
            }
        } else {
            //Tudo OK
        }
        locationManager.requestLocationUpdates(provider, 400, 1, this);

    }
}

@Override
protected void onPause() {
    super.onPause();

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(MapsActivity.this,Manifest.permission.ACCESS_FINE_LOCATION) && (ActivityCompat.shouldShowRequestPermissionRationale(MapsActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION))) {
            // Caso o usuário tenha negado a permissão anteriormente, e não tenha marcado o check "nunca mais mostre este alerta"
            // Podemos mostrar um alerta explicando para o usuário porque a permissão é importante.
        } else {
            // Solicita a permissão
            ActivityCompat.requestPermissions(MapsActivity.this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},0);
            ActivityCompat.requestPermissions(MapsActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},0);
        }
    } else {
        //Tudo OK
    }
    locationManager.removeUpdates(this);
}


private void setUpMapIfNeeded() {

    // Do a null check to confirm that we have not already instantiated the map.
    if (mMap == null) {
        // Try to obtain the map from the SupportMapFragment.
        mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                .getMap();
        mMap.setOnMapLongClickListener(this);
        // Check if we were successful in obtaining the map.
        if (mMap != null) {
            setUpMap();
        }
    }
}

/**
 * This is where we can add markers or lines, add listeners or move the camera. In this case, we
 * just add a marker near Africa.
 * <p/>
 * This should only be called once and when we are sure that {@link #mMap} is not null.
 */
private void setUpMap() {

    if (location != -1 && location != 0) {

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(MapsActivity.this,Manifest.permission.ACCESS_FINE_LOCATION) && (ActivityCompat.shouldShowRequestPermissionRationale(MapsActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION))) {
                // Caso o usuário tenha negado a permissão anteriormente, e não tenha marcado o check "nunca mais mostre este alerta"
                // Podemos mostrar um alerta explicando para o usuário porque a permissão é importante.
            } else {
                // Solicita a permissão
                ActivityCompat.requestPermissions(MapsActivity.this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},0);
                ActivityCompat.requestPermissions(MapsActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},0);
            }
        } else {
            //Tudo OK
        }
        locationManager.removeUpdates(this);

        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(MainActivity.locations.get(location), 10));

        mMap.addMarker(new MarkerOptions().position(MainActivity.locations.get(location)).title(MainActivity.places.get(location)));

    } else {

        locationManager.requestLocationUpdates(provider, 400, 1, this);

    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    for (int result : grantResults) {
        if (result == PackageManager.PERMISSION_DENIED) {
            // Alguma permissão foi negada
            alertAndFinish();
            return;
        }
    }

    // Se chegou aqui está OK
}

private void alertAndFinish() {
    {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.app_name).setMessage("Para utilizar este aplicativo, você precisa aceitar as permissões.");
        // Add the buttons
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                finish();
            }
        });
        android.support.v7.app.AlertDialog dialog = builder.create();
        dialog.show();

    }
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(MapsActivity.this,Manifest.permission.ACCESS_FINE_LOCATION) && (ActivityCompat.shouldShowRequestPermissionRationale(MapsActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION))) {
                    // Caso o usuário tenha negado a permissão anteriormente, e não tenha marcado o check "nunca mais mostre este alerta"
                    // Podemos mostrar um alerta explicando para o usuário porque a permissão é importante.
                } else {
                    // Solicita a permissão
                    ActivityCompat.requestPermissions(MapsActivity.this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},0);
                    ActivityCompat.requestPermissions(MapsActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},0);
                }
            } else {
                //Tudo OK
            }
            locationManager.removeUpdates(this);
            this.finish();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

@Override
public void onLocationChanged(Location userLocation) {

    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(userLocation.getLatitude(), userLocation.getLongitude()), 10));


}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {

}

@Override
public void onProviderEnabled(String provider) {

}

@Override
public void onProviderDisabled(String provider) {

}

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

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    client.connect();
    Action viewAction = Action.newAction(
            Action.TYPE_VIEW, // TODO: choose an action type.
            "Maps Page", // TODO: Define a title for the content shown.
            // TODO: If you have web page content that matches this app activity's content,
            // make sure this auto-generated web page URL is correct.
            // Otherwise, set the URL to null.
            Uri.parse("http://host/path"),
            // TODO: Make sure this auto-generated app deep link URI is correct.
            Uri.parse("android-app://luizugliano.com.br.lugaresfavoritos/http/host/path")
    );
    AppIndex.AppIndexApi.start(client, viewAction);
}

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

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    Action viewAction = Action.newAction(
            Action.TYPE_VIEW, // TODO: choose an action type.
            "Maps Page", // TODO: Define a title for the content shown.
            // TODO: If you have web page content that matches this app activity's content,
            // make sure this auto-generated web page URL is correct.
            // Otherwise, set the URL to null.
            Uri.parse("http://host/path"),
            // TODO: Make sure this auto-generated app deep link URI is correct.
            Uri.parse("android-app://luizugliano.com.br.lugaresfavoritos/http/host/path")
    );
    AppIndex.AppIndexApi.end(client, viewAction);
    client.disconnect();
}
}

1 个答案:

答案 0 :(得分:1)

您从setUpMap()间接调用的

onCreate()需要权限。您还没有要求用户提供这些权限。