Disable contextual Action bar in android webview on text selection - android

How to disable contextual action bar in web view? I Want text selection feature to remain as it is , but i don't want the Contextual action bar to come, how can i disable it ?
Using this code hides the contextual action bar but it is looking bad(whole screen is shaking ) and also text selection is not retaining.
#Override
public void onSupportActionModeStarted(ActionMode mode) {
super.onSupportActionModeStarted(mode);
mode.finish();
}
How can i disable the contextual actionbar ? Is there any other way?

I know it is late to answer question but i just found it and it works fine.(I tested it on 5.0.1 and it works fine)(Following code will only clear copy , paste and select all option from menu.)
inject folliwing code in your html code which you will be loading in webview,
"<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n" +
"<script>\n" +
"$(function() {\n" +
" $(document.body).bind('touchstart', function(e) {\n" +
" var selection;\n" +
"\n" +
" if (window.getSelection) {\n" +
" selection = window.getSelection();\n" +
" } else if (document.selection) {\n" +
" selection = document.selection.createRange();\n" +
" }\n" +
"\n" +
" selection.toString() !== '' && ReaderJavaScript.onTextselectionEnded(true)\n" +
" });\n" +
"});\n" +
"</script>"
see in code i used ReaderJavaScript interface which will act as bridge between js code and activity to carry information on call of ReaderJavaScript.onTextselectionEnded(true).
so whenever user end selection it will indicate and at that time you just have to add following code to clear menus in your activity,
readerView.setTextSelectionFinishedListener(new ReaderView.TextSelectionFinishedListener() {
#Override
public void onTextSelectionEnded(boolean textSelectionEnded) {
if (mActionMode != null){
if (mActionMode.getMenu() != null){
mActionMode.getMenu().clear();
}
}
}
});

Simply remove it manually.
When the legacy action mode bar is triggered, the view hierachy would be:
So just fix the unwanted hierachy by the following code:
View p2th = Utils.getNthParent(root, 2);
if (p2th!=null && p2th.getId()==R.id.action_bar_root) {
Utils.replaceView(Utils.getNthParent(root, 1), p2th);
}
where Utils.getNthParent returns N-th parent of the root view, and Utils.replaceView just replace the action bar root with our content view .
(tested on android 4.4 and 5 sucessfully, without flicker or crash.)
What a genius solution, so simple and so stupid……

Related

Android 11 - Detect apps that can interrupt in DND mode

How I can detect expected apps that can interrupt in DND mode?
Or when the app's notification shows up, can I know that app in the expected list?
Update: After few days investigation, I'm not sure this is good solution but It's the only clue. In NotificationManager#Policy#toString has something like below
return "NotificationManager.Policy["
+ "priorityCategories=" + priorityCategoriesToString(priorityCategories)
+ ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders)
+ ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders)
+ ",priorityConvSenders="
+ conversationSendersToString(priorityConversationSenders)
+ ",suppressedVisualEffects="
+ suppressedEffectsToString(suppressedVisualEffects)
+ ",areChannelsBypassingDnd=" + (((state & STATE_CHANNELS_BYPASSING_DND) != 0)
? "true" : "false")
+ "]";
areChannelsBypassingDnd value is the only clue.

Open google maps POI links in system browser

I have a huge problem with my ionic app.
When the user clicks on a point of interest, for example train stations and clicks on "open in Google Maps" The App opens the link fullscreen in the app and you have to kill the app, since there is no close button. The Softkeys don't work.
See here:
I guess I have to use the inappbrowser, but how can I enable it inside the map? Deactivating the POI's isn't an option.
Any help much appreciated!
In my case i had in controller.js:
'<a onclick="goto('+obj1[j].places.items[0][0]+','+obj1[j].places.items[0][1]+')">Open in google maps!</a>'
and then in function goto:
window.goto = function(lat,lon){
window.open("https://www.google.com/maps/dir//"+lat+","+lon+"/#",'_system', 'location=yes');
}
Edit:
(....your code....)
var popupContent1 = '<div id="locationContent1">' +
'<div> ' + item.storeName + '</div>' +
'<div> ' + item.address + '</div>' +
'<div> ' + item.city + '</div>' +
'<div>' +'<a onclick="goto('+item.latitude+','+item.longitude+')">Open in google maps!</a>'+ '</div>' +
'</div>';
createInfoWindow(marker, popupContent1);
//marker.bindTo('map',cat.data('goo'),'map');
var infoWindow = new google.maps.InfoWindow();
function createInfoWindow(marker, popupContent1) {
google.maps.event.addListener(marker,'click',function(){ infowindow.setContent(popupContent1);
infowindow.open(map,this);
})
}

Selenium isSelected() method for CheckBox always return false for Android

I have a list of checkboxes in my Android app, that i need to test. So when i use isSelected() method, it always return false, no matter if this Checkbox is checked or not.
Was trying to use findelementById() and byXpath(). Same result.
Here is the parts of the code what i used:
WebElement checkBox = driver.findElementById(appType + id);
if (!checkBox.isSelected()){
Reporter.log(backupDataType + " checkbox isn't checked. clicking on it...", true);
...}
Using Xpath:
checkBox = driver.findElementByXPath("//android.widget.CheckBox[#resource-id='" + appType + checkSms + "']");
if (!driver.findElementByXPath("//android.widget.CheckBox[#resource-id='" + appType + checkSms + "']").isSelected()){
Reporter.log(backupDataType + " checkbox isn't checked. clicking on it...", true);
...}
Path to the element is correct, because it's always clicking on it. No matter, if it checked, or not.
Considering you are using an android checkbox widget, you shall try using the getAttribute property of a WebElement as follows-
WebElement element = <find element by your locator strategy>; // in your case driver.findElementByXPath("//android.widget.CheckBox[#resource-id='" + appType + checkSms + "']");
String checkboxAttribute = element.getAttribute("checked");
if(!checkboxAttribute.equalsIgnoreCase("true")) {
Reporter.log(backupDataType + " checkbox isn't checked. clicking on it...", true);
...
}
P.S - try and practice saving a WebElement instead of finding it again.

Button.setTextPosition(Label.LEFT); render wrong

My NetBeans recently updated new CodenameOne plugin and it looks like the Button.setTextPosition(Label.LEFT); renders wrong position of the icon on Android and iOS, the icon always overlaps with the text. It still renders with the simulator correctly and the function still renders with Label.RIGHT, Label.TOP and Label.BOTTOM parameters correctly. Do you have any idea?
Thanks,
William
Shai, I think the problem is that the icon was scaled to font.getHeight() of the button.
public void start() {
if(current != null){
current.show();
return;
}
Form hi = new Form("Test", new BoxLayout(BoxLayout.Y_AXIS));
Font font = new Button("Test").getUnselectedStyle().getFont();
Image t = pictures.getImage("Play.png").scaled(font.getHeight(), font.getHeight());
hi.add(b(Button.LEFT, " Left 123", t))
.add(b(Button.RIGHT, " Right ", t))
.add(b(Button.TOP, " Top ", t))
.add(b(Button.BOTTOM, " Bottom ", t));
hi.add(b(Button.LEFT, " Left ", t))
.add(b(Button.RIGHT, " Right ", t))
.add(b(Button.TOP, " Top ", t))
.add(b(Button.BOTTOM, " Bottom ", t));
hi.show();
}
private Button b(int pos, String txt, Image t) {
Button btn = new Button(txt, t);
btn.setTextPosition(pos);
return btn;
}
Here is the screenshots:
Simulator:
Nexus (android):
I see the issue there, its a regression that only occurs with smaller icons since the width of the icon is used instead of the width of the text only in the case of left aligned text which is more rare.
We'll fix this in the next server update.

Managing data in android cache?

I'm trying to finish the 'backbone' of my app in the next 3 weeks, however, one of the few obstacles I stutter at is saving data. I've had a look at saving data internally, but there is limited tutorials from what I can find of reading and writing multiple lines to files in the apps cache directory.
Basically what I'm trying to do is save the values stored inside a fragment. This fragment resets all its values when the user clicks a button and changes text to match a page number. (A number of duplicates that contain various values.) I would do multiple fragments, however, thought it would be beneficial to use just one fragment to minimize storage space needed.
I've only got round to writing to the files, and created two methods to manage this which are then called on the click of a button. One creates these files and the other writes to them. Unfortunately I'm inexperienced using adb and could only find that the files are created, but don't know if they are being correctly written to. Is there any chance someone could review this and possibly assist with re-reading the files? Help is much appreciated.
The two methods (Warning: A great number of lines ahead):
public void createEmptyFiles() {
try {
outputTempExerciseFileE1 = File.createTempFile("temp_exercise_1",
".txt", outputTempExerciseDir);
outputTempExerciseFileE2 = File.createTempFile("temp_exercise_2",
".txt", outputTempExerciseDir);
outputTempExerciseFileE3 = File.createTempFile("temp_exercise_3",
".txt", outputTempExerciseDir);
} catch (IOException e) {
e.printStackTrace();
Log.w("rscReporter", "Encountered an error when creating empty files!");
}
}
public void writeTemporaryFiles() {
try {
if (counterAnotherExercise == 1) {
writerTemp = new FileWriter(outputTempExerciseFileE1);
writerTemp
.write(editTextExerciseName.getText().toString() + "\n"
+ counterNoSets + "\n" + counterRepsPerSet
+ "\n" + counterMeanRepTime + "\n"
+ counterMeanRepTimeRefined + "\n"
+ counterSetInterval);
writerTemp.close();
} else if (counterAnotherExercise == 2) {
writerTemp = new FileWriter(outputTempExerciseFileE2);
writerTemp
.write(editTextExerciseName.getText().toString() + "\n"
+ counterNoSets + "\n" + counterRepsPerSet
+ "\n" + counterMeanRepTime + "\n"
+ counterMeanRepTimeRefined + "\n"
+ counterSetInterval);
writerTemp.close();
} else if (counterAnotherExercise == 3) {
writerTemp = new FileWriter(outputTempExerciseFileE3);
writerTemp
.write(editTextExerciseName.getText().toString() + "\n"
+ counterNoSets + "\n" + counterRepsPerSet
+ "\n" + counterMeanRepTime + "\n"
+ counterMeanRepTimeRefined + "\n"
+ counterSetInterval);
writerTemp.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Any of the text files should look like:
editTextExerciseName
counterNoSets
counterRepsPerSet
counterMeanRepTime
counterMeanRepTimeRefined
counterSetInterval
Where the two methods are called:
// In a switch statement as there are around 15 buttons
case R.id.button_another_exercise_foreground:
// Increases page number in fragment
counterAnotherExercise++;
// This then checks the page number and changes text
checkPageNo();
// Writing to files is called, files were created in onCreateView()
writeTemporaryFiles();
// Resets all the counters, giving the imitation it is a completely new fragment
counterReset();
// default array exercise is then set to the page number which is then displayed as title
// For example: Exercise 1, Exercise 2, Exercise 3...
textViewExerciseTitle.setText(defaultArrayExercise);
break;
I only know the basics of Java and Android, for myself this is ambitious, however, you gotta learn somewhere! Additional suggestion for saving values are welcomed.
You don't really need files as you are only writing and then reading a handful of fixed data. Use SharedPreferences like this:
to write:
PreferenceManager.getDefaultSharedPreferences(YourActivity.this).edit().putString("editTextExerciseName", "my exercise").commit();
to read:|
PreferenceManager.getDefaultSharedPreferences(YourActivity.this).getString("editTextExerciseName");

Categories

Resources