Using Accountmanager i get the token now what?
m using the following class
package com.googleaccount;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.Toast;
public class GoogleAccountTestActivity extends Activity {
/** Called when the activity is first created. */
private static final int DIALOG_ACCOUNTS = 0;
private static final int REQUEST_AUTHENTICATE = 0;
protected static final String AUTH_TOKEN_TYPE = "";
private String authToken;
Context context;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context=this;
gotAccount(false);
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_ACCOUNTS:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select a Google account");
final AccountManager manager = AccountManager.get(this);
final Account[] accounts = manager.getAccountsByType("com.google");
final int size = accounts.length;
String[] names = new String[size];
for (int i = 0; i < size; i++) {
names[i] = accounts[i].name;
}
builder.setItems(names, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
gotAccount(manager, accounts[which]);
}
});
return builder.create();
}
return null;
}
private void gotAccount(boolean tokenExpired) {
SharedPreferences settings = getSharedPreferences("test", 0);
String accountName = settings.getString("accountName", null);
if (accountName != null) {
AccountManager manager = AccountManager.get(this);
Account[] accounts = manager.getAccountsByType("com.google");
int size = accounts.length;
for (int i = 0; i < size; i++) {
Account account = accounts[i];
if (accountName.equals(account.name)) {
Toast.makeText(this,"OLD accunt name"+account.name , Toast.LENGTH_SHORT).show();
if (tokenExpired) {
Toast.makeText(this,"Token EXpired", Toast.LENGTH_SHORT).show();
manager.invalidateAuthToken("com.google", this.authToken);
}
gotAccount(manager, account);
return;
}
}
}
showDialog(DIALOG_ACCOUNTS);
}
private void gotAccount(final AccountManager manager, final Account account) {
SharedPreferences settings = getSharedPreferences("test", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("accountName", account.name);
editor.commit();
new Thread() {
#Override
public void run() {
try {
final Bundle bundle =
manager.getAuthToken(account, AUTH_TOKEN_TYPE, true, null, null)
.getResult();
runOnUiThread(new Runnable() {
public void run() {
try {
if (bundle.containsKey(AccountManager.KEY_INTENT)) {
Intent intent =
bundle.getParcelable(AccountManager.KEY_INTENT);
int flags = intent.getFlags();
flags &= ~Intent.FLAG_ACTIVITY_NEW_TASK;
intent.setFlags(flags);
startActivityForResult(intent, REQUEST_AUTHENTICATE);
} else if (bundle.containsKey(AccountManager.KEY_AUTHTOKEN)) {
authenticatedClientLogin(
bundle.getString(AccountManager.KEY_AUTHTOKEN));
}
} catch (Exception e) {
// handleException(e);
Toast.makeText(context,e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
} catch (Exception e) {
//handleException(e);
Toast.makeText(context,e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}.start();
}
#Override
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_AUTHENTICATE:
if (resultCode == RESULT_OK) {
Toast.makeText(this,"Result OK!!" , Toast.LENGTH_SHORT).show();
gotAccount(false);
} else {
Toast.makeText(this,"Result False!!" , Toast.LENGTH_SHORT).show();
showDialog(DIALOG_ACCOUNTS);
}
break;
}
}
private void authenticatedClientLogin(String authToken) {
this.authToken = authToken;
Toast.makeText(this,"Token "+authToken, Toast.LENGTH_LONG).show();
//((GoogleHeaders) transport.defaultHeaders).setGoogleLogin(authToken);
//authenticated();
}
}
Your best bet is to use the Google API Client library:
http://code.google.com/p/google-api-java-client/wiki/Setup
Download the core jars(link to be found in the wiki) and dependencies. In particular, you should be looking for these jars:
google-api-client-version-alpha.jar
google-api-client-googleapis-version-alpha.jar
guava-version.jar
jackson-core-asl-version.jar
Next. set up your model classes that describe your feed. For DocList, refer this sample:
Google API DocList Sample
DocUrl.java, DocumentListEntry.java, DocumentListFeed.java, Entry.java, Feed.java & Link.java are the model classes which should set you up.
Next, initialize your HTTPTransport by choosing the parser i.e. Atom/Json and fire your request.
public static final XmlNamespaceDictionary NAMESPACE_DICTIONARY = new XmlNamespaceDictionary();
static {
NAMESPACE_DICTIONARY.set("", "http://www.w3.org/2005/Atom");
NAMESPACE_DICTIONARY.set("app", "http://www.w3.org/2007/app");
NAMESPACE_DICTIONARY.set("batch", "http://schemas.google.com/gdata/batch");
NAMESPACE_DICTIONARY.set("docs", "http://schemas.google.com/docs/2007");
NAMESPACE_DICTIONARY.set("gs", "http://schemas.google.com/spreadsheets/2006");
NAMESPACE_DICTIONARY.set("gd", "http://schemas.google.com/g/2005");
NAMESPACE_DICTIONARY.set("gsx", "http://schemas.google.com/spreadsheets/2006/extended");
NAMESPACE_DICTIONARY.set("openSearch", "http://a9.com/-/spec/opensearch/1.1/");
NAMESPACE_DICTIONARY.set("xml", "http://www.w3.org/XML/1998/namespace");
}
private static HttpTransport transport;
private void setupTransport() {
transport = new NetHttpTransport();
GoogleHeaders headers = new GoogleHeaders();
transport.defaultHeaders = headers;
headers.setApplicationName("MyApp/1.0");
headers.gdataVersion = "3.0";
((GoogleHeaders) transport.defaultHeaders)
.setGoogleLogin(<yourtoken>);
AtomParser parser = new AtomParser();
parser.namespaceDictionary = Util.NAMESPACE_DICTIONARY;
transport.addParser(parser);
}
public processDocs() {
setupTransport();
DocUrl url = DocUrl.relativeToRoot(<URL suffix>);
DocListFeed feed = DocListFeed.executeGet(transport, url);
if (feed.entries != null) {
for (DocEntry entry : feed.entries) {
//<do whatever>
}
}
Related
I'm working on a project that takes student attendance using a camera based barcode scanner. i'm using zxing as a barcode canner. i followed instructions on a web page and created a package and added two files called IntentResult.java and IntentIntegrater.java
these are the files.
intentResult.java
package google.zxing.integration.android;
public final class IntentResult {
private final String contents;
private final String formatName;
private final byte[] rawBytes;
private final Integer orientation;
private final String errorCorrectionLevel;
IntentResult() {
this(null, null, null, null, null);
}
IntentResult(String contents,
String formatName,
byte[] rawBytes,
Integer orientation,
String errorCorrectionLevel) {
this.contents = contents;
this.formatName = formatName;
this.rawBytes = rawBytes;
this.orientation = orientation;
this.errorCorrectionLevel = errorCorrectionLevel;
}
public String getContents() {
return contents;
}
public String getFormatName() {
return formatName;
}
public byte[] getRawBytes() {
return rawBytes;
}
public Integer getOrientation() {
return orientation;
}
public String getErrorCorrectionLevel() {
return errorCorrectionLevel;
}
#Override
public String toString() {
StringBuilder dialogText = new StringBuilder(100);
dialogText.append("Format: ").append(formatName).append('\n');
dialogText.append("Contents: ").append(contents).append('\n');
int rawBytesLength = rawBytes == null ? 0 : rawBytes.length;
dialogText.append("Raw bytes: (").append(rawBytesLength).append(" bytes)\n");
dialogText.append("Orientation: ").append(orientation).append('\n');
dialogText.append("EC level: ").append(errorCorrectionLevel).append('\n');
return dialogText.toString();
}
}
and IntentIntegrater.java`
package google.zxing.integration.android;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
public class IntentIntegrator {
public static final int REQUEST_CODE = 0x0000c0de; // Only use bottom 16 bits
private static final String TAG = IntentIntegrator.class.getSimpleName();
public static final String DEFAULT_TITLE = "Install Barcode Scanner?";
public static final String DEFAULT_MESSAGE =
"This application requires Barcode Scanner. Would you like to install it?";
public static final String DEFAULT_YES = "Yes";
public static final String DEFAULT_NO = "No";
private static final String BS_PACKAGE = "com.google.zxing.client.android";
private static final String BSPLUS_PACKAGE = "com.srowen.bs.android";
// supported barcode formats
public static final Collection<String> PRODUCT_CODE_TYPES = list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "RSS_14");
public static final Collection<String> ONE_D_CODE_TYPES =
list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "CODE_39", "CODE_93", "CODE_128",
"ITF", "RSS_14", "RSS_EXPANDED");
public static final Collection<String> QR_CODE_TYPES = Collections.singleton("QR_CODE");
public static final Collection<String> DATA_MATRIX_TYPES = Collections.singleton("DATA_MATRIX");
public static final Collection<String> ALL_CODE_TYPES = null;
public static final List<String> TARGET_BARCODE_SCANNER_ONLY = Collections.singletonList(BS_PACKAGE);
public static final List<String> TARGET_ALL_KNOWN = list(
BS_PACKAGE, // Barcode Scanner
BSPLUS_PACKAGE, // Barcode Scanner+
BSPLUS_PACKAGE + ".simple" // Barcode Scanner+ Simple
// What else supports this intent?
);
private final Activity activity;
private String title;
private String message;
private String buttonYes;
private String buttonNo;
private List<String> targetApplications;
private final Map<String,Object> moreExtras;
public IntentIntegrator(Activity activity) {
this.activity = activity;
title = DEFAULT_TITLE;
message = DEFAULT_MESSAGE;
buttonYes = DEFAULT_YES;
buttonNo = DEFAULT_NO;
targetApplications = TARGET_ALL_KNOWN;
moreExtras = new HashMap<String,Object>(3);
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public void setTitleByID(int titleID) {
title = activity.getString(titleID);
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void setMessageByID(int messageID) {
message = activity.getString(messageID);
}
public String getButtonYes() {
return buttonYes;
}
public void setButtonYes(String buttonYes) {
this.buttonYes = buttonYes;
}
public void setButtonYesByID(int buttonYesID) {
buttonYes = activity.getString(buttonYesID);
}
public String getButtonNo() {
return buttonNo;
}
public void setButtonNo(String buttonNo) {
this.buttonNo = buttonNo;
}
public void setButtonNoByID(int buttonNoID) {
buttonNo = activity.getString(buttonNoID);
}
public Collection<String> getTargetApplications() {
return targetApplications;
}
public final void setTargetApplications(List<String> targetApplications) {
if (targetApplications.isEmpty()) {
throw new IllegalArgumentException("No target applications");
}
this.targetApplications = targetApplications;
}
public void setSingleTargetApplication(String targetApplication) {
this.targetApplications = Collections.singletonList(targetApplication);
}
public Map<String,?> getMoreExtras() {
return moreExtras;
}
public final void addExtra(String key, Object value) {
moreExtras.put(key, value);
}
public final AlertDialog initiateScan() {
return initiateScan(ALL_CODE_TYPES);
}
public final AlertDialog initiateScan(Collection<String> desiredBarcodeFormats) {
Intent intentScan = new Intent(BS_PACKAGE + ".SCAN");
intentScan.addCategory(Intent.CATEGORY_DEFAULT);
// check which types of codes to scan for
if (desiredBarcodeFormats != null) {
// set the desired barcode types
StringBuilder joinedByComma = new StringBuilder();
for (String format : desiredBarcodeFormats) {
if (joinedByComma.length() > 0) {
joinedByComma.append(',');
}
joinedByComma.append(format);
}
intentScan.putExtra("SCAN_FORMATS", joinedByComma.toString());
}
String targetAppPackage = findTargetAppPackage(intentScan);
if (targetAppPackage == null) {
return showDownloadDialog();
}
intentScan.setPackage(targetAppPackage);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
attachMoreExtras(intentScan);
startActivityForResult(intentScan, REQUEST_CODE);
return null;
}
protected void startActivityForResult(Intent intent, int code) {
activity.startActivityForResult(intent, code);
}
private String findTargetAppPackage(Intent intent) {
PackageManager pm = activity.getPackageManager();
List<ResolveInfo> availableApps = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (availableApps != null) {
for (ResolveInfo availableApp : availableApps) {
String packageName = availableApp.activityInfo.packageName;
if (targetApplications.contains(packageName)) {
return packageName;
}
}
}
return null;
}
private AlertDialog showDownloadDialog() {
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
downloadDialog.setTitle(title);
downloadDialog.setMessage(message);
downloadDialog.setPositiveButton(buttonYes, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
String packageName = targetApplications.get(0);
Uri uri = Uri.parse("market://details?id=" + packageName);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
try {
activity.startActivity(intent);
} catch (ActivityNotFoundException anfe) {
// Hmm, market is not installed
Log.w(TAG, "Google Play is not installed; cannot install " + packageName);
}
}
});
downloadDialog.setNegativeButton(buttonNo, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {}
});
return downloadDialog.show();
}
public static IntentResult parseActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
String contents = intent.getStringExtra("SCAN_RESULT");
String formatName = intent.getStringExtra("SCAN_RESULT_FORMAT");
byte[] rawBytes = intent.getByteArrayExtra("SCAN_RESULT_BYTES");
int intentOrientation = intent.getIntExtra("SCAN_RESULT_ORIENTATION", Integer.MIN_VALUE);
Integer orientation = intentOrientation == Integer.MIN_VALUE ? null : intentOrientation;
String errorCorrectionLevel = intent.getStringExtra("SCAN_RESULT_ERROR_CORRECTION_LEVEL");
return new IntentResult(contents,
formatName,
rawBytes,
orientation,
errorCorrectionLevel);
}
return new IntentResult();
}
return null;
}
public final AlertDialog shareText(CharSequence text, CharSequence type) {
Intent intent = new Intent();
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setAction(BS_PACKAGE + ".ENCODE");
intent.putExtra("ENCODE_TYPE", type);
intent.putExtra("ENCODE_DATA", text);
String targetAppPackage = findTargetAppPackage(intent);
if (targetAppPackage == null) {
return showDownloadDialog();
}
intent.setPackage(targetAppPackage);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
attachMoreExtras(intent);
activity.startActivity(intent);
return null;
}
private static List<String> list(String... values) {
return Collections.unmodifiableList(Arrays.asList(values));
}
private void attachMoreExtras(Intent intent) {
for (Map.Entry<String,Object> entry : moreExtras.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// Kind of hacky
if (value instanceof Integer) {
intent.putExtra(key, (Integer) value);
} else if (value instanceof Long) {
intent.putExtra(key, (Long) value);
} else if (value instanceof Boolean) {
intent.putExtra(key, (Boolean) value);
} else if (value instanceof Double) {
intent.putExtra(key, (Double) value);
} else if (value instanceof Float) {
intent.putExtra(key, (Float) value);
} else if (value instanceof Bundle) {
intent.putExtra(key, (Bundle) value);
} else {
intent.putExtra(key, value.toString());
}
}
}
}
And Barcodereader.java page where i call the two classes
package com.example.marys.barcodereader;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class BarReader extends AppCompatActivity {
static final String ACTION_SCAN = "com.google.zxing.client.android.SCAN";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//set the main content layout of the Activity
setContentView(R.layout.activity_bar_reader);
}
//product barcode mode
public void scanBar(View v) {
try {
//start the scanning activity from the com.google.zxing.client.android.SCAN intent
Intent intent = new Intent(ACTION_SCAN);
intent.putExtra("SCAN_MODE", "PRODUCT_MODE");
startActivityForResult(intent, 0);
} catch (ActivityNotFoundException anfe) {
//on catch, show the download dialog
showDialog(BarReader.this, "No Scanner Found", "Download a scanner code activity?", "Yes", "No").show();
}
}
//product qr code mode
public void scanQR(View v) {
try {
//start the scanning activity from the com.google.zxing.client.android.SCAN intent
Intent intent = new Intent(ACTION_SCAN);
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
startActivityForResult(intent, 0);
} catch (ActivityNotFoundException anfe) {
//on catch, show the download dialog
showDialog(BarReader.this, "No Scanner Found", "Download a scanner code activity?", "Yes", "No").show();
}
}
//alert dialog for downloadDialog
private static AlertDialog showDialog(final Activity act, CharSequence title, CharSequence message, CharSequence buttonYes, CharSequence buttonNo) {
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(act);
downloadDialog.setTitle(title);
downloadDialog.setMessage(message);
downloadDialog.setPositiveButton(buttonYes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
Uri uri = Uri.parse("market://search?q=pname:" + "com.google.zxing.client.android");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
try {
act.startActivity(intent);
} catch (ActivityNotFoundException anfe) {
}
}
});
downloadDialog.setNegativeButton(buttonNo, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
}
});
return downloadDialog.show();
}
//on ActivityResult method
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == 0) {
if (resultCode == RESULT_OK) {
//get the extras that are returned from the intent
String contents = intent.getStringExtra("SCAN_RESULT");
String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
Toast toast = Toast.makeText(this, "Content:" + contents + " Format:" + format, Toast.LENGTH_LONG);
toast.show();
}
}
}
}
I didn't make the zxing as a library. If i should tell me. At the moment when you first run the app it make you download a barcode scanner from google store.
I hope this is enough. If you need any more information let me know. Thanks in advance
`
How to create custom buttons for social login auth for twitter on android application development. By default social media have different SDK, which SDK twitter already has its own button social login but i want to use my own custom button and i wrote some code but getting exception
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
my code:-
TwitterConfig config = new TwitterConfig.Builder(this)
.logger(new DefaultLogger(Log.DEBUG))
.twitterAuthConfig(new TwitterAuthConfig("KEY",
"KEY"))
.debug(true)
.build();
Twitter.initialize(config);
client = new TwitterAuthClient();
final TwitterSession session = TwitterCore.getInstance().getSessionManager().getActiveSession();
twitterButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
client.requestEmail(session, new Callback<String>() {
#Override
public void success(Result<String> result) {
System.out.println("Email is=====>" + result.data);
}
#Override
public void failure(TwitterException exception) {
}
});
}
});
please try this
add this gradle line in you project
compile 'com.twitter.sdk.android:twitter:3.0.0'
Write in your Activity/Fragment
//Your Custom Button
private ivTwitter;
//Twitter Login Button
private TwitterLoginButton ivTwitterMain;
//init twitter
TwitterConfig config = new TwitterConfig.Builder(this)
.logger(new DefaultLogger(Log.DEBUG))
.twitterAuthConfig(new TwitterAuthConfig(Const.CONSUMER_KEY, Const.CONSUMER_SECRET))
.debug(false)
.build();
Twitter.initialize(config);
//Write in onCreate method
ivTwitter = (ImageView) view.findViewById(R.id.ivTwitter);
ivTwitterMain = (TwitterLoginButton)view.findViewById(R.id.ivTwitterMain);
ivTwitterMain.setCallback(new Callback<TwitterSession>() {
#Override
public void success(Result<TwitterSession> result) {
// Do something with result, which provides a TwitterSession for making API calls
TwitterSession session = TwitterCore.getInstance().getSessionManager().getActiveSession();
TwitterAuthToken authToken = session.getAuthToken();
String token = authToken.token;
String secret = authToken.secret;
getTwitterUserProfile(session);
}
#Override
public void failure(TwitterException exception) {
// Do something on failure
Log.d(Const.FRAGMENT_REGISTER, exception.getMessage());
}
});
//getTwitterUserProfile
private void getTwitterUserProfile(TwitterSession session) {
AccountService accountService = new TwitterApiClient(session).getAccountService();
Call<User> callback = accountService.verifyCredentials(true, true, true);
callback.clone().enqueue(new Callback<User>() {
#Override
public void success(Result<User> result) {
Log.d("NAME ", result.data.name);
Log.d("EMAIL", result.data.email);
Log.d("PICTURE ", result.data.profileImageUrl);
}
#Override
public void failure(TwitterException exception) {
}
});
}
at last generate Click event of custom button
ivTwitter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//twitter login button
ivTwitterMain.performClick();
}
});
/**Try to implement Below code Snipeet**/
First Download the Twitter Library from Below mentioned Link:
Link -> http://twitter4j.org/maven2/org/twitter4j/twitter4j-core/4.0.4/
Add the library to your build.gradle
/******************************************************/
Make "Twitter_Handler" Class inside your project
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import oauth.signpost.OAuthProvider;
import oauth.signpost.basic.DefaultOAuthProvider;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.User;
import twitter4j.auth.AccessToken;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Handler;
import android.os.Message;
import android.view.Window;
public class Twitter_Handler
{
public static Twitter twitterObj;
private final TwitterSession mSession;
private AccessToken mAccessToken;
private final CommonsHttpOAuthConsumer mHttpOauthConsumer;
private final OAuthProvider mHttpOauthprovider;
private final String mConsumerKey;
private final String mSecretKey;
private final ProgressDialog mProgressDlg;
private TwDialogListener mListener;
private final Activity context;
public static final String CALLBACK_URL = "twitterapp://connect";
private static final String TWITTER_ACCESS_TOKEN_URL = "https://api.twitter.com/oauth/access_token";
private static final String TWITTER_AUTHORZE_URL = "https://api.twitter.com/oauth/authorize";
private static final String TWITTER_REQUEST_URL = "https://api.twitter.com/oauth/request_token";
public Twitter_Handler(Activity context, String consumerKey,String secretKey)
{
this.context = context;
twitterObj = new TwitterFactory().getInstance();
mSession = new TwitterSession(context);
mProgressDlg = new ProgressDialog(context);
mProgressDlg.requestWindowFeature(Window.FEATURE_NO_TITLE);
mConsumerKey = consumerKey;
mSecretKey = secretKey;
mHttpOauthConsumer = new CommonsHttpOAuthConsumer(mConsumerKey,mSecretKey);
String request_url = TWITTER_REQUEST_URL;
String access_token_url = TWITTER_ACCESS_TOKEN_URL;
String authorize_url = TWITTER_AUTHORZE_URL;
mHttpOauthprovider = new DefaultOAuthProvider(request_url,access_token_url, authorize_url);
mAccessToken = mSession.getAccessToken();
configureToken();
}
public void setListener(TwDialogListener listener) {
mListener = listener;
}
private void configureToken()
{
if (mAccessToken != null)
{
twitterObj.setOAuthConsumer(mConsumerKey, mSecretKey);
twitterObj.setOAuthAccessToken(mAccessToken);
}
}
public boolean hasAccessToken() {
return (mAccessToken == null) ? false : true;
}
public void resetAccessToken() {
if (mAccessToken != null) {
mSession.resetAccessToken();
mAccessToken = null;
}
}
public String getUsername() {
return mSession.getUsername();
}
public void updateStatus(String status) throws Exception {
try {
twitterObj.updateStatus(status);
} catch (TwitterException e) {
throw e;
}
}
public void authorize()
{
mProgressDlg.setMessage("Loading ...");
mProgressDlg.show();
new Thread() {
#Override
public void run() {
String authUrl = "";
int what = 1;
try {
authUrl = mHttpOauthprovider.retrieveRequestToken(mHttpOauthConsumer, CALLBACK_URL);
what = 0;
} catch (Exception e) {
e.printStackTrace();
}
mHandler.sendMessage(mHandler.obtainMessage(what, 1, 0, authUrl));
}
}.start();
}
public void processToken(String callbackUrl)
{
mProgressDlg.setMessage("Finalizing ...");
mProgressDlg.show();
final String verifier = getVerifier(callbackUrl);
new Thread() {
#Override
public void run() {
int what = 1;
try {
mHttpOauthprovider.retrieveAccessToken(mHttpOauthConsumer,verifier);
mAccessToken = new AccessToken(mHttpOauthConsumer.getToken(),mHttpOauthConsumer.getTokenSecret());
configureToken();
User user = twitterObj.verifyCredentials();
mSession.storeAccessToken(mAccessToken, user.getName());
what = 0;
} catch (Exception e) {
e.printStackTrace();
}
mHandler.sendMessage(mHandler.obtainMessage(what, 2, 0));
}
}.start();
}
private String getVerifier(String callbackUrl) {
String verifier = "";
try {
callbackUrl = callbackUrl.replace("twitterapp", "http");
URL url = new URL(callbackUrl);
String query = url.getQuery();
String array[] = query.split("&");
for (String parameter : array) {
String v[] = parameter.split("=");
if (URLDecoder.decode(v[0]).equals(
oauth.signpost.OAuth.OAUTH_VERIFIER)) {
verifier = URLDecoder.decode(v[1]);
break;
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
return verifier;
}
private void showLoginDialog(String url) {
final TwDialogListener listener = new TwDialogListener() {
#Override
public void onComplete(String value) {
processToken(value);
}
#Override
public void onError(String value) {
mListener.onError("Failed opening authorization page");
}
};
new TwitterDialog(context, url, listener).show();
}
#SuppressLint("HandlerLeak")
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
mProgressDlg.dismiss();
if (msg.what == 1)
{
if (msg.arg1 == 1)
mListener.onError("Error getting request token");
else
mListener.onError("Error getting access token");
}
else
{
if (msg.arg1 == 1)
showLoginDialog((String) msg.obj);
else
mListener.onComplete("");
}
}
};
public interface TwDialogListener {
public void onComplete(String value);
public void onError(String value);
}
}
/******************************************************/
Now Make "Twitt_LoginOnly" Class inside your project
import android.app.Activity;
import android.widget.Toast;
public class Twitt_LoginOnly {
private final Twitter_Handler mTwitter;
private final Activity activity;
public static interface LoginResult
{
public abstract void loginResult(String message);
}
public LoginResult loginCallback;
public Twitt_LoginOnly( Activity act, String consumer_key, String consumer_secret,LoginResult loginCallback) {
this.activity = act;
mTwitter = new Twitter_Handler(activity, consumer_key, consumer_secret);
this.loginCallback = loginCallback;
}
public void loginToTwitter()
{
mTwitter.setListener(mTwLoginDialogListener);
if (mTwitter.hasAccessToken())
{
// this will post data in asyn background thread
//showTwittDialog();
showToast("Already Logged in");
loginCallback.loginResult("Already Logged in");
}
else
{
mTwitter.authorize();
}
}
private final TwDialogListener mTwLoginDialogListener = new TwDialogListener() {
#Override
public void onError(String value) {
loginCallback.loginResult("Login Failed");
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
showToast("Login Failed");
mTwitter.resetAccessToken();
}
});
}
#Override
public void onComplete(String value)
{
//showTwittDialog();
loginCallback.loginResult("Login Successfully");
showToast("Login Successfully");
}
};
void showToast(final String msg)
{
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show();
}
});
}
}
/******************************************************/
Now Implement the Code in your Activity or Fragment Class
twitter_login = (ImageView) findViewById(R.id.twitter_login);
twitter_login.setOnClickListener(new OnClickListener()
{
public void onClick(View button)
{
Twitt_LoginOnly logintwitter = new Twitt_LoginOnly(Activity.this,
“YOUR TWITTER_CONSUMER_KEY”, “YOUR TWITTER_CONSUMER_SECRET”, new Twitt_LoginOnly.LoginResult()
{
#Override
public void loginResult(String message)
{
TwitterSession twittersession = new TwitterSession(Activity.this);
if (twittersession.getAccessToken() != null)
{
}
}
});
logintwitter.loginToTwitter();
}
});
I am using the following open-source webrtc android application:
https://github.com/pchab/AndroidRTC
I have just modified this application to use my socket.io server instead of using the following one which is given by same author:
https://github.com/pchab/ProjectRTC
To do this, I needed to do some changes in the two classes of the above AndroidRTC Application. After this, when I started the application it did not call the 'createOffer()' or 'createAnswer()' function which is part of libjingle_peerconnection library. I am confused whether these two functions are not getting called or they are not able to use 'sendMessage()' function.
From debugging, I came to know that line which calls 'createAnswer()' function is successfully reached. After this, I expect the 'createAnswer()' function to use my 'sendMessage()' function to send the answer back to other party by using my socket.io server. I am not able to peek inside this 'createAnswer()' function as it is part of the library.
Before changing the above application to use my own server, I had tested it with the server given by auhtor. It ran successfully. I don't know what is wrong when I use my own server to make calls and do handshaking. I just modified few lines to support the way I do signalling on the server.
My server code is already used for webrtc web application. Web Applications are successful in making calls using this server. It should work for this android application too with little modification on the application.
I modified the following two classes in android application:
RTCActivity.java
package fr.pchab.AndroidRTC;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Window;
import android.widget.Toast;
import org.json.JSONException;
import org.webrtc.MediaStream;
import org.webrtc.PeerConnectionFactory;
import org.webrtc.VideoRenderer;
import java.util.List;
public class RTCActivity extends Activity implements WebRtcClient.RTCListener{
private final static int VIDEO_CALL_SENT = 666;
private VideoStreamsView vsv;
private WebRtcClient client;
private String mSocketAddress;
private String callerId;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
mSocketAddress = "https://" + getResources().getString(R.string.host);
mSocketAddress += (":"+getResources().getString(R.string.port)+"/");
PeerConnectionFactory.initializeAndroidGlobals(this);
// Camera display view
Point displaySize = new Point();
getWindowManager().getDefaultDisplay().getSize(displaySize);
vsv = new VideoStreamsView(this, displaySize);
client = new WebRtcClient(this, mSocketAddress);
final Intent intent = getIntent();
final String action = intent.getAction();
if (Intent.ACTION_VIEW.equals(action)) {
final List<String> segments = intent.getData().getPathSegments();
callerId = segments.get(0);
}
}
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
#Override
public void onPause() {
super.onPause();
vsv.onPause();
}
#Override
public void onResume() {
super.onResume();
vsv.onResume();
}
#Override
public void onCallReady(String callId) {
startCam();
}
public void answer(String callerId) throws JSONException {
client.sendMessage(callerId, "init", null);
startCam();
}
public void call(String callId) {
Intent msg = new Intent(Intent.ACTION_SEND);
msg.putExtra(Intent.EXTRA_TEXT, mSocketAddress + callId);
msg.setType("text/plain");
startActivityForResult(Intent.createChooser(msg, "Call someone :"), VIDEO_CALL_SENT);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == VIDEO_CALL_SENT) {
startCam();
}
}
public void startCam() {
setContentView(vsv);
// Camera settings
client.setCamera("front", "640", "480");
client.start("android_test", true);
}
#Override
public void onStatusChanged(final String newStatus) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), newStatus, Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onLocalStream(MediaStream localStream) {
localStream.videoTracks.get(0).addRenderer(new VideoRenderer(new VideoCallbacks(vsv, 0)));
}
#Override
public void onAddRemoteStream(MediaStream remoteStream, int endPoint) {
remoteStream.videoTracks.get(0).addRenderer(new VideoRenderer(new VideoCallbacks(vsv, endPoint)));
vsv.shouldDraw[endPoint] = true;
}
#Override
public void onRemoveRemoteStream(MediaStream remoteStream, int endPoint) {
remoteStream.videoTracks.get(0).dispose();
vsv.shouldDraw[endPoint] = false;
}
// Implementation detail: bridge the VideoRenderer.Callbacks interface to the
// VideoStreamsView implementation.
private class VideoCallbacks implements VideoRenderer.Callbacks {
private final VideoStreamsView view;
private final int stream;
public VideoCallbacks(VideoStreamsView view, int stream) {
this.view = view;
this.stream = stream;
}
#Override
public void setSize(final int width, final int height) {
view.queueEvent(new Runnable() {
public void run() {
view.setSize(stream, width, height);
}
});
}
#Override
public void renderFrame(VideoRenderer.I420Frame frame) {
view.queueFrame(stream, frame);
}
}
}
WebRTCClient.java
package fr.pchab.AndroidRTC;
import java.util.HashMap;
import java.util.LinkedList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.webrtc.DataChannel;
import org.webrtc.IceCandidate;
import org.webrtc.MediaConstraints;
import org.webrtc.MediaStream;
import org.webrtc.PeerConnection;
import org.webrtc.PeerConnectionFactory;
import org.webrtc.SdpObserver;
import org.webrtc.SessionDescription;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoSource;
import android.os.Handler;
import android.util.Log;
import com.koushikdutta.async.http.socketio.Acknowledge;
import com.koushikdutta.async.http.socketio.ConnectCallback;
import com.koushikdutta.async.http.socketio.EventCallback;
import com.koushikdutta.async.http.socketio.SocketIOClient;
class WebRtcClient {
private final static int MAX_PEER = 2;
private boolean[] endPoints = new boolean[MAX_PEER];
private PeerConnectionFactory factory;
private HashMap<String, Peer> peers = new HashMap<String, Peer>();
private LinkedList<PeerConnection.IceServer> iceServers = new LinkedList<PeerConnection.IceServer>();
private MediaConstraints pcConstraints = new MediaConstraints();
private MediaStream lMS;
private RTCListener mListener;
private SocketIOClient client;
private final MessageHandler messageHandler = new MessageHandler();
private final static String TAG = WebRtcClient.class.getCanonicalName();
public interface RTCListener{
void onCallReady(String callId);
void onStatusChanged(String newStatus);
void onLocalStream(MediaStream localStream);
void onAddRemoteStream(MediaStream remoteStream, int endPoint);
void onRemoveRemoteStream(MediaStream remoteStream, int endPoint);
}
private interface Command{
void execute(String peerId, JSONObject payload) throws JSONException;
}
private class CreateOfferCommand implements Command{
public void execute(String peerId, JSONObject payload) throws JSONException {
Log.d(TAG,"CreateOfferCommand");
Peer peer = peers.get(peerId);
peer.pc.createOffer(peer, pcConstraints);
}
}
private class CreateAnswerCommand implements Command{
public void execute(String peerId, JSONObject payload) throws JSONException {
Log.d(TAG,"CreateAnswerCommand");
Peer peer = peers.get(peerId);
SessionDescription sdp = new SessionDescription(
SessionDescription.Type.fromCanonicalForm(payload.getString("type")),
payload.getString("sdp")
);
peer.pc.setRemoteDescription(peer, sdp);
peer.pc.createAnswer(peer, pcConstraints);
}
}
private class SetRemoteSDPCommand implements Command{
public void execute(String peerId, JSONObject payload) throws JSONException {
Log.d(TAG,"SetRemoteSDPCommand");
Peer peer = peers.get(peerId);
SessionDescription sdp = new SessionDescription(
SessionDescription.Type.fromCanonicalForm(payload.getString("type")),
payload.getString("sdp")
);
peer.pc.setRemoteDescription(peer, sdp);
}
}
private class AddIceCandidateCommand implements Command{
public void execute(String peerId, JSONObject payload) throws JSONException {
Log.d(TAG,"AddIceCandidateCommand");
PeerConnection pc = peers.get(peerId).pc;
if (pc.getRemoteDescription() != null) {
IceCandidate candidate = new IceCandidate(
payload.getString("id"),
payload.getInt("label"),
payload.getString("candidate")
);
pc.addIceCandidate(candidate);
}
}
}
public void sendMessage(String to, String type, JSONObject payload) throws JSONException {
JSONObject message = new JSONObject();
//message.put("room", to);
message.put("type", type);
message.put("msg", payload);
message.put("room", "sojharo");
client.emit("message", new JSONArray().put(message));
}
private class MessageHandler implements EventCallback {
private HashMap<String, Command> commandMap;
public MessageHandler() {
this.commandMap = new HashMap<String, Command>();
commandMap.put("init", new CreateOfferCommand());
commandMap.put("offer", new CreateAnswerCommand());
commandMap.put("answer", new SetRemoteSDPCommand());
commandMap.put("candidate", new AddIceCandidateCommand());
}
#Override
public void onEvent(String s, JSONArray jsonArray, Acknowledge acknowledge) {
try {
Log.d(TAG,"MessageHandler.onEvent() "+ (s == null ? "nil" : s));
if(s.equals("id")) {
JSONObject message = new JSONObject();
message.put("room", "sojharo");
message.put("username", "android");
client.emit("create or join livehelp",
new JSONArray().put(message));
} else if (s.equals("joined")) {
mListener.onCallReady("Not Initiator");
} else {
JSONObject json = jsonArray.getJSONObject(0);
try{
if(json.getString("msg").equals("got user media"))
return ;
}catch(JSONException e){}
String from = json.getString("from");
String type = null;
try{
type = json.getString("type");
}catch(JSONException e){}
// if peer is unknown, try to add him
if(!peers.containsKey(from)) {
// if MAX_PEER is reach, ignore the call
int endPoint = findEndPoint();
if(endPoint != MAX_PEER) {
addPeer(from, endPoint);
commandMap.get(type).execute(from, json);
}
} else {
commandMap.get(type).execute(from, json);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
private class Peer implements SdpObserver, PeerConnection.Observer{
private PeerConnection pc;
private String id;
private int endPoint;
#Override
public void onCreateSuccess(final SessionDescription sdp) {
try {
JSONObject payload = new JSONObject();
payload.put("type", sdp.type.canonicalForm());
payload.put("sdp", sdp.description);
sendMessage(id, sdp.type.canonicalForm(), payload);
pc.setLocalDescription(Peer.this, sdp);
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onSetSuccess() {}
#Override
public void onCreateFailure(String s) {}
#Override
public void onSetFailure(String s) {}
#Override
public void onSignalingChange(PeerConnection.SignalingState signalingState) {}
#Override
public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) {
if(iceConnectionState == PeerConnection.IceConnectionState.DISCONNECTED) {
removePeer(id);
mListener.onStatusChanged("DISCONNECTED");
}
}
#Override
public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) {}
#Override
public void onIceCandidate(final IceCandidate candidate) {
try {
JSONObject payload = new JSONObject();
payload.put("label", candidate.sdpMLineIndex);
payload.put("id", candidate.sdpMid);
payload.put("candidate", candidate.sdp);
sendMessage(id, "candidate", payload);
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onError() {}
#Override
public void onAddStream(MediaStream mediaStream) {
Log.d(TAG,"onAddStream "+mediaStream.label());
// remote streams are displayed from 1 to MAX_PEER (0 is localStream)
mListener.onAddRemoteStream(mediaStream, endPoint+1);
}
#Override
public void onRemoveStream(MediaStream mediaStream) {
mListener.onRemoveRemoteStream(mediaStream, endPoint);
removePeer(id);
}
#Override
public void onDataChannel(DataChannel dataChannel) {}
public Peer(String id, int endPoint) {
Log.d(TAG,"new Peer: "+id + " " + endPoint);
this.pc = factory.createPeerConnection(iceServers, pcConstraints, this);
this.id = id;
this.endPoint = endPoint;
pc.addStream(lMS, new MediaConstraints());
mListener.onStatusChanged("CONNECTING");
}
}
public WebRtcClient(RTCListener listener, String host) {
mListener = listener;
factory = new PeerConnectionFactory();
SocketIOClient.connect(host, new ConnectCallback() {
#Override
public void onConnectCompleted(Exception ex, SocketIOClient socket) {
if (ex != null) {
Log.e(TAG,"WebRtcClient connect failed: "+ex.getMessage());
return;
}
Log.d(TAG,"WebRtcClient connected.");
client = socket;
// specify which events you are interested in receiving
client.addListener("id", messageHandler);
client.addListener("message", messageHandler);
client.addListener("joined", messageHandler);
}
}, new Handler());
iceServers.add(new PeerConnection.IceServer("stun:23.21.150.121"));
iceServers.add(new PeerConnection.IceServer("stun:stun.l.google.com:19302"));
pcConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
pcConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"));
}
public void setCamera(String cameraFacing, String height, String width){
MediaConstraints videoConstraints = new MediaConstraints();
videoConstraints.mandatory.add(new MediaConstraints.KeyValuePair("maxHeight", height));
videoConstraints.mandatory.add(new MediaConstraints.KeyValuePair("maxWidth", width));
VideoSource videoSource = factory.createVideoSource(getVideoCapturer(cameraFacing), videoConstraints);
lMS = factory.createLocalMediaStream("ARDAMS");
lMS.addTrack(factory.createVideoTrack("ARDAMSv0", videoSource));
lMS.addTrack(factory.createAudioTrack("ARDAMSa0"));
mListener.onLocalStream(lMS);
}
private int findEndPoint() {
for(int i = 0; i < MAX_PEER; i++) {
if(!endPoints[i]) return i;
}
return MAX_PEER;
}
public void start(String name, boolean privacy){
try {
JSONObject message = new JSONObject();
message.put("msg", new JSONObject().put("msg", "got user media"));
message.put("room", "sojharo");
client.emit("message", new JSONArray().put(message));
} catch (JSONException e) {
e.printStackTrace();
}
}
/*
Cycle through likely device names for the camera and return the first
capturer that works, or crash if none do.
*/
private VideoCapturer getVideoCapturer(String cameraFacing) {
int[] cameraIndex = { 0, 1 };
int[] cameraOrientation = { 0, 90, 180, 270 };
for (int index : cameraIndex) {
for (int orientation : cameraOrientation) {
String name = "Camera " + index + ", Facing " + cameraFacing +
", Orientation " + orientation;
VideoCapturer capturer = VideoCapturer.create(name);
if (capturer != null) {
return capturer;
}
}
}
throw new RuntimeException("Failed to open capturer");
}
private void addPeer(String id, int endPoint) {
Peer peer = new Peer(id, endPoint);
peers.put(id, peer);
endPoints[endPoint] = true;
}
private void removePeer(String id) {
Peer peer = peers.get(id);
peer.pc.close();
peer.pc.dispose();
peers.remove(peer.id);
endPoints[peer.endPoint] = false;
}
}
The code is able to receive the offer and candidates from other party. It is not able to send the answer or candidates to that party in return.
I have not modified other two classes which can be found on the above link for android application.
Here is snippet of my socket.io server code written in nodejs:
socket.on('create or join livehelp', function (room) {
var numClients = socketio.sockets.clients(room.room).length;
if (numClients === 0){
socket.join(room.room);
socket.set('nickname', room.username);
socket.emit('created', room);
} else if (numClients < 2) {
socket.join(room.room);
socket.set('nickname', room.username);
socket.emit('joined', room);
socket.broadcast.to(room.room).emit('join', room);
} else { // max three clients
socket.emit('full', room.room);
}
console.log(socketio.sockets.manager.rooms)
console.log(room)
});
socket.on('message', function (message) {
//console.log('Got message:', message);
//socket.broadcast.emit('message', message);
message.msg.from = socket.id;
//socketio.sockets.in(message.room).emit('message', message.msg);
socket.broadcast.to(message.room).emit('message', message.msg);
//console.log('Got message:', message.msg);
//console.log(socketio.sockets.manager.rooms)
});
I am confused if there is any error why I am not able to find it in debugging. Log for this is very difficult to read as it runs very fast and I am not able to catch each and every line. But apparently, it looked fine at a glance.
Please help. Thanks.
I think you are not able to generate answer but you are able to generate offer?. If this is the case try adding
pcConstraints.optional.add(new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true"));
to your pc constraints.
Hope this will help..
client.on('message', function (details) {
console.log('message',details.to);
console.log(details.type);
if(details.type !== 'init'){
var otherClient = io.sockets.connected[details.to];
if (!otherClient) {
return;
}
delete details.to;
details.from = client.id;
otherClient.emit('message', details);
}
else
{
if (io.sockets.adapter.rooms[client.room] !== undefined ) {
for(var member in io.sockets.adapter.rooms[client.room]){
console.log(member);
if(member !== client.id){
var otherClient = io.sockets.connected[member];
if (!otherClient) {
return;
}
delete details.to;
details.from = client.id;
otherClient.emit('message', details);
}
else{
console.log("no need to send self again!");
}
}
} else {
client.emit("update", "Please connect to a room.");
}
}
});
Please download latest libjingle from here
http://repo.spring.io/libs-release-remote/io/pristine/libjingle/
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am having a problem with a task that shows live content from a site.
I have been playing around with this code for a while and playing around with the status but I can't seem to get it to work correctly.
The only solution I have been able to come up with so far is completely disable orientation changes, but I would prefer not to do that if possible.
Here is the Stack Trace:
STACK_TRACE = java.lang.IllegalArgumentException: View not attached to window manager
at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:653)
at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:349)
at android.view.WindowManagerImpl$CompatModeWrapper.removeView(WindowManagerImpl.java:160)
at android.app.Dialog.dismissDialog(Dialog.java:319)
at android.app.Dialog.dismiss(Dialog.java:302)
at cl.cromer.tronwell.concepcion.Progress.dismiss(Progress.java:72)
at cl.cromer.tronwell.concepcion.AdditionalMaterial.databaseLoaded(AdditionalMaterial.java:149)
at cl.cromer.tronwell.concepcion.AdditionalMaterial.access$13(AdditionalMaterial.java:122)
at cl.cromer.tronwell.concepcion.AdditionalMaterial$1$1.run(AdditionalMaterial.java:73)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5031)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
at dalvik.system.NativeStart.main(Native Method)
Here is my code for the class that is crashing:
package cl.cromer.tronwell.concepcion;
import java.util.Calendar;
import java.util.HashMap;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import cl.cromer.tronwell.concepcion.DBSchema.DBAdditionalMaterial;
import cl.cromer.tronwell.concepcion.DBSchema.DBAdditionalMaterialGroups;
import cl.cromer.tronwell.concepcion.Files.Download;
public class AdditionalMaterial extends ActionBarActivity implements ListenerXML, ListenerDownload, ListenerAsync {
private final static String URL = "action=downloads";
private XMLParser xmlParser;
private Progress progress = null;
// Parsers
private SQLParser sqlParser;
private Handler threadHandler = new Handler();
// The database
private SQLiteDatabase tronDB;
private int downloadId = 0;
private boolean downloadAll = false;
private int downloadCount = 1;
private int firstDownloadAvailable = 0;
private String fileName;
private Files files = new Files();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("debug", "onCreate");
setContentView(R.layout.activity_additional_material);
//progress = new Progress();
//progress.show(this, this, false);
sqlParser = new SQLParser(this);
new Thread(new Runnable() {
public void run() {
tronDB = sqlParser.getWritableDatabase();
threadHandler.post(new Runnable() {
public void run() {
databaseLoaded();
}
});
}
}).start();
}
#Override
protected void onStart() {
super.onStart();
Log.d("debug", "onStart");
}
#Override
protected void onRestart() {
super.onRestart();
Log.d("debug", "onRestart");
}
#Override
protected void onResume() {
super.onResume();
progress = new Progress();
progress.show(this, this, false);
Log.d("debug", "onResume");
}
#Override
protected void onStop() {
super.onStop();
Log.d("debug", "onStop");
}
#Override
protected void onDestroy() {
super.onDestroy();
progress = null;
Log.d("debug", "onDestroy");
}
#Override
public void onPause() {
super.onPause();
Log.d("debug", "onDestroy");
}
private void databaseLoaded() {
SharedPreferences settings = getSharedPreferences(Settings.PREFERENCES, MODE_PRIVATE);
long materialDate = settings.getLong(Settings.MATERIAL_DATE, Settings.MATERIAL_DATE_DEFAULT);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
long currentDate = calendar.getTimeInMillis();
if (currentDate > materialDate ) {
// Update the database
String rut = settings.getString(Settings.RUT, Settings.RUT_DEFAULT);
String password = settings.getString(Settings.PASSWORD, Settings.PASSWORD_DEFAULT);
HashMap<String, String> postData = new HashMap<String, String>();
postData.put("rut", rut);
postData.put("pass", password);
xmlParser = new XMLParser(this, postData);
xmlParser.fetchListener = this; // Tell the XMLParser that this activity has the listener
xmlParser.execute(MainActivity.URL + URL);
}
else {
// Material does not need to be updated, just show what is in the database
if (progress != null && progress.isShowing()) {
progress.dismiss();
}
ShowContent showContent = new ShowContent(this);
showContent.asyncListener = this; // Tell the task that this class is listening
showContent.execute();
}
}
private void fetchFinished(HashMap<String, HashMap<String, String>> xmlData) {
// Let's put the groups in the database
HashMap<String, String> xmlHash = xmlData.get("1");
String groups = xmlHash.get("groups");
for (int i = 1; i <= Integer.valueOf(groups); i++) {
ContentValues values = new ContentValues();
values.put(DBAdditionalMaterialGroups.COLUMN_ID, String.valueOf(i));
values.put(DBAdditionalMaterialGroups.COLUMN_NAME, xmlHash.get("group" + String.valueOf(i)));
tronDB.replace(
DBAdditionalMaterialGroups.TABLE_NAME,
null,
values);
}
// Now the material
for (int i = 2; i <= xmlData.size() - 1; i++) {
xmlHash = xmlData.get(String.valueOf(i));
ContentValues values = new ContentValues();
values.put(DBAdditionalMaterial.COLUMN_ID, xmlHash.get("id"));
values.put(DBAdditionalMaterial.COLUMN_NAME, xmlHash.get("title"));
values.put(DBAdditionalMaterial.COLUMN_GROUP, xmlHash.get("group"));
values.put(DBAdditionalMaterial.COLUMN_TYPE, xmlHash.get("type"));
values.put(DBAdditionalMaterial.COLUMN_URL1, xmlHash.get("url1"));
values.put(DBAdditionalMaterial.COLUMN_URL2, xmlHash.get("url2"));
tronDB.replace(
DBAdditionalMaterial.TABLE_NAME,
null,
values);
}
SharedPreferences settings = getSharedPreferences(Settings.PREFERENCES, MODE_PRIVATE);
SharedPreferences.Editor settingsEditor = settings.edit();
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
long currentDate = calendar.getTimeInMillis();
settingsEditor.putLong(Settings.MATERIAL_DATE, currentDate);
settingsEditor.commit();
progress.dismiss();
ShowContent showContent = new ShowContent(this);
showContent.asyncListener = this; // Tell the task that this class is listening
showContent.execute();
}
#TargetApi(Build.VERSION_CODES.FROYO)
protected class ShowContent extends AsyncTask<String, View, Void> {
private Context context;
private PowerManager.WakeLock wakeLock;
protected ListenerAsync asyncListener = null; // This needs to be set from the parent activity
private LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linear_layout);
protected ShowContent(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// Let's make sure the CPU doesn't go to sleep
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
wakeLock.acquire();
}
#SuppressLint("InflateParams")
#Override
protected Void doInBackground(String... passedInfo) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View categoryView;
View downloadView;
View seperatorView;
TextView textView = new TextView(context);
ImageButton imageButton = new ImageButton(context);
Cursor cursorMaterialGroups = tronDB.query(
DBAdditionalMaterialGroups.TABLE_NAME,
DBAdditionalMaterialGroups.ALL_COLUMNS,
null,
null,
null,
null,
DBAdditionalMaterialGroups.COLUMN_ID + " ASC",
null);
while (cursorMaterialGroups.moveToNext()) {
// Create a group TextView by inflating a layout
categoryView = inflater.inflate(R.layout.additional_material_category, null);
textView = (TextView) categoryView;
textView.setText(cursorMaterialGroups.getString(cursorMaterialGroups.getColumnIndex(DBAdditionalMaterialGroups.COLUMN_NAME)));
publishProgress(textView);
// Now to get the downloads from the group
Cursor cursorMaterial = tronDB.query(DBAdditionalMaterial.TABLE_NAME,
DBAdditionalMaterial.ALL_COLUMNS,
DBAdditionalMaterial.COLUMN_GROUP + "=" + cursorMaterialGroups.getString(cursorMaterialGroups.getColumnIndex(DBAdditionalMaterialGroups.COLUMN_ID)),
null,
null,
null,
DBAdditionalMaterial.COLUMN_ID + " ASC",
null);
downloadCount += cursorMaterial.getCount();
while (cursorMaterial.moveToNext()) {
downloadView = inflater.inflate(R.layout.additional_material_download, null);
// Download title
textView = (TextView) downloadView.findViewById(R.id.download_title);
textView.setText(cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_NAME)));
// Download/play button
imageButton = (ImageButton) downloadView.findViewById(R.id.download_button);
imageButton.setId(Integer.valueOf(cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_ID))));
String fileName = null;
if (cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_TYPE)).equals("pdf")) {
fileName = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_ID)) + ".pdf";
}
else {
fileName = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_ID)) + ".mp3";
}
Drawable drawable = getResources().getDrawable(R.drawable.ic_action_play);
if (!files.fileExists(context, fileName)) {
if (firstDownloadAvailable == 0) {
firstDownloadAvailable = imageButton.getId();
}
drawable = getResources().getDrawable(R.drawable.ic_action_save);
imageButton.setImageDrawable(drawable);
imageButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
downloadId = view.getId();
download();
}
});
}
else {
imageButton.setImageDrawable(drawable);
imageButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String contentId = String.valueOf(view.getId());
openContent(contentId);
}
});
}
publishProgress(downloadView);
if (!cursorMaterial.isLast()) {
seperatorView = inflater.inflate(R.layout.additional_material_seperator, null);
publishProgress(seperatorView);
}
}
cursorMaterial.close();
}
// Other
categoryView = inflater.inflate(R.layout.additional_material_category, null);
textView = (TextView) categoryView;
textView.setText("OTHER");
publishProgress(textView);
// Download all
downloadView = inflater.inflate(R.layout.additional_material_download, null);
// Download title
textView = (TextView) downloadView.findViewById(R.id.download_title);
textView.setText("Download all material");
// Download/play button
imageButton = (ImageButton) downloadView.findViewById(R.id.download_button);
imageButton.setId(1);
Drawable drawable = getResources().getDrawable(R.drawable.ic_action_play);
drawable = getResources().getDrawable(R.drawable.ic_action_save);
imageButton.setImageDrawable(drawable);
imageButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
downloadId = firstDownloadAvailable;
downloadAll = true;
download();
}
});
publishProgress(downloadView);
cursorMaterialGroups.close();
return null;
}
#Override
protected void onProgressUpdate(View... view) {
linearLayout.addView(view[0]);
}
#Override
protected void onPostExecute(Void result) {
wakeLock.release();
if (asyncListener != null) {
// Call the listener if one is set
asyncListener.onAsyncComplete();
}
}
}
private void download() {
progress.show(this, this, true);
Files files = new Files();
// Check if the memory card can be written to
if (files.isWriteable()) {
Cursor cursorMaterial = tronDB.query(DBAdditionalMaterial.TABLE_NAME,
DBAdditionalMaterial.ALL_COLUMNS,
DBAdditionalMaterial.COLUMN_ID + "=" + String.valueOf(downloadId),
null,
null,
null,
null,
"1");
cursorMaterial.moveToFirst();
String title = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_NAME));
String type = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_TYPE));
String url1 = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_URL1));
String url2 = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_URL2));
cursorMaterial.close();
if (type.equals("pdf")) {
fileName = String.valueOf(downloadId) + ".pdf";
}
else {
fileName = String.valueOf(downloadId) + ".mp3";
}
// Change the message in the downloading prompt
progress.setMessage(getString(R.string.general_downloading) + " " + title);
SharedPreferences settings = getSharedPreferences(Settings.PREFERENCES, MODE_PRIVATE);
String rut = settings.getString(Settings.RUT, Settings.RUT_DEFAULT);
String url = url1 + rut + url2;
url = url.replace(" ", "%20");
final Download download = files.new Download(this, fileName, progress);
download.downloadListener = this;
download.execute(url);
progress.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
downloadAll = false;
download.cancel(true);
}
});
}
else {
progress.dismiss();
Toast.makeText(this, getString(R.string.general_no_memory), Toast.LENGTH_SHORT).show();
}
}
private void openContent(String contentId) {
Cursor cursorMaterial = tronDB.query(DBAdditionalMaterial.TABLE_NAME,
DBAdditionalMaterial.ALL_COLUMNS,
DBAdditionalMaterial.COLUMN_ID + "=" + contentId,
null,
null,
null,
null,
"1");
cursorMaterial.moveToFirst();
String type = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_TYPE));
cursorMaterial.close();
String fileName = "";
String mimeType = "";
if (type.equals("pdf")) {
fileName = contentId + ".pdf";
mimeType = "application/pdf";
}
else {
fileName = contentId + ".mp3";
mimeType = "audio/mp3";
}
files.openFile(this, fileName, mimeType);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (intent.getBooleanExtra(ConnectionFailed.RETRY, false)) {
// Failed, let's try the connection again
SharedPreferences settings = getSharedPreferences(Settings.PREFERENCES, MODE_PRIVATE);
String rut = settings.getString(Settings.RUT, Settings.RUT_DEFAULT);
String password = settings.getString(Settings.PASSWORD, Settings.PASSWORD_DEFAULT);
HashMap<String, String> postData = new HashMap<String, String>();
postData.put("rut", rut);
postData.put("pass", password);
xmlParser = new XMLParser(this, postData);
xmlParser.fetchListener = this; // Tell the XMLParser that this activity has the listener
xmlParser.execute(MainActivity.URL + URL);
}
}
// This is the listener for the xml
public void onFetchComplete(String xml) {
if (xml == null) {
progress.dismiss();
// Failed to fetch xml, either a server error or an internet connection problem
Intent intent = new Intent(this, ConnectionFailed.class);
startActivityForResult(intent, 1);
}
else {
HashMap<String, HashMap<String, String>> xmlHash = xmlParser.parseXML(xml);
new User().checkUserValidation(xmlHash.get("0"));
fetchFinished(xmlHash);
}
}
// This is the listener for the download
public void onDownloadComplete(boolean result) {
progress.dismiss();
if (!result) {
Toast.makeText(this, getString(R.string.general_failed_download), Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(this, getString(R.string.general_download_complete), Toast.LENGTH_SHORT).show();
Drawable drawable = getResources().getDrawable(R.drawable.ic_action_play);
ImageButton buttonView = (ImageButton) findViewById(downloadId);
buttonView.setImageDrawable(drawable);
buttonView.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String contentId = String.valueOf(view.getId());
openContent(contentId);
}
});
if (downloadAll) {
while (downloadCount >= downloadId) {
downloadId++;
Cursor cursorMaterial = tronDB.query(DBAdditionalMaterial.TABLE_NAME,
DBAdditionalMaterial.ALL_COLUMNS,
DBAdditionalMaterial.COLUMN_ID + "=" + String.valueOf(downloadId),
null,
null,
null,
null,
"1");
cursorMaterial.moveToFirst();
String type = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_TYPE));
cursorMaterial.close();
if (type.equals("pdf")) {
fileName = String.valueOf(downloadId) + ".pdf";
}
else {
fileName = String.valueOf(downloadId) + ".mp3";
}
if (!files.fileExists(this, fileName)) {
download();
break;
}
}
if (downloadCount == downloadId) {
// The last one downloaded we can now stop the process
downloadAll = false;
}
}
}
}
// This is the listener for the Async
public void onAsyncComplete() {
progress.dismiss();
}
}
Here is the code for my progress bar:
package cl.cromer.tronwell.concepcion;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
public final class Progress {
protected ProgressDialog progressBar = null;
private int oldOrientation = -1; // Orientation not set
private Activity activity;
protected void show(Context context, Activity activity, boolean cancelable) {
this.activity = activity;
// Disable rotation while we are loading something
oldOrientation = activity.getRequestedOrientation();
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
if (progressBar != null && progressBar.isShowing()) {
activity.setRequestedOrientation(oldOrientation);
progressBar.dismiss();
}
progressBar = new ProgressDialog(context);
progressBar.setCancelable(cancelable);
if (!cancelable) {
progressBar.setMessage(context.getString(R.string.general_loading));
progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
}
else {
progressBar.setIndeterminate(true);
progressBar.setCanceledOnTouchOutside(false);
progressBar.setMessage(context.getString(R.string.general_downloading));
progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
}
progressBar.setProgress(0);
progressBar.setMax(100);
progressBar.show();
}
protected void setMessage(String message) {
progressBar.setMessage(message);
}
protected void setIndeterminate(boolean indeterminate) {
progressBar.setIndeterminate(indeterminate);
}
protected void setProgress(int progress) {
progressBar.setProgress(progress);
}
protected void setOnCancelListener(DialogInterface.OnCancelListener listener) {
progressBar.setOnCancelListener(listener);
}
protected boolean isShowing() {
if (progressBar.isShowing()) {
return true;
}
return false;
}
protected void dismiss() {
// Turn rotation back to it's previous state
activity.setRequestedOrientation(oldOrientation);
if (progressBar != null && progressBar.isShowing()) {
progressBar.dismiss();
}
}
}
Check answer of this question Answer
I think you facing same issue
Check this one as well Answer 2
I have been Using this SDK http://www.easyfacebookandroidsdk.com/ to integrate Facebook in my App.
I only want to update a statur from my App. It worked great using this class in Android API 10. Running it on phone with API 15 gives me a android.os.NetworkOnMainThreadException. here my code:
package com.my.wod;
import android.app.Activity;
import android.content.Context;
import com.main.xfit.R;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.Toast;
import com.facebook.android.*;
import com.facebook.android.Facebook.DialogListener;
public class PostFaceBookStatus extends Activity {
private static final String APP_ID = "ID OF MY APP";
private static final String[] PERMISSIONS = {"publish_stream" };
private static final String TOKEN = "access_token";
private static final String EXPIRES = "expires_in";
private static final String KEY = "facebook-credentials";
private Facebook facebook;
private String messageToPost;
public boolean saveCredentials(Facebook facebook) {
Editor editor = getApplicationContext().getSharedPreferences(KEY, Context.MODE_PRIVATE).edit();
editor.putString(TOKEN, facebook.getAccessToken());
editor.putLong(EXPIRES, facebook.getAccessExpires());
return editor.commit();
}
public boolean restoreCredentials(Facebook facebook) {
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(KEY, Context.MODE_PRIVATE);
facebook.setAccessToken(sharedPreferences.getString(TOKEN, null));
facebook.setAccessExpires(sharedPreferences.getLong(EXPIRES, 0));
return facebook.isSessionValid();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
facebook = new Facebook(APP_ID);
restoreCredentials(facebook);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.facebook);
String facebookMessage = getIntent().getStringExtra("facebookMessage");
Toast.makeText(getApplicationContext(), facebookMessage, Toast.LENGTH_LONG).show();
if (facebookMessage == null){
facebookMessage = "SUNDAY 120506 2012 CrossFit Games Regional: Individual Event 4 For time: 135 pound Back squat, 50 reps 40 Pull-ups 135 pound Shoulder-to-overhead, 30 reps 85 pound Front squat, 50 reps 40 Pull-ups 85 pound Shoulder-to-overhead, 30 reps 65 pound Overhead squat, 50 reps 40 Pull-ups 65 pound Shoulder-to-overhead, 30 reps";
}
//messageToPost = facebookMessage;
messageToPost = "Post random shit" ;
}
public void doNotShare(View button){
finish();
}
public void share(View button){
if (! facebook.isSessionValid()) {
loginAndPostToWall();
}
else {
postToWall(messageToPost);
}
}
public void loginAndPostToWall(){
facebook.authorize(this, PERMISSIONS, Facebook.FORCE_DIALOG_AUTH, new LoginDialogListener());
}
public void postToWall(String message){
Bundle parameters = new Bundle();
parameters.putString("message", message);
parameters.putString("description", "topic share");
try {
facebook.request("me");
String response = facebook.request("me/feed", parameters, "POST");
Log.d("Tests", "got response: " + response);
if (response == null || response.equals("") ||
response.equals("false")) {
showToast("Blank response.");
}
else {
showToast("Message posted to your facebook wall!");
}
finish();
} catch (Exception e) {
showToast("Failed to post to wall!");
e.printStackTrace();
finish();
}
}
class LoginDialogListener implements DialogListener {
public void onComplete(Bundle values) {
saveCredentials(facebook);
if (messageToPost != null){
postToWall(messageToPost);
}
}
public void onFacebookError(FacebookError error) {
showToast("Authentication with Facebook failed!");
finish();
}
public void onError(DialogError error) {
showToast("Authentication with Facebook failed!");
finish();
}
public void onCancel() {
showToast("Authentication with Facebook cancelled!");
finish();
}
}
private void showToast(String message){
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
}
Any ideas?
You can't run network operations on the UI thread, and if you think it is is the API code doing it, then you'll have to wrap the API call's in a Thread.
Looks like this line is using the network:
String response = facebook.request("me/feed", parameters, "POST");
You need to do long running tasks on a worker thread.
You used to get an ANR (Activity Not Responsding) but ICS is a little cleverer and kicks you off before this happens.
Get reading:
http://developer.android.com/guide/practices/responsiveness.html
http://developer.android.com/training/basics/network-ops/connecting.html#AsyncTask < This is one possible alternative answer
To make it work for API level 10 and higher i just employed and AsyncTask and it Worked!!
Use the below code:
//make this global declaration
private Facebook mFacebook;
private class FbLoginAsync extends AsyncTask<Void, Void, User> {
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(ConstantsCtc.DIALOG_PROGRESS);
}
#Override
protected User doInBackground(Void... params) {
// facebooklogin();
return getFacebookData();
}
#Override
protected void onPostExecute(User u) {
super.onPostExecute(u);
// your facebook information is in User bean 'u'.
}
}
public User getFacebookData() {
User u = new User();
try {
JSONObject jsonME = null;
JSONObject jsonfrnd = null;
try {
jsonME = Util.parseJson(mFacebook.request("me"));
// jsonfrnd =
// Util.parseJson(mFacebook
// .request("me/friends"));
} catch (FacebookError e) {
e.printStackTrace();
u = null;
}
Log.w("fbjsonMe", " *\n " + jsonME);
// Log.e("fbjsonfrnds", " *\n " + jsonfrnd);
String mUserId = jsonME.getString("id");
String mUserName = jsonME.getString("first_name");
String mUseremail = jsonME.getString("email");
String birthday = jsonME.getString("birthday");
String gender = jsonME.getString("gender");
String full_name = jsonME.getString("name");
// Log.w("UserName", mUserName + " * " + mUseremail + " *\n "
// + jsonME);
// calculate age
String ag[] = birthday.split("/");
int y = Integer.parseInt(ag[2]);// get birth year
final Calendar cal = Calendar.getInstance();
int currentyear = cal.get(Calendar.YEAR);
int age = currentyear - y;
if (gender.equalsIgnoreCase("male"))
gender = "0";
else
gender = "1";
u.setUserId(mUserId);
u.setUserFullName(full_name);
u.setEmail(mUseremail);
u.setAge(age + "");
u.setGender(gender);
} catch (Exception e) {
e.printStackTrace();
u = null;
}
return u;
}
// then make a call to below method form your activity's button click or
// else
public void facebookLogin() {
this.mFacebook = new Facebook(appId);// give your appId
if (mFacebook.isSessionValid()) {
new FbLoginAsync().execute();
} else {
SessionEvents.AuthListener listener = new SessionEvents.AuthListener() {
#Override
public void onAuthSucceed() {
new FbLoginAsync().execute();
}
#Override
public void onAuthFail(String error) {
showDialogCustome("Error in Facebook Login, please try again later");
Log.e("onAuthFail", "onAuthFail");
}
};
SessionEvents.addAuthListener(listener);
mFacebook.authorize(this.activity, this.permissions,
Facebook.FORCE_DIALOG_AUTH, new LoginDialogListener());
}
}
I hope this solves your problem. let me know