我正在尝试使用FourSquare api创建Android应用程序。我使用了EasyFoursquare4Android Library,但是当我尝试使用它时出现错误。
以下是此错误的完整logcat跟踪。
952-7520/com.example.mikhail.testfsq W/dalvikvm﹕ threadid=26: thread exiting with uncaught exception (group=0x40018578)
03-25 23:20:57.609 6952-7520/com.example.mikhail.testfsq E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:200)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
at java.lang.Thread.run(Thread.java:1019)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:121)
at android.widget.Toast.<init>(Toast.java:69)
at android.widget.Toast.makeText(Toast.java:232)
at com.example.mikhail.testfsq.MyActivity.onError(MyActivity.java:50)
at com.example.mikhail.testfsq.tasks.AccessTokenRequest.doInBackground(AccessTokenRequest.java:74)
at com.example.mikhail.testfsq.tasks.AccessTokenRequest.doInBackground(AccessTokenRequest.java:22)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
at java.lang.Thread.run(Thread.java:1019)
03-25 23:21:04.890 6952-6952/com.example.mikhail.testfsq E/WindowManager﹕ Activity com.example.mikhail.testfsq.MyActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@405b6110 that was originally added here
android.view.WindowLeaked: Activity com.example.mikhail.testfsq.MyActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@405b6110 that was originally added here
at android.view.ViewRoot.<init>(ViewRoot.java:263)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:171)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:114)
at android.view.Window$LocalWindowManager.addView(Window.java:424)
at android.app.Dialog.show(Dialog.java:241)
at com.example.mikhail.testfsq.tasks.AccessTokenRequest.onPreExecute(AccessTokenRequest.java:38)
at android.os.AsyncTask.execute(AsyncTask.java:391)
at com.example.mikhail.testfsq.FoursquareDialog$FoursquareWebViewClient.shouldOverrideUrlLoading(FoursquareDialog.java:131)
at android.webkit.CallbackProxy.uiOverrideUrlLoading(CallbackProxy.java:218)
at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:337)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
at dalvik.system.NativeStart.main(Native Method)
这是代码
public class AccessTokenRequest extends AsyncTask<String, Integer, String> {
private Activity mActivity;
private ProgressDialog mProgress;
private AccessTokenRequestListener mListener;
public AccessTokenRequest(Activity activity, AccessTokenRequestListener listener) {
mActivity = activity;
mListener = listener;
}
@Override
protected void onPreExecute() {
mProgress = new ProgressDialog(mActivity);
mProgress.setCancelable(false);
mProgress.setMessage("Getting access token ...");
mProgress.show();
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
String code = params[0];
String token = "";
// Check if there is a parameter called "code"
if (code != null) {
try {
// Call Foursquare again to get the access token
JSONObject tokenJson = executeHttpGet("https://foursquare.com/oauth2/access_token"
+ "?client_id="
+ FoursquareConstants.CLIENT_ID
+ "&client_secret="
+ FoursquareConstants.CLIENT_SECRET
+ "&grant_type=authorization_code"
+ "&redirect_uri="
+ FoursquareConstants.CALLBACK_URL
+ "&code="
+ code);
token = tokenJson.getString("access_token");
//saving token
Log.i("Access Token", token);
SharedPreferences settings = mActivity.getSharedPreferences(FoursquareConstants.SHARED_PREF_FILE, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString(FoursquareConstants.ACCESS_TOKEN, token);
// Commit the edits!
editor.commit();
} catch (Exception exp) {
Log.e("LoginTest", "Getting Access token failed", exp);
mListener.onError(exp.toString());
}
} else {
Toast.makeText(mActivity, "Unknown login error", Toast.LENGTH_SHORT)
.show();
mListener.onError("Unknown login error");
}
return token;
}
@Override
protected void onPostExecute(String access_token) {
mProgress.dismiss();
mListener.onAccessGrant(access_token);
super.onPostExecute(access_token);
}
// Calls a URI and returns the answer as a JSON object
private JSONObject executeHttpGet(String uri) throws Exception {
HttpGet req = new HttpGet(uri);
HttpClient client = new DefaultHttpClient();
HttpResponse resLogin = client.execute(req);
BufferedReader r = new BufferedReader(new InputStreamReader(resLogin
.getEntity().getContent()));
StringBuilder sb = new StringBuilder();
String s = null;
while ((s = r.readLine()) != null) {
sb.append(s);
}
return new JSONObject(sb.toString());
}
}
public class MyActivity extends Activity implements
AccessTokenRequestListener, ImageRequestListener {
private com.example.mikhail.testfsq.EasyFoursquareAsync async;
private ImageView userImage;
private ViewSwitcher viewSwitcher;
private TextView userName;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
userImage = (ImageView) findViewById(R.id.imageView1);
viewSwitcher = (ViewSwitcher) findViewById(R.id.viewSwitcher1);
userName = (TextView) findViewById(R.id.textView1);
//ask for access
async = new EasyFoursquareAsync(this);
async.requestAccess(this);
}
@Override
public void onError(String errorMsg) {
// Do something with the error message
Toast.makeText(this, errorMsg, Toast.LENGTH_LONG).show();
}
@Override
public void onAccessGrant(String accessToken) {
// with the access token you can perform any request to foursquare.
// example:
async.getUserInfo(new UserInfoRequestListener() {
@Override
public void onError(String errorMsg) {
// Some error getting user info
Toast.makeText(MyActivity.this, errorMsg, Toast.LENGTH_LONG)
.show();
}
@Override
public void onUserInfoFetched(User user) {
// OWww. did i already got user!?
if (user.getBitmapPhoto() == null) {
UserImageRequest request = new UserImageRequest(
MyActivity.this, MyActivity.this);
request.execute(user.getPhoto());
} else {
userImage.setImageBitmap(user.getBitmapPhoto());
}
userName.setText(user.getFirstName() + " " + user.getLastName());
viewSwitcher.showNext();
Toast.makeText(MyActivity.this, "Got it!", Toast.LENGTH_LONG)
.show();
}
});
//for another examples uncomment lines below:
//requestTipsNearby();
checkin();
}
@Override
public void onImageFetched(Bitmap bmp) {
userImage.setImageBitmap(bmp);
}
private void requestTipsNearby() {
Location loc = new Location("");
loc.setLatitude(40.4363483);
loc.setLongitude(-3.6815703);
TipsCriteria criteria = new TipsCriteria();
criteria.setLocation(loc);
async.getTipsNearby(new TipsRequestListener() {
@Override
public void onError(String errorMsg) {
Toast.makeText(MyActivity.this, "error", Toast.LENGTH_LONG).show();
}
@Override
public void onTipsFetched(ArrayList<Tip> tips) {
Toast.makeText(MyActivity.this, tips.toString(), Toast.LENGTH_LONG).show();
}
}, criteria);
}
private void checkin() {
CheckInCriteria criteria = new CheckInCriteria();
criteria.setBroadcast(CheckInCriteria.BroadCastType.PUBLIC);
criteria.setVenueId("4c7063da9c6d6dcb9798d27a");
async.checkIn(new CheckInListener() {
@Override
public void onCheckInDone(Checkin checkin) {
Toast.makeText(MyActivity.this, checkin.getId(), Toast.LENGTH_LONG).show();
}
@Override
public void onError(String errorMsg) {
Toast.makeText(MyActivity.this, "error", Toast.LENGTH_LONG).show();
}
}, criteria);
}