How do I use kotlin loop to avoid ANR in android app? - android

I am using kotlin in my android app. I wrote following function for decoding coordinates :
private fun decodeCoordinates(address: String) {
var lat: String = ""
var lng: String = ""
var flag = true
var count = 0
while (count < address.length) {
if (address[count].equals(',')) {
flag = false;
continue
}
if (flag) {
lat += address[count]
} else {
lng += address[count]
}
count++;
}
Log.i("dxdiag", "Lat: $lat")
Log.i("dxdiag", "Lng: $lng")
}
but app hangs, if I remove continue , app does not hang

Issue is that you are changing the length of list inside the loop which leads to ANR. Use follinwg loop code:
var length = address.legth
while (count < length) {
if (address[count].equals(',')) {
flag = false;
continue
}
if (flag) {
lat += address[count]
} else {
lng += address[count]
}
count++;
}

Related

Concurrent modification during iteration: Instance(length:5) of '_GrowableList'. Flutter

I'm trying to do a change to a list in flutter, but it keeps giving me this error :
Concurrent modification during iteration: Instance(length:5) of '_GrowableList'.
I've searched and didn't find an answer or solution that fits the situation
Here I smy code:
void addProductsToCart() {
int addedAmount = cardNum * widget.currentProduct.price;
String note = noteTextController.text;
int total = cardNum * widget.currentProduct.price;
OrderItem orderItemInstance = OrderItem(
productName: widget.currentProduct.name,
productPrice: widget.currentProduct.price.toString(),
productQuantity: cardNum.toString(),
productNotes: note,
productSupplierName: widget.supplierName,
productImage: widget.currentProduct.image,
totalPrice: total.toString());
int theTotal = widget.cart.total;
if (widget.cart.orderDetails.length > 0){
for (var item in widget.cart.orderDetails){
if (item.productName == orderItemInstance.productName){
item.productQuantity += orderItemInstance.productQuantity;
item.totalPrice += orderItemInstance.totalPrice;
theTotal += addedAmount;
} else {
widget.cart.orderDetails.add(orderItemInstance);
theTotal += addedAmount;
}
}
} else {
theTotal += addedAmount;
widget.cart.orderDetails.add(orderItemInstance);
}
widget.cart.total += total;
setState(() {});
}
Based on the debugger in android studio . the error is being catched in one of the lines that adds or removes data from the list
Like this :
theTotal += addedAmount;
widget.cart.orderDetails.add(orderItemInstance);
I've solved it by delaying the add part after finishing the loop .. here is the working code :
void addProductsToCart() {
int addedAmount = cardNum * widget.currentProduct.price;
String note = noteTextController.text;
int total = cardNum * widget.currentProduct.price;
OrderItem orderItemInstance = OrderItem(
productName: widget.currentProduct.name,
productPrice: widget.currentProduct.price.toString(),
productQuantity: cardNum.toString(),
productNotes: note,
productSupplierName: widget.supplierName,
productImage: widget.currentProduct.image,
totalPrice: total.toString());
int theTotal = widget.cart.total;
List<OrderItem> toAdd= [];
if (widget.cart.orderDetails.length > 0){
for (var item in widget.cart.orderDetails){
if (item.productName == orderItemInstance.productName){
item.productQuantity += orderItemInstance.productQuantity;
item.totalPrice += orderItemInstance.totalPrice;
theTotal += addedAmount;
} else {
toAdd.add(orderItemInstance);
theTotal += addedAmount;
}
}
} else {
theTotal += addedAmount;
// widget.cart.orderDetails.add(orderItemInstance);
toAdd.add(orderItemInstance);
}
widget.cart.total += total;
toAdd.forEach((element) {
widget.cart.orderDetails.add(element);
});
setState(() {});
}

Is there a way to make WebView identify an item where user selected text?

I have developed an app, sort of an text reader, and need to introduce a new functionality to it (users are asking for it- I've intended to incorporate it all along, just that I never figured out how to do it). I'm generating an html from the text and displaying it in a webview. I want the user to be able to select a section of the text and then open the context menu. What I want to identify is on which section he has longClicked on (each line of the html consists of pre-formatted line/section number, the line text and may be finished with a href link), and which part of it was selected. Once I figure the first part out, the second is just a matter of sorting it out.
I've tried using <span id='someuniquenumber'> for the line text, but webView does not recognize it as an anchor*. I've also, unsuccessfully, tried to enable text selection on links (which IMHO is not a desirable option, but will resort to it, if there are no other options left).
Here's an example of the text selection problem- I want to be able to identify the selection as "line 5, words 4 through 10", or at least that the user has selected the text from the line marked as 5.
Any help would be greatly appreciated- just bear in mind that I can affect both the webView behaviour and the HTML code displayed. Thanks in advance. :)
event handler returns get extra=0 in type='null'
If I use tags, I do not know the way to allow text selection within that link, whereas without it I cannot identify the element user has clicked on (and the selected text may certainly not be unique, and therefore may not be searched within HTML).
EDIT
Here's the code I have regarding webView (onCreate in MainActivity):
mWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
int temp = url.lastIndexOf("/") + 1;
String link = url.substring(temp);
if (link.charAt(0) == 'L') {
link = link.substring(1);
LinksFragment mLinksFragment = LinksFragment.newInstance(Integer.valueOf(link),textZoom,zoomAll,sans,fragNo);
mLinksFragment.show(fm,"fragment_links");
} else if (link.charAt(0) == 'C') {
// show or add comment
} else {
// follow link
// append link to clipboard
ClipData tmp = myCB.getPrimaryClip();
if (!myCB.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
tmp = ClipData.newPlainText("text","");
myCB.setPrimaryClip(tmp);
}
ClipData.Item tmpI = tmp.getItemAt(0);
String ts = tmpI.getText().toString();
ts += link + " ";
tmp = ClipData.newPlainText("text",ts);
myCB.setPrimaryClip(tmp);
}
return true;
}
});
// detect clicked element
mWebView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View view, MotionEvent event) {
WebView.HitTestResult hr = ((WebView)view).getHitTestResult();
Toast.makeText(MainActivity.this, "getExtra = "+ hr.getExtra() + "Type= " + hr.getType(),
Toast.LENGTH_LONG).show();
//return true;
return false;
}
});
mWebView.getSettings().setDefaultFontSize(14);
mWebView.setBackgroundColor(0x00000000);
mWebView.getSettings().setBuiltInZoomControls(true);
mWebView.getSettings().setDisplayZoomControls(false);
updateFields(); // applies custom fontface and fontsize to elements incl. mWebView
mWebView.loadDataWithBaseURL("file:///android_asset/",wV,"text/html; charset=utf-8","utf-8",null);
And here's the code for generating html inserted into the webView (a separate function fetching text, adding headings and chapter titles, formatting the text)-the actual text is stored in tmpStr variable:
public String fetchText(Bible mB, boolean append, boolean filter, String wV) {
BibleInfo.Error mE;
String tN;
char tT;
int[] Lines;
String[] Lttrs;
int[] noVerses = new int[3];
String fS1 = "<p class='ps'>";
String Psalm = getResources().getString(R.string.Psalm);
String Chapter = getResources().getString(R.string.Chapter);
boolean estExc = false;
char lttr = 'a'-1;
mE = mB.mBI.mE;
int tmp = 0;
for (int i=0; i<3; i++) {
tmp += mB.mBI.noBooks(i);
noVerses[i] = mB.mBI.getLine(tmp,1,1);
}
// separating link data
int cnt = 0;
Lines = new int[mB.mLink.getLines().length];
Lttrs = new String[mB.mLink.getLines().length];
for (String tS:mB.mLink.getLines()) {
tN = "";
Lttrs[cnt] = "";
for (tmp=0; tmp<tS.length(); tmp++) {
tT = tS.charAt(tmp);
if (tT>='0' && tT<='9') {
tN += tT;
} else {
Lttrs[cnt] += tT;
}
}
Lines[cnt++] = Integer.valueOf(tN);
}
if (!append) {
wV = "";
}
noVerses = mB.mBI.getTriLink(Lines[0],mE);
if ((noVerses[1] == 0 || (noVerses[1] == 1 && noVerses[0] != mB.mBI.getSirach())) && mB.mLink.isLong()) {
if (mB.mBI.getTitles() != null) {
wV += "<h1>" + mB.mBI.getTitles()[noVerses[0]] + "</h1>";
}
}
for (int i=0; i<Lines.length; i++) {
int tX = Lines[i];
int[] temp = mB.mBI.getTriLink(tX, mE);
if (temp[2] == 1 && mB.mLink.isLong() && temp[1] != 0) {
if (temp[0] == mB.mBI.getPsalms()) {
wV += "<h2>" + Psalm + " " + temp[1] + "</h2>";
} else {
wV += "<h2>" + Chapter + " " + temp[1] + "</h2>";
}
}
String tmpStr = mB.getLineText(tX - 1,filter);
if (noVerses[0] == mB.mBI.getPsalms()) {
wV += fS1;
if (Lttrs[i] != "") {
tmpStr = parseVerse(tmpStr,Lttrs[i]);
}
tmpStr = tmpStr.replace(mB.mBI.mSeparator, "<br>");
} else {
wV += "<p>";
if (noVerses[0] == mB.mBI.getEsther()) {
int noBrks = 0;
int lastOccurrence = 0;
if ((temp[1]==1) & (temp[2]==1)) {
estExc = true;
while (lastOccurrence != -1){
lastOccurrence = tmpStr.indexOf(mB.mBI.mSeparator,lastOccurrence);
String tStr = "<br><sup>" + temp[2] + (char)(98+noBrks) + "</sup> ";
if (lastOccurrence != -1) {
if (noBrks == 0) {
tmpStr = "<span id='apoch'>" + tmpStr;
}
tmpStr = tmpStr.replaceFirst("\\|", tStr);
noBrks +=1;
}
}
if (tmpStr.lastIndexOf(mB.mBI.mSeparator) != -1) {
tmpStr += "</span>";
}
// remove character before last </sup>
} else {
estExc = false;
while (lastOccurrence != -1){
lastOccurrence = tmpStr.indexOf(mB.mBI.mSeparator,lastOccurrence);
String tStr = "<br><sup>" + temp[2] + (char)(97+noBrks) + "</sup> ";
if (lastOccurrence != -1) {
if (noBrks == 0) {
tmpStr = "<span id='apoch'>" + tmpStr;
}
tmpStr = tmpStr.replaceFirst("\\|", tStr);
noBrks +=1;
}
}
if (noBrks != 0) {
tmpStr += "</span>";
}
tmpStr = tmpStr.replaceFirst("<span id='apoch'>","");
tmpStr = tmpStr.replaceFirst("<br>","<br><span id='apoch'>");
}
}
}
// add hyperlink for links
if (!TextUtils.isEmpty(mB.getLinks()[tX-1])) {
lttr++;
if (lttr>'z') { lttr = 'a'; }
String ts= "<sup><span id='links'><a href='L" + (tX-1) + "'>" + lttr;
ts += "</a></span></sup>";
tmpStr += ts;
}
if (estExc) {
wV += "<sup>" + temp[2] + "a</sup> " + tmpStr + "</p>";
} else {
wV += "<sup>" + temp[2] + "</sup> " + tmpStr + "</p>";
}
}
wV = fS2 + wV;
return wV;
}
Calls to log events or set user properties fired from within a WebView must be forwarded to native code before they can be sent to Google Analytics for Firebase.
Implement JavaScript handler
The first step in using Google Analytics for Firebase in a WebView is to create JavaScript functions to forward events and user properties to native code. The following example shows how to do this in a way that is compatible with both Android and iOS native code
function logEvent(name, params) {
if (!name) {
return;
}
if (window.AnalyticsWebInterface) {
// Call Android interface
window.AnalyticsWebInterface.logEvent(name, JSON.stringify(params));
} else if (window.webkit
&& window.webkit.messageHandlers
&& window.webkit.messageHandlers.firebase) {
// Call iOS interface
var message = {
command: 'logEvent',
name: name,
parameters: params
};
window.webkit.messageHandlers.firebase.postMessage(message);
} else {
// No Android or iOS interface found
console.log("No native APIs found.");
}
}
function setUserProperty(name, value) {
if (!name || !value) {
return;
}
if (window.AnalyticsWebInterface) {
// Call Android interface
window.AnalyticsWebInterface.setUserProperty(name, value);
} else if (window.webkit
&& window.webkit.messageHandlers
&& window.webkit.messageHandlers.firebase) {
// Call iOS interface
var message = {
command: 'setUserProperty',
name: name,
value: value
};
window.webkit.messageHandlers.firebase.postMessage(message);
} else {
// No Android or iOS interface found
console.log("No native APIs found.");
}
}
Implement native interface
public class AnalyticsWebInterface {
public static final String TAG = "AnalyticsWebInterface";
private FirebaseAnalytics mAnalytics;
public AnalyticsWebInterface(Context context) {
mAnalytics = FirebaseAnalytics.getInstance(context);
}
#JavascriptInterface
public void logEvent(String name, String jsonParams) {
LOGD("logEvent:" + name);
mAnalytics.logEvent(name, bundleFromJson(jsonParams));
}
#JavascriptInterface
public void setUserProperty(String name, String value) {
LOGD("setUserProperty:" + name);
mAnalytics.setUserProperty(name, value);
}
private void LOGD(String message) {
// Only log on debug builds, for privacy
if (BuildConfig.DEBUG) {
Log.d(TAG, message);
}
}
private Bundle bundleFromJson(String json) {
// ...
}
}
Once you have created the native interface, register it with your WebView so that it is visible to Javascript code running in the WebView:
// Only add the JavaScriptInterface on API version JELLY_BEAN_MR1 and above, due to
// security concerns, see link below for more information:
// https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,%20java.lang.String)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
mWebView.addJavascriptInterface(
new AnalyticsWebInterface(this), AnalyticsWebInterface.TAG);
} else {
Log.w(TAG, "Not adding JavaScriptInterface, API Version: " + Build.VERSION.SDK_INT);
}
Source: Firebase

Unexpected 0 as a result of mean calculation

As a part of my thread I want to calculate the mean value of 30 readings. To calculate it I am using formula
This is the code of run() method of my thread (the variables are defined before in thread - I've just put them to see the types of variables used):
//Thread's variables
float[] values;
String[] str1;
String[] str2;
int counter = 0;
int calibrationCounter = 0;
StringBuilder strBuilder;
ReadingsUpdateData updater;
String msg;
float[] calibrationValues;
public void run() {
while (true) {
try{
msg = inputList.poll();
} catch(NoSuchElementException nse){
continue;
}
if (msg == null) {
continue;
}
String[] msgArray = msg.split("!");
for (String m : msgArray) {
if (m.length() == 0) {
continue;
}
if(m.charAt(0)!='A'){
strBuilder.append(m);
continue;
} else {
str1 = strBuilder.toString().split(":");
if (str1.length != 2) {
if(str1.length>2){
strBuilder.delete(0,strBuilder.length());
continue;
}
strBuilder.append(m);
continue;
}
if (!str1[0].equals("ANG")) {
strBuilder.delete(0,strBuilder.length());
continue;
}
str2 = str1[1].split(",");
if (str2.length != 3) {
if(str2.length >3){
strBuilder.delete(0,strBuilder.length());
strBuilder.append(m);
continue;
}
strBuilder.append(m);
continue;
}
try {
if(readingsCalibration) {
if(calibrationCounter<30) {
Log.d(LOG_TAG,calibrationValues[0] + " = (1/(" +calibrationCounter +"+1))*("+calibrationValues[0] + "*"+calibrationCounter +"+"+str2[0]+"))");
calibrationValues[0] = (1/(calibrationCounter + 1))*
(calibrationValues[0]*calibrationCounter+Float.parseFloat(str2[0]));
calibrationValues[1] = (1/(calibrationCounter + 1))*
(calibrationValues[1]*calibrationCounter+Float.parseFloat(str2[1]));
calibrationValues[2] = (1/(calibrationCounter + 1))*
(calibrationValues[2]*calibrationCounter+Float.parseFloat(str2[2]));
calibrationCounter++;
} else {
readingsCalibration = false;
calibrationCounter = 0;
}
} else {
values[0] = Float.parseFloat(str2[0]) - calibrationValues[0];//x
values[1] = Float.parseFloat(str2[1]) - calibrationValues[1];//y
values[2] = Float.parseFloat(str2[2]) - calibrationValues[2];//z
updater.setData(values);
EventBus.getDefault().post(updater);
}
} catch (NullPointerException npe) {
} catch (NumberFormatException nfe) {
}
strBuilder.delete(0,strBuilder.length());
strBuilder.append(m);
}
}
}
}
Unfortunately, I am getting all the time only zeros as a result. Only at a first run I get some value but next one and each after gives 0. I was thinking about some problem with type casting but then I wouldn't get also first value.
Since you're dividing two ints, you're performing integer division, i.e., keeping only the whole part of the result.
to get a floating point result, it would suffice to define one of the operands as a double. e.g.:
double calibrationCounter = 0.0;

EditText selection on focus not working

Since I am very disappointed in a way that Android is doing decimal input I decided to write my own EditDecimal control that inherits from EditText. I want it to select all on click and to put cursor on first position on focus. I don't want cursor to show because it's usless on most Android phones (you mostly cannot put it in right place and it makes me very nervous)
Problem is when you tap on control - FocusChanged is called but it does not set position of (hidden) cursor on first position but on position where user tapped. I can not find the problem... is there some other event that happens after FocusChange that moves cursor?
public class EditDecimal : EditText
{
// Every constructor is calling Initialize ...
private void Initialize()
{
FocusChange += OnFocusChanged;
Click += OnClicked;
SetCursorVisible(false);
}
private void OnFocusChanged(object sender, FocusChangeEventArgs e)
{
if (IsFocused)
SetSelection(1);
}
private void OnClicked(object sender, EventArgs e)
{
SelectAll();
}
}
I finnaly solved it. I had to subscribe to OnTouch event and to change cursor position from there.
public class EditDecimal : EditText
{
// Every constructor is calling Initialize ...
private InputMethodManager _imm ;
public int DecimalSpaces { get; set; }
readonly DecimalFormatSymbols _dfs = new DecimalFormatSymbols();
private void Initialize(Context context, IAttributeSet attrs)
{
AfterTextChanged += OnAfterTextChanged;
SetSelectAllOnFocus(true);
SetCursorVisible(false);
Touch += OnTouch;
_imm = (InputMethodManager)context.GetSystemService(Context.InputMethodService);
var a = context.ObtainStyledAttributes(attrs, Resource.Styleable.EditDecimal);
try
{
DecimalSpaces = a.GetInteger(Resource.Styleable.EditDecimal_decimalSpaces, 2);
}
finally
{
a.Recycle();
}
}
private void OnTouch(object sender, TouchEventArgs e)
{
base.OnTouchEvent(e.Event);
if (e.Event.Action == MotionEventActions.Up)
{
SelectAll();
}
}
protected override void OnFocusChanged(bool gainFocus, FocusSearchDirection direction, Rect previouslyFocusedRect)
{
base.OnFocusChanged(gainFocus, direction, previouslyFocusedRect);
SelectAll();
}
private void OnAfterTextChanged(object sender, AfterTextChangedEventArgs e)
{
const char ch1 = '.';
const char ch2 = ',';
switch (_dfs.DecimalSeparator)
{
case ch2:
{
if (Text.Contains(ch1.ToString()))
{
var position = Text.IndexOf(ch1);
if (Text.Contains(ch2.ToString()))
e.Editable.Delete(position, position + 1);
else
e.Editable.Replace(position, position + 1, ch2.ToString());
}
// we have to prevent showing two commas in number
var firstCommaPosition = Text.IndexOf(ch2);
var lastCommaPosition = Text.LastIndexOf(ch2);
if (firstCommaPosition > 0 && lastCommaPosition > 0 && firstCommaPosition != lastCommaPosition)
e.Editable.Delete(lastCommaPosition, lastCommaPosition+1);
}
break;
case ch1:
{
if (Text.Contains(ch2.ToString()))
{
var position = Text.IndexOf(ch2);
e.Editable.Delete(position, position + 1);
}
// we have to prevent showing two points in number
var firstPointPosition = Text.IndexOf(ch1);
var lastPointPosition = Text.LastIndexOf(ch1);
if (firstPointPosition > 0 && lastPointPosition > 0 && firstPointPosition != lastPointPosition)
e.Editable.Delete(lastPointPosition, lastPointPosition + 1);
}
break;
}
//thnx to http://stackoverflow.com/users/2240673/tom
var length = e.Editable.Length();
if (length <= 0) return;
if (NrOfDecimal(e.Editable.ToString()) > DecimalSpaces)
e.Editable.Delete(length - 1, length);
}
private int NrOfDecimal(string nr)
{
if (nr == null) return 0;
var nrCharArray = nr.ToCharArray();
var len = nr.Length;
var pos = len;
for (var i = 0; i < len; i++)
{
if (nrCharArray[i] != '.') continue;
pos = i + 1;
break;
}
return len - pos;
}
}
What came as suprize to me was a fact that EditText selection behaves differently if SetCursorVisible is set to true than when it is set to false. I thought that it was just visibility property.
Grepcode is your friend. It shows that TextView's onFocusChanged method checks if there's an Editor object defined for the View (which is the case with EditText) and a look at the Editor code shows this at line 889 ff:
// If a tap was used to give focus to that view, move cursor at tap position.
// Has to be done before onTakeFocus, which can be overloaded.
final int lastTapPosition = getLastTapPosition();
if (lastTapPosition >= 0) {
Selection.setSelection((Spannable) mTextView.getText(), lastTapPosition);
}
So perhaps the best way would be to write your own implementation of Editor. Although if have no idea right now how you attach that to your TextView resp. EditText. class.
Or you just set the selection back to the first position if that is what you want.

jQuery Mobile show() and hide() Don't Work in Android

I am trying to get a "Please wait..." message to display when I make an ajax call to get information. Basically, the user puts in their search term, hits Search, I want to display "Please wait..." while the page is doing the ajax call, then hide it once it is done.
I have a div on my jsp page that looks like this:
<div id="modalWindow">Please Wait...</div>
My jQuery looks like this:
jQuery('#modalWindow').css({
'text-align' : 'center',
'font-size' : '20px'
}).hide(); //this is called when the page initially loads
jQuery('#modalWindow').show(); //I call this in the function that does the Ajax call
jQuery('#modalWindow').hide(); //I call this once the Ajax is done.
This is my entire Ajax call:
jQuery.ajax(
{
url : urlContext + "/getItems.html",
data :
{
txtItemReference : txtItemReference
},
dataType : "json",
cache : false,
async : false,
timeout : 100000,
success : function(jsonResponse)
{
if ( jsonResponse instanceof Object)
{
if (jQuery.isEmptyObject(jsonResponse))
{
createLocationDisplayPanel(false);
createSimilarItemsPanel(false);
}
else if (jsonResponse['Locations'] != undefined)
{
responseArray = new Array();
arrayStart = 0;
intPage = 1;
if (jsonResponse['Locations'].length <= 20)
{
for (var x = arrayStart; x < jsonResponse['Locations'].length; x++)
{
responseArray[x] = jsonResponse['Locations'][x];
}
}
else
{
responseArray = new Array();
for (var x = arrayStart; x < (20 * intPage); x++)
{
responseArray[x] = jsonResponse['Locations'][x];
}
}
createLocationDisplayPanel(jsonResponse, responseArray, txtItemReference, urlContext, callback);
}
else
{
if (jsonResponse['Items'].length <= 20)
{
for (var x = arrayStart; x < jsonResponse['Items'].length; x++)
{
responseArray[x] = jsonResponse['Items'][x];
}
}
else
{
for (var x = arrayStart; x < (20 * intPage); x++)
{
responseArray[x] = jsonResponse['Items'][x];
}
}
createSimilarItemsPanel(jsonResponse, responseArray, txtItemReference, urlContext, callback);
}
if (callback != undefined)
{
callback();
}
}
else
{
alertLogout(document.URL);
}
},
error : function(jsonResponse)
{
if (jsonResponse.hasOwnProperty('ERROR'))
{
alertError("There was no response from the server.");
}
}
});
This works perfectly in Firefox on my desktop as well as Firefox for Android. However, on every Android browser I've tried, the "Please wait..." text never displays, and I am getting frustrated. Can anyone please tell me the workaround to get the show() and hide() functions to work in an Android browser? Thanks.
Have you checked if jQuery is loaded at that point? Write this before your script.
if (typeof jQuery == 'undefined') {
alert('jQuery is not loaded');
}
You might need to combine the scripts or find a way to ensure they are loaded in the order you need them.
I found the issue was with the async property of the Ajax call:
jQuery.ajax(
{
url : urlContext + "/getItems.html",
data :
{
txtItemReference : txtItemReference
},
dataType : "json",
cache : false,
async : true, //was false before
timeout : 100000,
success : function(jsonResponse)
{
if ( jsonResponse instanceof Object)
{
if (jQuery.isEmptyObject(jsonResponse))
{
createLocationDisplayPanel(false);
createSimilarItemsPanel(false);
}
else if (jsonResponse['Locations'] != undefined)
{
responseArray = new Array();
arrayStart = 0;
intPage = 1;
if (jsonResponse['Locations'].length <= 20)
{
for (var x = arrayStart; x < jsonResponse['Locations'].length; x++)
{
responseArray[x] = jsonResponse['Locations'][x];
}
}
else
{
responseArray = new Array();
for (var x = arrayStart; x < (20 * intPage); x++)
{
responseArray[x] = jsonResponse['Locations'][x];
}
}
createLocationDisplayPanel(jsonResponse, responseArray, txtItemReference, urlContext, callback);
}
else
{
if (jsonResponse['Items'].length <= 20)
{
for (var x = arrayStart; x < jsonResponse['Items'].length; x++)
{
responseArray[x] = jsonResponse['Items'][x];
}
}
else
{
for (var x = arrayStart; x < (20 * intPage); x++)
{
responseArray[x] = jsonResponse['Items'][x];
}
}
createSimilarItemsPanel(jsonResponse, responseArray, txtItemReference, urlContext, callback);
}
if (callback != undefined)
{
callback();
}
}
else
{
alertLogout(document.URL);
}
},
error : function(jsonResponse)
{
if (jsonResponse.hasOwnProperty('ERROR'))
{
alertError("There was no response from the server.");
}
}
});
Once I changed that, the show and hide worked in Android. Thanks for the help guys.

Categories

Resources