Hiding HTML Elements with no Id and Class Name in a WebView - android

I have gone through multiple question on stack overflow but could not find working answer. I need to hide html elements with no id and class name in webview android.

First of all it's probably impossible to do it in Java so you need to do it in Javascript. Second problem is that I don't think there is a simple or good enough way to do that. If you own the HTML page try to add id or class to elements you want to hide.
When you do that you can run it like this:
String classToHide = "some-class";
String jsCode = "for (let el of document.querySelectorAll('." + classToHide + "')) el.style.visibility = 'hidden';";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
webView.evaluateJavascript(jsCode, null);
} else {
webView.loadUrl("javascript:" + jsCode);
}
Note that you need javacsript enabled like this:
webView.getSettings().setJavaScriptEnabled(true);

Related

How can I list all opened activities on Xamarin.Android?

I'm new to mobile development and I'm learning Xamarin. I already have some experience with C#.
I'm currently studying hierarchical navigation with Xamarin.Android.
In my project, I have the main activity, second and third activities where I navigate between them. I would like to know how can I list all opened activities?
For example, if I'm in the main activity and I request the list of opened activities, the function should return me a list with the name of the main activity only, but if I'm in the third activity, the function should return me a list containing the name of the main, second and third activities, more or less like this:
MainActivity
SecondActivity
ThirdActivity
How can I get this information?
I am working with Xamarin.Android and not Xamarin.Forms.
You could use ActivityManager to get the details of the Activities.
The GetRunningTasks would return a list of the tasks that are currently running. But this method was deprecated in API level 21. For backwards compatibility, it will still return a small subset of its data: at least the caller's own tasks, and possibly some other tasks such as home that are known to not be sensitive.
For now, we only could use the BaseActivity to get the first activity and use the TopActivity to get the current one.
ActivityManager m = (ActivityManager)this.GetSystemService(ActivityService);
var runningTaskInfoList = m.GetRunningTasks(10);
foreach (var item in runningTaskInfoList)
{
string first = item.BaseActivity.ShortClassName;
string current = item.TopActivity.ShortClassName;
}
thanks for your help.
I think that's almost it. I made a small modification to your code, looking like this:
public string ListAllActivities()
{
string result = "";
ActivityManager activityManager = (ActivityManager)this.GetSystemService(ActivityService);
var runningTaskInfoList = activityManager.GetRunningTasks(10);
foreach (var item in runningTaskInfoList)
{
string first = item.BaseActivity.ShortClassName.Substring((item.BaseActivity.ShortClassName.LastIndexOf('.') + 1), item.BaseActivity.ShortClassName.Length - (item.BaseActivity.ShortClassName.LastIndexOf('.') + 1));
string current = item.TopActivity.ShortClassName.Substring((item.TopActivity.ShortClassName.LastIndexOf('.') + 1), item.TopActivity.ShortClassName.Length - (item.TopActivity.ShortClassName.LastIndexOf('.') + 1));
result += first + " - " + current + "\n";
}
return result;
}
And the result is this:Activities Stack
When I'm in the third activity, I don't get the list for the second activity. If I, being in the third activity, could list the second and main activities, the issue would be resolved.

textView updates do not show

Ok - preface with I am new to android and new to java as well. But I did code in a previous lifetime.....
I am working on an application and now trying to pull some methods out and place into a utility class. In particular, I have a method which updates text views that I wanted to move out of an activity.
When in the activity, I had two versions of the method the only difference being that one would accept a view in the parameter list (I used this to populate some fields in a custom dialog). They all worked fine.
Once placed in the external utility package/class, the method no longer works - no errors, and it appears to have all it needs - I've done some logging and the view claims to be visible and the textview ids appear to be correct. Yet nothing changes on the screen.
I'm guessing this is something completely obvious and stupid but I can't seem to sort it out.
package xxx.xxx.Utility;
(some imports)
public class Utility {
public static void updateTextView(int id, String opt_data, View v) {
String TAG = "updateTextView: ";
if (v.getVisibility() == View.VISIBLE) Log.i(TAG," visible");
TextView tvTarget = (TextView) v.findViewById(id);
if (tvTarget == null) {
Log.i(TAG, "Error: updateTextView target is null");
}
if (opt_data != null) {
if (tvTarget != null) {
tvTarget.setText(opt_data);
}
} else {
if (tvTarget != null) {
tvTarget.setText(" ");
}
}
}
}
EDIT w/ Additional Info:
In the inital description I mentioned that this method was also being used to populate some fields of a pop-up dialog with data. In fact, I can request any number of dialogs in that manner and they all display properly and with the correct (and different) data. So it seems to fail only when trying to update the tv data of the main activity (the initial) view.
I'm guessing this is something completely obvious and stupid but I
can't seem to sort it out.
It helps to get the root(?) parent (?) view properly. IE,
currentView = this.findViewById(android.R.id.content).getRootView();
and now all is well.

Parsing XML in android, but not the attributes

I'm trying to parse a really simple XML in my android app, for example:
<data>
<section id="123">bla</section>
<area>blabla</area>
</data>
But in every example I find I see how to extract the data in the attribute (id being 123) when what I need to extract is the data displayed - "bla" and "blabla".
How do I do that using SAXParser?
this tutorial respond to exactly what you want hope you gonna enjoy
See how The characters method in the parser handler takes care of extreacting an element's text value
The characters method in the parser handler takes care of an element's text value.
You need to override the characters method.
Well, writing parsers by hand is of course fun & error-prone, I'd however recommend using a framework - even a simple one like the built in android.sax package.
Using the StartElementListener (if you want the attributes at all that is) & EndTextListener (captures the body text of the element):
class Section implements StartElementListener, EndTextElementListener {
String mValue;
String mId;
#Override
public void end(String body) {
mValue = body;
}
#Override
public void start(Attributes attributes) {
mId = attributes.getValue("", "id");
}
}
Listeners of these types are attached to Elements derived from a RootElement, like so:
Section section = new Section();
RootElement data = new RootElement("data");
// Use "requireChild" if a "section" is required as a child of "data".
Element s = data.getChild("section");
s.setStartElementListener(section);
s.setEndTextElementListener(section);
try {
Xml.parse(xml, data.getContentHandler());
} catch (SAXException e) {
}
Basically, this helps you build content handlers for SAX that cares about the hierarchy and keeps track of what element you are parsing easily. Short & nifty code also I guess.

Trying to use FlexGlobals to access ArrayCollection?

I am currently trying to use the new approach of using FlexGlobals to access an ArrayCollection that I have on the Default view of a mobile application I am developing. Below is the code that makes up the creation and population of that array on the Default view which happens as soon as the app is initiated:
private var ids:ArrayCollection = new ArrayCollection();
private function loop():void
{
var index:int;
for( index = 0; index < compsCollection.length; index++ )
{
trace( "Element " + index + " is " + compsCollection[index].comp_id );
trace( ids.length);
ids.addItem(compsCollection[index].comp_id);
}
}
Now when this code is run i can clearly see from the console that the "ids" ArrayCollection is being populated correctly. Now on a different view within the app I want to access this data and use it for various things. I have used the code below to try and access the data for the ArrayCollection:
protected var ids_list:ArrayCollection = new ArrayCollection();
protected function view1_viewActivateHandler(event:ViewNavigatorEvent):void
{
var obj:Object = FlexGlobals.topLevelApplication.parameters;
ids_list.source = obj.ids;
trace(ids_list.length);
}
When i tried this i do not get an error however the Trace statement returns "0". So I also tried:
protected function view1_viewActivateHandler(event:ViewNavigatorEvent):void
{
ids_list.source = FlexGlobals.topLevelApplication.parameters.ids;
trace(ids_list.length);
}
Which again returned "0" in the trace statement. I finally tried this to see if it would work:
protected function view1_viewActivateHandler(event:ViewNavigatorEvent):void
{
ids_list.source = FlexGlobals.topLevelApplication.ids;
trace(ids_list.length);
}
When I tried this and navigated to the view where this code would be initated I got this error:
Error #1069: Property ids not found on Main and there is no default value.
I could only assume that the ArrayCollection I had created in my default view has no value once I navigate away from it. Is there anyway anyone can please help me with this as there seems to be next to no documentation on how to do these types of things with FlexGlobals? Thanks
You can't access a private property, try it
/*
Replace
private var ids:ArrayCollection = new ArrayCollection();
by
*/
private var _ids:ArrayCollection = new ArrayCollection();
public set ids(value:ArrayCollection):void{
_ids = value;
}
public get ids():ArrayCollection{
return _ids
}
It's extremely bad practice for a child component to know anything at all about the structure of its parent/ancestor. That being said, the reason you can't see the value of the Application's member variable is because you've made it private. If you want it to be visible outside its own scope, you need to make it public.
Pass the ArrayCollection as a property to your view from the main application.

Link keyword in TextView to file/directory

Is there any way that I can link a keyword in a TextView to a file or directory on the user's SD card? My app produces stack trace files when it crashes and I want the user to able to click a link in my About dialog to view either the latest one or the folder containing all of them. (Something like "If this app crashes, please send [link]the latest stack.trace file[/link] to us at myapp#example.com.")
I know it is possible to use the following code to make a Web link but I tried to modify it to use "file:///sdcard/path/to/file/stack.trace" which causes my app to Force Close when the link is clicked.
<string name="strSample">This is Web link to <a href="http://www.google.com">Google</a>!</string>
final TextView tvSample = (TextView)findViewById(R.id.tvSample);
tvSample.setMovementMethod(LinkMovementMethod.getInstance());
String strSample = getResources().getString(R.string.strSample);
tvSample.setText(Html.fromHtml(strSample));
You can extend your method by replacing Html.fromHtml(strSample) part which returns Spannable. Create your own Spannable and add ClickableSpan to it. In the onClick method you can place whatever logic you need. Here's quick examle that you can extend
public Spannable getProfileLink(final Context context) {
final String name = firstName + " " + lastName;
Spannable spans = SpannableStringBuilder.valueOf(name);
ClickableSpan clickSpan = new ClickableSpan() {
#Override
public void onClick(View widget) {
// TODO - call profile here
Toast.makeText(context, "Will call profile", Toast.LENGTH_LONG);
}
};
spans.setSpan(clickSpan, 0, name.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return spans;
}

Categories

Resources