1

我还是 Android 编程的新手。我正在学习一本名为 Learning Android 的书中的教程。当我单击更新按钮时,我最终崩溃了。知道为什么吗?堆栈跟踪如下。我得到一个致命的例外:主要

package com.marakana.yamba;

import winterwell.jtwitter.Twitter;
import winterwell.jtwitter.TwitterException;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class StatusActivity extends Activity implements OnClickListener{

private static final String TAG ="StatusActivity";
    Twitter twitter;
    EditText editText;
    Button updateButton ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.status);
//      Find Views
        editText = (EditText) findViewById(R.id.editText);
        updateButton = (Button) findViewById(R.id.updateButton);
        updateButton.setOnClickListener(this);

        twitter = new Twitter("Yamba18", "undertaker");

        twitter.setAPIRootUrl("http://yamba.marakana.com/api");


    }


//Asynchronously Post to Twitter
class PostToTwitter extends AsyncTask<String, Integer, String>{

    @Override
    protected String doInBackground(String... statuses){
        try{
            winterwell.jtwitter.Status status = twitter.updateStatus(statuses[0]);
            return status.text;
        }catch(TwitterException e){
            Log.e(TAG,e.toString());
            e.printStackTrace();
            return "Failedd to Post";
        }
    }

    @Override
    protected void onProgressUpdate (Integer... values){
        super.onProgressUpdate(values);
    }
    @Override
    protected void onPostExecute(String result){
        Toast.makeText(StatusActivity.this, result, Toast.LENGTH_LONG).show();
    }
}



public void onClick(View v){

    twitter.setStatus(editText.getText().toString());
    Log.d(TAG, "onClicked");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.status, menu);
    return true;
}
}

这是日志猫。

09-26 17:25:56.469: D/AndroidRuntime(612): Shutting down VM
09-26 17:25:56.469: W/dalvikvm(612): threadid=1: thread exiting with uncaught exception (group=0x409961f8)
09-26 17:25:56.529: E/AndroidRuntime(612): FATAL EXCEPTION: main
09-26 17:25:56.529: E/AndroidRuntime(612): winterwell.jtwitter.TwitterException: java.io.IOException: Received authentication challenge is null
09-26 17:25:56.529: E/AndroidRuntime(612):  at winterwell.jtwitter.URLConnectionHttpClient.processError(URLConnectionHttpClient.java:533)
09-26 17:25:56.529: E/AndroidRuntime(612):  at winterwell.jtwitter.URLConnectionHttpClient.post2_connect(URLConnectionHttpClient.java:413)
09-26 17:25:56.529: E/AndroidRuntime(612):  at winterwell.jtwitter.URLConnectionHttpClient.post2(URLConnectionHttpClient.java:379)
09-26 17:25:56.529: E/AndroidRuntime(612):  at winterwell.jtwitter.URLConnectionHttpClient.post(URLConnectionHttpClient.java:348)
09-26 17:25:56.529: E/AndroidRuntime(612):  at winterwell.jtwitter.Twitter.updateStatus(Twitter.java:2762)
09-26 17:25:56.529: E/AndroidRuntime(612):  at winterwell.jtwitter.Twitter.updateStatus(Twitter.java:2694)
09-26 17:25:56.529: E/AndroidRuntime(612):  at winterwell.jtwitter.Twitter.setStatus(Twitter.java:2482)
09-26 17:25:56.529: E/AndroidRuntime(612):  at com.marakana.yamba.StatusActivity.onClick(StatusActivity.java:68)
09-26 17:25:56.529: E/AndroidRuntime(612):  at android.view.View.performClick(View.java:3480)
09-26 17:25:56.529: E/AndroidRuntime(612):  at android.view.View$PerformClick.run(View.java:13983)
09-26 17:25:56.529: E/AndroidRuntime(612):  at android.os.Handler.handleCallback(Handler.java:605)
09-26 17:25:56.529: E/AndroidRuntime(612):  at android.os.Handler.dispatchMessage(Handler.java:92)
09-26 17:25:56.529: E/AndroidRuntime(612):  at android.os.Looper.loop(Looper.java:137)
09-26 17:25:56.529: E/AndroidRuntime(612):  at android.app.ActivityThread.main(ActivityThread.java:4340)
09-26 17:25:56.529: E/AndroidRuntime(612):  at java.lang.reflect.Method.invokeNative(Native Method)
09-26 17:25:56.529: E/AndroidRuntime(612):  at java.lang.reflect.Method.invoke(Method.java:511)
09-26 17:25:56.529: E/AndroidRuntime(612):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-26 17:25:56.529: E/AndroidRuntime(612):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-26 17:25:56.529: E/AndroidRuntime(612):  at dalvik.system.NativeStart.main(Native Method)
09-26 17:25:56.529: E/AndroidRuntime(612): Caused by: java.io.IOException: Received authentication challenge is null
09-26 17:25:56.529: E/AndroidRuntime(612):  at libcore.net.http.HttpURLConnectionImpl.processAuthHeader(HttpURLConnectionImpl.java:397)
09-26 17:25:56.529: E/AndroidRuntime(612):  at libcore.net.http.HttpURLConnectionImpl.processResponseHeaders(HttpURLConnectionImpl.java:345)
09-26 17:25:56.529: E/AndroidRuntime(612):  at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:276)
09-26 17:25:56.529: E/AndroidRuntime(612):  at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:479)
09-26 17:25:56.529: E/AndroidRuntime(612):  at winterwell.jtwitter.URLConnectionHttpClient.processError(URLConnectionHttpClient.java:468)
09-26 17:25:56.529: E/AndroidRuntime(612):  ... 18 more
09-26 17:25:59.169: I/Process(612): Sending signal. PID: 612 SIG: 9
4

2 回答 2

2

类似的例子对我有用,希望它有所帮助:

  • 添加库:signpost (signpost-core-1.2.1.1.jar)
  • 在网上生成OAUTH_KEY和OAUTH_SECRET:https ://dev.twitter.com/apps/
  • 修改 MainActivity.java:

    private static final String OAUTH_KEY = "your_OAUTH_KEY";
    private static final String OAUTH_SECRET = "your_OAUTH_SECRET";
    private static final String TWITTER_USER = "your_email";
    

我的文件:

MainActivity.java

package com.marakana.oauth;

import com.marakana.oauth.R;    
import oauth.signpost.OAuth;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import oauth.signpost.basic.DefaultOAuthConsumer;
import oauth.signpost.basic.DefaultOAuthProvider;
import oauth.signpost.exception.OAuthCommunicationException;
import oauth.signpost.exception.OAuthExpectationFailedException;
import oauth.signpost.exception.OAuthMessageSignerException;
import oauth.signpost.exception.OAuthNotAuthorizedException;
import winterwell.jtwitter.OAuthSignpostClient;
import winterwell.jtwitter.Twitter;
import winterwell.jtwitter.TwitterException;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

    private static final String TAG = "OAuthDemo";

    /********************************
       Generate your values ​​on the web::
       https://dev.twitter.com/apps/
    *********************************/
    private static final String OAUTH_KEY = "your_OAUTH_KEY";
    private static final String OAUTH_SECRET = "your_OAUTH_SECRET";
    private static final String TWITTER_USER = "your_email";

    private static final String OAUTH_CALLBACK_SCHEME = "x-marakana-oauth-twitter";
    private static final String OAUTH_CALLBACK_URL = OAUTH_CALLBACK_SCHEME + "://callback";  
    private OAuthSignpostClient oauthClient;
    private OAuthConsumer mConsumer;
    private OAuthProvider mProvider;
    private Twitter twitter;
    SharedPreferences prefs;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         mConsumer = new DefaultOAuthConsumer(OAUTH_KEY, OAUTH_SECRET);
         //mConsumer = new CommonsHttpOAuthConsumer(OAUTH_KEY, OAUTH_SECRET);
        mProvider = new DefaultOAuthProvider(
                "https://api.twitter.com/oauth/request_token",
                "https://api.twitter.com/oauth/access_token",
                "https://api.twitter.com/oauth/authorize");

        // Read the prefs to see if we have token
        prefs = PreferenceManager.getDefaultSharedPreferences(this);
        String token = prefs.getString("token", null);
        String tokenSecret = prefs.getString("tokenSecret", null);
        if (token != null && tokenSecret != null) {
            // We have token, use it
            mConsumer.setTokenWithSecret(token, tokenSecret);
            // Make a Twitter object
            oauthClient = new OAuthSignpostClient(OAUTH_KEY, OAUTH_SECRET,
                    token, tokenSecret);
            twitter = new Twitter(TWITTER_USER, oauthClient);
        }
    }

    /*
     * Callback once we are done with the authorization of this app with
     * Twitter.
     */
    @Override
    public void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.d(TAG, "intent: " + intent);

        // Check if this is a callback from OAuth
        Uri uri = intent.getData();
        if (uri != null && uri.getScheme().equals(OAUTH_CALLBACK_SCHEME)) {
            Log.d(TAG, "callback: " + uri.getPath());

            String verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);
            Log.d(TAG, "verifier: " + verifier);

            new RetrieveAccessTokenTask().execute(verifier);
        }

    }

    public void onClickAuthorize(View view) {
        new OAuthAuthorizeTask().execute();
    }

    public void onClickTweet(View view) {
        if (twitter == null) {
            Toast.makeText(this, "Authenticate first", Toast.LENGTH_LONG)
                    .show();
            return;
        }

        EditText status = (EditText) findViewById(R.id.status);
        new PostStatusTask().execute(status.getText().toString());
    }

    public void onClickGetStatus(View view) {
        if (twitter == null) {
            Toast.makeText(this, "Authenticate first", Toast.LENGTH_LONG)
                    .show();
            return;
        }
        new GetStatusTask().execute();
    }

    /* Responsible for starting the Twitter authorization */
    class OAuthAuthorizeTask extends AsyncTask<Void, Void, String> {

        @Override
        protected String doInBackground(Void... params) {
            String authUrl;
            String message = null;
            try {
                authUrl = mProvider.retrieveRequestToken(mConsumer,
                        OAUTH_CALLBACK_URL);
                Intent intent = new Intent(Intent.ACTION_VIEW,
                        Uri.parse(authUrl));
                startActivity(intent);
            } catch (OAuthMessageSignerException e) {
                message = "OAuthMessageSignerException";
                e.printStackTrace();
            } catch (OAuthNotAuthorizedException e) {
                message = "OAuthNotAuthorizedException";
                e.printStackTrace();
            } catch (OAuthExpectationFailedException e) {
                message = "OAuthExpectationFailedException";
                e.printStackTrace();
            } catch (OAuthCommunicationException e) {
                message = "OAuthCommunicationException";
                e.printStackTrace();
            }
            return message;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            if (result != null) {
                Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG)
                        .show();
            }
        }
    }

    /* Responsible for retrieving access tokens from twitter */
    class RetrieveAccessTokenTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {
            String message = null;
            String verifier = params[0];
            try {
                // Get the token
                Log.d(TAG, "mConsumer: " + mConsumer);
                Log.d(TAG, "mProvider: " + mProvider);
                mProvider.retrieveAccessToken(mConsumer, verifier);
                String token = mConsumer.getToken();
                String tokenSecret = mConsumer.getTokenSecret();
                mConsumer.setTokenWithSecret(token, tokenSecret);

                Log.d(TAG, String.format(
                        "verifier: %s, token: %s, tokenSecret: %s", verifier,
                        token, tokenSecret));

                // Store token in prefs
                prefs.edit().putString("token", token)
                        .putString("tokenSecret", tokenSecret).commit();

                // Make a Twitter object
                oauthClient = new OAuthSignpostClient(OAUTH_KEY, OAUTH_SECRET,
                        token, tokenSecret);

                /* "NameTest" (any word) */
                twitter = new Twitter("NameTest", oauthClient);

                Log.d(TAG, "token: " + token);
            } catch (OAuthMessageSignerException e) {
                message = "OAuthMessageSignerException";
                e.printStackTrace();
            } catch (OAuthNotAuthorizedException e) {
                message = "OAuthNotAuthorizedException";
                e.printStackTrace();
            } catch (OAuthExpectationFailedException e) {
                message = "OAuthExpectationFailedException";
                e.printStackTrace();
            } catch (OAuthCommunicationException e) {
                message = "OAuthCommunicationException";
                e.printStackTrace();
            }
            return message;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            if (result != null) {
                Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG)
                        .show();
            }
        }
    }

    /* Responsible for getting Twitter status */
    class GetStatusTask extends AsyncTask<Void, Void, String> {
        @Override
        protected String doInBackground(Void... params) {
            return twitter.getStatus().text;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();
        }
    }

    /* Responsible for posting new status to Twitter */
    class PostStatusTask extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... params) {
            try {
                twitter.setStatus(params[0]);
                return "Successfully posted: " + params[0];
            } catch (TwitterException e) {
                return "Error connecting to server.";
            }
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();
        }

    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.marakana.oauth"
  android:versionCode="1"
  android:versionName="1.0">
  <uses-sdk
    android:minSdkVersion="11" />
  <uses-permission
    android:name="android.permission.INTERNET" />

  <application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name">
    <activity
      android:name=".MainActivity"
      android:label="@string/app_name"
      android:launchMode="singleInstance">
      <intent-filter>
        <action
          android:name="android.intent.action.MAIN" />
        <category
          android:name="android.intent.category.LAUNCHER" />
      </intent-filter>

      <!-- Used for OAuth callback -->
      <intent-filter>
        <action
          android:name="android.intent.action.VIEW" />
        <category
          android:name="android.intent.category.DEFAULT" />
        <category
          android:name="android.intent.category.BROWSABLE" />
        <data
          android:scheme="x-marakana-oauth-twitter"
          android:host="callback" />
      </intent-filter>

    </activity>

  </application>
</manifest>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:gravity="center_horizontal">

  <TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/app_name"
    android:textSize="50sp"
    android:gravity="center" />
  <Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Authenticate"
    android:onClick="onClickAuthorize"
    android:textSize="40sp"></Button>
  <EditText
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:id="@+id/status"
    android:textSize="40sp"
    android:hint="What's up?"></EditText>
  <Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Tweet"
    android:onClick="onClickTweet"
    android:textSize="40sp"></Button>
  <Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Get Status"
    android:textSize="40sp"
    android:onClick="onClickGetStatus"></Button>

</LinearLayout>
于 2013-09-30T00:06:57.647 回答
0

看看http://www.winterwell.com/software/jtwitter.php

代码示例的第一部分:获得授权

于 2013-09-26T16:01:43.220 回答