java.lang.IllegalArgumentException:无效的提供程序:打开MapsActivity时为null

时间:2017-02-23 10:38:14

标签: android google-maps-api-3

我只是从项目中复制粘贴部分代码

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.google.android.gms.location.LocationListener;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


public class MapsActivity extends Activity implements LocationListener {

private GoogleMap mMap;         // Null si les services Google Play APK ne sont pas disponible.

// Ma position par defaut pour test
private static final LatLng position_gps = new LatLng(43.701397, 1.838987);

// Positions pour test des trackers
private static final LatLng position_gps_track1 = new LatLng(43.602577, 1.362320);
private static final LatLng position_gps_track2 = new LatLng(43.602529, 1.362634);
private static final LatLng position_gps_track3 = new LatLng(43.602349, 1.362681);
private static final LatLng position_gps_track4 = new LatLng(43.602767, 1.362435);

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

    final ListView listview = (ListView) findViewById(R.id.listViewMap);
    String[] values = new String[]{"00:44 - Alert Area", "10:24 - Connect Lost", "10:35 - BLE true", "10:40 - Alert Area", "10:49 - Alert Area", "11:43 - Connect Lost", "11:57 - BLE true"};

    final ArrayList<String> list = new ArrayList<String>();
    for (int i = 0; i < values.length; ++i) {
        list.add(values[i]);
    }

    final StableArrayAdapter adapter = new StableArrayAdapter(this,
            R.layout.list_view_ligne, list);
    listview.setAdapter(adapter);
    listview.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);

    LocationManager locationManager;

    locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

    Criteria criteria = new Criteria();

    // Recupere le nom du meilleur fournisseur disponible
    String provider = locationManager.getBestProvider(criteria, true);

    // Recupere la derniere position connue

    Location location = locationManager.getLastKnownLocation(provider);
    LatLng pos_gps;
    if (location == null) {    // SI on arrive pas a recuperer la position GPS
        pos_gps = position_gps;     // Met la position GPS par defaut
    } else {                    // SINON recupere la position courante
        pos_gps = new LatLng(location.getLatitude(), location.getLongitude());
    }

    // Recupere la carte
    mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
    if (mMap != null) {
        // Ajout des trackers sur la carte
        mMap.addMarker(new MarkerOptions().position(position_gps_track1).title("T1 - Thomas"));
        mMap.addMarker(new MarkerOptions().position(position_gps_track2).title("T2 - Paul"));
        mMap.addMarker(new MarkerOptions().position(position_gps_track3).title("T3 - Sebastien"));
        mMap.addMarker(new MarkerOptions().position(position_gps_track4).title("T4 - Marc"));

        // Affiche la carte par rapport a la position courante
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(pos_gps, 15));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(15), 2000, null);
        mMap.setMyLocationEnabled(true);                        // Affiche le bouton Ma Position
        mMap.getUiSettings().setCompassEnabled(true);           // Affiche la boussole
        mMap.getUiSettings().setZoomControlsEnabled(true);      // Affiche les boutons de Zoom
    } else {
        Toast.makeText(this, "Services GoogleMap indisponibles!", Toast.LENGTH_SHORT).show();
    }
}

@Override
public void onLocationChanged(Location location) {

    // Met a jour la position
    int latitude = (int) (location.getLatitude());
    int longitude = (int) (location.getLongitude());
    LatLng position_gps = new LatLng(location.getLatitude(), location.getLongitude());
    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(position_gps, 15));
}

private class StableArrayAdapter extends ArrayAdapter<String> {

    HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();

    public StableArrayAdapter(Context context, int textViewResourceId,
                              List<String> objects) {
        super(context, textViewResourceId, objects);
        for (int i = 0; i < objects.size(); ++i) {
            mIdMap.put(objects.get(i), i);
        }
    }

    @Override
    public long getItemId(int position) {
        String item = getItem(position);
        return mIdMap.get(item);
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }
}
}

此活动应该提供一些LOcationInformation,但是,当我启动活动时,我的应用程序崩溃并显示以下错误消息:

FATAL EXCEPTION: main
   Process: package.connectivapp, PID: 7694
   java.lang.RuntimeException: Unable to start activity ComponentInfo{package.connectivapp/package.connectivapp.MapsActivity}: java.lang.IllegalArgumentException: invalid provider: null
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
    at android.app.ActivityThread.-wrap12(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6077)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
    Caused by: java.lang.IllegalArgumentException: invalid provider: null
    at android.location.LocationManager.checkProvider(LocationManager.java:2248)
    at android.location.LocationManager.getLastKnownLocation(LocationManager.java:1199)
    at package.connectivapp.MapsActivity.onCreate(MapsActivity.java:72)
    at android.app.Activity.performCreate(Activity.java:6662)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
    at android.app.ActivityThread.-wrap12(ActivityThread.java) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:154) 
    at android.app.ActivityThread.main(ActivityThread.java:6077) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 
02-23 09:20:41.705 1589-2845/system_process W/ActivityManager:   Force finishing activity package.connectivapp/.MapsActivity
02-23 09:20:41.712 1589-2845/system_process W/ActivityManager:   Force finishing activity package.connectivapp/.MainActivity

我知道我没有以良好的方式实施我的Google API。 在第一次,我将元数据添加到我的Manifest:

    <meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value="[A Big String]" />

并在我的项目结构依赖项中添加了“com.google.android.gms:play-services:7.5.0”。

知道,我不知道为什么我的应用程序崩溃了,你知道吗?

3 个答案:

答案 0 :(得分:1)

确保将android.permission.ACCESS_FINE_LOCATION或android.permission.ACCESS_COARSE_LOCATION添加到您的Manifest文件中,这解决了我的问题(所有提供商都已在位置设置中启用)。

用户需要允许应用程序的位置权限从API级别23开始运行,因此如果您使用的是23 API,请执行以下操作

if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                MY_PERMISSIONS_REQUEST_FINE_LOCATION);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
} else {
        //Permission is granted
}

您还必须覆盖此方法:

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

                // permission was granted
            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
                showAlert(getString(R.string.error), getString(R.string.message));
            }
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

如果您对降级API版本没问题,请执行以下操作:

更改build.gradle,如下所示:

compileSdkVersion 21

buildToolsVersion&#34; 21.1.2&#34;

希望它有所帮助。

答案 1 :(得分:1)

之后

<meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="[A Big String]" />

把这个元

<meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />

答案 2 :(得分:0)

不要使用直接提供程序字符串,因为不能保证它在运行时存在。

仅使用从LocationManager获得的提供程序,如下所示:

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

        Criteria criteria = new Criteria();
        criteria.setAccuracy( Criteria.ACCURACY_COARSE );
        String provider = locationManager.getBestProvider( criteria, true );

        if ( provider == null ) {
            Log.e( TAG, "No location provider found!" );
            return;
        }

        lastLocation = locationManager.getLastKnownLocation(provider);

并确保将android.permission.ACCESS_FINE_LOCATION或android.permission.ACCESS_COARSE_LOCATION添加到您的清单文件中。

如果您运行的代码更大,那么Andoird 5.0也会检查premissions

并尝试使用Fused Location API ...位置管理器是获取位置的旧方式。