Call DialogFragment from a custom Fragment, then set its property - android

After having successfully followed the guide Accessing Google APIs, I am trying to move all the Google+ related code from my MainActivity to a separate custom GoogleFragment.
However I am stuck at the very last spot - in my custom Fragment, I don't know how to access the mResolvingError field after the DialogFragment has been dismissed:
public class GoogleFragment extends Fragment
implements GoogleApiClient.OnConnectionFailedListener {
private boolean mResolvingError = false; // HOW TO ACCESS?
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (mResolvingError) {
// Already attempting to resolve an error.
return;
} else if (connectionResult.hasResolution()) {
try {
mResolvingError = true;
connectionResult.startResolutionForResult(getActivity(), REQUEST_RESOLVE_ERROR);
} catch (IntentSender.SendIntentException e) {
// There was an error with the resolution intent. Try again.
if (mGoogleApiClient != null)
mGoogleApiClient.connect();
}
} else {
// Show dialog using GoogleApiAvailability.getErrorDialog()
showErrorDialog(connectionResult.getErrorCode());
mResolvingError = true;
}
}
private void showErrorDialog(int errorCode) {
// Create a fragment for the error dialog
ErrorDialogFragment dialogFragment = new ErrorDialogFragment();
// Pass the error that should be displayed
Bundle args = new Bundle();
args.putInt(ARGS_DIALOG_ERROR, errorCode);
dialogFragment.setArguments(args);
dialogFragment.show(getActivity().getSupportFragmentManager(), TAG_DIALOG_ERROR);
}
public static class ErrorDialogFragment extends DialogFragment {
public ErrorDialogFragment() {
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the error code and retrieve the appropriate dialog
int errorCode = this.getArguments().getInt(ARGS_DIALOG_ERROR);
return GoogleApiAvailability.getInstance().getErrorDialog(
this.getActivity(),
errorCode,
REQUEST_RESOLVE_ERROR);
}
#Override
public void onDismiss(DialogInterface dialog) {
mResolvingError = false; // DOES NOT COMPILE
}
}
}
What should I do here please?
If I make the ErrorDialogFragment non-static I get compile error:
This fragment inner class should be static
(GoogleFragment.ErrorDialogFragment)
If I keep it static - I can not access the variable either.
I am thinking of 2 workarounds for my problem:
Using LocalBroadcastManager to send a custom Intent from ErrorDialogFragment to GoogleFragment
Define a custom method in GoogleFragment and access it through getSupportFragmentManager().findFragmentByTag()
But is there maybe a simpler solution?
UPDATE:
I've changed the mResolvingError field to public and have tried this code:
#Override
public void onDismiss(DialogInterface dialog) {
GoogleFragment f = (GoogleFragment) getActivity().getSupportFragmentManager().findFragmentByTag(GoogleFragment.TAG);
if (f != null && f.isVisible()) {
f.mResolvingError = false;
}
}
but I am not sure how to test this properly and if f.isVisible() is needed there...
UPDATE 2:
Maybe I should somehow use DialogInterface.OnDismissListener with GoogleApiAvailability.getInstance().getErrorDialog in my code?

BladeCoder's comments have been very insightful, thanks.
However I have realized, that all the hassle with saving and restoring mResolvingError is unnecessary, because startResolutionForResult() starts a separate Activity anyway and obstructs my app - so it doesn't really matter if I rotate device or not.
Here is my final code to initiate GCM and fetch Google+ user data -
MainActivity.java:
public static final int REQUEST_GOOGLE_PLAY_SERVICES = 1972;
public static final int REQUEST_GOOGLE_PLUS_LOGIN = 2015;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null)
startRegistrationService();
}
private void startRegistrationService() {
GoogleApiAvailability api = GoogleApiAvailability.getInstance();
int code = api.isGooglePlayServicesAvailable(this);
if (code == ConnectionResult.SUCCESS) {
onActivityResult(REQUEST_GOOGLE_PLAY_SERVICES, Activity.RESULT_OK, null);
} else if (api.isUserResolvableError(code) &&
api.showErrorDialogFragment(this, code, REQUEST_GOOGLE_PLAY_SERVICES)) {
// wait for onActivityResult call (see below)
} else {
String str = GoogleApiAvailability.getInstance().getErrorString(code);
Toast.makeText(this, str, Toast.LENGTH_LONG).show();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode) {
case REQUEST_GOOGLE_PLAY_SERVICES:
if (resultCode == Activity.RESULT_OK) {
Intent i = new Intent(this, RegistrationService.class);
startService(i); // OK, init GCM
}
break;
case REQUEST_GOOGLE_PLUS_LOGIN:
if (resultCode == Activity.RESULT_OK) {
GoogleFragment f = (GoogleFragment) getSupportFragmentManager().
findFragmentByTag(GoogleFragment.TAG);
if (f != null && f.isVisible())
f.onActivityResult(requestCode, resultCode, data);
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
}
}
GoogleFragment.java:
public class GoogleFragment extends Fragment
implements View.OnClickListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
public final static String TAG = "GoogleFragment";
private GoogleApiClient mGoogleApiClient;
private ImageButton mLoginButton;
private ImageButton mLogoutButton;
public GoogleFragment() {
// required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_google, container, false);
mGoogleApiClient = new GoogleApiClient.Builder(getContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_PROFILE)
.build();
mLoginButton = (ImageButton) v.findViewById(R.id.login_button);
mLoginButton.setOnClickListener(this);
mLogoutButton = (ImageButton) v.findViewById(R.id.logout_button);
mLogoutButton.setOnClickListener(this);
return v;
}
private void googleLogin() {
mGoogleApiClient.connect();
}
private void googleLogout() {
if (mGoogleApiClient.isConnecting() || mGoogleApiClient.isConnected())
mGoogleApiClient.disconnect();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK)
mGoogleApiClient.connect();
}
#Override
public void onClick(View v) {
if (v == mLoginButton)
googleLogin();
else
googleLogout();
}
#Override
public void onConnected(Bundle bundle) {
Person me = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
if (me != null) {
String id = me.getId();
Person.Name name = me.getName();
String given = name.getGivenName();
String family = name.getFamilyName();
boolean female = (me.hasGender() && me.getGender() == 1);
String photo = null;
if (me.hasImage() && me.getImage().hasUrl()) {
photo = me.getImage().getUrl();
photo = photo.replaceFirst("\\bsz=\\d+\\b", "sz=300");
}
String city = "Unknown city";
List<Person.PlacesLived> places = me.getPlacesLived();
if (places != null) {
for (Person.PlacesLived place : places) {
city = place.getValue();
if (place.isPrimary())
break;
}
}
Toast.makeText(getContext(), "Given: " + given + ", Family: " + family + ", Female: " + female + ", City: " + city, Toast.LENGTH_LONG).show();
}
}
#Override
public void onConnectionSuspended(int i) {
// ignore? don't know what to do here...
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(getActivity(), MainActivity.REQUEST_GOOGLE_PLUS_LOGIN);
} catch (IntentSender.SendIntentException e) {
mGoogleApiClient.connect();
}
} else {
int code = connectionResult.getErrorCode();
String str = GoogleApiAvailability.getInstance().getErrorString(code);
Toast.MakeText(getContext(), str, Toast.LENGTH_LONG).show();
}
}
}

Related

GoogleMapSnapshot NullPointerException

I am trying to take a screenshot of google maps android and pass the image to a new activity but I keep getting this error:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.GoogleMap.snapshot(com.google.android.gms.maps.GoogleMap$SnapshotReadyCallback)' on a null object reference
at com.jjoey.transportr.activities.BookRideActivity.initViews(BookRideActivity.java:480)
at com.jjoey.transportr.activities.BookRideActivity.onCreate(BookRideActivity.java:101)
at android.app.Activity.performCreate(Activity.java:5990)
I have tried writing the code in onResume and onMapReady methods of activity but still error persists.
Here's my code for activity:
public class BookRideActivity extends FirebaseUtils implements OnMapReadyCallback {
private static final String TAG = BookRideActivity.class.getSimpleName();
private static final int LOC_REQ_CODE = 2035;
private Toolbar toolbar;
private ImageView backIV;
private SharedPrefsHelper prefsHelper;
private SupportMapFragment mapFragment;
private GoogleMap mGmap;
private LocationRequest locationRequest;
private FusedLocationProviderClient fusedLocationProviderClient;
private LocationCallback callback;
private Location mCurrLocation;
private Marker marker;
private Bitmap locnImg;
private EditText startET, dropET, et_coupon, et_payment_options, et_rider;
private TextView estimatedPUTimeTV;
private Button bookNowBtn, cancelBtn;
private double lat = 0f, lon = 0f;
private String start = null, drop = null;
private boolean isValid = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book_ride);
initViews();
start = getIntent().getStringExtra("start_addr");
drop = getIntent().getStringExtra("dest_addr");
if (start != null && drop != null) {
startET.setText(start);
dropET.setText(drop);
} else {
clearInputs();
}
setSupportActionBar(toolbar);
prefsHelper = new SharedPrefsHelper(this);
prefsHelper.setLoggedOut(false);
backIV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(BookRideActivity.this, ClientHomeActivity.class));
}
});
et_coupon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d(TAG, "Coupon Clicked");
showCouponDialog();
}
});
checkPerms();
handlePlacesInput();
}
private void checkPerms() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
reqPerms();
} else {
startLocationListener();
}
}
private void reqPerms() {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOC_REQ_CODE);
}
private void startLocationListener() {
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setSmallestDisplacement(DISPLACEMENT);
locationRequest.setFastestInterval(FASTEST_INTERVAL);
locationRequest.setInterval(UPDATE_INTERVAL);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(locationRequest);
LocationSettingsRequest settingsRequest = builder.build();
SettingsClient client = LocationServices.getSettingsClient(this);
client.checkLocationSettings(settingsRequest);
drawLocationOnMap();
}
private void drawLocationOnMap() {
callback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
mCurrLocation = locationResult.getLastLocation();
if (marker != null && mCurrLocation != null) {
marker.remove();
lat = mCurrLocation.getLatitude();
lon = mCurrLocation.getLongitude();
}
MarkerOptions options = new MarkerOptions();
options.position(new LatLng(lat, lon));
options.title("You");
options.icon(BitmapDescriptorFactory.fromResource(R.drawable.user_marker));
marker = mGmap.addMarker(options);
mGmap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lon), 18.0f));
}
};
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
fusedLocationProviderClient.requestLocationUpdates(locationRequest, callback, Looper.myLooper());
//mGmap.setMyLocationEnabled(true);
} else {
reqPerms();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case LOC_REQ_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startLocationListener();
}
break;
}
}
private void handlePlacesInput() {
startET.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startET.setText("");
try {
Intent intent =
new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_OVERLAY)
.build(BookRideActivity.this);
startActivityForResult(intent, START_PLACE_AUTOCOMPLETE_REQUEST_CODE);
} catch (GooglePlayServicesRepairableException e) {
Log.d(TAG, "Play-Services-Repairable Err:\t" + e.getMessage());
} catch (GooglePlayServicesNotAvailableException e) {
Log.d(TAG, "Play-Services-Unavailable Err:\t" + e.getMessage());
}
}
});
dropET.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dropET.setText("");
try {
Intent intent =
new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_OVERLAY)
.build(BookRideActivity.this);
startActivityForResult(intent, DROP_PLACE_AUTOCOMPLETE_REQUEST_CODE);
} catch (GooglePlayServicesRepairableException e) {
Log.d(TAG, "Play-Services-Repairable Err:\t" + e.getMessage());
} catch (GooglePlayServicesNotAvailableException e) {
Log.d(TAG, "Play-Services-Unavailable Err:\t" + e.getMessage());
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case START_PLACE_AUTOCOMPLETE_REQUEST_CODE:
if (resultCode == RESULT_OK) {
Place place = PlaceAutocomplete.getPlace(this, data);
String txt = place.getAddress().toString();
startET.setText(txt);
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
Status status = PlaceAutocomplete.getStatus(this, data);
Log.d(TAG, status.getStatusMessage());
} else if (resultCode == RESULT_CANCELED) {
}
break;
case DROP_PLACE_AUTOCOMPLETE_REQUEST_CODE:
if (resultCode == RESULT_OK) {
Place place = PlaceAutocomplete.getPlace(this, data);
String txt = place.getAddress().toString();
dropET.setText(txt);
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
Status status = PlaceAutocomplete.getStatus(this, data);
Log.d(TAG, status.getStatusMessage());
} else if (resultCode == RESULT_CANCELED) {
}
break;
}
}
private boolean validate() {
String startAddr = startET.getText().toString();
String destAddr = dropET.getText().toString();
if (TextUtils.isEmpty(startAddr) && TextUtils.isEmpty(destAddr)) {
isValid = false;
} else if (!TextUtils.isEmpty(startAddr) && !TextUtils.isEmpty(destAddr)) {
isValid = true;
}
return true;
}
private void clearInputs() {
startET.setText("");
dropET.setText("");
}
private void initViews() {
toolbar = findViewById(R.id.toolbar);
backIV = findViewById(R.id.backIV);
dropET = findViewById(R.id.dropLocationET);
startET = findViewById(R.id.startLocationET);
bookNowBtn = findViewById(R.id.bookNowBtn);
cancelBtn = findViewById(R.id.cancelBtn);
GoogleMap.SnapshotReadyCallback snapshotReadyCallback = new GoogleMap.SnapshotReadyCallback() {
#Override
public void onSnapshotReady(Bitmap bitmap) {
locnImg = bitmap;
Log.d(TAG, "Snapshot Ready");
}
};
mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapFragment);
mapFragment.getMapAsync(this);
mGmap.snapshot(snapshotReadyCallback);
Log.d(TAG, "Snapshot Taken");
}
#Override
public void onMapReady(GoogleMap googleMap) {
mGmap = googleMap;
View mapBtn = (View) ((View) mapFragment.getView().findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mapBtn.getLayoutParams();
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
params.setMargins(0, 0, 30, 30);
}
}
I have tried following this tutorial but it doesn't work in my case.The error occurs when I try mGmap.snapshot(snapshotReadyCallback);. I have initialized the map in the lines above and gotten the location using FusedLocationProviderClient api.
Can anyone help me understand why it's throwing this error? Thanks

How to implement Google Fit step counter within a Fragment

I've been looking for a solution to this and I came across several answers that didn't fit the use-case. The sample code from Google works fine if imported as is, but the code sits in an Activity and is messy if you want to integrate into a real project where the code would ideally be in a fragment.
The issue is with the enableAutoManage functionality and what to do in the fresh install case where the googleApiClient is built but the authentication/account-pick screen is not yet done and you end up with connection failed on the googleApiClient. I'm going to answer this in full, below.
Here is a sample Activity that will load the GoogleFit_Fragment into the FrameLayout:
public class Main_Activity extends AppCompatActivity {
public static int USER_AUTHORISED_REQUEST_CODE = 5;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
This will load the GoogleFit_Fragment into the FrameLayout,
which will cause the buildFitnessClient() function to be called from the Fragment,
which will cause this Activity to popup the authentication screen
*/
getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.fade_in, R.anim.fade_out)
.replace(R.id.fragment_container, new GoogleFit_Fragment()).commit();
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
/*
The result of the account chooser is here,
send it to the fragment so we can handle it inside
*/
fragmentReplace.onActivityResult(USER_AUTHORISED_REQUEST_CODE, resultCode, data);
}
}
The GoogleFit_Fragment:
public class GoogleFit_Fragment extends Fragment {
public static final String TAG = "Sample";
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 1;
private GoogleApiClient googleApiFitnessClient;
private OnDataPointListener mListener;
private View fragmentView;
private Activity parentActivity;
#Override
public void onStop() {
super.onStop();
if (googleApiFitnessClient != null) {
Log.d(TAG, "onStop REACHED, client not null and is connected");
googleApiFitnessClient.stopAutoManage(getActivity());
googleApiFitnessClient.disconnect();
}
}
#Override
public void onResume() {
super.onResume();
if (googleApiFitnessClient != null) {
Log.d(TAG, "onResume REACHED, client not null");
googleApiFitnessClient.stopAutoManage(getActivity());
googleApiFitnessClient.disconnect();
googleApiFitnessClient.connect();
} else {
Log.d(TAG, "onResume REACHED, client null, buildingClient");
buildFitnessClient();
googleApiFitnessClient.connect();
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof Activity) {
parentActivity = (Activity) context;
}
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
fragmentView = inflater.inflate(R.layout.fragment_google_fit, container, false);
initializeLogging();
if (!checkPermissions()) {
requestPermissions();
}
return fragmentView;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Main_Activity.USER_AUTHORISED_REQUEST_CODE && googleApiFitnessClient != null) {
Log.d(TAG, "Activity result finished authorissation, disconnect the client and reconnect");
googleApiFitnessClient.stopAutoManage(getActivity());
googleApiFitnessClient.disconnect();
googleApiFitnessClient.connect();
}
}
private void buildFitnessClient() {
googleApiFitnessClient = new GoogleApiClient.Builder(parentActivity)
.addApi(Fitness.SENSORS_API)
// .addScope(new Scope(Scopes.FITNESS_LOCATION_READ))
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
// .addScope(new Scope(Scopes.FITNESS_NUTRITION_READ_WRITE))
// .addScope(new Scope(Scopes.FITNESS_BODY_READ_WRITE))
.addConnectionCallbacks(
new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Connected!!!");
// Now you can make calls to the Fitness APIs.
findFitnessDataSources();
}
#Override
public void onConnectionSuspended(int i) {
// If your connection to the sensor gets lost at some point,
// you'll be able to determine the reason and react to it here.
if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
Log.i(TAG, "Connection lost. Cause: Network Lost.");
} else if (i
== GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
Log.i(TAG,
"Connection lost. Reason: Service Disconnected");
}
}
}
)
.addOnConnectionFailedListener(
new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "Connection failed! " + connectionResult.getErrorMessage());
}
}
)
.enableAutoManage((FragmentActivity) parentActivity, 0, new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Google Play services connection failed. Cause: " +
result.toString());
}
})
.build();
}
private void findFitnessDataSources() {
// Note: Fitness.SensorsApi.findDataSources() requires the ACCESS_FINE_LOCATION permission.
Fitness.SensorsApi.findDataSources(googleApiFitnessClient, new DataSourcesRequest.Builder()
// At least one datatype must be specified.
.setDataTypes(DataType.TYPE_STEP_COUNT_CUMULATIVE)
// Can specify whether data type is raw or derived.
.setDataSourceTypes(DataSource.TYPE_RAW)
.build())
.setResultCallback(new ResultCallback<DataSourcesResult>() {
#Override
public void onResult(DataSourcesResult dataSourcesResult) {
Log.i(TAG, "Result: " + dataSourcesResult.getStatus().toString());
for (DataSource dataSource : dataSourcesResult.getDataSources()) {
Log.i(TAG, "Data source found: " + dataSource.toString());
Log.i(TAG, "Data Source type: " + dataSource.getDataType().getName());
//Let's register a listener to receive Activity data!
if (dataSource.getDataType().equals(DataType.TYPE_STEP_COUNT_CUMULATIVE)
&& mListener == null) {
Log.i(TAG, "Data source for " + dataSource.getDataType() + " found! Registering.");
registerFitnessDataListener(dataSource,
DataType.TYPE_STEP_COUNT_CUMULATIVE);
}
}
}
});
}
/**
* Register a listener with the Sensors API for the provided {#link DataSource} and
* {#link DataType} combo.
*/
private void registerFitnessDataListener(DataSource dataSource, DataType dataType) {
mListener = new OnDataPointListener() {
#Override
public void onDataPoint(DataPoint dataPoint) {
for (Field field : dataPoint.getDataType().getFields()) {
Value val = dataPoint.getValue(field);
Log.i(TAG, "Detected DataPoint field: " + field.getName());
Log.i(TAG, "Detected DataPoint value: " + val);
}
}
};
Fitness.SensorsApi.add(
googleApiFitnessClient,
new SensorRequest.Builder()
.setDataSource(dataSource) // Optional but recommended for custom data sets.
.setDataType(DataType.TYPE_STEP_COUNT_CUMULATIVE) // Can't be omitted.
.setSamplingRate(1, TimeUnit.SECONDS)
.build(),
mListener)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
if (status.isSuccess()) {
Log.i(TAG, "Listener registered!");
} else {
Log.i(TAG, "Listener not registered.");
}
}
});
}
private void initializeLogging() {
/*
Not really needed, you can just log to Logcat without having a view in this fragment
*/
LogWrapper logWrapper = new LogWrapper();
Log.setLogNode(logWrapper);
MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
logWrapper.setNext(msgFilter);
LogView logView = (LogView) fragmentView.findViewById(R.id.sample_logview);
logView.setTextAppearance(parentActivity, R.style.Log);
logView.setBackgroundColor(Color.WHITE);
msgFilter.setNext(logView);
Log.i(TAG, "Ready");
}
/**
* Return the current state of the permissions needed.
*/
private boolean checkPermissions() {
int permissionState = ActivityCompat.checkSelfPermission(parentActivity,
Manifest.permission.ACCESS_FINE_LOCATION);
return permissionState == PackageManager.PERMISSION_GRANTED;
}
private void requestPermissions() {
boolean shouldProvideRationale =
ActivityCompat.shouldShowRequestPermissionRationale(parentActivity,
Manifest.permission.ACCESS_FINE_LOCATION);
if (shouldProvideRationale) {
Log.i(TAG, "Displaying permission rationale to provide additional context.");
Snackbar.make(
fragmentView.findViewById(R.id.main_activity_view),
R.string.permission_rationale,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok, new View.OnClickListener() {
#Override
public void onClick(View view) {
// Request permission
ActivityCompat.requestPermissions(parentActivity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BODY_SENSORS},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
})
.show();
} else {
Log.i(TAG, "Requesting permission");
ActivityCompat.requestPermissions(parentActivity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BODY_SENSORS},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
Log.i(TAG, "onRequestPermissionResult");
if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
if (grantResults.length <= 0) {
Log.i(TAG, "User interaction was cancelled.");
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
buildFitnessClient();
} else {
Snackbar.make(
fragmentView.findViewById(R.id.main_activity_view),
R.string.permission_denied_explanation,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.settings, new View.OnClickListener() {
#Override
public void onClick(View view) {
// Build intent that displays the App settings screen.
Intent intent = new Intent();
intent.setAction(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",
BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
})
.show();
}
}
}
}
Flow:
Launch app
Google API client is built, causing a connection failed callback, but also causing the Account Picker dialog to appear
Account is picked, onActivityResult from Activity is called, result is sent to onActivityResult in Fragment
Google API client is restarted (stopAutoManage, disconnect, connect)
Logging starts STEP_COUNT_CUMULATIVE or any other data type you choose
This works and is tested a lot, please ask if you're unsure of anything

Android: How to resolve Google API connection fail from a Service?

here is the code provided by the official guide, while this is a snippet causing problems.
#Override
public void onConnectionFailed(ConnectionResult result) {
if (mResolvingError) {
// Already attempting to resolve an error.
return;
} else if (result.hasResolution()) {
try {
mResolvingError = true;
result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
} catch (IntentSender.SendIntentException e) {
// There was an error with the resolution intent. Try again.
mGoogleApiClient.connect();
}
} else {
// Show dialog using GooglePlayServicesUtil.getErrorDialog()
mResolvingError = true;
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, REQUEST_RESOLVE_ERROR)
.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
mResolvingError = false;
}
});
}
}
If I use it in a Service, when you read the variable this passed as argument to those functions, they expect an Activity type.
How should I do? It's a Service.
For the same reason I can't get activity result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_RESOLVE_ERROR) {
mResolvingError = false;
if (resultCode == RESULT_OK) {
// Make sure the app is not already connected or attempting to connect
if (!mGoogleApiClient.isConnecting() &&
!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
}
}
This answer assumes your service is a "started" service. If it is a bound service or intent service, indicate that in a comment and I'll update the description and code included here.
The solution I suggest is to implement the activity shown below to handle the resolution UI. Replace the onConnectionFailed() method in your service with this code to hand off the resolution processing to the ResolverActivity:
#Override
public void onConnectionFailed(ConnectionResult result) {
Intent i = new Intent(this, ResolverActivity.class);
i.putExtra(ResolverActivity.CONNECT_RESULT_KEY, result);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
Add the activity shown below to your app. When the connection request in your service fails, the connection result, which is a Parcelable, is passed to the activity. The activity handles the resolution UI and when finished, returns the status to the service as an intent extra. You will need to modify the code in your service's onStartCommand() to examine the extras in the intent to determine if it is being called to start the service for the first time, or to receive resolution status from the ResolverActivity.
An enhancement to this approach would be to post a notification with a PendingIntent for ResolverActivity instead of launching the activity immediately. That would give the user the option of deferring resolution of the connection failure.
public class ResolverActivity extends AppCompatActivity {
public static final String TAG = "ResolverActivity";
public static final String CONNECT_RESULT_KEY = "connectResult";
public static final String CONN_STATUS_KEY = "connectionStatus";
public static final int CONN_SUCCESS = 1;
public static final int CONN_FAILED = 2;
public static final int CONN_CANCELLED = 3;
// Request code to use when launching the resolution activity
private static final int REQUEST_RESOLVE_ERROR = 1111;
private static final String ERROR_CODE_KEY = "errorCode";
private static final String DIALOG_FRAG_TAG = "errorDialog";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate()");
// No content needed.
//setContentView(R.layout.activity_main);
Intent i = getIntent();
ConnectionResult result = i.getParcelableExtra(CONNECT_RESULT_KEY);
if (result.hasResolution()) {
try {
Log.i(TAG, "Starting error resolution...");
result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
} catch (IntentSender.SendIntentException e) {
// There was an error with the resolution intent.
sendStatusToService(CONN_FAILED);
finish();
}
} else {
// Show dialog using GooglePlayServicesUtil.getErrorDialog()
ErrorDialogFragment.newInstance(result.getErrorCode())
.show(getSupportFragmentManager(), DIALOG_FRAG_TAG);
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent result) {
if (requestCode == REQUEST_RESOLVE_ERROR) {
if (resultCode == RESULT_OK) {
Log.i(TAG, "onActivityResult(): Connection problem resolved");
sendStatusToService(CONN_SUCCESS);
} else {
sendStatusToService(CONN_CANCELLED);
Log.w(TAG, "onActivityResult(): Resolution cancelled");
}
// Nothing more to do in this activity
finish();
}
}
private void sendStatusToService(int status) {
Intent i = new Intent(this, MyGoogleApiService.class);
i.putExtra(CONN_STATUS_KEY, status);
startService(i);
}
// Fragment to display an error dialog
public static class ErrorDialogFragment extends DialogFragment {
public static ErrorDialogFragment newInstance(int errorCode) {
ErrorDialogFragment f = new ErrorDialogFragment();
// Pass the error that should be displayed
Bundle args = new Bundle();
args.putInt(ERROR_CODE_KEY, errorCode);
f.setArguments(args);
return f;
}
#Override
#NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the error code and retrieve the appropriate dialog
int errorCode = getArguments().getInt(ERROR_CODE_KEY);
return GooglePlayServicesUtil.getErrorDialog(
errorCode, getActivity(), REQUEST_RESOLVE_ERROR);
}
#Override
public void onDismiss(DialogInterface dialog) {
Log.i(TAG, "Dialog dismissed");
}
}
}

Getting user date from Facebook session ? - Android

I'm trying get name and email from a facebook session opened. I want to get these informations an add in a EditText. When I try get these informations the Facebook is opened to type my login and password to access after this doesn't return the informations.
How can I do it ?
I'm trying this.
public class CadUsuarioFrag extends Fragment implements View.OnClickListener, RadioGroup.OnCheckedChangeListener{
private EditText etNome, etEmail, etSenha;
private ImageButton ibImage;
private Button btnSingUp;
private String pathImage;
private static final int RESULT_LOAD_IMAGE = 1;
private ProgressDialog progress;
private final String TAG = getClass().getSimpleName() + "->";
//radiogroup
private RadioGroup rgTipoCad;
//
private String nome = "";
private String email = "";
private String senha = "";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((CustomDrawerLayout)getActivity()).getSupportActionBar().hide();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == getActivity().RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getActivity().getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
pathImage = cursor.getString(columnIndex);
cursor.close();
}
Session.getActiveSession().onActivityResult(getActivity(), requestCode, resultCode, data);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.form_cadusuario, container, false);
etNome = (EditText)view.findViewById(R.id.etNome);
etEmail = (EditText)view.findViewById(R.id.etEmail);
etSenha = (EditText)view.findViewById(R.id.etSenha);
ibImage = (ImageButton)view.findViewById(R.id.ibImage);
btnSingUp = (Button)view.findViewById(R.id.btnSingUp);
rgTipoCad = (RadioGroup)view.findViewById(R.id.rgTipoCad);
//listeners
rgTipoCad.setOnCheckedChangeListener(this);
ibImage.setOnClickListener(this);
btnSingUp.setOnClickListener(this);
etNome.requestFocus();
return view;
}
#Override
public void onClick(View v) {
if(v == ibImage){
Intent i = new Intent(
Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
}else if(v == btnSingUp){
if(checkFields()){
addUsuario();
}
}
}
/** verifica se todos os campos foram informados para o insert */
private boolean checkFields(){
nome = etNome.getText().toString().trim();
email = etEmail.getText().toString().trim();
senha = etSenha.getText().toString().trim();
int selected = rgTipoCad.getCheckedRadioButtonId();
if(nome.length() == 0 || email.length() == 0 || senha.length() == 0){
Toast.makeText(getView().getContext(), "Informe todos os campos", Toast.LENGTH_SHORT).show();
etNome.requestFocus();
etNome.selectAll();
return false;
}else{
return true;
}
}
private void addUsuario(){
progress = new CustomProgressDialog().getCustomProgress(null, getView().getContext());
progress.show();
Usuario u = new Usuario(nome, email, senha, "1");
JsonObjectRequest app = new UsuarioDAO().addUsuario(u, new UsuarioAdapter(){
#Override
public void onUsuarioCadastrado(Boolean value) {
if(!value){
Toast.makeText(getView().getContext(), "Usuário não cadastrado", Toast.LENGTH_SHORT).show();
}else{
sucesso();
}
progress.dismiss();
}
});
CustomVolleySingleton.getInstance(getView().getContext()).addToRequestQueue(app);
}
private void sucesso(){
AlertDialog.Builder alert = new AlertDialog.Builder(getView().getContext());
alert.setTitle("Guia Store");
alert.setMessage("Obrigado por se cadastrar\nEfetue agora seu login para acesso");
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
FragmentTransaction ft;
Fragment frag;
frag = new LoginFrag();
ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fl, frag, "InicioFrag");
ft.commit();
removeFrag();
}
});
AlertDialog dialog = alert.create();
dialog.show();
}
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if(checkedId == R.id.rbGuiaStore){
//Log.i(TAG, "rbGuiaStore selecionado");
etNome.setHint("Nome");
etEmail.setHint("Email");
etSenha.setHint("Senha");
etNome.requestFocus();
}else{
//Log.i(TAG, "rbFacebook selecionado");
etNome.setHint("Nome");
etEmail.setHint("Email facebook");
etSenha.setHint("Senha facebook");
etNome.requestFocus();
checkFacebookSession();
}
}
private void checkFacebookSession(){
// start Facebook Login
Session.openActiveSession(getActivity(), true, new Session.StatusCallback() {
// callback when session changes state
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
// make request to the /me API
Request.newMeRequest(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
Toast.makeText(getView().getContext(), user.getName(), Toast.LENGTH_SHORT).show();
etNome.setText(user.getName());
Log.i("usuario", user.getName());
}
}
}).executeAsync();
}
}
});
}
/** remove o fragment da fila */
private void removeFrag(){
getActivity().getSupportFragmentManager().popBackStack();
//getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onStop() {
super.onStop();
CustomVolleySingleton.getInstance(getView().getContext()).cancelPendingRequests(CustomVolleySingleton.TAG);
}
}
You can do something like below.
Request.newMeRequest(session, new Request.GraphUserCallback()
{
#Override
public void onCompleted(GraphUser user, Response response)
{
if (response != null)
{
try
{
String name = user.getName();
String email = (String) user.getProperty("email");
Log.e(LOG_TAG, "Name: " + name + " Email: " + email);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}).executeAsync();
P.S. Session should be opened before running this request. You can check sessionState through isOpened() method

Google+ Login Not working properly on Android fragment

I am working with google+ login to my application and when i done it using a activity its work charm and after that i move my code into a fragment and after that when i try to login to google+ its not working i have to open the fragment activity 2 times to login to the google+ can anyone tell me what happen the code to the fragment is added below
public class GooglePluseFragment extends Fragment implements
ConnectionCallbacks, OnConnectionFailedListener {
private static final int RC_SIGN_IN = 0;
private static final String TAG = "MainActivity";
private static final int PROFILE_PIC_SIZE = 800;
private GoogleApiClient mGoogleApiClient;
private boolean mIntentInProgress;
private boolean mSignInClicked;
private ConnectionResult mConnectionResult;
private SignInButton btnSignIn;
private Button btnSignOut;
private Context mContext;
private Activity mActivity;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivity = getActivity();
mContext = getActivity().getApplicationContext();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.compund_google_pluse_fragment,
container, false);
btnSignIn = (SignInButton) view.findViewById(R.id.btn_sign_in);
btnSignOut = (Button) view.findViewById(R.id.btn_sign_out);
sharedPref = view.getContext().getSharedPreferences(
Constantz.SHEARED_PREFEREANCE, Context.MODE_PRIVATE);
mGoogleApiClient = new GoogleApiClient.Builder(view.getContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API, null)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
btnSignIn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signInWithGplus();
}
});
btnSignOut.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signOutFromGplus();
}
});
return view;
}
#Override
public void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
public void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
public void onActivityResult(int requestCode, int responseCode,
Intent intent) {
if (requestCode == RC_SIGN_IN) {
if (responseCode != Activity.RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (!result.hasResolution()) {
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(),
mActivity, 0).show();
Log.e(TAG, "" + result.getErrorCode());
return;
}
if (!mIntentInProgress) {
mConnectionResult = result;
if (mSignInClicked) {
Log.e(TAG, "" + result.getErrorCode());
resolveSignInError();
}
}
}
#Override
public void onConnected(Bundle arg0) {
mSignInClicked = false;
getProfileInformation();
updateUI(true);
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
updateUI(false);
}
private void updateUI(boolean isSignedIn) {
if (isSignedIn) {
btnSignIn.setVisibility(View.GONE);
btnSignOut.setVisibility(View.VISIBLE);
} else {
btnSignIn.setVisibility(View.VISIBLE);
btnSignOut.setVisibility(View.GONE);
}
}
/**
* Sign-in into google
* */
private void signInWithGplus() {
if (!mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInError();
}
}
/**
* Method to resolve any signin errors
* */
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(mActivity,
RC_SIGN_IN);
} catch (SendIntentException e) {
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
/**
* Fetching user's information name, email, profile pic
* */
private void getProfileInformation() {
try {
if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
Person currentPerson = Plus.PeopleApi
.getCurrentPerson(mGoogleApiClient);
String personName = currentPerson.getDisplayName();
String personPhotoUrl = currentPerson.getImage().getUrl();
String personGooglePlusProfile = currentPerson.getUrl();
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.e(TAG, "Name: " + personName + ", plusProfile: "
+ personGooglePlusProfile + ", email: " + email
+ ", Image: " + personPhotoUrl + " user id:"
+ currentPerson.getId());
} else {
Toast.makeText(mContext, "Person information is null",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Sign-out from google
* */
private void signOutFromGplus() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
updateUI(false);
}
}
}
this is how i added framgent in the fragment activity
pluseFragment = new GooglePluseFragment();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.pluse_frame_layout, pluseFragment);
transaction.commit();
can somebody tell me what i have done wrong ? why i have to open the activity two times to login thank you
Finally found the answer, Problem was when the result activity call in the fragment was catch by the parent activity so you have to manually redirect the result to your fragment. Just have to add this line in your Parent Fragment Activity
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == GooglePluseFragment.RC_SIGN_IN) {
GooglePluseFragment fragment = (GooglePluseFragment) getSupportFragmentManager()
.findFragmentById(R.id.pluse_frame_layout);
fragment.onActivityResult(requestCode, resultCode, data);
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
Easy Solution for this ::
just create the static method in fragment
"
public static myOnActivityResult(int requestCode, int resultCode, Intent data){
.....Enter same code
}
and
call this method from Parant Activity on
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
.....
MyFragment.myOnActivityResult(requestCode,resultCode,data)
}
thats it

Categories

Resources