I'm trying to get an authorization code via Google Plus login to use it on the server. The G+ login works, I am logged in on the device, but when I try to get the Token, I get an exception with the super helpful message Unknown. This is the code:
private class GoogleLoginTask extends AsyncTask<Void, Void, String> {
private static final String LOGIN_SCOPES =
"https://www.googleapis.com/auth/plus.login " +
"https://www.googleapis.com/auth/userinfo.email";
#Override
protected String doInBackground(Void[] params) {
String apiKey = getApplicationMetaData("google.client-id");
String scopes = "oauth2:server:client_id:" + apiKey
+ ":api_scope:" + LOGIN_SCOPES;
Bundle appActivities = new Bundle();
appActivities.putString(GoogleAuthUtil.KEY_REQUEST_VISIBLE_ACTIVITIES,
"http://schema.org/AddAction");
String code = null;
try {
code = GoogleAuthUtil.getToken(getBaseContext(),
getPlusClient().getAccountName(), scopes, appActivities);
} catch (IOException e) {
Toast.makeText(getBaseContext(), R.string.error_network, Toast.LENGTH_LONG).show();
} catch (UserRecoverableAuthException e) {
startActivityForResult(e.getIntent(), AUTH_CODE_REQUEST_CODE);
} catch (GoogleAuthException e) {
Log.e(TAG, "Google auth exception: ", e);
} catch (Exception e) {
throw new RuntimeException(e);
}
return code;
}
}
I have taken the code directly from the Developer Page. Though the docs don't clarify about many of the parameters, I think I have it correctly.
I have triple checked the apiKey and the getPlusClient().getAccountName() contents, they're correct. And I made sure the application and the server are in the same project on the API console.
No idea what else I could be doing wrong.
I have found the problem: The build.gradle file had a slightly (typoed) different valued for applicationId than what was set in the API-Console.
Though some simple error message in this case would have been great.
Related
I am trying to get youtube title from url using json file but i do not get any result and i also do not get any exception. I try to toast exception in toast message is null / blank. Can any one help me please. my code is here...
String link = youtube url;
URL embededURL = null;
try {
embededURL = new URL("http://www.youtube.com/oembed?url=" + link + "&format=json");
} catch (MalformedURLException e) {
e.printStackTrace();
makeToast(e.getMessage());
}
try {
title = new JSONObject(IOUtils.toString(embededURL)).getString("title");
} catch (JSONException e) {
e.printStackTrace();
makeToast(e.getMessage());
} catch (IOException e) {
e.printStackTrace();
makeToast(e.getMessage());
}
makeToast(title);
First of all, since your question tag is android-volley, I'm going to give you an android-volley answer. However, there are a lot of libraries to look into that manage HTTP calls in a subjectively nicer way like OkHttp.
Now, the short answer to your question is your code is not even making a call to the internet.
Longer answer:
Add the volley dependency to your build.gradle
dependencies {
//... other dependencies
implementation 'com.android.volley:volley:1.1.1'
}
Put <uses-permission android:name="android.permission.INTERNET" /> in your AndroidManifest.xml
Make the app call to the internet like below. I tweaked the Android Volley simple example.
RequestQueue queue = Volley.newRequestQueue(context);
// sample of a URL-encoded url param, so you'll need to convert your link variable if you haven't already
String url = "https://www.youtube.com/oembed?url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DiwGFalTRHDA&format=json";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
String title = new JSONObject(response).getString("title");
Toast.makeText(context, title, Toast.LENGTH_LONG).show();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(context, "Error!", Toast.LENGTH_LONG).show();
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
i'm creating android application with Socket.io and node.js server.
My js server:
var http = require('http');
var server = http.createServer(function(req, res) {
});
var mysql = require('mysql');
var db = mysql.createConnection({
host:,
port:,
user:,
password:,
database:
});
var resultconnection = "";
db.connect(function(err){
if (err) {
resultconnection = err;
}
});
var io = require('socket.io').listen(server);
io.on('connection',function(socket){
console.log('Connected!');
socket.on("createaccount", function(data){
console.log('Create account executed.');
if(resultconnection != ""){
db.query("INSERT INTO USER (USERNAME, PASSWORD, EMAIL, BIRTHDATE) VALUES('"+data["username"]+"', SHA1('"+data["password"]+"'), '"+data["email"]+"', "+data["birthdate"]+"')");
resultconnection = "OK";
}
socket.emit('response', {"response": resultconnection});
});
});
server.listen(8080);
Android client(java):
try {
socket = IO.socket("http://localhost:8080");
socket.on("response", new Emitter.Listener() {
#Override
public void call(Object... args) {
JSONObject obj = (JSONObject) args[0];
try {
result = obj.getString("message");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
socket.connect();
JSONObject createUser = new JSONObject();
try {
createUser.put("username", username);
createUser.put("password", password);
createUser.put("email", email);
createUser.put("birthdate", datanasc);
} catch (JSONException e) {
e.printStackTrace();
}
socket.emit("createaccount", "");
} catch (URISyntaxException e) {
result = e.getMessage();
}
Console.log("Connected") is running but when I run the socket.emit("createaccount") the client does not run on the server.
I think the server IP you gave in the client code is not correct. It is trying to connect to the localhost of your Android device while your server is running on some other remote system.
Try changing the server IP in the following snippet(ideally this should be something other than localhost):
try {
socket = IO.socket("<server_IP:server_PORT");
socket.on("response", new Emitter.Listener() {
#Override
public void call(Object... args) {
JSONObject obj = (JSONObject) args[0];
try {
result = obj.getString("message");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
socket.connect();
JSONObject createUser = new JSONObject();
try {
createUser.put("username", username);
createUser.put("password", password);
createUser.put("email", email);
createUser.put("birthdate", datanasc);
} catch (JSONException e) {
e.printStackTrace();
}
socket.emit("createaccount", "");
} catch (URISyntaxException e) {
result = e.getMessage();
}
There are significant structural problems with how your server is designed:
You're trying to save resultconnection in a module global. That means you can only ever have one socket.io client connection that will work properly. The second connection will see the resultconnection from the previous client connection. There's just no way this is a proper way to do things. It could possibly work if you never ever had more than one client connect to your server - not just one client at a time, but one client all time.
The way you handle the async database operation in the createaccount message handler is just wrong. You are trying to .emit() the resultconnection back to the client before it has been set.
Your error handling for the db.connect() call does not seem correct. When you can't connect to the database you need to take some action, not just set a variable as such and proceed on as if nothing is wrong. Even that variable you set is being used wrong later. You're checking to see if you had an error on the connect and if you did, then you're trying to do a database operation. Besides just a messed up design, this logic is even backwards.
To think about how to fix the first issue, you need to explain what you're trying to do with this statement:
if(resultconnection != ""){
because that will need to be done a different way. You can't just save global state in your server and expect that to represent the state of any incoming connection.
How to fix the second issue will depend upon what is done for the first issue.
How to fix the third issue involves some design decisions about what to do with your server when you can't connect to the database (shut-down, retry, log, etc...).
I developed a little Java Swing application to look up character statistics in World of Warcraft with their developer API using Netbeans in Ubuntu Gnome 14.04. Everything works as I've intended with the exception of a button that calls a method that opens a link in the default browser to the specified character's profile. On Ubuntu, the string I use in the URL renders correctly, but on Windows it does not. If I run the application (in Windows) using a batch file that specifies UTF-8 encoding for the JVM, I do not have this issue. When running it directly from the .jar file, characters such as "â" register as "â" in the URL on Windows despite my attempt at encoding all of my strings as UTF-8. How can I get the URL be properly formatted? I'm assuming there's something I'm missing. If you need to see more of the code, let me know. Thank you in advance.
ArmoryScanner_UI.java
private void openArmoryLink() {
ArmoryScanner_Backend armory = new ArmoryScanner_Backend();
String name;
String realm;
String locale;
try {
name = new String(jTextField_Name.getText().getBytes("UTF-8"));
realm = jComboBox_Realm.getSelectedItem().toString();
locale = jComboBox_Locale.getSelectedItem().toString();
if (!name.trim().isEmpty()) {
name = formatName(name);
realm = formatRealm(realm);
locale = formatLocale(locale);
armory.setPlayerInfo(name, realm, locale);
if (armory.isCharacterFound()) {
armory.setArmoryLink();
} else {
showErrorMessage("Character not found.");
jTextField_Name.setText("");
jTextField_Name.setCaretPosition(0);
jTextField_Name.requestFocus();
}
} else {
showErrorMessage("Please enter a character name.");
jTextField_Name.setText("");
jTextField_Name.setCaretPosition(0);
jTextField_Name.requestFocus();
}
} catch (UnsupportedEncodingException e) {
showErrorMessage("Error converting name to UTF-8\n"
+ e.getMessage());
}
}
private String formatName(String name) {
String result;
try {
result = new String(name.getBytes("UTF-8"), "UTF-8");
} catch (UnsupportedEncodingException e) {
showErrorMessage("Error converting name to UTF-8\n"
+ e.getMessage());
result = "";
}
return result;
}
ArmoryScanner_Backend.java
public void setArmoryLink () {
try {
String baseURL = "https://us.battle.net/wow/en/character/";
String fullURL = (baseURL + realm + "/" + name + "/simple");
System.out.println("Full URL: " + fullURL);
if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().browse(new URL(fullURL).toURI());
} else {
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("xdg-open " + fullURL);
} catch (IOException e) {
System.out.println("I/O exception (non-Windows system)");
}
}
} catch (UnsupportedOperationException e) {
System.out.println("Unsupported OS");
} catch (MalformedURLException e) {
System.out.println("Bad URL");
} catch (IOException e) {
System.out.println("I/O exception.");
} catch (URISyntaxException e) {
System.out.println("Bad URI syntax");
}
}
This method works fine:
private void submit() {
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
ArmoryScanner_Backend armory = new ArmoryScanner_Backend();
String name;
String realm;
String locale;
try {
name = new String(jTextField_Name.getText().getBytes("UTF-8"));
realm = jComboBox_Realm.getSelectedItem().toString();
locale = jComboBox_Locale.getSelectedItem().toString();
if (!name.trim().isEmpty()) {
name = formatName(name);
realm = formatRealm(realm);
locale = formatLocale(locale);
armory.setPlayerInfo(name, realm, locale);
if (armory.isCharacterFound()) {
setStatistics(armory);
setProgression(armory);
} else {
showErrorMessage("Character not found.");
jTextField_Name.setText("");
jTextField_Name.setCaretPosition(0);
jTextField_Name.requestFocus();
}
} else {
showErrorMessage("Please enter a character name.");
jTextField_Name.setText("");
jTextField_Name.setCaretPosition(0);
jTextField_Name.requestFocus();
}
} catch (UnsupportedEncodingException e) {
showErrorMessage("Error converting name to UTF-8\n"
+ e.getMessage());
}
this.setCursor(Cursor.getDefaultCursor());
}
Java uses Unicode on the inside, so you don't usually need to set the encoding EXCEPT when you read/write outside resources.
There you need to have it explicitly.
In your case you need to encode the elements of the URL with the class URLEncoder.
Have a look at the documentation.
I have read a half dozen threads regarding this and I'm no where closer to a solution. No matter what I change I get ftp return code 500 "The command was not accepted and the requested action did not take place." and I'm not sure how to debug that.
This is my site and I can connect with CoreFTP and read and write, so it does not seem to be a permissions issue. I've tried two different accounts, with this code and CoreFTP. One writes to the root and another is pointed to an "image_in" folder.
imageData is a byte array with a length of 166578 and stream has the same length after the InputStream call. storeFile() always returns false with a return code of 500.
One thread implied enterLocalPassiveMode() and enterRemotePassiveMode() were the culprits, but I have tried this code both with and without those lines and still I get a 500 return code.
Any idea what I'm missing?
Greg
class ImageUploadTask extends AsyncTask <Void, Void, String>{
#Override
protected String doInBackground(Void... unsued) {
try {
boolean status = false;
try {
FTPClient mFtpClient = new FTPClient();
String ip = "my domain dot com";
String userName = "ftp79815757-0";
String pass = "my password";
mFtpClient.connect(InetAddress.getByName(ip));
mFtpClient.login(userName, pass);
int reply = mFtpClient.getReplyCode();
if (FTPReply.isPositiveCompletion(reply)) {
//one thread said this would do the trick
mFtpClient.enterLocalPassiveMode();
mFtpClient.enterRemotePassiveMode();
InputStream stream = new ByteArrayInputStream(imageData);
mFtpClient.changeWorkingDirectory("/images_in");
String currdir = mFtpClient.printWorkingDirectory();
if (!mFtpClient.storeFile("remoteName.jpg", stream)) {
Log.e("FTPUpload", String.valueOf(mFtpClient.getReplyCode()));
}
stream.close();
mFtpClient.disconnect();
}
else {
Log.e("FTPConnected", String.valueOf(reply));
}
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
} catch (Exception e) {
if (dialog.isShowing())
dialog.dismiss();
Toast.makeText(getApplicationContext(),
"Error",
Toast.LENGTH_LONG).show();
Log.e(e.getClass().getName(), e.getMessage(), e);
return null;
}
}
You forgot to set file type
mFtpClient.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
If it still doesn't work then you have following options:
If you insist on using Apache FTP Client then follow this example
Or you could try this example
The second example worked in my case.
You need to use: enterLocalPassiveMode
mFtpClient.enterLocalPassiveMode();
If you then do other operations, you might have to go back active with enterLocalActiveMode.
I am working on an application that retrieves files from different URL's.
There is a TreeSet that contains the target to download. This is processed in a loop with each item being called with an ExecutorService. Here's some code:
private void retrieveDataFiles() {
if (this.urlsToRetrieve.size() > 0) {
System.out.println("Target URLs to retrieve: " + this.urlsToRetrieve.size());
ExecutorService executorProcessUrls = Executors.newFixedThreadPool(this.urlsToRetrieve.size());//could use fixed pool based on size of urls to retrieve
for (Entry target : this.urlsToRetrieve.entrySet()) {
final String fileName = (String) target.getKey();
final String url = (String) target.getValue();
String localFile = localDirectory + File.separator + fileName;
System.out.println(localFile);
executorProcessUrls.submit(new WikiDumpRetriever(url, localFile));
dumpFiles.add(localFile);
//TODO: figure out why only 2 files download
}
executorProcessUrls.shutdown();
try {
executorProcessUrls.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException ex) {
System.out.println("retrieveDataFiles InterruptedException: " + ex.getMessage());
}
} else {
System.out.println("No target URL's were retrieved");
}
}
Then the WikiDumpRetriever:
private static class WikiDumpRetriever implements Runnable {
private String wikiUrl;
private String downloadTo;
public WikiDumpRetriever(String targetUrl, String localDirectory) {
this.downloadTo = localDirectory;
this.wikiUrl = targetUrl;
}
public void downloadFile() throws FileNotFoundException, IOException, URISyntaxException {
HTTPCommunicationGet httpGet = new HTTPCommunicationGet(wikiUrl, "");
httpGet.downloadFiles(downloadTo);
}
#Override
public void run() {
try {
downloadFile();
} catch (FileNotFoundException ex) {
System.out.println("WDR: FileNotFound " + ex.getMessage());
} catch (IOException ex) {
System.out.println("WDR: IOException " + ex.getMessage());
} catch (URISyntaxException ex) {
System.out.println("WDR: URISyntaxException " + ex.getMessage());
}
}
}
As you can see this is an inner class. The TreeSet contains:
Key : Value
enwiki-latest-pages-articles.xml.bz2 : http://dumps.wikimedia.org/enwiki/latest/enwiki-latest-pages-articles.xml.bz2
elwiki-latest-pages-articles.xml.bz2 : http://dumps.wikimedia.org/enwiki/latest/elwiki-latest-pages-articles.xml.bz2
zhwiki-latest-pages-articles.xml.bz2 : http://dumps.wikimedia.org/enwiki/latest/zhwiki-latest-pages-articles.xml.bz2
hewiki-latest-pages-articles.xml.bz2 : http://dumps.wikimedia.org/enwiki/latest/hewiki-latest-pages-articles.xml.bz2
The problem is that this process downloads 2 of the four files. I know that all four are available and I know that they can be downloaded. However, only 2 of them process at any time.
Can anyone shed any light on this for me please - what am I missing or what am I getting wrong?
Thanks
nathj07
Thanks to ppeterka - it was a limit from the source. So, to overcome this I set the fixed thread pool size to 2. This means that only 2 files are downloaded simultaneously.
The answer then was to find the vendor imposed limit and set the thread pool:
ExecutorService executorProcessUrls = Executors.newFixedThreadPool(2);
I wanted to accept an answer but couldn't seem to do it with the comments. Sorry if this was the wrong way to do it.
Thanks for all the pointers - the 'group think' really helped solve this for me.