Background Firebase Push Notification data handling - android

I am a web developer and am trying to develop an application that basically is a Webview that can receive instructions through push requests to redirect the user to specific pages. It is already functional, I just need to correct an issue:
I have tried to make a function in the class that receives and processes the push information that updates the contents of the Webview. But there is some conflict and it is impossible to do so, because one class is static and the other not due to their inheritance.
The way I found around this was creating an string variable inside my "watch messages class" started with "EMPTY" value that receives the value sent in a specific field within the push request 'date' when the notification is clicked. There's my public class FireBaseWatchMessages that extends FirebaseMessagingService:
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d("LOG_ONRECEIVE_1", "From: " + remoteMessage.getFrom());
if (remoteMessage.getData().size() > 0) {
Log.d("LOG_VALID_DATA", "Message data payload: " + remoteMessage.getData());
}
if (remoteMessage.getNotification() != null) {
Log.d("LOG_NULL_NOTIFICATION", "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
Map<String, String> data = remoteMessage.getData();
sendNotification(remoteMessage);
if (data.containsKey("appReportedAction")) {
Log.d("SET_ACTION", "/appReportedAction/" + data.get("appReportedAction"));
NEW_URL_FROM_ACTION = MainActivity.SSLPROTOCOL + "://" + MainActivity.MAIN_URL +"/appReportedAction/" + data.get("appReportedAction");
}
}
In my MainActivity there's a function to change webview content. It works like this:
public void changeViewContent(String actionView){
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.activity_main_webview);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
if(FireBaseWatchMessages.NEW_URL_FROM_ACTION != "EMPTY"){
mWebView.loadUrl(FireBaseWatchMessages.NEW_URL_FROM_ACTION);
} else {
mWebView.loadUrl( SSLPROTOCOL + "://" + MAIN_URL + actionView);
}
mWebView.setWebViewClient(new HelloWebViewClient());
}
So when the application opens it checks if this variable has a value other than "EMPTY", if so Webview opens the modified URL according to its value, not the default URL.
It happens that when the application is closed when clicking on the message sent by the push the URL doesn't open with the appropriate modifications, as if the variable was not really receiving the value sent by the push.
Using the app debugger I noticed that its log commands do not appear on the console when it is not open, which makes me believe that the function does not really run when the application is closed.
Any idea how I can correct this behavior? How can I make the action of clicking the notification send the parameter to the webview?

I want to first say that your approach is uncommon and I do not recommend storing url in such a manner, since services can be killed/stopped (by user or device) and so you lose your data or the device was turned off so you lose your data. So instead of using variables I have made two methods using Shared Preferences its easy and the storage is permanent in the device even when your app is not in use!
HERE HOW:
The first method is:
public boolean addNewUrl(Context context, String url) {
SharedPreferences sharedPref = context.getSharedPreferences("SHARED URL", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("url", url);
return editor.commit();
}
Define the first method in the FireBaseWatchMessages and it stores the URL and returns true if successfully stored.
And the second is:
public String getUrlAndSetEmpty(Context context) {
SharedPreferences sharedPref = context.getSharedPreferences("SHARED URL", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
String current_url = sharedPref.getString("url", "EMPTY");
editor.putString("url", "EMPTY");
editor.apply();
return current_url;
}
Define this in the MainActivity to get Url returned and also sets the url to "EMPTY" after its takes it!
The first method will be called from the Service FireBaseWatchMessages. This will accept context which for our case it is this or FireBaseWatchMessages.this and it will also accept a URL in form of a string so change your URL into a String. It will then store it in your app internal storage as url!
So just call:
addNewUrl(this,your_url_string);
The second method will be called in the MainActivity or any activity that you want it to work. So define it in the MainActivity. What it does it check if there is a url stored in the storage if it doesn't find any it returns String "EMPTY" and if it finds it it returns it as a current url and also change the value of the stored String to empty because it has already got one. So just call:
String url= getUrlAndSetEmpty(this);
And cheers the url returned can be a really URL STRING OR just a String "EMPTY". Handle the Logic.
This is the best APPROACH for your case! It works any time! It does not depend if the app is visible on foreground or not!
Check your code if you handled the intent correctly on Activity creation!
But also in java when we compare Objects( String included) we use the (Object1.equals(Object2)) instead of (=) sign. So change the line where you called:
if(FireBaseWatchMessages.NEW_URL_FROM_ACTION != "EMPTY")
Change to:
if(!((FireBaseWatchMessages.NEW_URL_FROM_ACTION).equals("EMPTY")))
Do not forget the ! sign there in the condition!
If that doesn't work check the Intent you used to start the Activity.

Related

Android twitter callback URL error

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/

Autologin google, redirection webview not working

In Android i have a webview that lead to an google authentication form. When the authentication form is loaded in the webview it will call onReceivedLoginRequest:
public void onReceivedLoginRequest(final AuthenticationWebView client, final WebView view, final String realm,
final String account, final String args) {
...
}
When this method is called i get the Accounts stored on the device and let the user choose one and use that one to retrieve an authtoken:
mAccountManager.getAuthToken(account, mAuthToken, null, mWebViewActivity, this, null);
It all works perfectly fine (i think) and the next step looks good also:
final String result = bundle.getResult().getString(AccountManager.KEY_AUTHTOKEN);
if (result != null) {
// authentication succeeded, new url given as result for redirection
mWebView.loadUrl(result);
} else {
onLoginFailed();
}
A new method is called and returns the new url for redirection which i load in the webview. The result String returns a new adress which looks good but does nothing, it doens't log in but i don't get any message error either from the webview.
Url:
https://accounts.google.com/MergeSession?args=..&uberauth=WILL_NOT_SIGN_IN&source=AndroidWebLogin
I modified the url a bit with (triple)dots, don't know how secure it is and it was not such an interesting part of the url.
Anyone know why the url will not redirect me to the website behind it? When i use this url in my browser it recognizes my account, i only have to fill in my password and it redirects me correctly.
I use a native Android webview and i inject it with javascript but this only happens on the page after the login.
The settings i added to the webview are:
mSettings = getSettings();
mSettings.setJavaScriptEnabled(true);
mSettings.setDomStorageEnabled(true);
mSettings.setAllowFileAccess(true);
mSettings.setGeolocationEnabled(true);

Resubmit a Form when connection is lost in Android

I am trying to implement an app, that uses WebView to show a website which has a form inside. The problem is, when user fills the form and just before the Send button is pressed, the internet connection is lost. In this case, I receive onErrorReceived callback, and here is my implementation:
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
mDisconnected = true;
mDisconnectUrl = failingUrl;
mWebView = view;
mWebView.saveState(mWebViewState);
}
So I try to store the content of the form here and the failing url, so I can continue sending it when the connection established again. So I have another thread trying to make a new Socket connection with the server, and when it succeeds, I call a function in my WebViewClient class reconnect():
void reconnect(Context appContext) {
if (mDisconnected) {
try {
((Activity) appContext).runOnUiThread(new Runnable() {
public void run() {
mWebView.reload();
mWebView.restoreState(mWebViewState);
}
});
} catch (Exception e) {
mWebView.goBack();
}
mDisconnected = false;
}
}
So I try to make a reload and restore the form data so the WebView can continue with its send operation. The problem is when the page is again loaded, all the data entered in the form are lost and it does not continue with the Send operation, which was already clicked before the connection is lost. Has any one any idea, how to solve this problem.
The data is very sensitive, so it is important to continue with sending. It is also possible to let the user fill the form again and send it again, but it is not wanted in this scenario.
EDIT:
Maybe the question can be simplified. Is there any function or way to refresh a website in WebViewClient, which continues where it was left of and retrieves the form data into the state before the problem was occured.
Use database to store the contents of form and then send the data through service.
Delete the contents of database upon successfull submission.

How to establish communication between webview and html page in worklight?

I'm working on making a browser as a hybrid app using worklight framework for Android. I implemented my address bar as an input element which received the user input and pass the arguments to the webview to load the page.
However, I cannot figure out how to do the reverse: whenever the user click on a link in webview, I want the address bar to change to the new location.
Are you implementing a native page that is opened? If so, take a look at ChildBrowser, that basically does the same thing. It has a TextView being used as an address bar. You may decide to use it, or get the bits and pieces you want out of it. Regardless, I would image what you want to do something like this. By overriding the onLoadResource in the WebViewClient, you should be able to grab the url and change your TextBox.
In response to the comment below: inside your environment's main js file in the wlEnvInit() function:
function wlEnvInit(){
wlCommonInit();
// Environment initialization code goes here
document.onclick=manageLinks;
}
Then in this function get the url and set the text of your input element:
function manageLinks(event) {
var link = event.target;
//go up the family tree until we find the A tag
while (link && link.tagName != 'A') {
link = link.parentNode;
}
if (link) {
var url = link.href;
console.log("url = " + url);
//You can decide if you want to separate external or
//internal links, depending on your application
var linkIsExternal = ((url.indexOf('http://') == 0) || (url.indexOf('https://') == 0));
if (linkIsExternal) {
myInput.setText(url);
return false;
}
}
return true;
}
Inside of your WebView, inside the plugin, intercept the URL like this:
webview.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
//use this area to set your input. Depending on how you
//implemented your plugin, you may need to return this value
//back to your main activity
Toast.makeText(cordova.getActivity(), "Loading: " + url, Toast.LENGTH_LONG).show();
}
});
Have you try to get the url from the href of and assign to the input variable and do the get/post? I know that it is possible in SDK i figure it dont will be harder in a framework. You can store the hiperlinks in a array with a parser or something similar.
example pseudocode:
When_hiperlink_clicked: //could be like a listener (search about it)
url = hiperlink.getURL("myHiperlink");
myinput.setText(url);
execute_input_bar_action();
Is difficult to figure out without code or something more, sorry.

Android Jtwitter, authentication issues

Hello I am having difficulty using the JTwitter functions to authenticate with my twitter application. I always get a "TwitterException"
Here is my method
OAuthSignpostClient oauthClient = new OAuthSignpostClient(consumerKey,
privateKey, "oob");
a) I don't know what the "oob" value SHOULD be, it is the "callbackURL" and in my application on twitter it says "callBack URL: none" so I have tried putting "none", "None", and null where "oob" with no differing results.
then the rest is boilerplate
Intent i = new Intent(Intent.ACTION_VIEW,
Uri.parse(oauthClient.authorizeUrl().toString()));
startActivity(i);
// get the pin
String v = oauthClient.askUser("Please enter the verification PIN from Twitter");
oauthClient.setAuthorizationCode(v);
// Store the authorisation token details for future use
String[] accessToken = oauthClient.getAccessToken();
// Next time we can use new OAuthSignpostClient(OAUTH_KEY, OAUTH_SECRET,
// accessToken[0], accessToken[1]) to avoid authenticating again.
EditText twitterText = (EditText)findViewById(R.id.twitterText);
twitterText.getText();
// Make a Twitter object
Twitter twitter = new Twitter(null, oauthClient);
// Print Daniel Winterstein's status
//System.out.println(twitter.getStatus("winterstein"));
// Set my status
twitter.setStatus(twitterText.getText());
at this point, I'm simply not sure on how to make this work. Wish I could be more verbose about it, but it has something to do with the authentication. Online things I've seen haven't been helpful
Try this as your callback url:
OAuthSignpostClient oauthClient =
new OAuthSignpostClient(consumerKey, privateKey, "callback://twitter");
Remember! After:
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));
Do the following
override onResume() to get the verification code
protected void onResume() {
super.onResume();
if (this.getIntent()!=null && this.getIntent().getData()!=null){
Uri uri = this.getIntent().getData();
if (uri != null && uri.toString().startsWith("callback://twitter")) {
//Do whatever you want
//usually use uri.getQueryParameter(someString);
//test what could be someString using Log.v("",uri.toString());
//you want the Authorization code which is a couple of numbers
//so you could use oauthClient.setAuthorizationCode(v);
//and finally initialise Twitter
}
}
}
You can use uri.getQueryParameterNames() to get the parameter String names.
#BobVork
I'd just like to add that you'll need to have a callback URL set in the Settings tab for your Twitter app (on twitter.com).
It doesn't even matter what you put in the field, but if it's empty, callback urls will not work.
I'm not sure that's the problem, but it seems like you never set the user name for the twitter object.
Well, I don't know how it is with the Jtwitter API and I don't know enough Java at this point to really understand the inner workings of this code, but have you tried, instead of NULL or None, to try ? instead. That is the callback used with the restful API when making calls from Javascript. Try it out.

Categories

Resources