In my application I used Socket.io and I want when receive listener from socket I should update UI.
I write below codes, but not update my UI!
For test this i write Log.e when receive socket listener, show this Log, but not update UI!
My Codes:
#Override
public void onSocketUpdateBid(final JSONObject ob) {
Log.e("updateBidCount", "Receive");
super.onSocketUpdateBid(ob);
final int auction_id;
final String remainClick;
final JSONObject data = ob;
try {
UpdateBidResponse updateBidResponse = new Gson().fromJson(data.toString(), UpdateBidResponse.class);
auction_id = updateBidResponse.getAuction_id();
remainClick = updateBidResponse.getRemain_click();
Constants.currentActivity.runOnUiThread(() -> {
if (detail.getId() != null) {
Log.e("RemainClickLog", "" + remainClick);
if (detail.getId().equals(auction_id)) {
if (Integer.parseInt(remainClick) > 0) {
Log.e("updateBidLog", "RemainClick : " + remainClick);
auctionDetail_miniBottomBidTxt.setText(remainClick);
auctionDetail_footerPlusBidBtn.setAlpha(1.0f);
auctionDetail_footerPlusBidBtn.setEnabled(true);
auctionDetail_footerPlusBidBtn.setClickable(true);
Log.e("updateBidLog", "Enable");
auctionDetail_footerBottom.setEnabled(true);
auctionDetail_footerBottom.setClickable(true);
auctionDetail_footerBottom.setAlpha(1.0f);
isShowSendBid = true;
} else if (Integer.parseInt(remainClick) == 0) {
Log.e("updateBidLog", "Disable");
auctionDetail_footerBottom.setEnabled(false);
auctionDetail_footerBottom.setClickable(false);
auctionDetail_footerBottom.setAlpha(0.4f);
auctionDetail_miniBottomBidTxt.setText("0");
isNotEndBids = true;
isShowSendBid = false;
} else {
Log.e("updateBidLog", "Disable");
auctionDetail_footerBottom.setEnabled(false);
auctionDetail_footerBottom.setClickable(false);
auctionDetail_footerBottom.setAlpha(0.4f);
auctionDetail_miniBottomBidTxt.setText("0");
isNotEndBids = true;
isShowSendBid = false;
}
}
}
});
} catch (Exception e) {
Log.e("updateBidCount", "Err : " + e.getMessage());
}
}
When run application and receive socket listener i show Log.e("updateBidLog", "Disable"); into logcat tab.
But not run this code :
auctionDetail_footerBottom.setEnabled(false);
auctionDetail_footerBottom.setClickable(false);
auctionDetail_footerBottom.setAlpha(0.4f);
auctionDetail_miniBottomBidTxt.setText("0");
isNotEndBids = true;
isShowSendBid = false;
and not update UI !
Update : I used this Constants.currentActivity.runOnUiThread for update UI. but not update UI!
How can i fix it?
Related
I am making an app. I added google sign in and its working fine, but
everytime i close it and start the app, it get signed out. Please tell
me how to stay logged in with google.
using System; using
System.Collections; using System.Collections.Generic; using
System.IO; using System.Linq; using System.Threading.Tasks; using
Firebase; using Firebase.Auth; using Google; using UnityEngine;
using UnityEngine.UI; using UnityEngine.Networking;
public class GoogleSignInDemo : MonoBehaviour {
public Text infoText;
public Text Name;
public Text Email;
public RawImage ProfileImage;
public RawImage ProfileImage1;
public Button disable;
public string webClientId = "<your client id here>";
private FirebaseAuth auth;
private GoogleSignInConfiguration configuration;
private void Awake()
{
configuration = new GoogleSignInConfiguration { WebClientId = webClientId, RequestEmail = true, RequestIdToken = true };
CheckFirebaseDependencies();
}
private void CheckFirebaseDependencies()
{
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
{
if (task.IsCompleted)
{
if (task.Result == DependencyStatus.Available)
auth = FirebaseAuth.DefaultInstance;
else
AddToInformation("Could not resolve all Firebase dependencies: " + task.Result.ToString());
}
else
{
AddToInformation("Dependency check was not completed. Error : " + task.Exception.Message);
}
});
}
public void SignInWithGoogle() { OnSignIn(); }
public void SignOutFromGoogle() { OnSignOut(); }
private void OnSignIn()
{
GoogleSignIn.Configuration = configuration;
GoogleSignIn.Configuration.UseGameSignIn = false;
GoogleSignIn.Configuration.RequestIdToken = true;
AddToInformation("Calling SignIn");
GoogleSignIn.DefaultInstance.SignIn().ContinueWith(OnAuthenticationFinished);
}
private void OnSignOut()
{
AddToInformation("Calling SignOut");
GoogleSignIn.DefaultInstance.SignOut();
}
public void OnDisconnect()
{
AddToInformation("Calling Disconnect");
GoogleSignIn.DefaultInstance.Disconnect();
}
internal void OnAuthenticationFinished(Task<GoogleSignInUser> task)
{
if (task.IsFaulted)
{
using (IEnumerator<Exception> enumerator = task.Exception.InnerExceptions.GetEnumerator())
{
if (enumerator.MoveNext())
{
GoogleSignIn.SignInException error = (GoogleSignIn.SignInException)enumerator.Current;
AddToInformation("Got Error: " + error.Status + " " + error.Message);
}
else
{
AddToInformation("Got Unexpected Exception?!?" + task.Exception);
}
}
}
else if (task.IsCanceled)
{
AddToInformation("Canceled");
}
else
{
AddToInformation("Welcome: " + task.Result.DisplayName + "!");
AddToInformation("Email = " + task.Result.Email);
AddToInformation("Google ID Token = " + task.Result.IdToken);
AddToInformation("ImageUrl = " + task.Result.ImageUrl);
AddToInformation("Email = " + task.Result.Email);
SignInWithGoogleOnFirebase(task.Result.IdToken);
Name.text = task.Result.DisplayName;
Email.text = task.Result.Email;
disable.enabled = false;
PlayerPrefs.SetString("Name", task.Result.DisplayName);
PlayerPrefs.SetString("Email", task.Result.Email);
String stringUri;
stringUri = task.Result.ImageUrl.ToString();
PlayerPrefs.SetString("ImageURL", stringUri);
StartCoroutine(DownloadImage(stringUri));
IEnumerator DownloadImage(string MediaUrl)
{
UnityWebRequest request = UnityWebRequestTexture.GetTexture(MediaUrl);
yield return request.SendWebRequest();
if (request.isNetworkError || request.isHttpError)
Debug.Log(request.error);
else
ProfileImage.texture = ((DownloadHandlerTexture)request.downloadHandler).texture;
ProfileImage1.texture = ((DownloadHandlerTexture)request.downloadHandler).texture;
}
}
}
private void SignInWithGoogleOnFirebase(string idToken)
{
Credential credential = GoogleAuthProvider.GetCredential(idToken, null);
auth.SignInWithCredentialAsync(credential).ContinueWith(task =>
{
AggregateException ex = task.Exception;
if (ex != null)
{
if (ex.InnerExceptions[0] is FirebaseException inner && (inner.ErrorCode != 0))
AddToInformation("\nError code = " + inner.ErrorCode + " Message = " + inner.Message);
}
else
{
AddToInformation("Sign In Successful.");
}
});
}
public void OnSignInSilently()
{
GoogleSignIn.Configuration = configuration;
GoogleSignIn.Configuration.UseGameSignIn = false;
GoogleSignIn.Configuration.RequestIdToken = true;
AddToInformation("Calling SignIn Silently");
GoogleSignIn.DefaultInstance.SignInSilently().ContinueWith(OnAuthenticationFinished);
}
public void OnGamesSignIn()
{
GoogleSignIn.Configuration = configuration;
GoogleSignIn.Configuration.UseGameSignIn = true;
GoogleSignIn.Configuration.RequestIdToken = false;
AddToInformation("Calling Games SignIn");
}
private void AddToInformation(string str) { infoText.text += "\n" + str; }
}
Firebase automatically persists the user's authentication state, and tried to restore it when the app restarts. But since this requires a call to the servers, it may take some time, you'll need to listen to the AuthStateChanged event as shown in the documentation on getting the currently signed in user:
Firebase.Auth.FirebaseAuth auth;
Firebase.Auth.FirebaseUser user;
// Handle initialization of the necessary firebase modules:
void InitializeFirebase() {
Debug.Log("Setting up Firebase Auth");
auth = Firebase.Auth.FirebaseAuth.DefaultInstance;
auth.StateChanged += AuthStateChanged;
AuthStateChanged(this, null);
}
// Track state changes of the auth object.
void AuthStateChanged(object sender, System.EventArgs eventArgs) {
if (auth.CurrentUser != user) {
bool signedIn = user != auth.CurrentUser && auth.CurrentUser != null;
if (!signedIn && user != null) {
Debug.Log("Signed out " + user.UserId);
}
user = auth.CurrentUser;
if (signedIn) {
Debug.Log("Signed in " + user.UserId);
}
}
}
void OnDestroy() {
auth.StateChanged -= AuthStateChanged;
auth = null;
}
Now when the app reloads, your AuthStateChanged will immediately be called with no current user, and then it will/may be called again once the user's authentication state has been restored.
I've been implementing for the first time in-app billing in my app and even if all the code is correct, it is not working!
I have a BillingManager.java
public class BillingManager implements PurchasesUpdatedListener {
private static final String TAG = "BillingManager";
private final BillingClient mBillingClient;
private final Activity mActivity;
String base64Key = "mykey";
private static Context myCxt;
private String mAdRemovalPrice;
private static final String ITEM_SKU_ADREMOVAL = "myskuid";
public int billingResult;
public BillingManager(Activity activity) {
mActivity = activity;
mBillingClient = BillingClient.newBuilder(mActivity).setListener(this).build();
mBillingClient.startConnection(new BillingClientStateListener() {
#Override
public void onBillingSetupFinished(#BillingClient.BillingResponse int billingResponse) {
if (billingResponse == BillingClient.BillingResponse.OK) {
Log.i(TAG, "onBillingSetupFinished() good response: " + billingResponse);
List skuList = new ArrayList<>();
skuList.add(ITEM_SKU_ADREMOVAL);
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
mBillingClient.querySkuDetailsAsync(params.build(),
new SkuDetailsResponseListener() {
#Override
public void onSkuDetailsResponse(int responseCode, List skuDetailsList) {
// Process the result.
if (responseCode == BillingClient.BillingResponse.OK
&& skuDetailsList != null) {
for (Object skuDetailsObject : skuDetailsList) {
SkuDetails skuDetails = (SkuDetails) skuDetailsObject;
String sku = skuDetails.getSku();
String price = skuDetails.getPrice();
if (ITEM_SKU_ADREMOVAL.equals(sku)) {
mAdRemovalPrice = price;
}
}
}
}
});
} else {
Log.w(TAG, "onBillingSetupFinished() error code: " + billingResponse);
}
}
#Override
public void onBillingServiceDisconnected() {
Log.w(TAG, "onBillingServiceDisconnected()");
}
});
}
#Override
public void onPurchasesUpdated(int responseCode, List<Purchase> purchases) {
if (responseCode == BillingClient.BillingResponse.OK
&& purchases != null) {
for(Purchase purchase: purchases) {
// When every a new purchase is made
// Here we verify our purchase
Log.i(TAG, "onPurchasesUpdated() ourchase ok response: " + responseCode);
if (!verifyValidSignature(purchase.getOriginalJson(), purchase.getSignature())) {
// Invalid purchase
// show error to user
myCxt = MainActivity.proContext;
Toast.makeText(myCxt, myCxt.getString(R.string.purchase_err), Toast.LENGTH_LONG).show();
Log.i(TAG, "Got a purchase: " + purchase + "; but signature is bad. Skipping...");
return;
} else {
// purchase is valid
// Perform actions
myCxt = MainActivity.proContext;
Toast.makeText(myCxt, myCxt.getString(R.string.purchase_done), Toast.LENGTH_LONG).show();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(myCxt);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("isPro", true);
editor.apply();
}
}
} else if (responseCode == BillingClient.BillingResponse.USER_CANCELED) {
// Handle an error caused by a user cancelling the purchase flow.
Log.i(TAG, "onPurchasesUpdated() user canceled response: " + responseCode);
} else {
// Handle any other error codes.
Log.i(TAG, "onPurchasesUpdated() error response: " + responseCode);
}
}
public void startPurchaseFlow() {
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
.setSku(ITEM_SKU_ADREMOVAL)
.setType(BillingClient.SkuType.INAPP)
.build();
mBillingClient.launchBillingFlow(mActivity, flowParams);
Log.i(TAG, "StartPurchaseFlow called");
}
private boolean verifyValidSignature(String signedData, String signature) {
try {
return Security.verifyPurchase(base64Key, signedData, signature);
} catch (IOException e) {
Log.e(TAG, "Got an exception trying to validate a purchase: " + e);
return false;
}
}
And then i call it like this in my App menu:
if (id == R.id.action_pro) {
BillingManager mbilling = new BillingManager(MainActivity.this);
mbilling.startPurchaseFlow();
return true;
}
Actually it turns out that if I read the logs in debugging mode seems that onPurchasesUpdated() method throws the error -1 as response code! So this means that the responsecode is -1 which according to Java documentation is a generic error in http protocol... Why am I getting this?
The code seems pretty good even if compared to others or to guides found online. Does anyone have any suggestions?
Please make sure your billing client is initialized before you start the purchaseflow.
response code -1 indicates billingclient disconnected
So I creating an android app where I need to check if a file exist on a remote server really fast because I have to test ~1000 links before the app become usable.
I currently call a function that return the URL if it's valid and null if not.
public String CheckUrl(String url) {
try {
URL urll = new URL(url);
HttpURLConnection huc = (HttpURLConnection) urll.openConnection();
huc.setRequestMethod("GET"); //OR huc.setRequestMethod ("HEAD");
huc.connect();
int code = huc.getResponseCode();
System.out.println(code);
if (code == 200) {
return url;
} else {
return null;
}
} catch (Exception e) {
return null;
}
}
and I use it like this:
for (Element episode : episodes) {
globalEpisodeCounter++;
localEpisodeCounter++;
MLP_Episode currentEpisode = new MLP_Episode();
Elements links = episode.getElementsByTag("a");
Element linkObj = links.get(0);
Element thumObj = linkObj.getElementsByTag("img").get(0);
Element titleObj = linkObj.getElementsByTag("b").get(0);
int notRealsead = episode.getElementsByClass("btn btn-sm btn-error").size();
Boolean epReleased = false;
if (notRealsead == 0) {
epReleased = true;
}
currentEpisode.url = "https://www.newlunarrepublic.fr" + linkObj.attributes().get("href");
currentEpisode.thumbUrl = "https://www.newlunarrepublic.fr" + thumObj.attributes().get("src");
currentEpisode.title = titleObj.text();
currentEpisode.released = epReleased;
currentEpisode.id_local = localEpisodeCounter;
currentEpisode.id_global = globalEpisodeCounter;
currentEpisode.in_season_num = seasonCounter;
if (epReleased) {
currentEpisode.url_vo_1080p = CheckUrl(
"---------/NLR-1080p-" + addZero(seasonCounter) + "x" + addZero(localEpisodeCounter) + ".webm");
}
epList.add(currentEpisode);
}
At the and end of the search the search thread call a function to update UI
But the down side of the function is that it's very slow 1-2 link/sec which ranslate in 15min waiting before the app is usable
So the answer was to run the check in a separate thread:
Thread thread = new Thread() {
#Override
public void run() {
try {
currentEpisode.url_vo_1080p = CheckUrl("------------/NLR-1080p-"+addZero(seasonCounter2)+"x"+addZero(localEpisodeCounter2)+".webm");
}
catch (Exception e) {}
}
};
thread.start();
I have developed a plain native websocket + tomcat 8 websocket sample appliation works fine.
But when I use the sockjs.js , instead of native websocket , I genting 404 error .
I am getting error in my browser console as
GET http://localhost:8082/WebsocketsWithFallback/websocket/DataPublisher/info 404 (Not Found)
Here is my javascript code,
var ws = null;
var sessionId = null;
var target = "/WebsocketsWithFallback/websocket/DataPublisher";
var connectionLive = false;
var init = false;
var pageCount = 0;
var delay = 0;
$(document).ready(function(){
if(sessionId == null && init == false){
sendSessionId( $.trim($('#init').val()) );
}
});
function sendSessionId(session){
init = true;
sessionId = session;
// console.log("sessionId :"+sessionId);
if(sessionId != null ){
connect();
}
}
function connect() {
try{
if(connectionLive == false){
updateTarget(target);
}
if(ws == null){
try{
ws = new SockJS(target);
}
catch(e){
alert("WebSocket connection error :"+e.description);
setTimeout(function(){ connect(); }, 5000);
return;
}
}
try{
ws.onopen = function () {
console.log('Info: WebSocket connection was opened.');
initMessage();
connectionLive = true;
};
}
catch(e){
alert("WebSocket connection open error :"+e.description);
}
try{
ws.onmessage = function (event) {
// console.log('Received: ' + event.data);
//Process the data to UI
};
}
catch(e){
alert("WebSocket message send error :"+e.description);
}
try{
ws.onclose = function (event) {
console.log('Info: WebSocket connection closed, Code: ' + event.code + (event.reason == "" ? "" : ", Reason: " + event.reason));
ws = null;
setTimeout(function(){ connect(); }, 5000);
};
}
catch(e){
alert("webSocket connection closed Error :"+e.description);
}
}catch(e){
alert(e.description);
}
}
function disconnect() {
if (ws != null) {
ws.close();
ws = null;
}
}
function sendData(message) {
if (ws != null) {
// console.log('Sent: ' + message);
ws.send(message);
}
}
function updateTarget(val) {
var target = window.location.host + val;
}
//Send initial message to pass parameters
function initMessage(){
if(ws != null){
ws.send(sessionId);
}
}
My server side will be,
#ServerEndpoint("/websocket/DataPublisher/")
public class Test {
#OnMessage
public void pushData(Session session, String msg, boolean last) {
session.getBasicRemote().sendText(msg, last);
}
#OnOpen
public void openWebSocket(Session session) {
// My stuff
}
#OnClose
public void closeWebSocket(Session session) {
// My stuff
}
#OnError
public void errorWebSocket(Throwable exception,Session session) {
}
}
Please give any ideas or suggesstions.Thank you.
I was wondering, I have the following snippets of code that I would like to eliminate the use of sessions and make it RESTful. I have a controller servlet that uses several handlers, which are used to determine the page to return to. For example, here are two of my handlers:
public class ReporterLoginHandler implements ActionHandler {
public String handleIt(Map params, HttpSession session) {
String reporterId = null;
String passwd = null;
String errMsg = null;
ReporterBean reporterBean = null;
String returnPage = "home";
try {
reporterId = ((String[]) params.get("reporterid"))[0];
passwd = ((String[]) params.get("passwd"))[0];
} catch (Exception ex) {
System.out.println("Oops, couldn't parse the parameters for login!");
}
if (reporterId == null || reporterId.length() == 0 || passwd == null || passwd.length() == 0) {
errMsg = "The reporterID or password cannot be empty";
} else if ((reporterBean = ReporterBeanFactory.getReporter(reporterId, passwd)) == null) {
errMsg = "The reporterID or password is not valid";
}
if (errMsg != null) {
session.setAttribute("msg", errMsg); //should be removed and replaced by a RESTful API
} else }
returnPage = "reporter_home";
session.setAttribute("reporterBean", reporterBean);
}
return returnPage;
}
}
public class PostItemHandler implements ActionHandler {
#Override
public String handleIt(Map<String, String[]> params, HttpSession session) {
String title = params.get("title")[0];
String story = params.get("story")[0];
String itemId = null;
String returnPage = "home";
if (params.containsKey("item")) {
itemId = params.get("item")[0];
}
ReporterBean rBean = (ReporterBean) session.getAttribute("reporterBean"); // needs to be replaced by a RESTful API
String msg = "";
int id = 0;
String filename = session.getAttribute("newsfile").toString();
if (title != null && title.length() > 0 && story != null && story.length() > 0) {
if (itemId != null && itemId.length() > 0) {
try {
id = Integer.parseInt(itemId);
} catch (Exception exc) {
msg = "Invalid format for news item ID";
}
if (rBean != null) {
if (msg.equals("") && NewsItemBeanFactory.editNewsItem(id, title, story, rBean.getReporterId())) {
msg = "News item " + id + " successfully edited!";
returnPage = "reporter_home";
try {
NewsItemBeanFactory.saveNewsItems(filename);
} catch (IOException ex) {
Logger.getLogger(PostItemHandler.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
msg = "News item " + id + " could not be edited!";
}
} else }
msg = "Error: please log in before adding or editing an item.";
}
} else {
if (rBean != null) {
NewsItemBeanFactory.addNewsItem(title, story, rBean.getReporterId());
msg = "News item successfully added!";
returnPage = "reporter_home";
try {
NewsItemBeanFactory.saveNewsItems(filename);
} catch (IOException ex) {
Logger.getLogger(PostItemHandler.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
msg = "Error: please log in before adding a new item.";
}
}
}
if (params.get("returnpage") != null) {
if (params.get("returnpage")[0].toString().equals("mynews")) {
Collection<NewsItemBean> newsItems = NewsItemBeanFactory.getAllItems();
ArrayList<NewsItemBean> myNewsItems = new ArrayList<NewsItemBean>();
for (NewsItemBean item : newsItems) {
if (rBean != null && rBean.getReporterId().equals(item.getReporterId())) {
myNewsItems.add(item);
}
}
session.setAttribute("mynews", myNewsItems); //needs to be replaced by a RESTful API
returnPage = "mynews";
}
}
session.setAttribute("msg", msg); //needs to be replaced by a RESTful API
return returnPage;
}
}
Specifically, I would like to eliminate the use of all sessions from my handlers (as well as from my controller servlet) and would like to create a RESTful API where the java beans are represented with JSON.
I would prefer not to use an external REST API creator such as Spring or Jersey, however, I am open to using Google's Gson to convert my beans to and from JSON.
EDIT: Also, I would like the login to return an authorization token when successful.
Could anyone help me here?