I use the following methods to get status updates from multiple users.
public void getUserFeed(long userID, RequestListener listener) {
long time = System.currentTimeMillis();
Bundle params = new Bundle();
params.putString("uid", userID + "");
params.putString("fields", "statuses");
asyncFacebookRunner.request(FRIENDS, params, listener);
}
public void getFeedsForUsers(List<User> facebookUsersInFeed,
final RequestListener listener) {
for (final User user : facebookUsersInFeed) {
getUserFeed(user.getId(), listener);
}
}
Most of the time, this works fine. But every now and then, I get a response in which the data array is completely empty. Any ideas?
The most likely reason is because that specific user has blocked 3rd party apps from accessing their data, therefore, when you try to fetch their info it will return empty.
Related
I am trying to send app request to my facebook friend after authentication by using the following code snippet.
public void sendApplicationRequest(final List<String> userIdList, final String message, final String title, final int requestCode) {
final Bundle parameters = new Bundle();
parameters.putString("title", title);
parameters.putString("message", message);
parameters.putInt("requestCode", requestCode);
parameters.putString("frictionless", "1");
String to = getListOfUsersAsString(userIdList);
if (to != null) {
parameters.putString("to", to);
}
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
WebDialog requestDialog = createRequestDialog(parameters);
requestDialog.setOwnerActivity(activity);
requestDialog.show();
}
});
}
private WebDialog createRequestDialog(final Bundle parameters) {
final int requestCode = parameters.getInt("requestCode");
return (
new WebDialog.Builder( activity, "apprequests", parameters))
.setOnCompleteListener(new WebDialog.OnCompleteListener() {
#Override
public void onComplete(Bundle bundle, FacebookException e) {
//...
}
}
).build();
}
The problem is, the dialog shows on top of my app's activity but it requires authentication again. When I enter my credentials and login to facebook on the dialog, everything works well but players have to log in on every app request again and again.
I have also tried the new GameRequestDialog and GameRequestContent API's but the result is the same.
Do you have an idea about what is the problem here which force me to authenticate again on every web dialog?
Correction :
After authenticating on the web dialog for the first time, it never forces you to authenticate again. But still, players need to authenticate two times in total.
My Android application needs to do an initial http request on app start to fetch a config json file from a RESTful service. This request is done by Volley
As soon as the application gets the data, the MainActivity starts. I also defined some deeplinks, to open a WebView in my application with a given URI. The deeplinks have to be handled by the SplashActivity as the config needs to be loaded first by Volley. I don't know if this is the right way to handle this.
Maybe it would be an option to request the config in the Application class, so that the config is always available, no matter which Activity starts first?
This is the correct way.
In your Splash activity you should handle the incoming intent with your deeplinks, fire up your Volley request and only then you should move on with your logic.
BTW, in the meanwhile, you should show the user some loader/progress and handle failures of course.
If you are making an asynchronous call in the Application class, you can make the request with a callback and show the required activity.
public interface ConfigListener {
public void onConfigReceived(List<ofSomething> list, boolean error, String message);
}
private void requestConfig(){
final DownloadUsingVolley downloader = new DownloadUsingVolley(getActivity());
downloader.retrieveData(new ConfigListener() {
#Override
public void onConfigReceived(List<ofSomething> list, boolean error, String message) {
//Show your required activity here
}
});
}
private void retrieveData(String url, final ConfigListener configListener){
final JsonObjectRequest request = new JsonObjectRequest(url, null, new Response.Listener<JSONObject>(){
#Override
public void onResponse(JSONObject response) {
try {
//parse
configListener.onConfigReceived(result,false,null);
}catch (JSONException e){
configListener.onConfigReceived(0,true,e.getMessage());
}
}
},new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError volleyError) {
configListener.onConfigReceived(0,true,volleyError.getMessage());
}
});
//adding request into the queue
ApplicationClass.getInstance().addToRequestQueue(request,"aTag");
}
i was try to create login session with session key, the session key always generate new key either we do Login/registration, i can retrieve the data from my gson
LoginService loginService = retrofit.create(LoginService.class);
Observable<LoginResponse> obs = loginService.logins(emai,pass,"1", Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID), Build.MODEL, Build.VERSION.RELEASE);
obs.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).
subscribe(new Observer<LoginResponse>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
}
public void onNext(LoginResponse loginResponse) {
int responses = loginResponse.getCODE();
String texts="";
if(responses == 1)
{
User user = loginResponse.getDATALIST().get(0);
setPrefIsLogin(true);
setPrefSessionUid(user.getSESSIONKEY(),user.getUSERID());
nextActivity();
}
else{
}
}
});
the question is, how to make handler to handle the save session check if there is another login activity with the same account?
You should never assign two accessToken/Session for one user. You will send the same accessToken to the other instance of the new user. Plus side, user won't be able to duplicate his/her work by two accessToken.
If you want to force the other/first one AUTO-LOGOUT, you can use Firebase notification feature to send a notification to that particular deviceID and force it to stop. You can check firebase's tutorial to see how they work.
Another slow procedure is to check before login & everyother server side work to check if there are instance of same user. You will send an error and user end will receive it and show the error accompanying by logging out the user.
How to get incoming messages from specific user?
For example:
VKRequest requestOutMessages = VKApi.messages().get(VKParameters.from(VKApiConst.USER_ID, vkUserId));
VKRequest requestInMessages = VKApi.messages().get(VKParameters.from(VKApiConst.OUT, vkUserId));
Which is giving me all 40 last messages from all my last conversations.
EDIT
public class VKApiMessagesExtension extends VKApiMessages {
public VKRequest getHistory(VKParameters params) {
return prepareRequest("getHistory", params, new VKParser() {
#Override
public Object createModel(JSONObject object) {
return new VKApiGetMessagesResponse(object);
}
});
}
}
Messages in VK can only be accessed by the user involved in the conversation. If you use the VK API to get messages, they will be for the logged in user.
In other words, messages are private.
The documentation states that "Returns a list of the current user's incoming or outgoing private messages."
I am extremely new to Android, infact Java as a whole - I am from a PHP background which is creating a challenge for me to work on Android.
My first task in Android is to implement Facebook session management using Facebook SDK in an existing App. I have started by importing the requisite SDK files and in the Landing screen of my App (Main Activity) I have written code as follows:
onCreate() -
Creating FB object, storing it in Utility
Instantiating the asynrunner object for asynchronous api calls and giving FB object instance to AsyncronusRunner
Restoring session if one exists by calling SessionStore.restore(), *
Calling init() like so-
init(LandingPage.this, AUTHORIZE_ACTIVITY_RESULT_CODE, Utility.mFacebook, permissions);
public void init(final Activity activity, final int activityCode, final Facebook fb, final String[] permissions) {
mActivity = activity;
mActivityCode = activityCode;
mFb = fb;
mPermissions = permissions;
mHandler = new Handler();
SessionEvents.addAuthListener(mSessionListener);
SessionEvents.addLogoutListener(mSessionListener);
}// init()
onStart() -
I have created a custom FB login button and I am type casting it to
"Button" (not "LoginButton")
On the onClick() of this "Button" object am checking if FB session is
valid. If yes? get data from FB, proceed. If no? force user to see
the Login Dialog Box for FB.
#Override
protected void onStart() {
super.onStart();
mLoginButton = (Button) findViewById(R.id.fb_login);
mLoginButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (Utility.mFacebook.isSessionValid()) {
requestUserData();
}else{
Utility.mFacebook.authorize.authorize(mActivity, mPermissions, mActivityCode, new LoginDialogListener());
}
}
});
}//onStart()
private class LoginDialogListener implements DialogListener {
public void onComplete(Bundle values) {
SessionEvents.onLoginSuccess();
requestUserData(); //userData fetches FB profile data
}// onComplete()
}// class
requestUserData() -
Here I have simply created a Bundle to pass the fields that I need:
public void requestUserData() {
Bundle params = new Bundle();
params.putString("fields", "first_name, name, id, picture, gender, email");
Utility.mAsyncRunner.request("me", params, new UserRequestListener()); // callback for fetching fields
}// requestUserData()
public class UserRequestListener extends BaseRequestListener {
#SuppressWarnings("deprecation")
#Override
public void onComplete(final String response, final Object state) {
JSONObject jsonObject;
try {
jsonObject = new JSONObject(response);
final String picURL = jsonObject.getJSONObject("picture").getJSONObject("data").getString("url");
final String first_name = jsonObject.getString("first_name");
final String full_name = jsonObject.getString("name");
final String gender = jsonObject.getString("gender");
final String fb_id = jsonObject.getString("id");
String email = "" ; // initialized blank first otherwise gives Json exception if email returned null from FB
// store values in Singleton
Singleton.fb_firstname = first_name ; //although it says "first name", am storing full name in there
Singleton.fb_user_id = fb_id;
Singleton.fb_gender = gender;
try {
email = jsonObject.getString("email");//sometimes we dont get an email from Facebook
Singleton.fb_email_id = email;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bundle parameters = new Bundle();
String mAccessToken = access_token;
parameters.putString("format", "json");
parameters.putString(TOKEN, mAccessToken);
String url = "https://graph.facebook.com/me/friends";
String friends_response = null;
try {
friends_response = Util.openUrl(url, "GET", parameters);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
JSONObject obj = Util.parseJson(friends_response);
..........
// CALLING A WEBSERVICE THAT RETURNS A USER-ID BASED ON THE FACEBOOK ID
// If the service returns status=0, we need to redirect user to Screen A, else to ScreenB
..........
if(status.equals("0")){
Intent intent = new Intent(LandingPage.this,ScreenA.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}else {
Intent intent = new Intent(LandingPage.this, ScreenB.class);
startActivity(intent);
finish();
}//else
} catch (Exception e) {
e.printStackTrace();
}
]// onComplete()
}// class()
Now my issue lies in requestUserData()
Once I have all the Facebook profile data that I need for processing, I execute an if/else condition that is supposed to process the variables returned in FB call response and based on that redirect the user to ScreenA or ScreenB immediately, that is in this sequence:
1. User launches App, comes to "LandingPage" where MainActivity
starts
2. User clicks on "FB Connect" button on "LandingPage"
3. OnClick() event of the button fires invoking an instance of LoginDialogListener()
4. LoginDialogListener takes user to the FB login screen asking for username/password - user enters credentials and also
authorizes the App successfully via the permission screens
5. Once he clicks "Ok" on the final permission screen, the user is brought BACK to the "LandingPage" for a few seconds and then
redirected to "ScreenA" or "ScreenB" as given in the if/else block
given above.
Basically what I need is for the user to NOT be thrown back to the "LandingPage" and directly be sent to the respective screen as per my logic. But this doesn't seem to happen, no matter what I tried. For a fraction of a second the user always comes back to the LandingPage after authorizing the app and then is sent to the next screen. How can I avoid this?
Note: In my Native Android Facebook settings, I have given class name as: LandingPage. So I guess after authorization is completed, the user gets re-directed back to the LandingPage for a fraction of a second (but none of the methods such as create, start, init get called again) before getting redirected to ScreenA/ScreenB - I am really clueless here.
What I would ideally want is, if its not possible to direct a user to another screen halfway when the previous screen logic is still under processing, maybe can I sort of block the user from atleast seeing the landing page view again (which might make him think there was something wrong with the App) and instead show him an alert like "Processing..." or something replacing the current view of the landing page until he gets successfully redirected to ScreenA/ScreenB?
If anyone can guide me here, I would really appreciate it.
Regards,
Mahek