I am trying to integrate twiiter with my android app and I am facing some OS compatibility problem. When I am running my app in 2.3.4 android device its working properly, but when I am running same program on my 4.1.2 android jelly bean device its giving me an error due to doing background work on main thread. But I can't figure out how to do this job in background thread using async task.
My current implementation is as below
TwitterActivity.java
final Runnable mUpdateTwitterNotification = new Runnable() {
public void run() {
Toast.makeText(getBaseContext(), "Tweet sent !", Toast.LENGTH_LONG)
.show();
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Thread.setDefaultUncaughtExceptionHandler(new UnCaughtException(
TwitterActivity.this));
setContentView(R.layout.twitter_main);
this.prefs = PreferenceManager.getDefaultSharedPreferences(this);
Bundle extras = getIntent().getExtras();
message = extras.getString("message");
tvLoginStatus = (TextView) findViewById(R.id.login_status);
edtTweetMsg = (EditText) findViewById(R.id.tweet_msg);
btnTweet = (Button) findViewById(R.id.btn_tweet);
btnClearCredentials = (Button) findViewById(R.id.btn_clear_credentials);
tvHeader = (TextView)findViewById(R.id.header_text);
tvHeader.setText("Tweeter");
edtTweetMsg.setText(message);
btnTweet.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
message = edtTweetMsg.getText().toString();
if (!message.equals("")) {
if (message.length() <= 140) {
if (TwitterUtils.isAuthenticated(prefs)) {
sendTweet();
} else {
Intent i = new Intent(getApplicationContext(),
TwitterPrepareRequestTokenActivity.class);
i.putExtra("tweet_msg", message);
startActivity(i);
}
} else
Toast.makeText(TwitterActivity.this,
"Maximum 140 charecter allowed",
Toast.LENGTH_SHORT).show();
} else
Toast.makeText(TwitterActivity.this,
"Nothing to be post", Toast.LENGTH_SHORT).show();
}
});
btnClearCredentials.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
clearCredentials();
updateLoginStatus();
}
});
}
@Override
protected void onResume() {
super.onResume();
updateLoginStatus();
}
public void updateLoginStatus() { <-----------Location of error
tvLoginStatus.setText("Logged into Twitter : "
+ TwitterUtils.isAuthenticated(prefs));
}
public void sendTweet() {
Thread t = new Thread() {
public void run() {
try {
TwitterUtils.sendTweet(prefs, edtTweetMsg.getText()
.toString());
mTwitterHandler.post(mUpdateTwitterNotification);
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
t.start();
}
private void clearCredentials() {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this);
final Editor edit = prefs.edit();
edit.remove(OAuth.OAUTH_TOKEN);
edit.remove(OAuth.OAUTH_TOKEN_SECRET);
edit.commit();
}
It showing error on my method updateLogin()
TwitterUtil.java
public class TwitterUtils {
public static boolean isAuthenticated(SharedPreferences prefs) {
String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");
AccessToken a = new AccessToken(token, secret);
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(TwitterConstants.CONSUMER_KEY,
TwitterConstants.CONSUMER_SECRET);
twitter.setOAuthAccessToken(a);
try {
twitter.getAccountSettings();
return true;
} catch (TwitterException e) {
return false;
}
}
public static void sendTweet(SharedPreferences prefs, String msg)
throws Exception {
String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");
AccessToken a = new AccessToken(token, secret);
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(TwitterConstants.CONSUMER_KEY,
TwitterConstants.CONSUMER_SECRET);
twitter.setOAuthAccessToken(a);
twitter.updateStatus(msg);
}
}
I am using following jar files for this app
signpost-commonshttp4-1.2.1.1.jar
signpost-core-1.2.1.1.jar
twitter4j-core-3.0.1.jar
httpclient-4.0.1.jar
My error stacktrace is as below
Stack:
java.lang.RuntimeException: Unable to resume activity {com.appovative.poi/com.appovative.places.TwitterActivity}: android.os.NetworkOnMainThreadException
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2583)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2611)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2097)
at android.app.ActivityThread.access$600(ActivityThread.java:133)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1203)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4794)
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:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
at java.net.InetAddress.getAllByName(InetAddress.java:214)
at libcore.net.http.HttpConnection.<init>(HttpConnection.java:70)
at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:340)
at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87)
at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:315)
at libcore.net.http.HttpEngine.connect(HttpEngine.java:310)
at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289)
at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239)
at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273)
at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:486)
at twitter4j.internal.http.HttpResponseImpl.<init>(HttpResponseImpl.java:34)
at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:156)
at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:61)
at twitter4j.internal.http.HttpClientWrapper.get(HttpClientWrapper.java:89)
at twitter4j.TwitterImpl.get(TwitterImpl.java:1690)
at twitter4j.TwitterImpl.getAccountSettings(TwitterImpl.java:556)
at com.appovative.places.TwitterUtils.isAuthenticated(TwitterUtils.java:24)
at com.appovative.places.TwitterActivity.updateLoginStatus(TwitterActivity.java:112)
at com.appovative.places.TwitterActivity.onResume(TwitterActivity.java:107)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1184)
at android.app.Activity.performResume(Activity.java:5195)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2573)
Replace following code:
@Override
protected void onResume() {
super.onResume();
updateLoginStatus();
}
public void updateLoginStatus() { <-----------Location of error
tvLoginStatus.setText("Logged into Twitter : "
+ TwitterUtils.isAuthenticated(prefs));
}
with this:
@Override
protected void onResume() {
super.onResume();
new loginToTwitterTask().execute();
}
private class loginToTwitterTask extends AsyncTask<Void, Void, Void>
{
private ProgressDialog pdLoading;
private boolean isAuthenticated;
@Override
protected void onPreExecute() {
super.onPreExecute();
pdLoading = new ProgressDialog(TwitterActivity.this);
pdLoading.setMessage("\tLoading...");
pdLoading.setCancelable(false);
pdLoading.show();
}
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
isAuthenticated = TwitterUtils.isAuthenticated(prefs);
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
pdLoading.dismiss();
tvLoginStatus.setText("Logged into Twitter : "
+isAuthenticated);
}
}
Reference: AsyncTask in Android