XML parsing-best method, general discussion - XDA-University

I am relatively new to programing and have been teaching myself as I go. I am trying to now integrate ESPN's API into my app which outputs XML data. I have done enough research to understand that I need to use an XML parser and that the XML can be displayed as a list view or web view by adding HTML markup.
I would like this thread to become a general discussion for all new developers on what XML parsing is and what it does. How it works, the code behind it etc.
I am currently trying to modify a code snippet from the developer.google.com website.

Android includes built in libraries for XML Parsing.
You can see a minimal use of the library here:
Code:
import java.io.IOException;
import java.io.StringReader;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
public class SimpleXmlPullApp
{
public static void main (String args[])
throws XmlPullParserException, IOException
{
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput( new StringReader ( "<foo>Hello World!</foo>" ) );
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if(eventType == XmlPullParser.START_DOCUMENT) {
System.out.println("Start document");
} else if(eventType == XmlPullParser.START_TAG) {
System.out.println("Start tag "+xpp.getName());
} else if(eventType == XmlPullParser.END_TAG) {
System.out.println("End tag "+xpp.getName());
} else if(eventType == XmlPullParser.TEXT) {
System.out.println("Text "+xpp.getText());
}
eventType = xpp.next();
}
System.out.println("End document");
}
}
So essentially, you can grab the xml from ESPN, save it to a file, parse it with that library, and output as desired.
Full details here: http://developer.android.com/reference/org/xmlpull/v1/XmlPullParser.html

the fastest way I know is the parser written in c/c++ and compiled with ndk.

bitpushr said:
Android includes built in libraries for XML Parsing.
So essentially, you can grab the xml from ESPN, save it to a file, parse it with that library, and output as desired.
Full details here: http://developer.android.com/reference/org/xmlpull/v1/XmlPullParser.html
Click to expand...
Click to collapse
I will have to try out this code. Because I am learning as I go there are many things in java I don't yet understand which ultimately make it a lot harder to accomplish tasks but I am slowly catching on

If you want to do this in a .NET (Windows x86/64, Windows Mobile, Windows Phone) environment, or a Linux MONO environment then the following will carry out the bare minimum of parsing.
Assuming you have the data in an XML file :- PARAMS.XML in the same folder as the program, created similar to this:
Code:
<?xml version="1.0" encoding="UTF-8" ?>
<PARAMS>
<Library>TESTLIB</Library>
<Source>C:\RetData\</Source>
</PARAMS>
Then the following C# code will read and extract the parameters:
Code:
using System.Xml;
string LibName,RetDir;
XmlReader xrdr = XmlReader.Create(Application.StartupPath+"\\PARAMS.xml");
xrdr.ReadToFollowing("Library");
Libname=xrdr.ReadElementContentAsString();
xrdr.ReadToFollowing("Source");
RetDir = xrdr.ReadElementContentAsString();
xrdr.Close();
After executing this code then:
LibName = "TESTLIB"
RetDir = "C:\RetData\"
CAVEAT:
I mentioned that this is the bare minimum. An XmlReader object is a forward only reader. Also, this code has no error checking.
In this case the elements must be read in the order they occur or the reader will encounter a null element and throw an error.

Related

Theme Chooser themes, Windows, aapt, and uppercase letters in XML filenames

EDIT: A solution has been found, courtesy of XDA member titanic_fanatic, who compiled a Windows version of aapt that accepts uppercase letters in XML filenames! (Read his original message here.) I've attached it to this post. One of the biggest hurdles to effective theme creation in Windows is finally solved!
----------------------------------------------------------------------------------------​
Forgive me if this has already been asked, but I know that it's something that's annoyed theme developers under Windows for a while now. I seem to recall seeing hints about fixing this, but I've done search after search, and can't find it to save my life.
Theme Chooser theme developers under Windows are hobbled by the fact that XML filenames can't contain uppercase letters, which prevents us from theming certain applications (example: com_keramidas_TitaniumBackup.xml would be needed for Titanium Backup). I know that this is a problem related to aapt.exe. Has anyone come up with a workable solution for this issue? If not, I'd like to take a crack at it. I might not get anywhere, but I have nothing to lose.
Obviously, in order to do this, I'll need the source for it. I can do the heavy lifting regarding getting the source and working out how to compile it for Windows, but I need to know where the source is, what to get, and other requirements. If anyone can help and point me in the right direction(s), I'd really appreciate it!
MJPollard said:
Forgive me if this has already been asked, but I know that it's something that's annoyed theme developers under Windows for a while now. I seem to recall seeing hints about fixing this, but I've done search after search, and can't find it to save my life.
T-Mobile/CM7 theme developers under Windows are hobbled by the fact that XML filenames can't contain uppercase letters, which prevents us from theming certain applications (example: com_keramidas_TitaniumBackup.xml would be needed for Titanium Backup). I know that this is a problem related to aapt.exe. Has anyone come up with a workable solution for this issue? If not, I'd like to take a crack at it. I might not get anywhere, but I have nothing to lose.
Obviously, in order to do this, I'll need the source for it. I can do the heavy lifting regarding getting the source and working out how to compile it for Windows, but I need to know where the source is, what to get, and other requirements. If anyone can help and point me in the right direction(s), I'd really appreciate it!
Click to expand...
Click to collapse
Hmm .. + 1 with you .. but the only way is ... ask brut.all ....
Sent from my Galaxy Nexus using XDA App
qazsxdcfv said:
Hmm .. + 1 with you .. but the only way is ... ask brut.all ....
Click to expand...
Click to collapse
Thanks, I guess I'll have to after all (not that I mind doing it). Over 250 views and only one person to respond isn't giving me much hope that someone has an answer.
Have you found a solution for windows ?
Any solution?
Randomly came across this thread looking for info on compiling the aapt binary for Windows. I'm still looking for the answer for that but I do know the change that needs to be made and how to do that part, as I have already done this mod for aapt on Linux. You have to have a full build environment set up, and by that I mean set up to build a full ROM, like CM10 for example. The change to make is in the frameworks source code at frameworks/base/tools/aapt/Resource.cpp.
See this commit for the details:
http://review.cyanogenmod.org/#/c/24204/
Add the parts I highlighted in blue to the two lines below:
Code:
String16 baseName(it.getBaseName());
const char16_t* str = baseName.string();
const char16_t* const end = str + baseName.size();
while (str < end) {
if (!((*str >= 'a' && *str <= 'z')
[COLOR="RoyalBlue"][B]|| (*str >= 'A' && *str <= 'Z')[/B][/COLOR]
|| (*str >= '0' && *str <= '9')
|| *str == '_' || *str == '.')) {
fprintf(stderr, "%s: Invalid file name: must contain only [a-z[COLOR="RoyalBlue"][B]A-Z[/B][/COLOR]0-9_.]\n",
it.getPath().string());
hasErrors = true;
}
str++;
}
m4570d0n said:
Randomly came across this thread looking for info on compiling the aapt binary for Windows. I'm still looking for the answer for that but I do know the change that needs to be made and how to do that part, as I have already done this mod for aapt on Linux. You have to have a full build environment set up, and by that I mean set up to build a full ROM, like CM10 for example. The change to make is in the frameworks source code at frameworks/base/tools/aapt/Resource.cpp.
See this commit for the details:
http://review.cyanogenmod.org/#/c/24204/
Add the parts I highlighted in blue to the two lines below:
Code:
String16 baseName(it.getBaseName());
const char16_t* str = baseName.string();
const char16_t* const end = str + baseName.size();
while (str < end) {
if (!((*str >= 'a' && *str <= 'z')
[COLOR="RoyalBlue"][B]|| (*str >= 'A' && *str <= 'Z')[/B][/COLOR]
|| (*str >= '0' && *str <= '9')
|| *str == '_' || *str == '.')) {
fprintf(stderr, "%s: Invalid file name: must contain only [a-z[COLOR="RoyalBlue"][B]A-Z[/B][/COLOR]0-9_.]\n",
it.getPath().string());
hasErrors = true;
}
str++;
}
Click to expand...
Click to collapse
Thank you for your help but could you tell me where can I find frameworks/base/tools/aapt/Resource.cpp?
I don't understand where to find it?
Sorry to resurrect an old thread, but I've finally come across a Windows version of aapt.exe that accepts uppercase letters in XML filenames, courtesy of XDA user titanic_fanatic. I've modified the first post in the thread with the details. Happy theming!
MJPollard said:
Sorry to resurrect an old thread, but I've finally come across a Windows version of aapt.exe that accepts uppercase letters in XML filenames, courtesy of XDA user titanic_fanatic. I've modified the first post in the thread with the details. Happy theming!
Click to expand...
Click to collapse
That link does seem to work anymore (and the webpage gives malware warning in Norton).
Does anyone else have this file?

[Q] Impossible to hook a method in com.android.vending

Some week ago i posted into the request and index thread for set up a request to develop a module that will eliminate the need to have a certain amount of free space when you install app from the Play Store.
After some days i disassembled the play store apk [using APk_OneClick ] and i found the information and method i needed and wrote down into the forum, here my reply:
MonoS94 said:
Ok, i dig a bit into the play store apk for the 4.9.13 version in
Code:
com/google/android/finsky/download/
there is a class named
Code:
Storage
with two interesting method
Code:
dataPartitionAvailableSpace()
and
Code:
externalStorageAvailableSpace()
This two method return a long representing the available space into a particular partition using this formula [found in the partitionAvailable() method]
Code:
for (long l = localStatFs.getAvailableBytes(); ; l = localStatFs.getBlockSize() * localStatFs.getAvailableBlocks())
So hooking and replacing this two modules with a dummy version returning always full space we will defeat this annoying oddity, also being part of the play store apk i think that this will not affect any other app.
I hope that with this information someone will make a module.
Click to expand...
Click to collapse
I waited some days and about a week ago i download the ADT, set up the environment, learned a bit how to code for Android and Xposed and wrote down some code
Code:
package com.MonoS.FreeSpaceForPlayStore;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
public class Main implements IXposedHookLoadPackage {
private static final String GOOGLE_PLAYSTORE = "com.android.vending";
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.contains(GOOGLE_PLAYSTORE))
return;
XposedBridge.log("I'm in bro ;)" + lpparam.packageName);
findAndHookMethod("com.google.android.finsky.download.Storage", lpparam.classLoader, "dataPartitionAvailableSpace", XC_MethodReplacement.returnConstant(1073741824));
}
}
Compile the code, install on the phone, activate and reboot and the module don't work, it enter into the package but then throw me an ClassNotFoundError exception.
Then checked the name of all the method but they are right.
Then why can't my module hook the method??
Thanks for the attention

Build Variants / APK naming

So I can't seem to find an answer to get this to work the way i want, hoping someone here may know...
I have my gradle setup with different build variants and it works fine to switch between them or generate signed apk for the chosen variant. However what I'm looking to do (ideally in 1 click) is generate each variant's apk and name it accordingly with the version number and variant name.
Any ideas?
I've tried the following snippet
Code:
android {
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def fileName = outputFile.name.replace('.apk', "-${versionName}.apk")
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
but no joke, if i went to modify it..it froze android studio. thanks!

Help enabling downloads through webview (Kotlin)

Good day. I'm new to android development and I'm trying to develop a simple webview application, picked a nice template and went through the steps and made good progress, I managed to load my site fully and enable javascript, that works as intended, however I'm not able to make the app download anything, I host a few pdf files that should open or download through it, but nothing happens.
I looked at a few answers here and it is to my understanding that I need to specifically add a function for that, could you give me a hand? I have tried multiple different code and tweaking them, but I wasn't able to get it to work, here is my base code:
Code:
package com.logista.test.ui.home
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import android.app.DownloadManager
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.logista.test.R
class HomeFragment : Fragment() {
private lateinit var homeViewModel: HomeViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
homeViewModel =
ViewModelProvider(this).get(HomeViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_home, container, false)
val myWebView: WebView = root.findViewById(R.id.webview)
myWebView.webViewClient = WebViewClient()
myWebView.settings.javaScriptEnabled = true
myWebView.loadUrl("https://www.example.org/")
return root
}
}
I believe I should be adding
Code:
import android.app.DownloadManager
And tweak this
Code:
// Set web view download listener
web_view.setDownloadListener(DownloadListener {
url,
userAgent,
contentDescription,
mimetype,
contentLength ->
// Initialize download request
val request = DownloadManager.Request(Uri.parse(url))
// Get the cookie
val cookies = CookieManager.getInstance().getCookie(url)
// Add the download request header
request.addRequestHeader("Cookie",cookies)
request.addRequestHeader("User-Agent",userAgent)
// Set download request description
request.setDescription("Downloading requested file....")
// Set download request mime tytpe
request.setMimeType(mimetype)
// Allow scanning
request.allowScanningByMediaScanner()
// Download request notification setting
request.setNotificationVisibility(
DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
// Guess the file name
val fileName = URLUtil.guessFileName(url, contentDescription, mimetype)
// Set a destination storage for downloaded file
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
// Set request title
request.setTitle(URLUtil.guessFileName(url, contentDescription, mimetype));
// DownloadManager request more settings
request.setAllowedOverMetered(true)
request.setAllowedOverRoaming(false)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
request.setRequiresCharging(false)
request.setRequiresDeviceIdle(false)
}
request.setVisibleInDownloadsUi(true)
// Get the system download service
val dManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
// Finally, request the download to system download service
dManager.enqueue(request)
})
// Load button click listener
button_load.setOnClickListener{
// Load url in a web view
web_view.loadUrl(url)
}
}
Taken from here: https://android--code.blogspot.com/2018/03/android-kotlin-webview-file-download.html
I did the basics, renaming the function accordingly and such, but it gives me quite a few errors when building the app, for instance uri isn't defined, cookiemanager isn't defined, environment isn't defined, build isn't defined, and such, could you give me some guidance?

[DexKit] Xposed Module Jni Lib | An easy-to-use, high-performance dex deobfuscation library

Library: DexKit
Project Link: https://github.com/LuckyPray/DexKit
About: An easy-to-use, high-performance dex deobfuscation library. Easy to use your CMAKE/Android projects.
Highlight:
JNI multi-threaded processing Dex bytecode, more efficient than JVM implementation.
It single search is ms level, You can even inject the host application at runtime without causing an ANR, to the extent permitted.
You can use it to handle reinforced apps(use ClassLoader cookies).
API introduction​There are two APIs can meet most of your usage scenarios:
DexKit::BatchFindClassesUsingStrings
DexKit::BatchFindMethodsUsingStrings
Note: In all cases you should avoid searching for keywords that contain duplicate content, eg: {"key_word", "word"}, as this will cause tags to be overwritten, resulting in inaccurate search results. If there is such a need, open the advanced search mode as much as possible, and use the string to match the content exactly, for example, modify it to this: {"^key_word$", "^word$"}
Click to expand...
Click to collapse
And there are many other APIs:
DexKit::FindMethodCaller: find caller for specified method.
DexKit::FindMethodInvoking: find the called method
DexKit::FindMethodUsingField: Find method to get/set specified field
DexKit::FindMethodUsingString: find method used utf8 string
DexKit::FindMethod: find method by multiple conditions
DexKit::FindSubClasses: find all direct subclasses of the specified class
DexKit::FindMethodUsingOpPrefixSeq: find all method using opcode prefix sequence(op range: 0x00-0xFF)
DexKit::FindMethodUsingOpCodeSeq: find all method using opcode sequence(op range: 0x00-0xFF)
DexKit::GetMethodOpCodeSeq: get method opcode sequence(op range: 0x00-0xFF)
Note: At present, all instructions are only for standard dex instructions and do not include odex optimization instructions.
Click to expand...
Click to collapse
For more detailed instructions, please refer to dex_kit.h.
Quick start​However, this approach will import an extra so file. If you don't want to import an extra so file, please use the second/third method.
build.gradle:
Code:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
app/build.gradle:
Code:
dependencies {
implementation 'com.github.LuckyPray:DexKit:<version>'
}
​JAVA Example​DexKitBridge provides 2 factory methods to create Dexkit instances:
DexKitBridge.create(apkPath): normally, please use it.
DexKitBridge.create(classLoader, true): for reinforced apps, used classLoader and set option useCookieDexFile to true.
PS: DexKitBridge.create(classLoader, useCookieDexFile = false) ≈ DexKitBridge.create(apkPath), but the former may contain part of the system dex.
Java:
import io.luckypry.dexkit.DexKitBridge;
// ...
public class DexUtil {
static {
System.loadLibrary("dexkit");
}
public static void findMethod() {
// for no-reinforced apps please use apkpath to load, because of the exist of dex2oat and CompactDex(cdex),
// dexkit currently only handles StandardDex.
String apkPath = application.applicationInfo.sourceDir
// try-with-resources, auto close DexKitBridge, no need to call DexKitBridge.close()
// if you don't use try-with-resources, be sure to manually call DexKitBridge.close() to release the jni memory
try (DexKitBridge dexKitBridge = DexKitBridge.create(apkPath)) {
if (dexKitBridge == null) {
Log.e("DexUtil", "DexKitBridge create failed");
return;
}
List<DexClassDescriptor> classes = dexKitBridge.findSubClasses("android.app.Activity", null);
for (DexClassDescriptor clazz : classes) {
String name = clazz.getName();
String simpleName = clazz.getSimpleName();
Class<?> clz = clazz.getClassInstance(hostClassLoader);
Log.i("DexUtil", "findSubClasses: " + clz);
}
} catch (Throwable e) {
Log.e("DexUtil", Log.getStackTraceString(e));
}
}
}
If you have problems using it, please create an issue on the github repo.
Reserved

Categories

Resources