I use Facebook SDK for Android 3.0
I want to get the user's photos and show in my app.
Reference document, login was a success.
and I try to get the album.
I tried two methods fql and graph api.
graph_or_fql = "fql";
if (graph_or_fql.equals("fql")) {
String query = "SELECT aid, cover_pid, name, size, visible, object_id FROM album WHERE owner = "
+ userId;
Bundle params = new Bundle();
params.putString("method", "fql.query");
params.putString("query", query);
mAsyncRunner.request(null, params,
new PhotosRequestListener());
} else {
// Bundle params = new Bundle();
// params.putString("fields", "name, aid, size");
// mAsyncRunner.request("me/photos", params,
// new PhotosRequestListener());
mAsyncRunner.request("me/album",
new PhotosRequestListener());
}
/*
* callback after friends are fetched via me/friends or fql query.
*/
public class PhotosRequestListener extends BaseRequestListener {
#Override
public void onComplete(final String response, final Object state) {
dialog.dismiss();
Log.d("tag", "response: " + response);
try {
if (graph_or_fql.equals("fql")) {
jsonArray = new JSONObject(response).getJSONArray("data");
// jsonArray = new JSONArray(response);
// JSONObject jsonObj = new JSONObject(response);
// jsonArray = new JSONArray(jsonObj.getString("data"));
} else {
jsonArray = new JSONObject(response).getJSONArray("data");
}
} catch (JSONException e) {
showToast("JSONError: " + e.getMessage());
e.printStackTrace();
return;
}
gridView.setOnItemClickListener(MainActivity.this);
gridView.setAdapter(new GridViewAdapter(MainActivity.this));
}
public void onFacebookError(FacebookError error) {
dialog.dismiss();
Toast.makeText(getApplicationContext(),
"Facebook Error: " + error.getMessage(), Toast.LENGTH_SHORT)
.show();
}
}
But all error.
fql error message: "error_msg":"Session key invalid or no longer valid"
11-07 16:41:10.956: D/tag(468): response: {"error_code":102,"error_msg":"Session key invalid or no longer valid","request_args":[{"key":"query","value":"SELECT aid, cover_pid, name, size, visible, object_id FROM album WHERE owner = 100001791736733"},{"key":"method","value":"fql.query"},{"key":"format","value":"json"}]}
11-07 16:41:10.956: W/System.err(468): org.json.JSONException: No value for data
11-07 16:41:10.966: W/System.err(468): at org.json.JSONObject.get(JSONObject.java:354)
11-07 16:41:11.015: W/System.err(468): at org.json.JSONObject.getJSONArray(JSONObject.java:544)
11-07 16:41:11.015: W/System.err(468): at com.example.facebookphoto.MainActivity$PhotosRequestListener.onComplete(MainActivity.java:144)
11-07 16:41:11.015: W/System.err(468): at com.facebook.android.AsyncFacebookRunner$2.run(AsyncFacebookRunner.java:273)
graph api error message: "error":{"message":"An active access token must be used to query information about the current user.","type":"OAuthException","code":2500}
11-07 16:45:43.106: D/tag(538): response: {"error":{"message":"An active access token must be used to query information about the current user.","type":"OAuthException","code":2500}}
11-07 16:45:43.106: W/System.err(538): org.json.JSONException: No value for data
11-07 16:45:43.156: W/System.err(538): at org.json.JSONObject.get(JSONObject.java:354)
11-07 16:45:43.156: W/System.err(538): at org.json.JSONObject.getJSONArray(JSONObject.java:544)
11-07 16:45:43.176: W/System.err(538): at com.example.facebookphoto.MainActivity$PhotosRequestListener.onComplete(MainActivity.java:149)
11-07 16:45:43.176: W/System.err(538): at com.facebook.android.AsyncFacebookRunner$2.run(AsyncFacebookRunner.java:273)
I don't get it, because what causes. help me, thanks.
Related
Given a Feature result set passed into this function, I am trying to traverse up the project hierarchy up to the subscription. I can't I get a null pointer on the projResponse =... No even sure of the approach for this.
private static void getProjHierarchyForFeature(RallyRestApi restApi, QueryResponse featureSet,
Time2Market time2market, Integer featureInSet) {
String tempHierarchy = "";
JsonArray tempFeatures = featureSet.getResults();
//time2market.setProjectName(projectName);
try {
JsonObject obj1 = tempFeatures.get(featureInSet).getAsJsonObject();
JsonObject proj = obj1.get("Project").getAsJsonObject();
String url = proj.get("_ref").getAsString();
QueryRequest projQuery = new QueryRequest(url);
projQuery.setFetch(new Fetch("_ref", "_refObjectUUID", "_refObjectName"));
QueryResponse projResponse = restApi.query(projQuery);
if (projResponse.wasSuccessful()) {
JsonArray tempProj = projResponse.getResults();
// Here we have the project object, now process Parents...
Boolean moreParents = true;
while (moreParents) {
QueryRequest parentQuery = new QueryRequest(url);
//projQuery.setFetch(new Fetch("_ref", "_refObjectUUID", "_refObjectName"));
QueryResponse parentResponse = restApi.query(parentQuery);
if (parentResponse.wasSuccessful()) {
System.out.println ("proj Response... " + parentResponse.toString());
JsonArray projParent = parentResponse.getResults();
tempHierarchy.concat(projParent.get(0).getAsString());
JsonArray tempParent = parentResponse.getResults();
proj = tempParent.getAsJsonObject();
} else {
moreParents = false;
}
}
} else {
System.err.println("The following errors occurred: ");
for (String err : projResponse.getErrors()) {
System.err.println("\t" + err);
}
throw new java.lang.Error("Rally API Call Error Occurred");
}
} catch (Exception e) {
e.printStackTrace();
}
}
You probably want to use a GetRequest instead of a QueryRequest since you're just reading a single object. Also, include Parent in your fetch. Then you should have the data to be able to determine whether there is a parent and to continue looping or not.
Our application calls out-of-the-box Office 365 Management API to retrieve activities and events on files stored in SharePoint Online. However per our experiment, the application can’t seem to retrieve not enough logs.
Example: We upload 1000 files to document library in Sharepoint Online. We receive 8 subscriptiona. Each subscription, we only get maximum 100 logs. Total call API get logs to retrieve 600 logs. Not enough!
Here my code to get subscription
List<SubscriptionsContent> GetSubscriptionsContents(AuthenticationResult authenticationResult, ManagementAPI m, DateTime startDate, DateTime endDate, bool proxyRequired = false)
{
try
{
string jsonSubscription = string.Empty;
string url = string.Empty;
string logType = "Audit.SharePoint";
if (authenticationResult != null)
{
url = string.Format(UrlFormat, m.TenantId, string.Format("subscriptions/content?contentType={0}&startTime={1}&endTime={2}", logType, startDate.ToUniversalTime().ToString(DateFormat), endDate.ToUniversalTime().ToString(DateFormat)));
jsonSubscription = ExecuteRequest(url, HttpMethod.Get, authenticationResult);
//Log.Info("jsonSubscription:");
//Log.Info(jsonSubscription);
}
var listContent = Common.GetListSubscriptionsContent(jsonSubscription);
Log.Info("Common.GetListSubscriptionsContent(jsonSubscription); Count: " + (listContent != null ? listContent.Count.ToString() : "IS NULL"));
return listContent;
}
catch (Exception ex)
{
Log.Error(ex);
return new List<SubscriptionsContent>();
}
}
Here my code to execute Request
public string ExecuteRequest(string url, HttpMethod method, AuthenticationResult token)
{
var responseStr = "";
try
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage request = new HttpRequestMessage(method, url);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);
HttpResponseMessage response = client.SendAsync(request).Result;
Log.Info("ExecuteRequest(string url, HttpMethod method, AuthenticationResult token): response.StatusCode: " + response.StatusCode + " ; response.ReasonPhrase: " + response.ReasonPhrase + " ; response.RequestMessage: " + response.RequestMessage);
if (response.IsSuccessStatusCode)
{
responseStr = response.Content.ReadAsStringAsync().Result;
}
}
catch (Exception ex)
{
Log.Error(ex);
}
return responseStr;
}
Here my code to get audit log from each subscription
List<AuditLog> listAudit = new List<AuditLog>();
foreach (var item in listSubscription)
{
var jsonAudit = ExecuteRequest(item.ContentUri.ToString(), HttpMethod.Get, authenticationResult);
if (string.IsNullOrEmpty(jsonAudit))
continue;
var listAuditLog = Common.GetListAuditLog(jsonAudit);
}
Here my code to parser JsonString
public static List<AuditLog> GetListAuditLog(string jsonString)
{
try
{
return JsonConvert.DeserializeObject<List<AuditLog>>(jsonString);
}
catch (Exception ex)
{
Log.Error("public static List<AuditLog> GetListAuditLog(string jsonString)", ex.InnerException);
return new List<AuditLog>();
}
}
I think that you need to use the pagination header.
If the amount of data is too big, the API will return a header entry named NextPageUrl containing an address to be used to request the next page of results. This link (representing the query) will be available for 24 hours.
Ex.
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
NextPageUrl:https://manage.office.com/api/v1/{tenant_id}/activity/feed/subscriptions/content?contentType=Audit.SharePoint&startTime=2015-10-01&endTime=2015-10-02&nextPage=2015101900R022885001761
So, if the response contains this header entry, just use the value of NextPageUrl to request more data.
Repeat the process until this header entry doesn't exists anymore.
You can find more information in the Office 365 Management API reference
With this code i want to extract a list of my Friends and as next step all of the last checkins of my friends but the list is always empty.
public void onClick(View v) {
String fqlQuery = "SELECT uid,name,pic_square FROM user WHERE uid IN "
+ "(SELECT uid2 FROM friend WHERE uid1 = me() LIMIT 25)";
Bundle params = new Bundle();
params.putString("q", fqlQuery);
Session session = Session.getActiveSession();
Request request = new Request(session, "/fql", params, HttpMethod.GET, new Request.Callback() {
public void onCompleted(Response response) {
Log.i(TAG, "Result: " + response.toString());
try {
GraphObject graphObject = response.getGraphObject();
JSONObject jsonObject = graphObject.getInnerJSONObject();
Log.d("data", jsonObject.toString());
JSONArray array = jsonObject.getJSONArray("data");
System.out.println("länge array" + array.length());
for (int i = 0; i < array.length(); i++) { //
JSONObject friend = array.getJSONObject(i);
Log.d("uid", friend.getString("uid"));
Log.d("name", friend.getString("name"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Request.executeBatchAsync(request);
}
});
return view;
}
}
also i want to get all checkins of my friends but the data is empty
I would happy if someone could help me out
Output of LogCat:
{ "data": []}
As of Facebook API v2.0, friends list (/me/friends and FQL equivalent) returns ONLY user's friends who use your application. This limitation applies to apps that are on v1.0 mode too.
If you're looking to get friends for tagging actions: https://developers.facebook.com/docs/graph-api/reference/v2.0/user/taggable_friends
If you're looking to get friends for inviting to a GAME: https://developers.facebook.com/docs/graph-api/reference/v2.0/user/invitable_friends
Cheers!
NOTE: Using the Sign-in button is NOT an option
A year ago I was having a problem creating a moment. Back then I was using version 1.2 of the Google+ API .Net client. As I described in this post, I had it working although the code failed to insert a moment from time to time. I was hoping that the process is more stable and easier to implement now, and it seems like it as can be seen in the example that you can download here - the current version as of this writing is v1.8. So I created a simple project following the SimpleOAuth2 sample in the download, but implementing Google+. This is the code I came up:
public partial class _Default : System.Web.UI.Page
{
private PlusService service;
// Application logic should manage users authentication.
// This sample works with only one user. You can change
// it by retrieving data from the session.
private const string UserId = "user-id";
protected void Page_Load(object sender, EventArgs e)
{
GoogleAuthorizationCodeFlow flow;
var assembly = Assembly.GetExecutingAssembly();
using (var stream = assembly.GetManifestResourceStream(
"GPlusSample.client_secrets.json"))
{
flow = new GoogleAuthorizationCodeFlow(
new GoogleAuthorizationCodeFlow.Initializer
{
DataStore = new FileDataStore("GPlusSample.Store"),
ClientSecretsStream = stream,
//
// Tried only this scope but it did not work
//Scopes = new[] { PlusService.Scope.PlusMe }
//
// I tried the following: but did not work either
//Scopes = new[] { PlusService.Scope.PlusMe,
// "https://www.googleapis.com/auth/plus.moments.write" }
//
// I tried this as well and it failed
//Scopes = new[] { PlusService.Scope.PlusLogin }
//
// Maybe this... but still no joy
Scopes = new[] { PlusService.Scope.PlusLogin,
PlusService.Scope.PlusMe }
});
}
var uri = Request.Url.ToString();
var code = Request["code"];
if (code != null)
{
var token = flow.ExchangeCodeForTokenAsync(UserId, code,
uri.Substring(0, uri.IndexOf("?")), CancellationToken.None).Result;
// Extract the right state.
var oauthState = AuthWebUtility.ExtracRedirectFromState(
flow.DataStore, UserId, Request["state"]).Result;
Response.Redirect(oauthState);
}
else
{
var result = new AuthorizationCodeWebApp(flow, uri, uri)
.AuthorizeAsync(UserId, CancellationToken.None).Result;
if (result.RedirectUri != null)
{
// Redirect the user to the authorization server.
Response.Redirect(result.RedirectUri);
}
else
{
// The data store contains the user credential,
// so the user has been already authenticated.
service = new PlusService(new BaseClientService.Initializer
{
ApplicationName = "Plus API Sample",
HttpClientInitializer = result.Credential
});
}
}
}
/// <summary>Gets the TasksLists of the user.</summary>
public async System.Threading.Tasks.Task InsertMoment()
{
try
{
var me = service.People.Get("me").Execute();
var request = service.Moments.Insert(new Moment()
{
Target = new ItemScope {
Id=Guid.NewGuid().ToString(),
Image="http://www.google.com/s2/static/images/GoogleyEyes.png",
Type="",
Name = "test message",
Description="test",
Text="test message",
},
Type = "http://schemas.google.com/AddActivity",
}, me.Id, MomentsResource.InsertRequest.CollectionEnum.Vault);
var response =await request.ExecuteAsync();
output.Text = "<h1>" + response.Id + "</h1>";
}
catch (Exception ex)
{
var str = ex.ToString();
str = str.Replace(Environment.NewLine, Environment.NewLine + "<br/>");
str = str.Replace(" ", " ");
output.Text = string.Format("<font color=\"red\">{0}</font>", str);
}
}
protected async void createMomentButton_Click(object sender, EventArgs e)
{
await InsertMoment();
}
}
That code always give me a 401 Unauthorized error, even if I have the Google+ API turned on for my project. Here's the actual error I got:
The service plus has thrown an exception: Google.GoogleApiException:
Google.Apis.Requests.RequestError Unauthorized [401] Errors [
Message[Unauthorized] Location[ - ] Reason[unauthorized]
Domain[global] ]
It's interesting to see that the insert moment is failing even though the call to People.Get("me") works - get("me") works with all of the scope combinations I listed above. It's important to note that each time I try a new scope, I first log out of my Google account and delete the access token that is stored in GPlusSample.Store.
EDIT
I tried setting just the Url instead of individual items as suggested by Ian and I got the exact same error.
var request = service.Moments.Insert(new Moment()
{
Target = new ItemScope {
Url = "https://developers.google.com/+/web/snippet/examples/thing"
},
Type = "http://schemas.google.com/AddActivity",
}, me.Id, MomentsResource.InsertRequest.CollectionEnum.Vault);
var response =await request.ExecuteAsync();
https://www.googleapis.com/auth/plus.login is the right scope for writing moments, but you need to have requested the specific app activity types you want to write as well. The parameter for this is request_visible_actions, and it takes a space separated list of arguments of the types (Listed on https://developers.google.com/+/api/moment-types/ - e.g. http://schemas.google.com/AddActivity).
The client library may not have a method for adding request_visible_actions, so you may have to add it on to the auth URL you redirect the user to manually (remember to URLencode the app activity type URLs!)
I'm having a trouble when authenticating with the WSO2 Identity Server.
I have a web page named avis.com, when I enter the page, click the login button, then the web page navigates to the login form of WSO2 Identity Server. But, when I enter use name and password into the form and click login. A error page appears as:
SAML 2.0 based Single Sign-On
Error when processing the authentication request!
Please try login again.
At the Apache Tomcat Log, errors appear:
Nov 07, 2013 3:12:32 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [SAML2ConsumerServlet] in context with path [/travelocity.com] threw exception
java.lang.NullPointerException
at com.travelocity.saml.sso.SamlConsumerManager.getResult(SamlConsumerManager.java:272)
at com.travelocity.saml.sso.SamlConsumerManager.processResponseMessage(SamlConsumerManager.java:246)
at com.travelocity.saml.sso.SAML2ConsumerServlet.doPost(SAML2ConsumerServlet.java:73)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
At the com.avis.saml.sso.SamlConsumerManager.getResult(SamlConsumerManager.java:272):
private Map<String, String> getResult(XMLObject responseXmlObj) {
if (responseXmlObj.getDOM().getNodeName().equals("saml2p:LogoutResponse")) //line 722{
return null;
}
Response response = (Response) responseXmlObj;
Assertion assertion = response.getAssertions().get(0);
Map<String, String> resutls = new HashMap<String, String>(); // line 72
/*
* If the request has failed, the IDP shouldn't send an assertion.
* SSO profile spec 4.1.4.2 <Response> Usage
*/
if (assertion != null) {
String subject = assertion.getSubject().getNameID().getValue();
resutls.put("Subject", subject); // get the subject
List<AttributeStatement> attributeStatementList = assertion.getAttributeStatements();
if (attributeStatementList != null) {
// we have received attributes of user
Iterator<AttributeStatement> attribStatIter = attributeStatementList.iterator();
while (attribStatIter.hasNext()) {
AttributeStatement statment = attribStatIter.next();
List<Attribute> attributesList = statment.getAttributes();
Iterator<Attribute> attributesIter = attributesList.iterator();
while (attributesIter.hasNext()) {
Attribute attrib = attributesIter.next();
Element value = attrib.getAttributeValues().get(0).getDOM();
String attribValue = value.getTextContent();
resutls.put(attrib.getName(), attribValue);
}
}
}
}
return resutls;
}
At the com.avis.saml.sso.SAML2ConsumerServlet.doPost(SAML2ConsumerServlet.java:72)
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException,
IOException {
String responseMessage = request.getParameter("SAMLResponse");
if (responseMessage != null) { /* response from the identity provider */
Map<String, String> result = consumer.processResponseMessage(responseMessage);
if (result != null && result.size() == 1) {
/*
* No user attributes are returned, so just goto the default
* home page.
*/
response.sendRedirect("home.jsp?subject=" + result.get("Subject"));
} else if (request != null && result.size() > 1) {
/*
* We have received attributes, so lets show them in the
* attribute home page.
*/
String params = "home-attrib.jsp?";
Object[] keys = result.keySet().toArray();
for (int i = 0; i < result.size(); i++) {
String key = (String) keys[i];
String value = (String) result.get(key);
if (i != result.size()) {
params = params + key + "=" + value + "&";
} else {
params = params + key + "=" + value;
}
}
response.sendRedirect(params);
} else {
// something wrong, re-login
response.sendRedirect("index.jsp");
}
} else { /* time to create the authentication request or logout request */
try {
String requestMessage = consumer.buildRequestMessage(request);
response.sendRedirect(requestMessage);
} catch (IOException e) {
e.printStackTrace();
}
}
}
At the com.avis.saml.sso.SamlConsumerManager.processResponseMessage(SamlConsumerManager.java:246)
public Map<String, String> processResponseMessage(String responseMessage) {
XMLObject responseXmlObj = null;
try {
responseXmlObj = unmarshall(responseMessage);
} catch (ConfigurationException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (UnmarshallingException e) {
e.printStackTrace();
}
return getResult(responseXmlObj); // line 246
}
Actually, I have two web pages, but here I mentioned one because they are the same. I'm doing a single sign on project that two service provider (web pages) are central authenticated at WSO2 Identity Server using SAML2.0 and OpenSAML
I don't know whether I miss some step when configure or not? Are there any important point I must keep in mind for my web page to authenticate successfully.
I was getting the same exception.Updating unmarshall method as below resolved my problem.
private XMLObject unmarshall(String responseMessage) throws ConfigurationException,
ParserConfigurationException, SAXException,
IOException, UnmarshallingException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
byte[] base64DecodedResponse = responseMessage.getBytes("UTF-8");
byte[] decoded = Base64.decode(base64DecodedResponse,0,responseMessage.length());
System.out.println(new String(decoded, StandardCharsets.UTF_8));
String s = new String(decoded,StandardCharsets.UTF_8);
Document document = docBuilder.parse(new InputSource(new StringReader(s)));
Element element = document.getDocumentElement();
UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
return unmarshaller.unmarshall(element);
}