I want to authorize user from my app, I am following some example found on internet (http://www.programcreek.com/java-api-examples/index.php?api=org.scribe.model.Token):
public static void auth() throws IOException, FlickrException {
Properties properties;
InputStream in=null;
try {
in=AuthExample.class.getResourceAsStream("/setup.properties");
properties=new Properties();
properties.load(in);
}
finally {
IOUtilities.close(in);
}
Flickr flickr=new Flickr(properties.getProperty("apiKey"),properties.getProperty("secret"),new REST());
Flickr.debugStream=false;
AuthInterface authInterface=flickr.getAuthInterface();
Scanner scanner=new Scanner(System.in);
Token token=authInterface.getRequestToken();
System.out.println("token: " + token);
String url=authInterface.getAuthorizationUrl(token,Permission.READ);
System.out.println("Follow this URL to authorise yourself on Flickr");
System.out.println(url);
System.out.println("Paste in the token it gives you:");
System.out.print(">>");
String tokenKey=scanner.nextLine();
Token requestToken=authInterface.getAccessToken(token,new Verifier(tokenKey));
System.out.println("Authentication success");
Auth auth=authInterface.checkToken(requestToken);
System.out.println("Token: " + requestToken.getToken());
System.out.println("nsid: " + auth.getUser().getId());
System.out.println("Realname: " + auth.getUser().getRealName());
System.out.println("Username: " + auth.getUser().getUsername());
System.out.println("Permission: " + auth.getPermission().getType());
}
I am using webview, scribe and Flickr4Java for run URL which provide a code, authenticate and web view shows me a code, which I must pass to my app, but I can't understand how to retrieve this code from webview, and pass to tokenKey.
I am added onpageFinished and print URL which me give:
06-12 13:03:55.266 E/NEW﹕ uri is: https://m.flickr.com/services/oauth/authorize?oauth_token=72157654039925698-81abc00d035f5da0&perms=write
06-12 13:03:55.601 W/BindingManager﹕ Cannot call determinedVisibility() - never saw a connection for the pid: 4581
06-12 13:03:56.166 E/NEW﹕ uri is: https://m.flickr.com/#/services/oauth/authorize/_QM_oauth_token_IS_72157654039925698-81abc00d035f5da0_AND_perms_IS_write
06-12 13:03:56.476 W/BindingManager﹕ Cannot call determinedVisibility() - never saw a connection for the pid: 4581
06-12 13:03:56.476 E/NEW﹕ uri is: https://m.flickr.com/#/services/oauth/authorize/_QM_oauth_token_IS_72157654039925698-81abc00d035f5da0_AND_perms_IS_write
06-12 13:04:00.411 W/BindingManager﹕ Cannot call determinedVisibility() - never saw a connection for the pid: 4581
06-12 13:04:00.416 E/NEW﹕ uri is: https://m.flickr.com/#/#
Finaly, i found an answer (this provide a calback url: token = authInterface.getRequestToken("your calback url");), the code for auth for someone is:
public class FlickrLogin1 extends AsyncTask<String, String, String> {
public final String TAG = FlickrLogin1.class.getSimpleName();
String url;
int count = 0;
#Override
protected void onPreExecute() {
Log.d(TAG, "START");
}
#Override
protected String doInBackground(String... params) {
String result = "";
try {
Flickr.debugRequest = false;
Flickr.debugStream = false;
flickr = new Flickr(flickrKey, flickrSecret, new REST());
authInterface = flickr.getAuthInterface();
token = authInterface.getRequestToken("your calback url");
L("Token: " + token);
result = authInterface.getAuthorizationUrl(token, Permission.WRITE);
return result;
} catch (IllegalStateException e) {
e.printStackTrace();
return result;
} catch (VerifyError e) {
e.printStackTrace();
return result;
}
}
#Override
protected void onPostExecute(String result) {
if (result != null && result.length() > 0) {
L("Follow this URL to authorise yourself on Flickr");
L(result);
auth_dialog = new Dialog(getActivity());
auth_dialog.setContentView(R.layout.auth_dialog);
final WebView web = (WebView) auth_dialog.findViewById(R.id.webv);
web.getSettings().setJavaScriptEnabled(true);
web.loadUrl(result);
web.setWebViewClient(
new WebViewClient() {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
L("url to start " + url);
if (url.contains("&oauth_verifier")) {
auth_dialog.dismiss();
Uri uri = Uri.parse(url);
String oauth_verifier = uri.getQueryParameter("oauth_verifier");
String oauth_token = uri.getQueryParameter("oauth_token");
new FlickrLogin2().execute(oauth_token, oauth_verifier);
}
}
String authCode;
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
L("url to get " + url);
}
});
auth_dialog.show();
auth_dialog.setTitle("Authorize");
auth_dialog.setCancelable(true);
}
}
}
public class FlickrLogin2 extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... oauth_verifier) {
L("CODE " + oauth_verifier[0] + " " + oauth_verifier[1]);
try {
Verifier verifier = new Verifier(oauth_verifier[1]);
Token accessToken = authInterface.getAccessToken(token, verifier);
System.out.println("Authentication success");
Auth auth = new Auth();
authInterface = flickr.getAuthInterface();
Token requestToken = authInterface.getRequestToken();
L("auth tocen and secret: " + requestToken.getToken() + " , " + requestToken.getSecret());
auth.setToken(requestToken.getToken());
auth.setTokenSecret(requestToken.getSecret()); // thats the token I got from the registration, before I set the token of the requestToken
auth.setPermission(Permission.WRITE);
RequestContext requestContext = RequestContext.getRequestContext();
requestContext.setAuth(auth);
flickr.setAuth(auth);
L("checking for token" + accessToken);
auth = authInterface.checkToken(accessToken);
// This token can be used until the user revokes it.
L("Token: " + accessToken.getToken());
L("Secret: " + accessToken.getSecret());
L("nsid: " + auth.getUser().getId());
L("Realname: " + auth.getUser().getRealName());
L("Username: " + auth.getUser().getUsername());
L("Permission: " + auth.getPermission().getType());
} catch (FlickrException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
}
}
Anyone who's struggling to get this to work with more recent version of Android with Kotlin, I have a gist that can be found here.
Related
I'm currently trying to have my device (program) show up as a mock chromecast on the network. The application itself can see the Mock-Caster as a chromecast but if i try searching for it using Youtube or any other sender app, the "Mock-Caster" does not appear in the list.
I registered a service on jmDNS with all the criteria that would be available on an actual chromecast as well.
Is there something that I am missing or getting wrong?
Here's what I have so far.
public void postConstruct() throws Exception {
InetAddress discoveryInterface = InetAddress.getByName("192.168.1.1");
CAST_DEVICE_MONITOR.startDiscovery(discoveryInterface, "Mock-Server");
CAST_DEVICE_MONITOR.registerListener(new DeviceDiscoveryListener() {
#Override
public void deviceDiscovered(CastDevice castDevice) {
System.out.println("New chrome cast detected: " + castDevice);
}
#Override
public void deviceRemoved(CastDevice castDevice) {
System.out.println("New chrome cast detected: " + castDevice);
}
});
JmDNS jmdns = JmDNS.create(discoveryInterface, "Mock-Server");
final String name = "Mock-Caster";
final String id = UUID.randomUUID().toString();
// Register a service
HashMap<String, String> properties = new HashMap<>();
//values scraped from chromecast or another java project
properties.put("sf", "1");
properties.put("id", id);
properties.put("md", name);
properties.put("fd", name);
properties.put("s#", "1");
properties.put("ff", "0");
properties.put("ci", "1");
properties.put("c#", Integer.toString(1));
properties.put("pv", "1.1");
properties.put("cd", "E465315D08CFDEF2742E1264D78F6035");
properties.put("rm", "ED724E435DA8115C");
properties.put("ve", "05");
properties.put("ic", "/setup/icon.png");
properties.put("ca", "201221");
properties.put("st", "0");
properties.put("bs", "FA8FCA771881");
properties.put("nf", "1");
properties.put("rs", "");
ServiceInfo serviceInfo = ServiceInfo.create("_googlecast._tcp.local.", name, 8009, 1, 1, properties);
jmdns.registerService(serviceInfo);
}
//This is where i know that the mock-caster is registered and available
#Bean
public IntegrationFlow tcpServer() throws Exception {
TcpNioServerConnectionFactory factory = new TcpNioServerConnectionFactory(8009);
DefaultTcpSSLContextSupport defaultTcpSSLContextSupport = new DefaultTcpSSLContextSupport(keystore, keystore, password, password);
defaultTcpSSLContextSupport.setProtocol("TLS");
factory.setTcpNioConnectionSupport(new DefaultTcpNioSSLConnectionSupport(defaultTcpSSLContextSupport));
factory.setTcpSocketSupport(new DefaultTcpSocketSupport(false));
factory.setDeserializer(TcpCodecs.lengthHeader4());
factory.setSerializer(TcpCodecs.lengthHeader4());
TcpInboundGatewaySpec inboundGateway = Tcp.inboundGateway(factory);
return IntegrationFlows
.from(inboundGateway)
.handle(message -> {
String ip_address = message.getHeaders().get("ip_address").toString();
if(ip_address.equalsIgnoreCase("192.168.1.1")) {
System.out.println("Self IP Address received");
System.out.println("Payload: " + message.getPayload());
System.out.println("MessageHeaders: " + message.getHeaders());
}else{
System.out.println("Other IP address received: " + ip_address);
}
})
.get();
}
//Mock-Caster detected here
#Scheduled(fixedRate = 15000)
public void checkCasters() throws Exception {
Set<CastDevice> casters = CAST_DEVICE_MONITOR.getCastDevices();
System.out.println("Current CCs: " + casters.size());
for (CastDevice device : casters) {
System.out.println("CC (" + device.getDisplayName() + ")");
var receiver = new CastEvent.CastEventListener() {
#Override
public void onEvent(#Nonnull CastEvent<?> castEvent) {
System.out.println("Event: " + castEvent);
}
};
var appId = DEFAULT_MEDIA_RECEIVER_APP;
try {
if (!device.isConnected()) {
device.connect();
}
device.addEventListener(receiver);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
device.removeEventListener(receiver);
device.disconnect();
}
}
I need to set up a JITR (Just in time registration) process to AWS IOT core for my Android Application using Android AWS IOT SDK. My implementation is done referring this . However, When trying to create a thing after creating a fresh X.509 certificate (On the first connection attempt), Even though the certificate is created on the server, the Server returns errors regarding "unmatched signatures and an empty template body".
This is my current sample implementation,
public class MainActivity extends AppCompatActivity {
private boolean thingExist;
private String certificateARN;
// IoT endpoint
// AWS Iot CLI describe-endpoint call returns: XXXXXXXXXX.iot.<region>.amazonaws.com
private static final String CUSTOMER_SPECIFIC_ENDPOINT = "";
// Cognito pool ID. For this app, pool needs to be unauthenticated pool with
// AWS IoT permissions.
private static final String COGNITO_POOL_ID = "";
// Name of the AWS IoT policy to attach to a newly created certificate
private static final String AWS_IOT_POLICY_NAME = "";
// Region of AWS IoT
private static final Regions MY_REGION = Regions.US_EAST_2;
// Filename of KeyStore file on the filesystem
private static final String KEYSTORE_NAME = "iot_keystore";
// Password for the private key in the KeyStore
private static final String KEYSTORE_PASSWORD = "password";
// Certificate and key aliases in the KeyStore
private static final String CERTIFICATE_ID = "default";
AWSIotClient mIotAndroidClient;
AWSIotMqttManager mqttManager;
String clientId;
String keystorePath;
String keystoreName;
String keystorePassword;
private boolean isAWSConnected;
private listThings mTask;
private boolean certificateExist;
private final String LOG_TAG = "AWS";
private final String serialId = "1110";
KeyStore clientKeyStore = null;
String certificateId;
CognitoCachingCredentialsProvider credentialsProvider;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
clientId = Settings.Global.getString(getApplicationContext().getContentResolver(), "device_name");
// Initialize the AWS Cognito credentials provider
credentialsProvider = new CognitoCachingCredentialsProvider(
getApplicationContext(), // context
COGNITO_POOL_ID, // Identity Pool ID
MY_REGION // Region
);
Region region = Region.getRegion(MY_REGION);
// MQTT Client
mqttManager = new AWSIotMqttManager(clientId, CUSTOMER_SPECIFIC_ENDPOINT);
// Set keepalive to 10 seconds. Will recognize disconnects more quickly but will also send
// MQTT pings every 10 seconds.
mqttManager.setKeepAlive(10);
// Set Last Will and Testament for MQTT. On an unclean disconnect (loss of connection)
// AWS IoT will publish this message to alert other clients.
AWSIotMqttLastWillAndTestament lwt = new AWSIotMqttLastWillAndTestament("Last will",
new Gson().toJson("Android client lost connection"), AWSIotMqttQos.QOS0);
mqttManager.setMqttLastWillAndTestament(lwt);
mIotAndroidClient = new AWSIotClient(credentialsProvider);
mIotAndroidClient.setRegion(region);
keystorePath = getFilesDir().getPath();
keystoreName = KEYSTORE_NAME;
keystorePassword = KEYSTORE_PASSWORD;
certificateId = CERTIFICATE_ID;
// To load cert/key from keystore on filesystem
try {
if (AWSIotKeystoreHelper.isKeystorePresent(keystorePath, keystoreName)) {
if (AWSIotKeystoreHelper.keystoreContainsAlias(certificateId, keystorePath,
keystoreName, keystorePassword)) {
Log.i(LOG_TAG, "Certificate " + certificateId
+ " found in keystore - using for MQTT.");
// load keystore from file into memory to pass on connection
clientKeyStore = AWSIotKeystoreHelper.getIotKeystore(certificateId,
keystorePath, keystoreName, keystorePassword);
certificateExist = true;
mTask = (listThings) new listThings().execute();
} else {
Log.i(LOG_TAG, "Key/cert " + certificateId + " not found in keystore.");
}
} else {
Log.i(LOG_TAG, "Keystore " + keystorePath + "/" + keystoreName + " not found.");
}
} catch (Exception e) {
Log.e(LOG_TAG, "An error occurred retrieving cert/key from keystore.", e);
}
if (clientKeyStore == null) {
certificateExist = false;
Log.i(LOG_TAG, "Cert/key was not found in keystore - creating new key and certificate.");
new Thread(new Runnable() {
#Override
public void run() {
try {
// Create a new private key and certificate. This call
// creates both on the server and returns them to the
// device.
CreateKeysAndCertificateRequest createKeysAndCertificateRequest =
new CreateKeysAndCertificateRequest();
createKeysAndCertificateRequest.setSetAsActive(true);
final CreateKeysAndCertificateResult createKeysAndCertificateResult;
createKeysAndCertificateResult =
mIotAndroidClient.createKeysAndCertificate(createKeysAndCertificateRequest);
Log.i(LOG_TAG,
"Cert ID: " +
createKeysAndCertificateResult.getCertificateId() +
" created.");
// store in keystore for use in MQTT client
// saved as alias "default" so a new certificate isn't
// generated each run of this application
AWSIotKeystoreHelper.saveCertificateAndPrivateKey(certificateId,
createKeysAndCertificateResult.getCertificatePem(),
createKeysAndCertificateResult.getKeyPair().getPrivateKey(),
keystorePath, keystoreName, keystorePassword);
certificateARN = createKeysAndCertificateResult.getCertificateArn();
// load keystore from file into memory to pass on
// connection
clientKeyStore = AWSIotKeystoreHelper.getIotKeystore(certificateId,
keystorePath, keystoreName, keystorePassword);
// Attach a policy to the newly created certificate.
// This flow assumes the policy was already created in
// AWS IoT and we are now just attaching it to the
// certificate.
AttachPrincipalPolicyRequest policyAttachRequest =
new AttachPrincipalPolicyRequest();
policyAttachRequest.setPolicyName(AWS_IOT_POLICY_NAME);
policyAttachRequest.setPrincipal(createKeysAndCertificateResult
.getCertificateArn());
mIotAndroidClient.attachPrincipalPolicy(policyAttachRequest);
mTask = (listThings) new listThings().execute();
} catch (Exception e) {
Log.e(LOG_TAG,
"Exception occurred when generating new private key and certificate.",
e);
}
}
}).start();
}
}
private class listThings extends AsyncTask<Void, Void, Boolean> {
// Listing registered things to verify whether a thing already exist under the same device ID.
#Override
protected Boolean doInBackground(Void... voids) {
Log.d(LOG_TAG, "Listing Things");
final ListThingsRequest request = new ListThingsRequest().withAttributeName("Device_ID")
.withAttributeValue(serialId).withMaxResults(1);
final ListThingsResult result = mIotAndroidClient.listThings(request);
if (!result.getThings().isEmpty()) {
thingExist = true;
return true;
} else {
thingExist = false;
return false;
}
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
Log.d(LOG_TAG, "onPostExecute: " + aBoolean.toString());
if (certificateExist) {
new createThing().execute();
} else {
new awsAsync().execute();
}
mTask.cancel(true);
}
}
private class awsAsync extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
if (thingExist) {
//Thing Exist, certificate doesn't exist
AttachThingPrincipalRequest thingPrincipalRequest = new AttachThingPrincipalRequest();
thingPrincipalRequest.setThingName(serialId);
thingPrincipalRequest.setPrincipal(certificateARN);
Log.d(LOG_TAG, "certificateARN " + certificateARN);
mIotAndroidClient.attachThingPrincipal(thingPrincipalRequest);
/*check if previous certificates are available and delete them*/
} else {
//Thing Doesn't Exist, certificate doesn't exist
try {
Log.d(LOG_TAG, "Thing does not Exist, certificate doesn't exist");
Map<String, String> attributes = new HashMap<String, String>() {{
put("Device_ID", serialId);
put("Android_version", Build.VERSION.RELEASE);
}};
CreateThingRequest createThingRequest = new CreateThingRequest();
createThingRequest.setThingName(serialId);
AttributePayload attributePayload = new AttributePayload();
attributePayload.setAttributes(attributes);
createThingRequest.setThingTypeName("Consenz_search");
createThingRequest.setAttributePayload(attributePayload);
mIotAndroidClient.createThing(createThingRequest);
AddThingToThingGroupRequest addThingToThingGroupRequest = new AddThingToThingGroupRequest();
addThingToThingGroupRequest.setThingName(serialId);
addThingToThingGroupRequest.setThingGroupName("Consenz_Group");
mIotAndroidClient.addThingToThingGroup(addThingToThingGroupRequest);
AttachThingPrincipalRequest thingPrincipalRequest = new AttachThingPrincipalRequest();
thingPrincipalRequest.setThingName(serialId);
thingPrincipalRequest.setPrincipal(certificateARN);
mIotAndroidClient.attachThingPrincipal(thingPrincipalRequest);
} catch (Exception e) {
Log.e(LOG_TAG,
"Excepetion occured when creating thing",
e);
}
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
connectToAWS();
}
}
private class createThing extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
if (!thingExist) {
try {
//Thing doesn't exist, Certificate exist
Log.d(LOG_TAG, "Thing does not Exist. Creating a thing");
Map<String, String> attributes = new HashMap<String, String>() {{
put("Device_ID", serialId);
put("Android_version", Build.VERSION.RELEASE);
}};
CreateThingRequest createThingRequest = new CreateThingRequest();
createThingRequest.setThingName(serialId);
AttributePayload attributePayload = new AttributePayload();
attributePayload.setAttributes(attributes);
createThingRequest.setThingTypeName("Consenz_search");
createThingRequest.setAttributePayload(attributePayload);
mIotAndroidClient.createThing(createThingRequest);
AddThingToThingGroupRequest addThingToThingGroupRequest = new AddThingToThingGroupRequest();
addThingToThingGroupRequest.setThingName(serialId);
addThingToThingGroupRequest.setThingGroupName("Consenz_Group");
mIotAndroidClient.addThingToThingGroup(addThingToThingGroupRequest);
AttachThingPrincipalRequest thingPrincipalRequest = new AttachThingPrincipalRequest();
thingPrincipalRequest.setThingName(serialId);
thingPrincipalRequest.setPrincipal(AWSIotKeystoreHelper.AWS_IOT_INTERNAL_KEYSTORE_PASSWORD);
mIotAndroidClient.attachThingPrincipal(thingPrincipalRequest);
//need to attach the current thing to existing certificate.
} catch (Exception e) {
Log.e(LOG_TAG,
"Excepetion occured when creating thing",
e);
}
} else {
//Thing exist, Certificate exist
//need to attach the current thing to existing certificate.
Log.d(LOG_TAG, "We here");
final ListThingPrincipalsRequest request = new ListThingPrincipalsRequest().withThingName(serialId);
final ListThingPrincipalsResult result = mIotAndroidClient.listThingPrincipals(request);
DescribeCertificateRequest request1 = new DescribeCertificateRequest().withCertificateId("default");
DescribeCertificateResult result1 = mIotAndroidClient.describeCertificate(request1);
String arn = result1.getCertificateDescription().getCertificateArn();
result.toString();
Log.d(LOG_TAG, "arn " + arn);
Log.d(LOG_TAG, "certificates " + result);
//Log.d(LOG_TAG, "Thing Exists. Attaching thing to certificate");
AttachThingPrincipalRequest thingPrincipalRequest = new AttachThingPrincipalRequest();
thingPrincipalRequest.setThingName(serialId);
//String arn = thingPrincipalRequest.getPrincipal(c);
//Log.d(LOG_TAG, "arn "+arn);
mIotAndroidClient.attachThingPrincipal(thingPrincipalRequest);
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
//Log.d(LOG_TAG, "Done creating thing");
connectToAWS();
}
}
private void connectToAWS() {
try {
Log.d(LOG_TAG, "Client ID: " + clientId);
mqttManager.connect(clientKeyStore, new AWSIotMqttClientStatusCallback() {
#Override
public void onStatusChanged(final AWSIotMqttClientStatus status,
final Throwable throwable) {
Log.d(LOG_TAG, "Status = " + String.valueOf(status));
runOnUiThread(new Runnable() {
#Override
public void run() {
if (status == AWSIotMqttClientStatus.Connecting) {
Log.d(LOG_TAG, "Connecting...");
isAWSConnected = false;
} else if (status == Connected) {
Log.d(LOG_TAG, "Connected");
isAWSConnected = true;
//creatething
publishToAWS();
} else if (status == AWSIotMqttClientStatus.Reconnecting) {
if (throwable != null) {
Log.e(LOG_TAG, "Connection error.", throwable);
isAWSConnected = false;
}
isAWSConnected = false;
Log.d(LOG_TAG, "Reconnecting");
} else if (status == AWSIotMqttClientStatus.ConnectionLost) {
if (throwable != null) {
Log.e(LOG_TAG, "Connection error.", throwable);
isAWSConnected = false;
}
isAWSConnected = false;
Log.d(LOG_TAG, "Disconnected");
} else {
isAWSConnected = false;
Log.d(LOG_TAG, "Disconnected");
}
}
});
}
});
} catch (final Exception e) {
Log.d(LOG_TAG, "Error! " + e.getMessage());
}
}
private void publishToAWS() {
//publishing MQQT messages to AWS
String version = "";
String versionRelease = Build.VERSION.RELEASE;
try {
version = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
try {
mqttManager.publishString(new Gson().toJson(serialId), "Device_ID", AWSIotMqttQos.QOS0);
mqttManager.publishString(new Gson().toJson(version), "APK_Version", AWSIotMqttQos.QOS0);
mqttManager.publishString(new Gson().toJson(versionRelease), "Android_Version", AWSIotMqttQos.QOS0);
} catch (Exception e) {
Log.e(LOG_TAG, "Publish error.", e);
}
}
}
what am I doing wrong here? thanks in advance.
Dear developers I'm try to save data from Facebook I'm getting other all data but can't get the email and gender.
This is my code
loginButton.setReadPermissions("public_profile");
loginButton.setReadPermissions("email");
loginButton.setReadPermissions("user_friends");
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
AccessToken accessToken = loginResult.getAccessToken();
GraphRequest request = GraphRequest.newMeRequest( loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object,GraphResponse response) {
if (response != null) {
try {
email = object.getString("email");
} catch (JSONException e) {
e.printStackTrace();
}
try {
gender = object.getString("gender");
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "email,gender");
request.setParameters(parameters);
request.executeAsync();
Profile profile = Profile.getCurrentProfile();
userid = profile.getId();
userfirstname = profile.getFirstName();
middlename = profile.getMiddleName();
userlastname = profile.getLastName();
userimage = profile.getProfilePictureUri(30, 40);
linkuri = profile.getLinkUri();
name = profile.getName();
new AsyncTask<String, String, String>() {
#Override
protected String doInBackground(String... params) {
WebService ws = new WebService(URL);
Map<String, String> data = new HashMap<String, String>();
data.put("user_fb_id", userid);
data.put("first_name", userfirstname);
data.put("middle_name", userfirstname);
data.put("gender", gender);
data.put("email", email);
data.put("last_name", userfirstname);
data.put("user_fb_profile_name", name);
data.put("fb_profile_pic", userimage.toString());
try {
String response = ws.makeHTTPRequest(data, "POST");
JSONObject jsonObject = new JSONObject(response);
Log.e("Response", jsonObject.toString());
} catch (Exception e) {
Log.d("", "Exception : " + e.getMessage());
}
return null;
}
}.execute();
}
#Override
public void onCancel() {
//info = ("Login attempt canceled.");
}
#Override
public void onError(FacebookException e) {
// info = ("Login attempt failed.");
}
});
now I will let you know what is the error in my above code.
when i run the GraphRequest it will execute successfully but didn't get the email and gender. The email and gender is equal to null After the GrapRequest method i am running AsyncTask and send that data in my web services post class my class give me error of null email and gender but when i hover the email and gender after execution of AsyncTask they have that data please help me how to solve that issue.
what i want i want to store the user basic data if there is another way also let me know that i will try.
The problem occurs because In your code two Asynctask runs simultaneously.
Means that the GraphRequest class also runs an asynctask to get user data and you are also running a async to send the user data to server.
Async tasks always runs on separate thread(not on Main thread) and they don't wait for completion of other task.
So the solution is call your Async task in onCompleted() method. LIKE..
Write this async class for upload data to server outside of registerCallback.
private class Upload_Data extends AsyncTask<String, String, String>() {
#Override
protected String doInBackground(String... params) {
WebService ws = new WebService(URL);
Map<String, String> data = new HashMap<String, String>();
data.put("user_fb_id", userid);
data.put("first_name", userfirstname);
data.put("middle_name", userfirstname);
data.put("gender", gender);
data.put("email", email);
data.put("last_name", userfirstname);
data.put("user_fb_profile_name", name);
data.put("fb_profile_pic", userimage.toString());
try {
String response = ws.makeHTTPRequest(data, "POST");
JSONObject jsonObject = new JSONObject(response);
Log.e("Response", jsonObject.toString());
} catch (Exception e) {
Log.d("", "Exception : " + e.getMessage());
}
return null;
}
}
then call this async class in onCompleted method after getting the email and gender value and also check that email and gender is not null before calling Asynctask class.
#Override
public void onCompleted(JSONObject object,GraphResponse response) {
if (response != null) {
try {
email = object.getString("email");
} catch (JSONException e) {
e.printStackTrace();
}
try {
gender = object.getString("gender");
} catch (JSONException e) {
e.printStackTrace();
}
}
if(email!=null && gender!=null){
new Upload_Data().execute();
}
}
});
Hope this will helpful.
I am experiencing an interesting error. I am using mailgun and Retrofit to send e-mails through my application. On the first attempt after opening my application, the send attempt always returns a retrofit error (400 Bad Request). However, all subsequent attempts send through appropriately.
MailGunClient interface:
public interface MailGunClient {
#FormUrlEncoded
#POST("/messages")
void sendMessagePurchase(
#Field("from") String from,
#Field("to") String to,
#Field("h:Reply-To") String replyToAddress,
#Field("subject") String subject,
#Field("text") StringBuilder text,
Callback<Response> responseCallback);
}
Method instantiating the interface and attempting to send (MainActivity):
public void sendResume(String productID) {
if (productID.equals(EMAILSKU)) {
mMailGunClient = new RestAdapter.Builder()
.setEndpoint("https://api.mailgun.net/v3/mg.resumetemplatepro.com")
.setLogLevel(RestAdapter.LogLevel.FULL)
.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
final String credentials = "api" + ":" + "key-c5b8f0c0c7dcaabc23075b977a7b7e43";
final String authString = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.DEFAULT);
request.addHeader("Authorization", authString);
}
})
.build().create(MailGunClient.class);
StringBuilder messageBody = new StringBuilder();
messageBody.append("Hello," + "\r\n" + "\r\n");
messageBody.append("Thank you for purchasing a resume. You can view the resume at the following link: " + getResumeTemplateDownloadLink(pager.getCurrentItem()) + "\r\n" + "\r\n");
messageBody.append("Regards," + "\r\n");
messageBody.append("The Resume Template Pro Team");
mMailGunClient.sendMessagePurchase("resume#mg.resumetemplatepro.com", customerEmailAddress, RBPEMAIL, "Resume Template Email",
messageBody, new Callback<Response>() {
#Override
public void success(Response response, Response response2) {
System.out.println("Success");
Toast.makeText(getApplication(), R.string.successfully_sent, Toast.LENGTH_SHORT).show();
Apptentive.engage(MainActivity.this, "Post_Sale");
}
#Override
public void failure(RetrofitError error) {
Toast.makeText(getApplicationContext(), R.string.try_again, Toast.LENGTH_LONG).show();
}
});
} else if (productID.equals(RESUMECOVERLETTER)) {
mMailGunClient = new RestAdapter.Builder()
.setEndpoint("https://api.mailgun.net/v3/mg.resumetemplatepro.com")
.setLogLevel(RestAdapter.LogLevel.FULL)
.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
final String credentials = "api" + ":" + "key-c5b8f0c0c7dcaabc23075b977a7b7e43";
final String authString = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.DEFAULT);
request.addHeader("Authorization", authString);
}
})
.build().create(MailGunClient.class);
StringBuilder messageBody = new StringBuilder();
messageBody.append("Hello," + "\r\n" + "\r\n");
messageBody.append("The user with e-mail " + customerEmailAddress + " has purchased a professional edit. They purchased " + getResumeTemplateDownloadLink(pager.getCurrentItem()) + "." + "\r\n" + "\r\n");
messageBody.append("Regards," + "\r\n");
messageBody.append("The Resume Template Pro Team");
mMailGunClient.sendMessagePurchase("resume#mg.resumetemplatepro.com", RBPEMAIL, customerEmailAddress, "Resume Template Purchase",
messageBody, new Callback<Response>() {
#Override
public void success(Response response, Response response2) {
System.out.println("Success");
Toast.makeText(getApplication(), R.string.edit_purchase, Toast.LENGTH_SHORT).show();
Apptentive.engage(MainActivity.this, "Post_Sale");
}
#Override
public void failure(RetrofitError error) {
Toast.makeText(getApplicationContext(), R.string.try_again, Toast.LENGTH_LONG).show();
}
});
} else {
Toast.makeText(MainActivity.this, R.string.error, Toast.LENGTH_SHORT).show();
}
}
I'm developing (trying for now) portlet that will be integrated with LinkedIn.
Following the documentation about it:
http://developer.linkedin.com/docs/DOC-1008 -->
The first step to authorizing a LinkedIn member is requesting a requestToken. This request is done with an HTTP POST.
For the requestToken step, the following components should be present in your string to sign:
* HTTP Method (POST)
* Request URI (https://api.linkedin.com/uas/oauth/requestToken)
* oauth_callback
* oauth_consumer_key
* oauth_nonce
* oauth_signature_method
* oauth_timestamp
* oauth_version
I have already API(it's oauth_consumer_key) key and i need to generate specific URL string.
Have next java code for this URL and HTTP connection:
private void processAuthentication() {
Calendar cal = Calendar.getInstance();
Long ms = cal.getTimeInMillis();
Long timestamp = ms / 1000;
Random r = new Random();
Long nonce = r.nextLong();
String prefixUrl = "https://api.linkedin.com/uas/oauth/requestToken";
String oauthCallback = "oauth_callback=http://localhost/";
String oauthConsumerKey =
"&oauth_consumer_key=my_consumer_key";
String oauthNonce = "&oauth_nonce=" + nonce.toString();
String oauthSignatureMethod = "&oauth_signature_method=HMAC-SHA1";
String oauthTimestamp = "&oauth_timestamp=" + timestamp.toString();
String oauthVersion = "&oauth_version=1.0";
String mainUrl =
oauthCallback + oauthConsumerKey + oauthNonce + oauthSignatureMethod
+ oauthTimestamp + oauthVersion;
try {
prefixUrl =
URLEncoder.encode(prefixUrl, "UTF-8") + "&"
+ URLEncoder.encode(mainUrl, "UTF-8");
URL url = new URL(prefixUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
String msg = connection.getResponseMessage();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
The question is next,for those, who had faced this problem:
How should really look URL string for connection and how response is received?
For URL, it's interested the example of URL, you generated.
And for response interested, method to get it.
As i understand, after HTTP connection been established,that response is:
connection.getResponseMessage();
#sergionni I found answer to your Question from linkedin-developer
As you know
The first step to authorizing a Linked-In member is requesting a requestToken. This request is done with an HTTP POST.
Your base string should end up looking something like this if you're using a callback:
POST&https%3A%2F%2Fapi.linkedin.com%2Fuas%2Foauth%2FrequestToken
&oauth_callback%3Dhttp%253A%252F%252Flocalhost%252Foauth_callback%26o
auth_consumer_key%3DABCDEFGHIJKLMNOPQRSTUVWXYZ%26
oauth_nonce%3DoqwgSYFUD87MHmJJDv7bQqOF2EPnVus7Wkqj5duNByU%26
oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1259178158%26
oauth_version%3D1.0
You then sign this base string with your consumer_secret, computing a signature. In this case, if your secret was 1234567890, the signature would be TLQXuUzM7omwDbtXimn6bLDvfF8=.
Now you take the signature you generated, along with oauth_nonce, oauth_callback, oauth_signature_method, oauth_timestamp, oauth_consumer_key, and oauth_version and create an HTTP Authorization header. For this request, that HTTP header would look like:
Authorization: OAuth
oauth_nonce="oqwgSYFUD87MHmJJDv7bQqOF2EPnVus7Wkqj5duNByU",
oauth_callback="http%3A%2F%2Flocalhost%2Foauth_callback",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1259178158",
oauth_consumer_key="ABCDEFGHIJKLMNOPQRSTUVWXYZ",
oauth_signature="TLQXuUzM7omwDbtXimn6bLDvfF8=",
oauth_version="1.0"
Please note, that the HTTP header is a single header -- not an HTTP header for each component. You can optionally supply a realm="http://api.linkedin.com".
As a response to your request for a requestToken, your requestToken will be in the "oauth_token" response field, a validation that we acknowledged your callback with the "oauth_callback_confirmed" field, an oauth_token_secret, and a oauth_expires_in, and a few other values.
(here us Your answaer) response would look like:
oauth_token=94ab03c4-ae2c-45e4-8732-0e6c4899db63
&oauth_token_secret=be6ccb24-bf0a-4ea8-a4b1-0a70508e452b
&oauth_callback_confirmed=true&oauth_expires_in=599
You might try out the OAuth libraries to handle the connection: http://code.google.com/p/oauth/
I created a plugin for Play Framework to easily integrated with LinkedIn's OAuth: geeks.aretotally.in/projects/play-framework-linkedin-module. Hopefully it can help. You should def check out Play, very very cool Java framework.
portlet body:
public class LinkedInPortlet extends GenericPortlet {
public static final String PAGE_PIN = "pin";
public static final String PAGE_EDIT = "edit";
public static final String PAGE_PROFILE = "profile";
public static final String PAGE_CONNECTIONS = "connections";
public static final String FORM_LINKEDIN_PREFERENCES = "preferencesLinkedInForm";
public static final String PAGE_VIEW_MY_PROFILE = "/WEB-INF/portlets/linkedin/myProfile.jsp";
public static final String PAGE_VIEW_MY_CONNECTIONS =
"/WEB-INF/portlets/linkedin/myConnections.jsp";
public static final String PAGE_PREFERENCES = "/WEB-INF/portlets/linkedin/edit.jsp";
public void doView(RenderRequest request, RenderResponse response) throws PortletException,
IOException {
String view = PAGE_VIEW_MY_PROFILE;
String page =
(String) request.getPortletSession().getAttribute(
"page_" + getPortletIdentifier(request), PortletSession.PORTLET_SCOPE);
String accessTokenToken =
getStringConfiguration(request, LinkedInPreferencesForm.PARAM_ACCESS_TOKEN_TOKEN);
String accessTokenSecret =
getStringConfiguration(request, LinkedInPreferencesForm.PARAM_ACCESS_TOKEN_SECRET);
LinkedInContact profile = new LinkedInContact();
List<LinkedInContact> contacts = new ArrayList<LinkedInContact>();
if (PAGE_PIN.equals(page)) {
view = PAGE_PREFERENCES;
} else if (PAGE_EDIT.equals(page)) {
view = PAGE_PREFERENCES;
} else if (PAGE_CONNECTIONS.equals(page)) {
try {
contacts =
ServiceResolver.getResolver().getLinkedInService().getConnections(
accessTokenToken, accessTokenSecret);
} catch (ServiceException se) {
view = PAGE_PREFERENCES;
handleException(request, se);
}
view = PAGE_VIEW_MY_CONNECTIONS;
} else {
try {
profile =
ServiceResolver.getResolver().getLinkedInService().getProfile(
accessTokenToken, accessTokenSecret);
} catch (ServiceException se) {
view = PAGE_PREFERENCES;
handleException(request, se);
}
view = PAGE_VIEW_MY_PROFILE;
}
request.setAttribute("profile", profile);
request.setAttribute("contacts", contacts);
response.setContentType(request.getResponseContentType());
PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(view);
rd.include(request, response);
}
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException, IOException {
String action;
action = (String) request.getParameter("action");
String page = request.getParameter("page");
if (page == null) {
page = PAGE_PROFILE;
} else if ("auth".equals(action)) {
request.getPortletSession().setAttribute(
"requestToken_" + getPortletIdentifier(request),
ServiceResolver.getResolver().getLinkedInService().getRequestToken(),
PortletSession.APPLICATION_SCOPE);
LinkedInPreferencesForm form = new LinkedInPreferencesForm(request);
request.getPortletSession().setAttribute(
FORM_LINKEDIN_PREFERENCES + getPortletIdentifier(request), form,
PortletSession.APPLICATION_SCOPE);
response.setPortletMode(PortletMode.EDIT);
} else if ("save".equals(action)) {
try {
try {
savePreferences(request, response);
} catch (ServiceException e) {
handleException(request, e);
}
} catch (PortletModeException e) {
handleException(request, e);
}
} else if ("myProfile".equals(action)) {
page = PAGE_PROFILE;
} else if ("myConnections".equals(action)) {
page = PAGE_CONNECTIONS;
}
if (page != null) {
request.getPortletSession().setAttribute("page_" + getPortletIdentifier(request), page,
PortletSession.PORTLET_SCOPE);
}
}
private void savePreferences(ActionRequest request, ActionResponse response)
throws PortletModeException, ServiceException {
LinkedInPreferencesForm form = new LinkedInPreferencesForm(request);
if (validateForm(request, form)) {
LinkedInRequestToken requestToken =
(LinkedInRequestToken) request.getPortletSession().getAttribute(
"requestToken_" + getPortletIdentifier(request),
PortletSession.APPLICATION_SCOPE);
String pin = request.getParameter("pinCode");
LinkedInAccessToken accessToken;
try {
accessToken =
ServiceResolver.getResolver().getLinkedInService().getAccessToken(
requestToken, pin);
} catch (LinkedInOAuthServiceException ase) {
response.setPortletMode(PortletMode.EDIT);
throw new ServiceException("linkedin.authentication.failed");
}
String tokenToken = requestToken.getToken();
String secret = requestToken.getTokenSecret();
String tokenURL = requestToken.getAuthorizationUrl();
Properties configuration = new Properties();
configuration.setProperty(LinkedInPreferencesForm.PARAM_PIN, form.getPin());
configuration
.setProperty(LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_TOKEN, tokenToken);
configuration.setProperty(LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_SECRET, secret);
configuration.setProperty(LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_URL, tokenURL);
configuration.setProperty(LinkedInPreferencesForm.PARAM_ACCESS_TOKEN_TOKEN, accessToken
.getToken());
configuration.setProperty(LinkedInPreferencesForm.PARAM_ACCESS_TOKEN_SECRET,
accessToken.getTokenSecret());
ServiceResolver.getResolver().getPortalService().savePortletConfiguration(request,
configuration);
resetSessionForm(request, FORM_LINKEDIN_PREFERENCES);
response.setPortletMode(PortletMode.VIEW);
} else {
// store in session
request.getPortletSession().setAttribute(
FORM_LINKEDIN_PREFERENCES + getPortletIdentifier(request), form,
PortletSession.APPLICATION_SCOPE);
response.setPortletMode(PortletMode.EDIT);
logger.debug(FORM_LINKEDIN_PREFERENCES + " is in edit mode");
}
}
#Override
protected void addConfiguration(MessageSource messageSource, Locale locale,
Map<String, String> result) {
result.put(LinkedInPreferencesForm.PARAM_PIN, messageSource.getMessage(
"linkedIn.preferences.pin", null, locale));
result.put(LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_TOKEN, messageSource.getMessage(
"linkedIn.preferences.requestTokenToken", null, locale));
result.put(LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_SECRET, messageSource.getMessage(
"linkedIn.preferences.requestTokenSecret", null, locale));
result.put(LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_URL, messageSource.getMessage(
"linkedIn.preferences.requestTokenURL", null, locale));
result.put(LinkedInPreferencesForm.PARAM_ACCESS_TOKEN_TOKEN, messageSource.getMessage(
"linkedIn.preferences.accessToken", null, locale));
result.put(LinkedInPreferencesForm.PARAM_ACCESS_TOKEN_SECRET, messageSource.getMessage(
"linkedIn.preferences.accessTokenSecret", null, locale));
}
#Override
protected void addPreference(MessageSource messageSource, Locale locale,
Map<String, String> result) {
}
#Override
public String getAsyncTitle(RenderRequest request) {
return this.getTitle(request);
}
protected boolean validateForm(ActionRequest request, LinkedInPreferencesForm form) {
return form.validate();
}
protected String myEdit(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
LinkedInPreferencesForm form = new LinkedInPreferencesForm();
form.setPin(getStringConfiguration(request, LinkedInPreferencesForm.PARAM_PIN));
form.setRequestTokenToken(getStringConfiguration(request,
LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_TOKEN));
form.setRequestTokenSecret(getStringConfiguration(request,
LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_SECRET));
form.setRequestTokenURL(getStringConfiguration(request,
LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_URL));
registerSessionForm(request, FORM_LINKEDIN_PREFERENCES, form);
LinkedInRequestToken requestToken;
requestToken =
(LinkedInRequestToken) request.getPortletSession().getAttribute(
"requestToken_" + getPortletIdentifier(request),
PortletSession.APPLICATION_SCOPE);
if (requestToken == null) {
requestToken =
new LinkedInRequestToken(form.getRequestTokenToken(), form
.getRequestTokenSecret());
requestToken.setAuthorizationUrl(form.getRequestTokenURL());
}
request.setAttribute("requestToken", requestToken);
return PAGE_PREFERENCES;
}
}