我不知道请帮助...无法启动活动ComponentInfo {...}:java.lang.NullPointerException

时间:2018-10-27 12:07:15

标签: java android

我是韩国的大学生。 我用翻译器。 请原谅我不柔软。 编写代码,提问时无法解决问题 请帮助我。

下面的代码很简单,唯一的目标是从MainActivity.java导航到Mian2Activity.java。但是,我一直在很多教程中寻找解决方案,但我确实没有得到错了...

这是Main2Activity代码

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


private GoogleApiClient mGoogleApiClient = null;
private GoogleMap mGoogleMap = null;
private Marker currentMarker = null;

private static final String TAG = "googlemap_example";
private static final int GPS_ENABLE_REQUEST_CODE = 2001;
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 2002;
private static final int UPDATE_INTERVAL_MS = 1000;  // 1초
private static final int FASTEST_UPDATE_INTERVAL_MS = 500; // 0.5초

private AppCompatActivity mActivity;
boolean askPermissionOnceAgain = false;
boolean mRequestingLocationUpdates = false;
Location mCurrentLocatiion;
boolean mMoveMapByUser = true;
boolean mMoveMapByAPI = true;
LatLng currentPosition;

LocationRequest locationRequest = new LocationRequest()
        .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
        .setInterval(UPDATE_INTERVAL_MS)
        .setFastestInterval(FASTEST_UPDATE_INTERVAL_MS);


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
            WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    setContentView(R.layout.activity_main);


    Log.d(TAG, "onCreate");
    mActivity = this;


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


    MapFragment mapFragment = (MapFragment) getFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}


@Override
public void onResume() {

    super.onResume();

    if (mGoogleApiClient.isConnected()) {

        Log.d(TAG, "onResume : call startLocationUpdates");
        if (!mRequestingLocationUpdates) startLocationUpdates();
    }


    //앱 정보에서 퍼미션을 허가했는지를 다시 검사해봐야 한다.
    if (askPermissionOnceAgain) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            askPermissionOnceAgain = false;

            checkPermissions();
        }
    }
}


private void startLocationUpdates() {

    if (!checkLocationServicesStatus()) {

        Log.d(TAG, "startLocationUpdates : call showDialogForLocationServiceSetting");
        showDialogForLocationServiceSetting();
    }else {

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            Log.d(TAG, "startLocationUpdates : 퍼미션 안가지고 있음");
            return;
        }


        Log.d(TAG, "startLocationUpdates : call FusedLocationApi.requestLocationUpdates");
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, this);
        mRequestingLocationUpdates = true;

        mGoogleMap.setMyLocationEnabled(true);

    }

}



private void stopLocationUpdates() {

    Log.d(TAG,"stopLocationUpdates : LocationServices.FusedLocationApi.removeLocationUpdates");
    LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
    mRequestingLocationUpdates = false;
}



@Override
public void onMapReady(GoogleMap googleMap) {

    Log.d(TAG, "onMapReady :");

    mGoogleMap = googleMap;


    //런타임 퍼미션 요청 대화상자나 GPS 활성 요청 대화상자 보이기전에
    //지도의 초기위치를 서울로 이동
    setDefaultLocation();

    //mGoogleMap.getUiSettings().setZoomControlsEnabled(false);
    mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
    mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(15));
    mGoogleMap.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener(){

        @Override
        public boolean onMyLocationButtonClick() {

            Log.d( TAG, "onMyLocationButtonClick : 위치에 따른 카메라 이동 활성화");
            mMoveMapByAPI = true;
            return true;
        }
    });
    mGoogleMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {

        @Override
        public void onMapClick(LatLng latLng) {

            Log.d( TAG, "onMapClick :");
        }
    });

    mGoogleMap.setOnCameraMoveStartedListener(new GoogleMap.OnCameraMoveStartedListener() {

        @Override
        public void onCameraMoveStarted(int i) {

            if (mMoveMapByUser == true && mRequestingLocationUpdates){

                Log.d(TAG, "onCameraMove : 위치에 따른 카메라 이동 비활성화");
                mMoveMapByAPI = false;
            }

            mMoveMapByUser = true;

        }
    });


    mGoogleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {

        @Override
        public void onCameraMove() {


        }
    });
}


@Override
public void onLocationChanged(Location location) {

    currentPosition
            = new LatLng( location.getLatitude(), location.getLongitude());


    Log.d(TAG, "onLocationChanged : ");

    String markerTitle = getCurrentAddress(currentPosition);
    String markerSnippet = "위도:" + String.valueOf(location.getLatitude())
            + " 경도:" + String.valueOf(location.getLongitude());

    //현재 위치에 마커 생성하고 이동
    setCurrentLocation(location, markerTitle, markerSnippet);

    mCurrentLocatiion = location;
}


@Override
protected void onStart() {

    if(mGoogleApiClient != null && mGoogleApiClient.isConnected() == false){

        Log.d(TAG, "onStart: mGoogleApiClient connect");
        mGoogleApiClient.connect();
    }

    super.onStart();
}

@Override
protected void onStop() {

    if (mRequestingLocationUpdates) {

        Log.d(TAG, "onStop : call stopLocationUpdates");
        stopLocationUpdates();
    }

    if ( mGoogleApiClient.isConnected()) {

        Log.d(TAG, "onStop : mGoogleApiClient disconnect");
        mGoogleApiClient.disconnect();
    }

    super.onStop();
}


@Override
public void onConnected(Bundle connectionHint) {


    if ( mRequestingLocationUpdates == false ) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            int hasFineLocationPermission = ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION);

            if (hasFineLocationPermission == PackageManager.PERMISSION_DENIED) {

                ActivityCompat.requestPermissions(mActivity,
                        new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
                        PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);

            } else {

                Log.d(TAG, "onConnected : 퍼미션 가지고 있음");
                Log.d(TAG, "onConnected : call startLocationUpdates");
                startLocationUpdates();
                mGoogleMap.setMyLocationEnabled(true);
            }

        }else{

            Log.d(TAG, "onConnected : call startLocationUpdates");
            startLocationUpdates();
            mGoogleMap.setMyLocationEnabled(true);
        }
    }
}


@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

    Log.d(TAG, "onConnectionFailed");
    setDefaultLocation();
}


@Override
public void onConnectionSuspended(int cause) {

    Log.d(TAG, "onConnectionSuspended");
    if (cause == CAUSE_NETWORK_LOST)
        Log.e(TAG, "onConnectionSuspended(): Google Play services " +
                "connection lost.  Cause: network lost.");
    else if (cause == CAUSE_SERVICE_DISCONNECTED)
        Log.e(TAG, "onConnectionSuspended():  Google Play services " +
                "connection lost.  Cause: service disconnected");
}


public String getCurrentAddress(LatLng latlng) {

    //지오코더... GPS를 주소로 변환
    Geocoder geocoder = new Geocoder(this, Locale.getDefault());

    List<Address> addresses;

    try {

        addresses = geocoder.getFromLocation(
                latlng.latitude,
                latlng.longitude,
                1);
    } catch (IOException ioException) {
        //네트워크 문제
        Toast.makeText(this, "지오코더 서비스 사용불가", Toast.LENGTH_LONG).show();
        return "지오코더 서비스 사용불가";
    } catch (IllegalArgumentException illegalArgumentException) {
        Toast.makeText(this, "잘못된 GPS 좌표", Toast.LENGTH_LONG).show();
        return "잘못된 GPS 좌표";

    }


    if (addresses == null || addresses.size() == 0) {
        Toast.makeText(this, "주소 미발견", Toast.LENGTH_LONG).show();
        return "주소 미발견";

    } else {
        Address address = addresses.get(0);
        return address.getAddressLine(0).toString();
    }

}


public boolean checkLocationServicesStatus() {
    LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

    return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
            || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}


public void setCurrentLocation(Location location, String markerTitle, String markerSnippet) {

    mMoveMapByUser = false;


    if (currentMarker != null) currentMarker.remove();


    LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude());

    MarkerOptions markerOptions = new MarkerOptions();
    markerOptions.position(currentLatLng);
    markerOptions.title(markerTitle);
    markerOptions.snippet(markerSnippet);
    markerOptions.draggable(true);

    //구글맵의 디폴트 현재 위치는 파란색 동그라미로 표시
    //마커를 원하는 이미지로 변경하여 현재 위치 표시하도록 수정 fix - 2017. 11.27
    markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher));

    currentMarker = mGoogleMap.addMarker(markerOptions);


    if ( mMoveMapByAPI ) {

        Log.d( TAG, "setCurrentLocation :  mGoogleMap moveCamera "
                + location.getLatitude() + " " + location.getLongitude() ) ;
        // CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(currentLatLng, 15);
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLng(currentLatLng);
        mGoogleMap.moveCamera(cameraUpdate);
    }
}


public void setDefaultLocation() {

    mMoveMapByUser = false;


    //디폴트 위치, Seoul
    LatLng DEFAULT_LOCATION = new LatLng(37.56, 126.97);
    String markerTitle = "위치정보 가져올 수 없음";
    String markerSnippet = "위치 퍼미션과 GPS 활성 요부 확인하세요";


    if (currentMarker != null) currentMarker.remove();

    MarkerOptions markerOptions = new MarkerOptions();
    markerOptions.position(DEFAULT_LOCATION);
    markerOptions.title(markerTitle);
    markerOptions.snippet(markerSnippet);
    markerOptions.draggable(true);
    markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
    currentMarker = mGoogleMap.addMarker(markerOptions);

    CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(DEFAULT_LOCATION, 15);
    mGoogleMap.moveCamera(cameraUpdate);

}


//여기부터는 런타임 퍼미션 처리을 위한 메소드들
@TargetApi(Build.VERSION_CODES.M)
private void checkPermissions() {
    boolean fineLocationRationale = ActivityCompat
            .shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION);
    int hasFineLocationPermission = ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION);

    if (hasFineLocationPermission == PackageManager
            .PERMISSION_DENIED && fineLocationRationale)
        showDialogForPermission("앱을 실행하려면 퍼미션을 허가하셔야합니다.");

    else if (hasFineLocationPermission
            == PackageManager.PERMISSION_DENIED && !fineLocationRationale) {
        showDialogForPermissionSetting("퍼미션 거부 + Don't ask again(다시 묻지 않음) " +
                "체크 박스를 설정한 경우로 설정에서 퍼미션 허가해야합니다.");
    } else if (hasFineLocationPermission == PackageManager.PERMISSION_GRANTED) {


        Log.d(TAG, "checkPermissions : 퍼미션 가지고 있음");

        if ( mGoogleApiClient.isConnected() == false) {

            Log.d(TAG, "checkPermissions : 퍼미션 가지고 있음");
            mGoogleApiClient.connect();
        }
    }
}

@Override
public void onRequestPermissionsResult(int permsRequestCode,
                                       @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {

    if (permsRequestCode
            == PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION && grantResults.length > 0) {

        boolean permissionAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;

        if (permissionAccepted) {


            if ( mGoogleApiClient.isConnected() == false) {

                Log.d(TAG, "onRequestPermissionsResult : mGoogleApiClient connect");
                mGoogleApiClient.connect();
            }



        } else {

            checkPermissions();
        }
    }
}


@TargetApi(Build.VERSION_CODES.M)
private void showDialogForPermission(String msg) {

    AlertDialog.Builder builder = new AlertDialog.Builder(Main2Activity.this);
    builder.setTitle("알림");
    builder.setMessage(msg);
    builder.setCancelable(false);
    builder.setPositiveButton("예", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            ActivityCompat.requestPermissions(mActivity,
                    new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
                    PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
        }
    });

    builder.setNegativeButton("아니오", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            finish();
        }
    });
    builder.create().show();
}

private void showDialogForPermissionSetting(String msg) {

    AlertDialog.Builder builder = new AlertDialog.Builder(Main2Activity.this);
    builder.setTitle("알림");
    builder.setMessage(msg);
    builder.setCancelable(true);
    builder.setPositiveButton("예", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {

            askPermissionOnceAgain = true;

            Intent myAppSettings = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                    Uri.parse("package:" + mActivity.getPackageName()));
            myAppSettings.addCategory(Intent.CATEGORY_DEFAULT);
            myAppSettings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mActivity.startActivity(myAppSettings);
        }
    });
    builder.setNegativeButton("아니오", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            finish();
        }
    });
    builder.create().show();
}


//여기부터는 GPS 활성화를 위한 메소드들
private void showDialogForLocationServiceSetting() {

    AlertDialog.Builder builder = new AlertDialog.Builder(Main2Activity.this);
    builder.setTitle("위치 서비스 비활성화");
    builder.setMessage("앱을 사용하기 위해서는 위치 서비스가 필요합니다.\n"
            + "위치 설정을 수정하실래요?");
    builder.setCancelable(true);
    builder.setPositiveButton("설정", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int id) {
            Intent callGPSSettingIntent
                    = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivityForResult(callGPSSettingIntent, GPS_ENABLE_REQUEST_CODE);
        }
    });
    builder.setNegativeButton("취소", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int id) {
            dialog.cancel();
        }
    });
    builder.create().show();
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    switch (requestCode) {

        case GPS_ENABLE_REQUEST_CODE:

            //사용자가 GPS 활성 시켰는지 검사
            if (checkLocationServicesStatus()) {
                if (checkLocationServicesStatus()) {

                    Log.d(TAG, "onActivityResult : 퍼미션 가지고 있음");


                    if ( mGoogleApiClient.isConnected() == false ) {

                        Log.d( TAG, "onActivityResult : mGoogleApiClient connect ");
                        mGoogleApiClient.connect();
                    }
                    return;
                }
            }

            break;
    }
}

}

和此MainActivity代码

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button bttest1 = (Button)findViewById(R.id.bttest1);
    bttest1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(getApplicationContext(),Main2Activity.class);
            startActivity(intent);
        }
    });
}

}

无法启动活动ComponentInfo {...}:java.lang.NullPointerException

此处发生错误。(Main2Activity)

    mapFragment.getMapAsync(this);

该错误的原因是什么? 请帮帮我。

1 个答案:

答案 0 :(得分:1)

在Main2Activity onCreate中,您使用setContentView(R.layout.activity_main);  它似乎是来自MainActivity的布局,而不是Main2Activity。您应该在第二个活动中输入类似R.layout.activity_main2的内容。

然后输入您的代码

MapFragment mapFragment = (MapFragment) getFragmentManager() .findFragmentById(R.id.map);

可能找不到ID为R.id.map的视图,因为该视图不是第一个MainActivity布局的一部分。