Can't get passed Google Drive "Choose Account" screen in Android - java

I'm trying to incorporate the Google Drive API within my android application.
I have added google play services to my build.gradle along with getting the Android API key. My issue is within the OnResume() where the user picks the account.
It just keeps reprompting the user to choose account and does not proceed.
May anyone help me ?
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener{
private static final String TAG = "Google Drive Activity";
private static final int REQUEST_CODE_RESOLUTION = 1;
private static final int REQUEST_CODE_OPENER = 2;
private GoogleApiClient mGoogleApiClient;
private boolean fileOperation = false;
private DriveId mFileId;
public DriveFile file;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient != null) {
// disconnect Google API client connection
mGoogleApiClient.disconnect();
}
super.onPause();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
if (!result.hasResolution()) {
GoogleApiAvailability.getInstance().getErrorDialog(this, result.getErrorCode(), 0).show();
return;
}
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
#Override
public void onConnected(Bundle connectionHint) {
Toast.makeText(getApplicationContext(), "Connected", Toast.LENGTH_LONG).show();
}
#Override
public void onConnectionSuspended(int cause) {
Log.i(TAG, "GoogleApiClient connection suspended");
}
public void onClickCreateFile(View view){
fileOperation = true;
Drive.DriveApi.newDriveContents(mGoogleApiClient)
.setResultCallback(driveContentsCallback);
}
public void onClickOpenFile(View view){
fileOperation = false;
Drive.DriveApi.newDriveContents(mGoogleApiClient)
.setResultCallback(driveContentsCallback);
}
public void OpenFileFromGoogleDrive(){
IntentSender intentSender = Drive.DriveApi
.newOpenFileActivityBuilder()
.setMimeType(new String[] { "text/plain", "text/html" })
.build(mGoogleApiClient);
try {
startIntentSenderForResult(
intentSender, REQUEST_CODE_OPENER, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
Log.w(TAG, "Unable to send intent", e);
}
}
final ResultCallback<DriveApi.DriveContentsResult> driveContentsCallback =
new ResultCallback<DriveApi.DriveContentsResult>() {
#Override
public void onResult(DriveApi.DriveContentsResult result) {
if (result.getStatus().isSuccess()) {
if (fileOperation == true) {
CreateFileOnGoogleDrive(result);
} else {
OpenFileFromGoogleDrive();
}
}
}
};
public void CreateFileOnGoogleDrive(DriveApi.DriveContentsResult result){
final DriveContents driveContents = result.getDriveContents();
new Thread() {
#Override
public void run() {
// write content to DriveContents
OutputStream outputStream = driveContents.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
try {
writer.write("Hello abhay!");
writer.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("abhaytest2")
.setMimeType("text/plain")
.setStarred(true).build();
Drive.DriveApi.getRootFolder(mGoogleApiClient)
.createFile(mGoogleApiClient, changeSet, driveContents)
.setResultCallback(fileCallback);
}
}.start();
}
final private ResultCallback<DriveFolder.DriveFileResult> fileCallback = new
ResultCallback<DriveFolder.DriveFileResult>() {
#Override
public void onResult(DriveFolder.DriveFileResult result) {
if (result.getStatus().isSuccess()) {
Toast.makeText(getApplicationContext(), "file created: "+""+
result.getDriveFile().getDriveId(), Toast.LENGTH_LONG).show();
}
return;
}
};
#Override
protected void onActivityResult(final int requestCode,
final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_CODE_OPENER:
if (resultCode == RESULT_OK) {
mFileId = (DriveId) data.getParcelableExtra(
OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
Log.e("file id", mFileId.getResourceId() + "");
String url = "https://drive.google.com/open?id="+ mFileId.getResourceId();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
}
This is my manifest. Blocking the API Key.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="edu.moli9479csumb.version1googledrive">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyD_2eJ5pPdRMysVwxxxxxxxxxxxxxx"/>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"/>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

You get the AccountSelector when the GoogleApiClient is not able to connect and has a resolution which requires the user to authorize the App for the API. This happens when you call "result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);" from the onConnectionFailed method.
Once the user selects the account your activity gets a callback with the code REQUEST_CODE_RESOLUTION. This code must be handled and you should call apiClient.connect() to connect again when this code is received in onActivityResult method.
See this for more details. I hope it works :)

You can easily force to prompt the user to choose account by using [Account Picker](https://developer.android.com/reference/android/accounts/AccountManager.html#newChooseAccountIntent(android.accounts.Account, java.util.ArrayList, java.lang.String[], boolean, java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle)), common account picker is similar to the standard framework account picker introduced in newChooseAccountIntent. Returns an intent to an Activity that prompts the user to choose from a list of accounts. The caller will then typically start the activity by calling startActivityForResult(intent, ...);.
On success the activity returns a Bundle with the account name and type specified using keys KEY_ACCOUNT_NAME and KEY_ACCOUNT_TYPE.
The most common case is to call this with one account type, e.g.:
Intent intent = AccountPicker.newChooseAccountIntent(null, null, new String[]{"com.google"},
false, null, null, null, null);
startActivityForResult(intent, SOME_REQUEST_CODE);
The account picker activity will return when the user has selected and/or created an account, and the resulting account name can be retrieved as follows:
protected void onActivityResult(final int requestCode, final int resultCode,
final Intent data) {
if (requestCode == SOME_REQUEST_CODE && resultCode == RESULT_OK) {
String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
}
}
Here's the Official Google Sample code which uses the above code with concrete explanation how to use API: https://developers.google.com/drive/v3/web/quickstart/android#step_5_setup_the_sample

Take a look at your onResume() and onConnectionFailded() methods.
#Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
if (!result.hasResolution()) {
GoogleApiAvailability.getInstance().getErrorDialog(this, result.getErrorCode(), 0).show();
return;
}
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
What happens?
In onResume() you create GoogleApiClient and call connect(). Connection fails because you are not authorized with an account. Method onConnectionFailed() is executed which opens a resolution which is actually another activity called for result. You choose an acount but I guess authorization fails or is cancelled.
You return to your original activity and onResume() is executed. And you go a full circle again.
Why does your authorization fail? I guess because there is something wrong with your credentials. Go to Developer console and create O Auth credentials for your package and your key signature.

Related

Facebook reloaded twice in web browser from mobile app

While Clicking on facebook button,redirect to web browser and open facebook login page.After enter our credentials and need to click the CONTINUE Button, On first click of Continue button, facebook page reloaded and second time it fetched all User details (Email,first Name,Last Name,Profile pic) on Android 9 OS only..Android 10,11 12 OS devices working.
We have used android:launchmode as SINGLETASK for android 10,11 & 12.but Android 9 OS not supporting.
Library : implementation 'com.facebook.android:facebook-android-sdk:14.1.1'
Android Manifest:
<provider
android:name="com.facebook.FacebookContentProvider"
android:authorities="com.facebook.app.FacebookContentProvider399122648326004"
android:exported="true"
tools:ignore="ExportedContentProvider" />
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id" />
<meta-data
android:name="com.facebook.sdk.ClientToken"
android:value="#string/facebook_client_token" />
android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="#string/app_name"
android:launchMode="singleTask"
android:theme="#android:style/Theme.Translucent.NoTitleBar"
tools:replace="android:theme" />
In Android code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ThemeUtils.changeTheme(this);
setContentView(R.layout.activity);
FacebookSdk.sdkInitialize(ApprovalInHours.this);
callbackManager = CallbackManager.Factory.create();
facebookLogin();
});
Here We have written code for loginbutton and asking ReadPermissions
loginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loginManager.logInWithReadPermissions(ApprovalInHours.this, Arrays.asList(
"email",
"public_profile",
"user_birthday"));
}
});
Code for facebookLogin() and fetching user facebook details:
private void facebookLogin() {
LoginManager.getInstance().registerCallback(callbackManager,new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Log.d("onSuccess",""+loginResult.toString());
//Use GraphApi to get the information into the app.
GraphRequest request = GraphRequest.newMeRequest(
//pass two parameter
loginResult.getAccessToken(), //one is the current token
new GraphRequest.GraphJSONObjectCallback() //2nd is grahJSONObject callback
{
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
Log.v("MainActivity", response.toString() + "getToken" + AccessToken.getCurrentAccessToken());
// Application code
try {
String obj = object.toString(); //get complete JSON object refrence.
String name = object.getString("first_name"); //get particular JSON Object
String last_name = object.getString("last_name");
final_name = name + last_name;
Log.d("checkFinalName", "" + final_name);
} catch (Exception e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,gender,birthday");
parameters.putString(
"fields",
"id, first_name, last_name, name, picture, email,gender"
);
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
Log.d("onCancel","onCancel");
}
#Override
public void onError(FacebookException exception) {
Log.d("onError","onCancel"+exception.getMessage());
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
callbackManager.onActivityResult(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == -1){
LoginManager.getInstance().logOut();
}
Log.d("checkLog",""+"checkLog");
}

Why can't I implement Google places API?

I am trying to implement the Place Picker API by Google. But every time I start the activity, it just closes instantly.
Code for implementing Place Picker:
int PLACE_PICKER_REQUEST = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pop_up_2);
btn3 = (Button) findViewById(R.id.button2);
btn3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
Context context = getApplicationContext();
try {
startActivityForResult(builder.build(context), PLACE_PICKER_REQUEST);
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PLACE_PICKER_REQUEST) {
if (resultCode == RESULT_OK) {
Place place = PlacePicker.getPlace(data, this);
String toastMsg = String.format("Place: %s", place.getName());
Toast.makeText(this, toastMsg, Toast.LENGTH_LONG).show();
}
}
}
The API key has been declared in my manifest file:
<manifest>
<application
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_place_api" />
</application>
</manifest>
Logcat error:
BasicNetwork.performRequest: Unexpected response code 403 for https://www.googleapis.com/placesandroid/v1/search?key=AIzaSyCHWpRWCGo_YUKwzHn4Qv6yP5q9E5TNRJA
2019-04-28 07:49:21.729 2875-5225/? E/Places: Places API for Android does not seem to be enabled for your app. See https://developers.google.com/places/android/signup for more details.
Why does this error occur even though Google places is enabled on my account?
Note: I have also set up my billing account.
Places API for Android does not seem to be enabled for your app: double check it
private void openAutocompleteActivity(int req) {
try {
PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_FULLSCREEN)
// .build(this);
PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
startActivityForResult(builder.build(this), req);
// PlacePicker.IntentBuilder builder1= new PlacePicker().IntentBuilder();
// startActivity(builder1.build(this), 112);
// startActivityForResult(intent, REQUEST_CODE_AUTOCOMPLETE);
} catch (GooglePlayServicesRepairableException e) {
GoogleApiAvailability.getInstance().getErrorDialog(this,
e.getConnectionStatusCode(),
0 /* requestCode */).show();
} catch (GooglePlayServicesNotAvailableException e) {
String message = "Google Play Services is not available: " +
GoogleApiAvailability.getInstance().getErrorString(e.errorCode);
// Log.e(TAG, message);
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
}
/**
* Called after the autocomplete activity has finished to return its result.
*/
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Check that the result was from the autocomplete widget.
if (resultCode == RESULT_OK) {
Place place = PlaceAutocomplete.getPlace(this, data);
LatLng xyzlatlng= place.getLatLng();
double lat=xyzlatlng.latitude;
double lon=xyzlatlng.longitude;
}
}

How to force app to end if user disable their internet connection during running of app?

I want to force app to end if user disable his internet connection during running of app
I tried this code and work good at the begining of app but when I disable internet during running it isnt closed!
this is my code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_log_reg);
if(!isNetworkAvailable(this)) {
Toast.makeText(this,"No Internet connection",Toast.LENGTH_LONG).show();
finish(); //Calling this method to close this activity when internet is not available.
}
register_btn = (Button)findViewById(R.id.registerbtn);
register_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i=new Intent(LogRegActivity.this,RegisterActivity.class);
startActivity(i);
}
});
login_btn=(Button)findViewById(R.id.loginbtn);
login_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i =new Intent(LogRegActivity.this,LoginActivity.class);
startActivity(i);
}
});
}
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager conMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if(conMan.getActiveNetworkInfo() != null && conMan.getActiveNetworkInfo().isConnected())
return true;
else
return false;
}
}
this is my build.gradle when i used broadcast receiver it shows that using reciever is deprecated for N or higher how can i fix this problem??
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
android {
compileSdkVersion 27
defaultConfig {
applicationId "net.amr.myapplication"
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
Use broadcast receiver for connectivity change, here is steps for achieve this:
Step 1 : register receiver in manifest.xml
<receiver android:name="NetworkChangeReceiver ">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
<action android:name="android.location.PROVIDERS_CHANGED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Step 2 : Create broadcast receiver :
public class NetworkChangeReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
if(checkInternet(context))
{
Toast.makeText(context, "Network Available",Toast.LENGTH_LONG).show();
}
}
boolean checkInternet(Context context) {
ServiceManager serviceManager = new ServiceManager(context);
if (serviceManager.isNetworkAvailable()) {
return true;
} else {
return false;
}
}
}
Step 3 : Broadcast receiver which will handle network change:
public class HandleNetwork extend AppcompatActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerNetworkBroadcastForNougat();
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (isNetworkAvailable(this)) {
//logic on network enable
} else {
//logic on network disable
}
public static boolean isNetworkAvailable(Context context) {
if (context == null) return false;
try {
ConnectivityManager connManager = (ConnectivityManager) context.getSystemService
(Context.CONNECTIVITY_SERVICE);
if (connManager.getActiveNetworkInfo() != null && connManager.getActiveNetworkInfo()
.isAvailable() && connManager.getActiveNetworkInfo().isConnected()) {
return true;
}
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
return false;
}
//Register receiver
private void registerNetworkBroadcastForNougat() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
registerReceiver(mMessageReceiver , new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
registerReceiver(mMessageReceiver , new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
}
protected void unregisterNetworkChanges() {
try {
unregisterReceiver(mNetworkReceiver);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterNetworkChanges();
}
}
}
Hope it will help you!!
You need to register a broadcast receiver for CONNECTIVITY_ACTION. There you can check for the state of the connection.
Also see the official documentation.
You need to create one activity and and open that activity with following flags and then finish it by calling finish() in onCreate() of created activity.
add following code where you are checking internet connectivity
startActivity(new Intent(this, NoInternetActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK)))
in NoInternetActivity activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
finish();
}
and don't forget to add NoInternetActivity in manifest

WebService request response in Service when app is closed android

I have a Service class in my android app.
This service get user location and send location to server with ASP WebService.
Below is my service code :
public class ServiceSendLocation extends Service {
private static final String TAG = "ServiceSendLocation";
final long milliseconds_sleep = 3000;
private boolean isRunning = false;
#Override
public void onCreate() {
super.onCreate();
isRunning = true;
Log.i(TAG, "Service onCreate");
}
#Override
public int onStartCommand(Intent intent, int flags, final int startId) {
Log.i(TAG, "Service onStartCommand");
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
Thread.sleep(milliseconds_sleep);
} catch (Exception e) {}
getLocationAndSend();
if (isRunning)
Log.i(TAG, "Service running");
}
}
}
}).start();
return Service.START_STICKY;
}
private void getLocationAndSend() {
Log.i(TAG, "Service getLocationAndSend");
LocationManager locationManager = null;
LocationListener locationListener = new ServiceGetLocation();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Service PERMISSION_GRANTED");
try {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
HelperWS.register(structCheckUser.getUserId(), ServiceGetLocation.lat + "", ServiceGetLocation.lng + "", new HelperWS.InsertGpsDriver() {
#Override
public void onSuccess(StructInsertGpsDriver success) {
Log.i(TAG, "Success : " +ServiceGetLocation.lat + ", " + ServiceGetLocation.lng);
Toast.makeText(ServiceSendLocation.this, "success : " +ServiceGetLocation.lat + ", " + ServiceGetLocation.lng , Toast.LENGTH_SHORT).show();
}
#Override
public void onFail(String message) {
Log.i(TAG, "onFail");
}
});
} catch (Exception e) {}
} else {
Log.i(TAG, "Service PERMISSION_NOT_GRANTED");
}
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
isRunning = false;
Log.i(TAG, "Service onDestroy");
}
}
and in manifest :
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
...>
<service
android:name=".SendLocation.ServiceSendLocation" />
</application>
This code sends the location information to the server and get the response form WebService. But when app is closed this code get the location information and also send request but we don't get webService response
Somebody please help me.

android location apis : FusedLocationApi.getLastLocation is giving null

I am trying to find last known location of device using GoogleApiClient, So I used fine level access, but getting following exception because location coming is null.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.kuldeep.location2, PID: 1421
java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference
at com.example.kuldeep.location2.MainActivity.onConnected(MainActivity.java:51)
private GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onConnected(Bundle bundle) {
try {
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
Toast.makeText(this, mLastLocation.getLatitude() + ", " + mLastLocation.getLongitude(), Toast.LENGTH_SHORT);
} catch (SecurityException e){
e.printStackTrace();
}
}
My manifest file is as follow :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.kuldeep.location2">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
</manifest>
First of all, getLastLocation() can be null so you be carefull acessing directly to mLastLocation without a "null" check. In second place, i suggest you to add in your manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
and then call a LocationRequest.
if(locRequest== null)
{
locRequest= new LocationRequest();
locRequest.setInterval( interval );
locRequest.setFastestInterval( fastestInterval );
locRequest.setPriority( priority );
LocationServices.FusedLocationApi.requestLocationUpdates(yourGoogleApiClient, locRequest, this);
}
Using GoogleApiClient find a CurrentLocation like these:
private GoogleApiClient googleApiClient;
private Location mLastLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
isCheckLocationServiceisOn(context);
if(googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
protected void onResume() {
super.onResume();
isCheckLocationServiceisOn(context);
}
#Override
public void onConnected(Bundle arg0) {
if(googleApiClient.isConnected()) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (mLastLocation != null) {
System.out.println("latiTude....."+ String.valueOf(mLastLocation.getLatitude()));
System.out.println("longiTude....."+ String.valueOf(mLastLocation.getLongitude()));
}
}
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
System.out.println("onConnectionFailed...."+ arg0.toString());
}
#Override
public void onConnectionSuspended(int arg0) {
System.out.println("onConnectionSuspended...."+ arg0);
}
Add Permission in manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Here,
Implements ConnectionCallbacks, OnConnectionFailedListener interface for that supported override methods they must be com.google.android.gms.common.api.GoogleApiClient package.
MUST REMEMBER:
Wi-Fi and GSM and GPS is must be on in device if not then generate these kind of error in onConnected()
I give you code to check & open location service also:
public static void isCheckLocationServiceisOn (final Context context) {
LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
boolean gps_enabled = false;
boolean network_enabled = false;
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
catch(Exception ex) {}
try {
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
catch(Exception ex) {}
if(!gps_enabled && !network_enabled) {
// notify user
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setMessage("Location Services Disabled. \n Please enable location services.");
dialog.setPositiveButton("Enable", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
Intent myIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(myIntent);
//get gps
}
});
dialog.setNegativeButton("Cancle", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
}
});
dialog.show();
}
}

Categories