0

I am a Korean university student. I use a translator. Please excuse me for not being soft. Failed to resolve issue while writing code, asking questions Please help me.

The code below is quite simple and the only goal is to navigate from MainActivity.java to Mian2Activity.java However, I've been looking for a solution to this on a lot of tutorial and I really don't get what I'm doing wrong...

this is Main2Activity Code

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

}

and this MainActivity Code

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

}

Unable to start activity ComponentInfo{...}: java.lang.NullPointerException

An error occurs here.(Main2Activity)

    mapFragment.getMapAsync(this);

What is the reason for the error? Help me, please.

백영준
  • 3
  • 4

1 Answers1

1

In your Main2Activity onCreate, you use setContentView(R.layout.activity_main); It seems to be layout from MainActivity, not Main2Activity. You should make something like R.layout.activity_main2 for your second activity.

Then, your code

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

probably won't find view with ID R.id.map, because that view isn't part of first MainActivity layout.

Kubik
  • 610
  • 7
  • 15