I am using Gmail api and many users are complaining that sending emails does not work. For most users it works fine and I am not able to reproduce the issue. In Firebase I get the following crash report.
Non-fatal Exception: com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:297)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:868)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at com.dummydomain.myapp.EmailUtils.sendMessage(EmailUtils.java:397)
(...)
Caused by com.google.android.gms.auth.d: NeedPermission
at com.google.android.gms.auth.zze.zzb(zze.java:13)
at com.google.android.gms.auth.zzd.zza(zzd.java:77)
at com.google.android.gms.auth.zzd.zzb(zzd.java:20)
at com.google.android.gms.auth.zzd.getToken(zzd.java:7)
at com.google.android.gms.auth.zzd.getToken(zzd.java:5)
at com.google.android.gms.auth.zzd.getToken(zzd.java:2)
at com.google.android.gms.auth.GoogleAuthUtil.getToken(GoogleAuthUtil.java:55)
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:267)
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:292)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:868)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at com.dummydomain.myapp.EmailUtils.sendMessage(EmailUtils.java:397)
(...)
Below are the essentials of my authentication process. Manifest.permission.GET_ACCOUNTS is already granted at this point, and the appropriate API things in the Google Cloud Console are correctly configured and my app is verified for using the sensitive permission/scope GMAIL_SEND.
private void authenticate() {
String[] SCOPES = {GmailScopes.GMAIL_SEND};
GoogleAccountCredential mCredential = GoogleAccountCredential.usingOAuth2(
context,
Arrays.asList(SCOPES))
.setBackOff(new ExponentialBackOff());
startActivityForResult(mCredential.newChooseAccountIntent(),REQUEST_ACCOUNT_PICKER);
}
// which returns in
public void onActivityResult(...) {
// (...)
switch(requestCode) {
case REQUEST_ACCOUNT_PICKER:
if (resultCode == Activity.RESULT_OK && data != null && data.getExtras() != null) {
String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
// Check if not a gmail account, since gmail api only works with that gmail accounts...
if(!accountName.contains("#gmail.com") && !accountName.contains("#googlemail.com")){
// --> tell user to select a google account
return;
}
mCredential.setSelectedAccount(new Account(accountName, BuildConfig.APPLICATION_ID));
// Got account, now test if we have access
new CheckAccessTask().execute();
}else{
// (...)
}
}
break;
case REQUEST_AUTHORIZATION:
if (resultCode != Activity.RESULT_OK) {
// choose new account
startActivityForResult(mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}else{
// Got authorization, so test email
new CheckAccessTask().execute();
}
break;
}
}
private class CheckAccessTask extends AsyncTask<Void, Void, Boolean> {
private Exception mLastError = null;
#Override
protected Boolean doInBackground(Void... params) {
try {
// Check if we got token - will crash with UserRecoverableAuthException
// if user didn't accept the google consent screen
mCredential.getToken();
// access granted, return true
return true;
} catch (Exception e) {
mLastError = e;
cancel(true);
return false;
}
}
#Override
protected void onCancelled() {
if (mLastError != null) {
if (mLastError instanceof GooglePlayServicesAvailabilityIOException) {
// Play Services not found --> cancel activation
} else if (mLastError instanceof UserRecoverableAuthException) {
startActivityForResult(((UserRecoverableAuthException) mLastError).getIntent(), REQUEST_AUTHORIZATION);
} else if (mLastError instanceof UserRecoverableAuthIOException) {
startActivityForResult(((UserRecoverableAuthIOException) mLastError).getIntent(), REQUEST_AUTHORIZATION);
} else {
// Other error --> cancel activation
}
} else {
// --> cancel activation
}
}
#Override
protected void onPostExecute(Boolean accessGranted) {
if (accessGranted){
// SUCCESS! Save email in shared preferences for later use
String accountName = mCredential.getSelectedAccountName();
prefs.putString(Constants.SENDER_ACCOUNT, accountName);
}
}
}
Essentials of sending email process (in actual code emails are HTML)
private void sendEmail(){
GoogleAccountCredential mCredential = GoogleAccountCredential.usingOAuth2(
context,
Arrays.asList(SCOPES))
.setBackOff(new ExponentialBackOff());
// set sender account
String senderAccount = prefs.getString(Constants.SENDER_ACCOUNT, null);
if(senderAccount == null) return; // Authentication not complete
mCredential.setSelectedAccount(new Account(senderAccount, BuildConfig.APPLICATION_ID));
// Initialize service object
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
Gmail mGmailApiService = new Gmail.Builder(
transport, jsonFactory, mCredential)
.setApplicationName("My-App")
.build();
// Construct email
com.google.api.services.gmail.model.Message message;
try {
// create MimeMessage
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.setSubject("Test email");
mimeMessage.setText("Hello this is an email sent from android");
mimeMessage.setFrom(new InternetAddress(mCredential.getSelectedAccountName()));
mimeMessage.setRecipients(javax.mail.Message.RecipientType.TO, InternetAddress.parse(senderAccount)); // send to yourself
// Convert MimeMessage to Message
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
mimeMessage.writeTo(bytes);
String encodedEmail = Base64.encodeBase64URLSafeString(bytes.toByteArray());
message = new com.google.api.services.gmail.model.Message();
message.setRaw(encodedEmail);
} catch (MessagingException | IOException e) {
e.printStackTrace();
return;
}
// Send email
try {
mGmailApiService.users().messages().send("me", message).execute(); // (EmailUtils:397)
// Success, email sent!
} catch (IOException e) {
e.printStackTrace();
// ==== THIS is where users get UserRecoverableAuthIOExceptions ==== //
}
}
With firebase logging I've found out that the crash happens both shortly after authentication as well long after. I can also see that it sometimes happens that the code sends one email successfully and then crashes on the next one right after. I also get quite a few reports of SocketTimeoutException which I believe are caused by slow/faulty internet connection though.
Thank you for your time.
EDIT:
The only way I am able to reproduce the error is by manually removing my app from the list of "Third-party apps with account access". But I don't see why this should happen without user interaction.
Related
I'm making an app where user can increase their channel subscribers by sub4sub. But problems is that I want get all subscribers list of user channel for verify that user subscribe or not. Question is this how I can get all subscribers of user channel.
But from this code I only get user channel id not getting user subscribers list.
One more questions I want put user channel I'd into hashmap
Please tell me how I can do.
I tried this
private class GetSubscriptionTask extends AsyncTask<Account, Void, List<Subscription>> {
#Override
protected List<Subscription> doInBackground(Account... params) {
Log.d(TAG, "doInBackground: ");
try {
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(
LoginActivity.this,
Collections.singleton(YouTubeScopes.YOUTUBE_READONLY));
credential.setSelectedAccount(params[0]);
YouTube youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName("Get User's Own Channel")
.build();
ChannelListResponse channelListResponse = youtube
.channels()
.list("id,contentDetails")
.setMine(true)
.setFields("items(contentDetails/relatedPlaylists/uploads,id)")
.execute();
// get signed user channel id:
Channel myChannel = channelListResponse.getItems().get(0);
String channelId = myChannel.getId(); // this is user's channel ID
Log.d(TAG, "my youtube channel id: " + channelId);
SubscriptionListResponse connectionsResponse = youtube
.subscriptions()
.list("snippet")
.setChannelId(channelId)
.execute();
return connectionsResponse.getItems();
} catch (UserRecoverableAuthIOException userRecoverableException) {
Log.d(TAG, "getSubscription:recoverable exception"+userRecoverableException.getLocalizedMessage());
startActivityForResult(userRecoverableException.getIntent(), RC_RECOVERABLE);
} catch (IOException e) {
Log.d(TAG, "getSubscription:exception"+e.getLocalizedMessage());
}
return null;
}
#Override
protected void onPostExecute(List<Subscription> subscriptions) {
if (subscriptions != null) {
Log.d(TAG, "subscriptions : size=" + subscriptions.size());
for (Subscription subscription : subscriptions) {
Log.v(TAG, "subscription : " + subscription.getId());
displayToast(subscription.getId());
}
} else {
Log.d(TAG, "subscriptions: null");
}
}
}
I've been following the example code on https://github.com/box/box-android-sdk/ as well as the documentation. However whenever I try to upload a file to box.com I receive the following error:
11-13 18:25:45.222 20996-21555/com.caa.capturebox W/System.err: com.box.androidsdk.content.BoxException: An error occurred while sending the request (401)
11-13 18:25:45.237 20996-21555/com.caa.capturebox W/System.err: at com.box.androidsdk.content.requests.BoxRequestUpload.send(BoxRequestUpload.java:114)
11-13 18:25:45.238 20996-21555/com.caa.capturebox W/System.err: at com.caa.capturebox.MainActivity$5.run(MainActivity.java:441)
Below is the last attempt I made however whether I try to upload from an input stream or from a local file I get the same error above.
private void uploadFile() {
mDialog = ProgressDialog.show(MainActivity.this, getText(R.string.boxsdk_Please_wait), getText(R.string.boxsdk_Please_wait));
new Thread() {
#Override
public void run() {
try {
Log.e("mya", "uploadFile: entered try");
FileInputStream uploadStream = new FileInputStream(image_name);
//InputStream uploadStream = getResources().getAssets().open(uploadFileName);
String destinationFolderId = "0";
String uploadName = "BoxSDKUpload.jpg";
//BoxRequestsFile.UploadFile request = mFileApi.getUploadRequest(uploadStream, uploadName, destinationFolderId);
BoxRequestsFile.UploadFile request = mFileApi.getUploadRequest(image_name, "0");
final BoxFile uploadFileInfo = request.send();
showToast("Uploaded " + uploadFileInfo.getName());
loadRootFolder();
} catch (IOException e) {
e.printStackTrace();
} catch (BoxException e) {
e.printStackTrace();
BoxError error = e.getAsBoxError();
if (error != null && error.getStatus() == HttpStatus.SC_CONFLICT) {
ArrayList<BoxEntity> conflicts = error.getContextInfo().getConflicts();
if (conflicts != null && conflicts.size() == 1 && conflicts.get(0) instanceof BoxFile) {
//uploadNewVersion((BoxFile) conflicts.get(0));
return;
}
}
showToast("Upload failed");
} finally {
mDialog.dismiss();
}
}
}.start();
}
since you have (401) response, I assume that it's Not Authorized http code returned. Have you been login to box : box login documentation
Please login in order to use box services with this code:
BoxSession session = new BoxSession(context);
session.authenticate();
need your help again :
I want to establish a connection to a obd2-bluetooth-adapter. For that reason i had a look at the BluetoothChat-Example from the AndroidSDK. I am able to establish a connection to my computer, but i am not able to pair my android tablet with my odb2-bluetooth-adapter (elm327). Found some hints, for instance :
myRemoteBluetoothDevice.setPassKey(....);
First, i can not use the function on 'myRemoteBluetoothDevice' - and then i don't know where to use this function. Within the connect-Thread ?
public synchronized void connect(BluetoothDevice device, boolean secure) {
if (D) Log.d(TAG, "connect to: " + device);
// Cancel any thread attempting to make a connection
if (mState == STATE_CONNECTING) {
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
// Start the thread to connect with the given device
mConnectThread = new ConnectThread(device, secure);
mConnectThread.start();
setState(STATE_CONNECTING);
}
I think a possible solution would be to implement a event-listener or something like this, which is called when the remote device needs a passcode ? But where i have to implement it ? And where i have to use it ?
Can somebody help me out there ?
Thanks in advance !!!
PS : My App is based on the following example :
https://android.googlesource.com/platform/development/+/25b6aed7b2e01ce7bdc0dfa1a79eaf009ad178fe/samples/BluetoothChat/src/com/example/android/BluetoothChat/BluetoothChatService.java
Greetings.
EDIT :
Tried to implement the first answer :
My BroadcastReceiver :
private final BroadcastReceiver mReceiverRequiresPin = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent){
try {
BluetoothDevice newDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Class<?> btDeviceInstance = Class.forName(BluetoothDevice.class.getCanonicalName());
Method convert = btDeviceInstance.getMethod("convertPinToBytes", String.class);
byte[] pin = (byte[]) convert.invoke(newDevice, "1234");
Method setPin = btDeviceInstance.getMethod("setPin", byte[].class);
boolean success = (Boolean) setPin.invoke(newDevice, pin);
}
catch (Exception e) {
e.printStackTrace();
}
}
};
And my connect-method, where i register the broadcastReceiver :
private void connect(CordovaArgs args, boolean secure,
CallbackContext callbackContext) throws JSONException {
final String actionPinRequested = "android.bluetooth.device.action.PAIRING_REQUEST";
IntentFilter intentFilterPinRequested = new IntentFilter(actionPinRequested);
cordova.getActivity().registerReceiver(mReceiverRequiresPin, intentFilterPinRequested);
String macAddress = args.getString(0);
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(macAddress);
if (device != null) {
connectCallback = callbackContext;
bluetoothSerialService.connect(device, secure);
PluginResult result = new PluginResult(
PluginResult.Status.NO_RESULT);
result.setKeepCallback(true);
callbackContext.sendPluginResult(result);
} else {
callbackContext.error("Could not connect to " + macAddress);
}
}
Would really appreciate your help !
Thanks in advance.
No one has a hint ??
Register a broadcast listener for: android.bluetooth.device.action.PAIRING_REQUEST.
In the onrecieve:
BluetoothDevice newDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Class<?> btDeviceInstance = Class.forName(BluetoothDevice.class.getCanonicalName());
Method convert = btDeviceInstance.getMethod("convertPinToBytes", String.class);
byte[] pin = (byte[]) convert.invoke(newDevice, "1234");
Method setPin = btDeviceInstance.getMethod("setPin", byte[].class);
success = (Boolean) setPin.invoke(newDevice, pin);
in my team's Android application I have a service running from boot which communicates with a server to perform operations such as logging in, registering, chatting between phones and updating the phone database.
I need to make my service communicate with the activity bi-directionally: for example I am working on the login activity at the moment and the username and passwords are Strings taken from a text field on the app screen and I have been able to pass them to the service for it to send an authorisation command to the server.
public void loginPressed(View v){
usernameStr = usernameField.getText().toString();
passwordStr = passwordField.getText().toString();
if (!bound) return;
Bundle b = new Bundle();
Message msg = Message.obtain(null, ChatService.LOGIN);
try {
b.putString("username", usernameStr);
b.putString("password", passwordStr);
msg.setData(b);
messenger.send(msg);
}
catch (RemoteException e) {
}
This works as I would have expected. When the server responds with a message saying whether or not the login was sucessful, I need it to pass a message back to the activity so that I can start the main activity if succesful or prompt for re-entry if not.
I tried to use the msg.replyTo field to get the return messenger to send the information back, but when I run the app it force closes with a null pointer exception and I have no idea why this is happening. Here is the code that seems to be the culprit:
private class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch(msg.what) {
case LOGIN:
Bundle b = msg.getData();
String username = b.getString("username");
String password = b.getString("password");
String loginMessage = TCPCall.login(username, password);
connection.sendMessage(loginMessage);
String loginReturn = connection.retrieveMessage();
Message m;
Scanner s = new Scanner(loginReturn);
s.useDelimiter(",");
String c = s.next();
String status = s.next();
String message = s.next();
if (status.equals("OK")) {
m = Message.obtain(null, LoginActivity.OK);
try {
msg.replyTo.send(m);
} catch (RemoteException e) {}
}
else {
m = Message.obtain(null, LoginActivity.ERR);
try {
msg.replyTo.send(m);
} catch (RemoteException e) {}
}
break;
The null pointer seems to be coming from the
msg.replyTo.send(m);
line of code in both cases (login succesful and login failed)
Any help to fix this problem would be greatly appreciated :)
As Gregg points out in the comments. You need to set msg.replyTo = messenger; int he place where you send the original message.
An example can be found here: http://www.survivingwithandroid.com/2014/01/android-bound-service-ipc-with-messenger.html
I think you forgot to send response to Login Activity by bundle from Service.
So, i made some changes in Messenger Service
define one global variable and made some changes in Incoming Handler
static final int LOGIN_STATUS = 1;
private class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch(msg.what) {
case LOGIN:
Bundle b = msg.getData();
String username = b.getString("username");
String password = b.getString("password");
String loginMessage = TCPCall.login(username, password);
connection.sendMessage(loginMessage);
String loginReturn = connection.retrieveMessage();
Message m = Message.obtain(null, LOGIN_STATUS);
Scanner s = new Scanner(loginReturn);
s.useDelimiter(",");
String c = s.next();
String status = s.next();
String message = s.next();
if (status.equals("OK")) {
b.putString("responseC",c);
b.putString("responseStatus",status);
b.putString("responseMessage",message)
m.setData(b);
try {
msg.replyTo.send(m);
} catch (RemoteException e) {}
}
else {
/*if something is wrong with username and password you can put
a toast*/
}
break;
Now we have to catch this response in our LoginActivity and
take IncomingHandler in Login Activity also
class IncomingHandler extends Handler{
#Override
public void handleMessage(Message msg) {
switch (msg.what){
case ChatService.LOGIN_STATUS:
String C = msg.getData().getString("responseC");
String Status = msg.getData().getString("responseStatus");
String Message = msg.getData().getString("responseMessage");
//Here is your response in LoginActivity, enjoy!!!
break;
default:
super.handleMessage(msg);
}
}
}
final Messenger mMessenger = new Messenger(new IncomingHandler());
public void loginPressed(View v){
usernameStr = usernameField.getText().toString();
passwordStr = passwordField.getText().toString();
if (!bound) return;
Bundle b = new Bundle();
Message msg = Message.obtain(null, ChatService.LOGIN_SATUS,0,0);
try {
b.putString("username", usernameStr);
b.putString("password", passwordStr);
msg.setData(b);
msg.replyTo = mMessenger;
messenger.send(msg);
}
catch (RemoteException e) {
// In this case the service has crashed before we could even
// do anything with it; we can count on soon being
// disconnected (and then reconnected if it can be restarted)
// so there is no need to do anything here.
}
This code is working perfectly, hope it will help you,
Thanks
I am trying to add a feature to my android app that allows users to "checkin" with other people tagged to the checkin.
I have the checkins method working no problem and can tag some one by adding the user ID as a parameter (see code below)
public void postLocationTagged(String msg, String tags, String placeID, Double lat, Double lon) {
Log.d("Tests", "Testing graph API location post");
String access_token = sharedPrefs.getString("access_token", "x");
try {
if (isSession()) {
String response = mFacebook.request("me");
Bundle parameters = new Bundle();
parameters.putString("access_token", access_token);
parameters.putString("place", placeID);
parameters.putString("Message",msg);
JSONObject coordinates = new JSONObject();
coordinates.put("latitude", lat);
coordinates.put("longitude", lon);
parameters.putString("coordinates",coordinates.toString());
parameters.putString("tags", tags);
response = mFacebook.request("me/checkins", parameters, "POST");
Toast display = Toast.makeText(this, "Checkin has been posted to Facebook.", Toast.LENGTH_SHORT);
display.show();
Log.d("Tests", "got response: " + response);
if (response == null || response.equals("") ||
response.equals("false")) {
Log.v("Error", "Blank response");
}
} else {
// no logged in, so relogin
Log.d(TAG, "sessionNOTValid, relogin");
mFacebook.authorize(this, PERMS, new LoginDialogListener());
}
} catch(Exception e) {
e.printStackTrace();
}
}
This works fine (I've posted it in case it is of help to anyone else!), the problem i am having is i am trying to create a list of the users friends so they can select the friends they want to tag. I have the method getFriends (see below) which i am then going to use to generate an AlertDialog that the user can select from which in turn will give me the id to use in the above "postLocationTagged" method.
public void getFriends(CharSequence[] charFriendsNames,CharSequence[] charFriendsID, ProgressBar progbar) {
pb = progbar;
try {
if (isSession()) {
String access_token = sharedPrefs.getString("access_token", "x");
friends = charFriendsNames;
friendsID = charFriendsID;
Log.d(TAG, "Getting Friends!");
String response = mFacebook.request("me");
Bundle parameters = new Bundle();
parameters.putString("access_token", access_token);
response = mFacebook.request("me/friends", parameters, "POST");
Log.d("Tests", "got response: " + response);
if (response == null || response.equals("") ||
response.equals("false")) {
Log.v("Error", "Blank response");
}
} else {
// no logged in, so relogin
Log.d(TAG, "sessionNOTValid, relogin");
mFacebook.authorize(this, PERMS, new LoginDialogListener());
}
} catch(Exception e) {
e.printStackTrace();
}
}
When i look at the response in the log it reads:
"got responce: {"error":{"type":"OAuthException", "message":"(#200) Permissions error"}}"
I have looked through the graphAPI documentation and searched for similar questions but to no avail! I'm not sure if i need to request extra permissions for the app or if this is something your just not allowed to do! Any help/suggestions would be greatly appreciated.
You might need the following permissions:
user_checkins
friends_checkins
read_friendlists
manage_friendlists
publish_checkins
Check the related ones from the API docs. Before that, make sure that which line causes this permission error and try to fix it.
The solution is to implement a RequestListener when making the request to the Facebook graph API. I have the new getFriends() method (see below) which uses the AsyncGacebookRunner to request the data.
public void getFriends(CharSequence[] charFriendsNames,String[] sFriendsID, ProgressBar progbar) {
try{
//Pass arrays to store data
friends = charFriendsNames;
friendsID = sFriendsID;
pb = progbar;
Log.d(TAG, "Getting Friends!");
//Create Request with Friends Request Listener
mAsyncRunner.request("me/friends", new FriendsRequestListener());
} catch (Exception e) {
Log.d(TAG, "Exception: " + e.getMessage());
}
}
The AsyncFacebookRunner makes the the request using the custom FriendsRequestListener (see below) which implements the RequestListener class;
private class FriendsRequestListener implements RequestListener {
String friendData;
//Method runs when request is complete
public void onComplete(String response, Object state) {
Log.d(TAG, "FriendListRequestONComplete");
//Create a copy of the response so i can be read in the run() method.
friendData = response;
//Create method to run on UI thread
FBConnectActivity.this.runOnUiThread(new Runnable() {
public void run() {
try {
//Parse JSON Data
JSONObject json;
json = Util.parseJson(friendData);
//Get the JSONArry from our response JSONObject
JSONArray friendArray = json.getJSONArray("data");
//Loop through our JSONArray
int friendCount = 0;
String fId, fNm;
JSONObject friend;
for (int i = 0;i<friendArray.length();i++){
//Get a JSONObject from the JSONArray
friend = friendArray.getJSONObject(i);
//Extract the strings from the JSONObject
fId = friend.getString("id");
fNm = friend.getString("name");
//Set the values to our arrays
friendsID[friendCount] = fId;
friends[friendCount] = fNm;
friendCount ++;
Log.d("TEST", "Friend Added: " + fNm);
}
//Remove Progress Bar
pb.setVisibility(ProgressBar.GONE);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FacebookError e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
Feel free to use any of this code in your own projects, or ask any questions about it.
You can private static final String[] PERMISSIONS = new String[] {"publish_stream","status_update",xxxx};xxx is premissions