I'm following simple tutorial at: https://developers.facebook.com/docs/android/getting-started/ and after I made everything work, I have problems onCompleted callback method.
My code looks like this:
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) {
TextView welcome = (TextView) findViewById(R.id.welcome);
welcome.setText("Hello " + user.getName() + "!");
}
}
}).executeAsync();
since executeMeRequestAsync method from tutorial was deprecated. Everything passes fine, and user != null evaluates as true so I come inside of the block, but on user.getName() I always get NullPointerException and I've checked while debugging GraphUser instance, and it was filled with null values. What I might be doing wrong? Can it be some problems with application configuration? I've generated new KeyHash and it's correct, so I don't know what else would be incorrect.
A NullPointerException can be thrown if findViewById(R.id.welcome) returns null. You can modify your logic to check for welcome as well:
public void onCompleted(GraphUser user, Response response) {
TextView welcome = (TextView) findViewById(R.id.welcome);
if(user != null && welcome != null) {
welcome.setText("Hello " + user.getName() + "!");
}
else {
// Log it in some way
}
}
Related
I am trying to use Jetpack in my Android development, I am able to display data from the the sports api but some of the data is null and not displaying, I am using data binding and this is was my first instinct check if null during my interview
android:text="#{model.league != null ? model.league : #string/app}"
During my interview however I failed I suppose due to not being able to identify what other location I can check for null data when the I display data. So my question is how do I change this code to ensure no textview is null or how do how I handle null api calls, and where, I just want to be able to not make the same mistake again.
Reponse Class
public LiveData<List<Match>> getEvents(String teamId) {
final MutableLiveData<List<Match>> events = new MutableLiveData<>();
Call<AppResponse> call = RetrofitClient.getEvents(teamId);
call.enqueue(new Callback<AppResponse>() {
#Override
public void onResponse(#NonNull Call<AppResponse> call, #NonNull Response<AppResponse> response) {
if (response.isSuccessful()) {
AppResponse appResponse = response.body();
if (appResponse != null)
events.setValue(appResponse.getEvents());
} else
Log.i(TAG, "Error: " + response.errorBody());
}
#Override
public void onFailure(#NonNull Call<AppResponse> call, #NonNull Throwable t) {
Log.i(TAG, "Error " + t.getMessage());
}
});
return events;
}
I'm trying to implement getLastLocation().addOnSuccessListener as documented here: https://developer.android.com/training/location/retrieve-current#last-known but in my case within a JobService which is periodically ran by the JobScheduler.
Here is the meaningful part of my jobService:
public class PeriodicJob extends JobService {
final String TAG = "BNA.Job";
private FusedLocationProviderClient fusedLocationClient;
#Override
public void onCreate() {
super.onCreate();
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
Log.i(TAG, "onCreate");
}
#Override
public boolean onStartJob(JobParameters params) {
Log.d(TAG, "Job started..."); // logs every 15mins
fusedLocationClient.getLastLocation()
.addOnSuccessListener(this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
Log.d(TAG, "got Location: " + location);
Log.d(TAG, "Accuracy:" + location.getAccuracy()+", LON:"
+location.getLongitude() + ", LAT:" + location.getLatitude());
}
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
(...) // never runs
});
return true;
}
When I run this (it compiles fine), I get: Caused by: java.lang.ClassCastException: (...)PeriodicJob cannot be cast to java.util.concurrent.Executor
I looked at Android app crashes on firebase phone authentication and Can't cast this into Executor in google reCAPTCHA but I still couldnt get it working. Just calling .addOnSuccessListener(new OnSuccessListener<Location>() like the second question's answer suggests, throws no error, but the code is never executed (at least, no log is written).
How can I get the call to onSuccess working?
EDIT: In fact it was working all the time (without the first parameter), I had neglected to detect the case when a null location was returned (which I wasnt expecting). Thanks to Mike M.!
Following instructions from: https://developer.android.com/training/in-app-billing/purchase-iab-products.html under Query Purchased Items, I am checking for purchased items.
My code looks like this:
private void lookForPurchases() {
IabHelper.QueryInventoryFinishedListener lookForPurchasesListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
if (result.isFailure()) {
Log.e(TAG, "Error checking for purchases:" + result.toString());
}
else {
Log.d(TAG, "Processing purchases." + inventory.toString());
if(inventory.hasPurchase(SKU_LEXCOINS_100)){
Purchase purchase = inventory.getPurchase(SKU_LEXCOINS_100);
consumeCoinPurchase(purchase);
}
if(inventory.hasPurchase(SKU_LEXCOINS_550)){
Purchase purchase = inventory.getPurchase(SKU_LEXCOINS_550);
consumeCoinPurchase(purchase);
}
if(inventory.hasPurchase(SKU_LEXCOINS_1200)){
Purchase purchase = inventory.getPurchase(SKU_LEXCOINS_1200);
consumeCoinPurchase(purchase);
}
}
}
};
Log.i(TAG, "Looking for purchases");
if(inAppBillingHelper == null) {
Log.e(TAG, "Null preventing query inventory");
} else {
try {
inAppBillingHelper.queryInventoryAsync(lookForPurchasesListener);
} catch (IabHelper.IabAsyncInProgressException ex) {
Log.e(TAG, "Error retrieving purchases.", ex);
}
}
}
In the log, though, the last thing I get is "Looking for purchases" with nothing following. It looks like I should get something on any branch, so, does anyone see what I'm doing wrong?
No errors or anything, it just never seems to come back.
The problem was on the line handler.post deep in IabHelper (Google Code) where it was executing my callback I was passing in. The handler.post was getting called, buy my callback never was. I'm not sure how that happened.
I replaced the handler.post with a AsyncTask and posted the call of my callback in the onPostExecute method to get it run on the UI thread. This appears to have solved my problem.
Below you can find my code for sharing custom story using open graph with some custom fields. Image and Url not working - I'm getting error: com.facebook.FacebookException, and nothing more when Url is added, when I set only image I'm getting Toast with "Unidentified error" message:
OpenGraphObject spent = OpenGraphObject.Factory.createForPost("namespace:spent");
spent.setProperty("og:type", "namespace:" + categorySlug.replace("-", "_"));
//Not working -- spent.setProperty("og:url", "http://example.com");
//Not working -- spent.setUrl("http://example.com");
//Not working -- spent.setProperty("og:image", "http://example.com/image.png");
//Not working -- spent.setImageUrls(Arrays.asList("http://example.com/image.png"));
spent.setProperty("og:title", "Title");
spent.setProperty("og:description", "Description");
spent.setProperty("namespace:hours", container.getHours());
spent.setProperty("namespace:minutes", container.getMinutes());
spent.setProperty("namespace:seconds", container.getSeconds());
spent.setType("namespace:mycustomobject");
OpenGraphAction action = GraphObject.Factory.create(OpenGraphAction.class);
action.setProperty("mycostomobject", spent);
action.setType("namespace:spent");
final FacebookDialog shareDialog = new FacebookDialog.OpenGraphActionDialogBuilder(
this,
action,
"mycustomobject"
).build();
if(FacebookDialog.canPresentShareDialog(context,FacebookDialog.ShareDialogFeature.SHARE_DIALOG)) {
uiLifecycleHelper.trackPendingDialogCall(shareDialog.present());
}
Image is showing in preview. But when I click publish I'm getting error mentioned above.
However my request with JSON code is working and sharing an image:
StringBuilder sb = new StringBuilder();
sb.append("{")
.append("\"").append("og:type").append("\":\"").append("namespace:").append(categorySlug.replace("-", "_")).append("\",")
.append("\"").append("og:url").append("\":\"").append("http://example.com").append("\",")
.append("\"").append("og:title").append("\":\"").append("Title").append("\",")
.append("\"").append("og:image").append("\":\"").append("http://example.com/icon.png").append("\",")
.append("\"").append("og:description").append("\":\"").append("Desc").append("\",")
.append("\"").append("namespace:hours").append("\":\"").append(container.getHours()).append("\",")
.append("\"").append("namespace:minutes").append("\":\"").append(container.getMinutes()).append("\",")
.append("\"").append("namespace:seconds").append("\":\"").append(container.getSeconds()).append("\"")
.append("}");
final Bundle object = new Bundle();
object.putString(categorySlug.replace("-","_"), sb.toString());
object.putBoolean("fb:explicitly_shared", true);
Request request = new Request(
Session.getActiveSession(),
"me/namespace:spent",
object,
HttpMethod.POST,
new Request.Callback() {
#Override
public void onCompleted(Response response) {
if(response != null && response.getError() != null) Log.d("Facebook Share", "Error message:" + response.getError().getErrorCode() + ", " + response.getError().getErrorMessage());
if(response != null && response.getGraphObject() != null){
Toast.makeText(context, "Success!", Toast.LENGTH_SHORT).show();
}
}
}
);
request.executeAsync();
Notes:
Images are present in server.
I've changed namespaces and domains so there could be an errors in names
Exception when I uncomment addProperty("og:image",""): https://gist.github.com/Averus89/55a86b3618f143926eb2
I'm trying very simply to test the 3.0 Facebook get started guide. https://developers.facebook.com/docs/getting-started/facebook-sdk-for-android/3.0/
I have had some problems with imports and references but I don't know it that's relevant. The issue I'm having is when I try to run the test Activity ant get this error:
Could not find class 'com.test1.test2.FacebookLogin$1', referenced from method com.test1.test2.FacebookLogin.onCreate
Code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_facebook_login);
//Error occurs here when I use 'this'
Session.openActiveSession(this, 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.executeMeRequestAsync(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
TextView welcome = (TextView) findViewById(R.id.welcome);
welcome.setText("Hello " + user.getName() + "!");
}
}
});
}
}
});
}
How can I get a NoClassDefFoundError when I use this?
UPDATE:
After testing with the Scrumtious tutorial https://developers.facebook.com/docs/tutorials/androidsdk/3.0/scrumptious/authenticate/ as well I'm getting the same error when I call the Session.StatusCallback() method. I still don't know what my problem is though.
Thanks for the help
Maybe you updated to Android sdk tools revision 22. There is an issue there. You have to add the libraries you use in the export path. Check:
Android Sdk tools Revision 22 issue?