I'm trying to learn Java right now and I've jumped in the deep end by starting with the Android Faceobok API. Right now, I'm trying to get some information from my graph data (a friend in this case) and display it in a text view. This seems rather trivial but it has been anything but.
JSONObject json_data = null;
try
{
JSONObject response = Util.parseJson(facebook.request("/me/friends", mBundle, "GET")); // Get a friend information from facebook
JSONArray jArray = response.getJSONArray("data");
json_data = jArray.getJSONObject(0);
String name = json_data.getString("name");
mText.setText(name);
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (JSONException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (FacebookError e)
{
e.printStackTrace();
}
The TextView doesn't change when I do this and I'm not exactly sure where I've gone wrong.
As an aside, there is a shortage of good Android Facebook API tutorials out there. Most are hundreds of lines of code; I don't have the energy or patience to consume all of that.
I have a feeling your initial request isnt working properly. you should try this line instead:
JSONObject response = Util.parseJson(facebook.request("me/friends"));
Firstly I think in your initial request, it should be "me/friends" rather than "/me/friends". Secondly you dont necessarily need the mBundleor "GET" parameters in what you're trying to achieve. Have you even defined parameters in mBundle? You're also getting information from the request method, so the "GET" parameter isn't necessary.
Try the line i just wrote, as it is simpler and will get your friends information. The rest of your code is fine.
Your assertion about being "trivial" is essentially true, but generally speaking "jumping into the deep end" rarely results in anything other than a drowning.
I'm going to be "that guy" and recommend you actually get to the point of having a general understanding and minimal competency in Java before tackling someone else's API. Once you know how Java works - the "PME" ... properties, methods, and events - learning anyone's API becomes just a question of following the proper steps.
Besides that little bit of PS, answer the following:
1) received data from your source?
2) what thread are you invoking this on?
3) any of the objects null?
4) any exceptions being thrown when you look in the Console or Log (print those out to the Log versus your current implementation)?
And, not for nothing, but if you don't have the time or patience to learn the "how's and why's" of an API or software dev in general then this will be a long exercise for you if the work ever becomes non-trivial.
Just one man's opinion who also has attempted to drink from fire hose before.
Update: Here's all of my code:
public class FriendsActivity extends Activity {
/** Called when the activity is first created. */
Facebook facebook = new Facebook("194653157245506");
TextView mText;
Bundle mBundle;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mText = (TextView) this.findViewById(R.id.text);
facebook.authorize(this, new String[] {"offline_access", "user_interests", "friends_interests"},
new DialogListener() {
#Override
public void onComplete(Bundle values) {}
#Override
public void onFacebookError(FacebookError error) {}
#Override
public void onError(DialogError e) {}
#Override
public void onCancel() {}
});
JSONObject json_data = null;
try
{
JSONObject response = Util.parseJson(facebook.request("/me/friends", mBundle, "GET")); // Get a friend information from facebook
JSONArray jArray = response.getJSONArray("data");
json_data = jArray.getJSONObject(0);
String name = json_data.getString("name");
Log.i("friend is", name);
mText.setText(name);
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (JSONException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (FacebookError e)
{
e.printStackTrace();
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
facebook.authorizeCallback(requestCode, resultCode, data);
}
}
I may be a little off key. but I have done facebook api development in C#, and i am wondering if you have had the client login.
Facebook works with OAuth to allow you to authorize through them for a client. (Even your own account as the client) therefore you may need to login.
Another thing to look at is, do you have the TextView that is in the Activity that is being displayed..
Try putting in a breakpoint and looking over the code as it is executing, Debug View is great for that.
see if your response is being populated.
make sure you have the Text from the Activity.
mText = (TextView)findViewById(R.id.TextView1); //or whatever you named it.
Also the LogCat should show you the stack trace for any errors that occur, maybe posting some of the output would help
Related
I'm trying to get the whole body page from youtube.com but only get a quarter of it for weird reasons
can somebody help me out here?
heres the code:
private static String data;
#Override
protected Void doInBackground(Void... voids) {
try {
Document doc = Jsoup.connect("https://www.youtube.com/results?search_query=Mettalica").get();
data = doc.body().html();
}
catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected void onPostExecute(Void aVoid) {
//basically sysout the html results of the youtube search
super.onPostExecute(aVoid);
Log.d(TAG, data);
}
I think Doc Object has full HTML as well, you need to dig deeper to look for a better way but doc.outerHtml() should do the Job for you. Below SS also illustrates this object's state in Debug mode To compare with View Source of URL
I am new to android development so I think this may be a teething issue on my part, but I am currently trying to use the PixelCopy function in android studio. I have code as shown below, and it matches what the base class is expecting although it is returning an error. Would anyone be able to assist me with this issue?
The code I currently have is as follows:
final HandlerThread handlerThread = new HandlerThread("PixelCopier");
handlerThread.start();
SurfaceView current = new SurfaceView(view.getContext());
PixelCopy.OnPixelCopyFinishedListener copyResult;
// Make the request to copy.
PixelCopy.request(current, bitmap, copyResult, handlerThread);
if (copyResult. == PixelCopy.SUCCESS) {
//If successful do tasks in here
}
Try crating extracting finish listener as shown below in class.
private static void onPixelCopyFinished(int result) {
if (result != PixelCopy.SUCCESS) {
Log.e("err", "errMsg");
return;
}
}
You can pass the listener as below and also you'll also need to wrap it in try catch as it might throw an exception.
try {
PixelCopy.request(current, bitmap, <YOUR CLASS>::onPixelCopyFinished, this.getHandler());
} catch (IllegalArgumentException e) {
// PixelCopy may throw IllegalArgumentException, make sure to handle it
e.printStackTrace();
}
I have a single incident where a complete duplicate of a entry was made into the database (the same user comment appeared twice). They had different object IDs but were otherwise the exact same. It was slower than usual to finish the posting and only happened once out of dozens of comments, so I want to say it was a Parse issue during the saveInBackground call. Even so, I expect a service like Parse to be a little more robust. As my first time working with Android though, I also can't be sure nothing is wrong on my end. Any help? Also just any criticisms? This is the method called when the user hits a comment submission button:
private void submitComment() {
String text = commentText.getText().toString().trim();
Intent intent = getIntent();
String ID = intent.getStringExtra("imageID");
String parentID = intent.getStringExtra("parent");
// Set up a progress dialog
final ProgressDialog loadingDialog = new ProgressDialog(CommentSubmitActivity.this);
loadingDialog.setMessage(getString(R.string.publishing_comment));
loadingDialog.show();
Comment comment = new Comment();
comment.setText(text);
comment.setUser((ParseUser.getCurrentUser()));
if (ID.equals("#child")) {
comment.setParent(parentID);
comment.setImage("#child");
ParseQuery<ParseObject> query = ParseQuery.getQuery("Comment");
query.getInBackground(parentID, new GetCallback<ParseObject>() {
public void done(ParseObject parentComment, ParseException e) {
if (e == null) {
int numChild = parentComment.getInt("numChild");
parentComment.put("numChild", ++numChild);
parentComment.saveInBackground();
} else {
Log.d("numChild: ", "error");
}
}
});
} else {
comment.setImage(ID);
comment.put("numChild", 0);
ParseQuery<ParseObject> query = ParseQuery.getQuery("ImageUpload");
query.getInBackground(ID, new GetCallback<ParseObject>() {
public void done(ParseObject image, ParseException e) {
if (e == null) {
int numComments = image.getInt("numComments");
image.put("numComments", ++numComments);
image.saveInBackground();
} else {
Log.d("numComments: ", "error");
}
}
});
}
comment.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
loadingDialog.dismiss();
finish();
}
}
});
}
I encountered similar problem like yours.
I created an app where user can create account and add photo to it and list of objects (friends in my case).
Once when I was testing it user was created twice.
I went through my code and my my suspicions are connected with async calls.
I see that you use asynchronous parse api in you application so no fragment of code is waiting for response and blocking the rest of operations.
You cannot control when parse server will response.
What I did I just put all synchronous requests in my custom async code (AsyncTask in Android).
Hope that my answer somehow meeets your expectations.
I'm using the example code on this page (http://altbeacon.github.io/android-beacon-library/samples.html) in the Starting an App in the Background section and I've got a working app.
It detects whenever a beacon is in range even on background.
The problem is I need to know which beacon is it (UUID, Major, Minor) to then match it against my local database and throw a notification with the app still on background.
The didEnterRegion(Region region) function only has a matchesBeacon method, and I've tried doing the following to identify which of the beacons is being seen but it's throwing a NullPointerException:
public class SightSeeing extends Activity implements BootstrapNotifier, RangeNotifier {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Region region = new Region("sightRegion", null, null, null);
regionBootstrap = new RegionBootstrap(this, region);
BeaconManager.getInstanceForApplication(this).getBeaconParsers().add(
new BeaconParser(). setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24")
);
BeaconManager.getInstanceForApplication(this).setRangeNotifier(this);
}
#Override
public void didEnterRegion(Region region) {
regionBootstrap.disable();
BeaconManager.getInstanceForApplication(this).setRangeNotifier(this);
try {
BeaconManager.getInstanceForApplication(this).startRangingBeaconsInRegion(region);
}
catch (RemoteException e) {
Log.e(TAG, "Can't start ranging");
}
}
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if (beacons.size() > 0) {
Iterator<Beacon> beaconIterator = beacons.iterator();
while (beaconIterator.hasNext()) {
Beacon beacon = beaconIterator.next();
//check if beacon exists in our DB and throw notification
}
}
}
Am I missing something obvious or isn't this possible with this library?
EDIT:
I've updated the code sample to give you guys a broader idea and I've tried implementing the suggestion by FOliveira without any success.
EDIT2:
Updated code to reflect the davidgyoung's suggestion. Still no luck. I have a Log.d() right on the first line of the didRangeBeaconsInRegion() function and it isn't being called.
I've tried adding BeaconManager.getInstanceForApplication(this).setRangeNotifier(this); before the try/catch block and the result is the same.
Did I implement the suggestion wrong or is there any other way to get this working?
If you want the app to launch itself on beacon detection, then the RegionBootstrap is the easiest way to go. In order to combine this with Ranging needed to detect individual beacons, then add code in your didEnterRegion method like this:
try {
BeaconManager.getInstanceForApplication(this).startRangingBeaconsInRegion(region);
}
catch (RemoteException e) {
Log.e(TAG, "Can't start ranging");
}
Then implement a ranging callback like you have.
You also need to remove the code below, which is probably what is causing your NullPointerException, because the :
for(int i=0; i< beaconsList.size(); i++) {
Beacon b = new Beacon.Builder()
.setId1(beaconsList.get(i).get("uuid"))
.setId2(beaconsList.get(i).get("major"))
.setId3(beaconsList.get(i).get("minor"))
.build();
if(region.matchesBeacon(b)) {
//get info from DB and throw notification
}
}
EDIT: I have updated the library's reference application to show how this can be done successfully. See here: https://github.com/AltBeacon/android-beacon-library-reference/blob/master/src/org/altbeacon/beaconreference/BeaconReferenceApplication.java
you can implement RangeNotifier interface and you can access all the beacon information captured in the public void didRangeBeaconsInRegion(Collection<Beacon> Beacons, Region region) method of that interface. Hope i got the question right
This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 9 years ago.
whoaa
i really need help, why my code result like that?
this is my code :
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(URL);
try{
HttpResponse response = httpClient.execute(httpPost);
String jsonResult = convertStreamToString((response.getEntity().getContent())).toString();
JSONObject obj = (JSONObject) new JSONTokener(jsonResult).nextValue();
JSONObject obj2 = obj.getJSONObject("GetRingkasObjekPajak_SingleResult");
String nameWP = obj2.getString("NM_WP");
TextView tv = (TextView)findViewById(R.id.dummy_text_three);
tv.setText(jsonResult);
}catch (MalformedURLException e) {
// URL is invalid
TextView tv = (TextView) findViewById(R.id.dummy_text_three);
tv.setText("url invalid");
} catch (SocketTimeoutException e) {
// data retrieval or connection timed out
TextView tv = (TextView) findViewById(R.id.dummy_text_three);
tv.setText("RTO");
} catch (IOException e) {
// could not read response body
// (could not create input stream)
TextView tv = (TextView) findViewById(R.id.dummy_text_three);
tv.setText("couldnt read response");
} catch (JSONException e) {
// response body is no valid JSON string
TextView tv = (TextView) findViewById(R.id.dummy_text_three);
tv.setText("json response fail");
}catch (Exception e) {
// TODO: handle exception
TextView tv = (TextView) findViewById(R.id.dummy_text_three);
tv.setText(e.toString());
}
i also have added internet permission
please help me
how to improve my code, so this problem solved.
Here is an example of Async task... Hope it will be helpfull to you.
private class YourAsyncTaskClass extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//your http network call here.
return null;
}
#Override
protected void onPostExecute(String result) {
//update your ui here
}
#Override
protected void onPreExecute() {
//do any code before exec
}
#Override
protected void onProgressUpdate(Void... values) {
//If you want to update a progress bar ..do it here
}
}
Finally call this class from anywhere you want like..
new YourAsyncTaskClass().execute();
you can not perform network operations from main UI thread. you need to do networking related tasks in different thread. Better use AsyncTask
According to the doc
The exception that is thrown when an application attempts to perform a
networking operation on its main thread.
This is only thrown for applications targeting the Honeycomb SDK or
higher. Applications targeting earlier SDK versions are allowed to do
networking on their main event loop threads, but it's heavily
discouraged.
NetworkOnMainThreadException: The exception that is thrown when an application attempts to perform a networking operation on its main thread.
There is an article about Painless Threading on the Android developer site which is a good introduction to this, and will provide you with much better depth of answer than can be realistically provided here.
Run your code in AsyncTask.
You can learn about asyncTask here is best explanation with good example .
call your webservice inside aynctask.
private class NetworkTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
// call your network operation here
}
}