I am working on Android app in which I need to post text message on twitter.
Its very easy task and I did that earlier in one shot perfectly but now I am getting a unknown stoppage. Application hang on at "Authenticating please wait" dialog.
While debugging I got to know that in OAuthRequestTokenTask activity during doInBackground(Void... params) method the URL becomes null and I get exception.
Please suggest me, whats going on, in my code?????
EDITED: I am getting null in OAuthRequestTokenTask Class in the below method:
#Override
protected Void doInBackground(Void... params) {
try {
**final String url = provider.retrieveRequestToken(consumer, Constants.OAUTH_CALLBACK_URL);**
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_FROM_BACKGROUND);
context.startActivity(intent);
} catch (Exception e) {
System.out.println(e+ "========");
}
return null;
}
I got the success in the above task.
The mistake which I was doing was, not providing the call back URL for application on my Twitter account.
:)
Related
I've been developing hybrid apps for many companies with mobile websites.
And as a matter of fact, there are some websites made with using jsp.
I already had the knowledge that iframes and javascripts xhr requests will not fire webViewClient's shouldOverrideUrlLoading override function. I'm fine with that.
But today I learned that SOME actions such as:
JSP Page Redirects
Link Clicks within a JSP page
JSP/JS induced URL Loads
will not ALWAYS fire this function.
Hence, shouldOverrideUrlLoading() does not fire, when the webView is asked to load a page that it cannot load(i.e. "intent://...",) it shows an error page.
Has anyone encountered this kind of behaviour and is there any solution to work around it ?
Below is the code I'm using to invoke activities, where urls with 'intent:' protocol (which will fail because this function never gets called when above actions are performed)
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// ... omitted ...
if ( url.startsWith("intent:") ) {
Intent intent = null;
try {
intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
// The following flags launch the app outside the current app
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
try {
getActivity().startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
return true;
}
}
ps. please notice that every other websites' page loads will perfectly call shouldOverrideUrlLoading().
I couldn't find any JSP related bugs on android webViews so I'm asking one.
ps. I am happily willing to provide sample websites that some gracious readers will try on.. but the website's written in Korean so I doubt it will help.
Thank you!
Your problem might not related to JSP, the real problem may be shouldOverrideUrlLoading() itself. In this case, using shouldOverrideUrlLoading() may not be a good idea, so why not try another perspective?
I've encountered many problems when using
shouldOverrideUrlLoading() loading XmlHttpRequest. At the end, I
came up with the idea using onProgressChanged() and it solved all
my problems. I've written a similar answer here.
I tried adding your code into my own webview project and tested it with some JSP sites, and looks like it always work. I also added loadUrl() after other activities are invoked, so after pressing the back button, the loading error page will not be displayed again. So try this one :
First declare a global variable to store last URL.
String strLastUrl = null;
Then override onProgressChanged(WebView view, int progress)
mWebView.setWebChromeClient(new MyWebChromeClient(){
#Override
public void onProgressChanged(WebView view, int progress) {
if (progress == 100) {
//A fully loaded url will come here
String StrNewUrl = view.getUrl();
if(TextUtils.equals(StrNewUrl,strLastUrl)){
//same page was reloaded, not doing anything
}else{
String strOldUrl = null;
//save old url to variable strOldUrl before overwriting it
strOldURL = strLastUrl;
//a new page was loaded,overwrite this new url to variable
strLastUrl = StrNewUrl;
if ( strLastUrl.startsWith("intent:") ) {
Log.d("TAG", "intent triggered");
Intent intent = null;
try {
intent = Intent.parseUri(strLastUrl, Intent.URI_INTENT_SCHEME);
// The following flags launch the app outside the current app
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
//reload the page before invoking other activities
view.loadUrl(strOldURL);
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}
}
super.onProgressChanged(view, progress);
}
});
When I try to open a Facebook Profile through the official Facebook App i have this error: error loading the biography, the content is not available.
I tried with many codes but nothing. Only if Facebook App is not installed on the device work right with the browser.
Here is the current code:
try
{
Intent followIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("fb://profile/"+id_facebook));
startActivity(followIntent);
final Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run() {
Intent followIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("fb://profile/"+id_facebook));
startActivity(followIntent);
}
}, 1000 * 2);
}
catch (Exception e)
{
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.facebook.com/"+id_facebook)));
String errorMessage = (e.getMessage()==null)?"Message is empty":e.getMessage();
Log.e("Unlock_ScreenActivity:FacebookAppNotFound" ,errorMessage);
}
UPDATE:
When I give up and i only put the https URI, Android let me choose between Facebook APP and the browser, and i like it! So my question is answered =D
I ran into a similar problem back in the day and found out that when I tried to use the same method as you it only worked if I wanted to view my own profile (or the current logged in user in the Facebook app) but whenever I tried to show someone else's facebook page so I eventually came across this answer:
https://stackoverflow.com/a/24547437/1879664
Long story short, it's no longer possible and the only workaround so far is to make facebook load the web page inside facebook just like you've mentioned but the difference is that without forcing it, if the user can't choose between apps or has already selected another browser as a default app you can no longer open that page through facebook. With this code you can ensure that it will always open that page with the facebook app if it's installed or it would load with your default browser. Here's the code that I use in my apps:
try {
mActivity.getPackageManager().getPackageInfo("com.facebook.katana", 0);
String url = "https://www.facebook.com/profile.php?id=USER_ID"
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("fb://facewebmodal/f?href="+url));
}
mActivity.startActivity(intent);
} catch (Exception e) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.facebook.com/profile.php?id=USER_ID"));
mActivity.startActivity(intent);
e.printStackTrace();
}
Okay so I am creating a twitter clone, the only problem I am having right now is that the callback URL is getting me back to the app but instead giving me a page not found error.
I saw some similar questions here in stackoverflow and followed the steps.
I am getting the Authentication URL using the code:
public String beginAuthorization(){
try{
if(null==currentRequestToken){
currentRequestToken = twitter.getOAuthRequestToken(TWITTER_CALLBACK_URL);
}
return currentRequestToken.getAuthenticationURL();
}catch (TwitterException te){
te.printStackTrace();
}
return null; }
Next I am retrieving the Access Token using the code:
public void setAccessToken(Uri uri) {
if (uri != null && uri.toString().startsWith(TWITTER_CALLBACK_URL)) {
String verifier = uri.getQueryParameter("oauth_token");
try {
AccessToken accessToken = twitter.getOAuthAccessToken(app.currentRequestToken, verifier);
//shared prefs
SharedPreferences.Editor e = yambaSharedPrefs.edit();
e.putString(PREF_KEY_OAUTH_TOKEN, accessToken.getToken());
e.putString(PREF_KEY_OAUTH_SECRET, accessToken.getTokenSecret());
//store log in status
e.putBoolean(PrefSharedTwitterLoggedIn, true);
e.apply();
Intent intent = new Intent(this, StatusActivity.class);
startActivity(intent);
} catch (TwitterException e) {
e.printStackTrace();
}
} }
My Callback URL looks like this:
public static final String OAUTH_CALLBACK_SCHEME = "twitter4j-MiYAMBA";public static final String OAUTH_CALLBACK_HOST = "callback";public static final String TWITTER_CALLBACK_URL = OAUTH_CALLBACK_SCHEME + "://" + OAUTH_CALLBACK_HOST;
I have also added the callback URL in the intent filter, like:
data android:host="callback" android:scheme="twitter4j-MiYAMBA"
Now I am not sure where the problem might be.
Also here is how the control flows through out the app:
StatusActivity is launched when the app is run, it checks if AccessToken are set or not using a function isAuthorised() which is defined in an Android application class named YAMBAapp, if it is defined then it begins the setup of layout, that is making buttons and stuff visible else it passes the control to a function beginAuthorization(), which starts an Activity named AuthorizationActivity, which gets the Authentication URL and passes it to the WebView, all of this is done in the function onResume, in this function I call another function setAccessToken and pass the 'uri' that has has data using:
uri = getIntent().getData();
setAccessToken(uri);
I have pasted the code for setAccessToken above.
Also in the manifest I have defined the "data" item in the intent filter of "AuthorizationActivity" and not the "StatusActivity", though it has no effect what so ever.
Please help, I really am stuck for few days now :)
First thing first, when you launch twitter authentication using default web browser, you will never return back to your main application, once access tokens are received and hence page not found, as url being invalid.
What you need is to load authenticaton using a web view through your own app, now you can override few functioanlities here like when being redirected. here you need to do final processing and terminate web view, which will result into control coming back to your own application rather then seeing page not found in browser.
Example: Here is how you oveerride an webview mechanism, now you create an actvity with theme like dialog or whatever, and load this webview in it with twitter auth url, once user authtenticate himself shouldOverrideUrlLoading will be called, here you retrive back verifier and quit..
webView.setWebViewClient( new WebViewClient()
{
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
// your url pattern here
if( url.contains("callback://twitter4j-MiYAMBA"))
{
Uri uri = Uri.parse( url );
// you get the verifier here
String oauthVerifier = uri.getQueryParameter( "oauth_verifier" );
// Do whateever u want here
..oauthVerifier.
//
// Finish this task, so you return back to activity from where it started
finish();
return true;
}
return false;
}
});
I guess this would be enough to finish rest of implementation. more info here '
http://daiwei.lu/2014/01/22/twitter-oauth-flow-on-android/
I am a newbie to Android App Development. My android app shows "Unfortunately, AppTest has stopped." when I try to connect to Internet with Jsoup with the following code.
I have already added Internet permission to AndroidManifest.xml.
Jsoup is working correctly when I test with just offline html such as <p>Nay</p>.
My Android phone is completely available Internet Connection. What is wrong?
Document doc;
try {
// need http protocol
doc = Jsoup.connect("http://google.com").get();
// get page title
String title = doc.title();
psi.setText(title);
} catch (IOException e) {
e.printStackTrace();
}
Thanks to all, but the answers and suggestions could not help me very much. After doing a lot of mistakes, I have found the solution. I would like to post my answer to help other people when meet this problem.
Jsoup seems to run in another thread than UI thread. Therefore, you just need to create another thread with AsyncTask to use Jsoup like the following.
class GetHtmlwithJsoup extends AsyncTask<String, Integer, String>
protected String doInBackground(String... param) {
try {
//Jsoup Connecting and Getting html page code at here
}
catch (TwitterException e) {
return "Failed to get";
}
}
#Override
protected void onProgressUpdate(Integer... values) { //
super.onProgressUpdate(values);
// Not used in my case
}
#Override
protected void onPostExecute(String result) { //
//show Jsoup HTML Ouput to UI widgets code at here...
}
}
If you use doc outside this block, you must check if it was properly initialized.
Other guess, does your app request the INTERNET permission?
I've made an app that sends a request to a webserver in a specified interval and gets XML data. It then parses the XML data, gets information from the phone (text messages, contacts or something similar) and shoots it back to the server with a http post request.
The problem is that it usually takes a few seconds for the app to get the info, which often leaves the app crashing. A dialog comes up saying the app has become unresponsive and asks if i want to close the app or wait, if i press wait it eventually starts working again.
Is AsyncTask the right solution to this problem?
Another thing i don't really understand is how AsyncTask actually works. Let's say i have two methods that do a lot of work and crashes the app, can i put both of them in one AsyncTask and just call them from doInBackground()?
I have also implemented something similar you are trying. That is sending request to server, receive XML response, parse XML, show result. View This. I have used AsyncTask for this.
Here is how i have implemented it using AsynTask
private class AsyncClass extends AsyncTask<Void, Void, Bundle>{
#Override
protected Bundle doInBackground(Void... arg0) {
Bundle b=startProcess();
// startBundle() method do all the processing and return result in a bundle. You can as many methods from within startBundle() method
return b;
}
#Override
protected void onPostExecute(Bundle result) {
Log.d(TAG , "In onPostExecute");
dialog.dismiss();
if(result==null)
Toast.makeText(cont, "Can't process query.\nTry again later.", Toast.LENGTH_LONG).show();
else{
Intent in = new Intent(cont, QueryResultDisplay.class);
Log.d(TAG , "Displaying");
in.putExtras(result);
cont.startActivity(in);
}
}
I give you brief description about your problem.
There are many possibility that you don't get data from server
if your network speed is very slow and you try to get all the
information from server and XML data then in this case if network crash then it show you error
if you're making request to that page which is not in server
Now, if you are facing the problem in code, then I give you the complete code of AsyncTask class which I had implemented in my project and it work fine.
private class GetLoginResponse extends AsyncTask<Void, Void, Boolean> {
private ProgressDialog progressDialog;
private String email;
private String password;
public GetLoginResponse(String emailId, String paswd) {
this.email = emailId;
this.password = paswd;
}
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(LoginActivity.this, "",
"Loading....", true, false);
}
#Override
protected Boolean doInBackground(Void... params) {
try {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpclient.execute(httpGet);
//here u can check the reponse is ok and 200
} catch (NetworkException e) {
isNetworkError = true;
}
return false;
}
#Override
protected void onPostExecute(Boolean data) {
progressDialog.dismiss();
System.out.println("lOGIN RESPONSE for email = " + email + data);
}
}// end AsyncTask
This would solve your problem.
Yes, you can use AsyncTask.
The code called in doInBackground() must not touch the UI.
You can touch the UI thread with publishProgress().