[Q] Last question about database - Android Software Development

I have currently developed 90% of my app, and i need help at the last part.
I want to thange the default database path to another user spezified path.
i get an error when i try this:
Code:
String myPath = "/data/data/com.android.providers.settings/databases/settings";
SQLiteDatabase myDB = SQLiteDatabase.openDatabase(myPath, null,SQLiteDatabase.OPEN_READWRITE);
The Debug monitor shows:
Code:
FATAL EXCEPTION: main
android.database.sqlite.SQLiteException: unable to open database file
i hope someone here can help me

It can't open it because it's not there.
You need to create the DB in that "settings" subdirectory. Or you can just use adb shell and copy the DB to .../settings.

the database exists, found with root explorer
when i want to acces the database with:
SQLiteDatabase myDB = set.this.openOrCreateDatabase("/data/data/com.android.providers.settings/databases/settings.db", MODE_PRIVATE, null);
it says, unable to open file, that means that the database not exists, but there is one, please, thats the last part, i need help

ilendemli said:
Code:
String myPath = "/data/data/com.android.providers.settings/databases/settings";
SQLiteDatabase myDB = SQLiteDatabase.openDatabase(myPath, null,SQLiteDatabase.OPEN_READWRITE);
Click to expand...
Click to collapse
Didn't you forget the ".db" at the end of /data/data/com.android.providers.settings/databases/settings ?

tryed with db and without db, the same problem:
Code:
SQLiteDatabase myDB = set.this.openOrCreateDatabase("/data/data/com.android.providers.settings/databases/settings.db", MODE_PRIVATE, null);

What does the Debug monitor shows when you do openOrCreateDatabase ? (can't be "unable to open database", if it were it would create it)

I am catching the Exception and showing the error as toast message,
at the debugger there is this error:
Database: sqlite3_open_v2("/data/data/com.android.providers.settings/settings.db", &handle, 6, NULL) failed

According to this link :http://www.sqlite.org/c3ref/open.html, you should be able to execute sqlite3_errmsg to have a description of the error.
But I have to admit that I don't know if you can do that easily with the SDK :/ I don't really know how it handles errors in this case (cause "failed" isn't really speaking to me ^^)
Edit : Hey, I just spotted something ! You missed your shot in writing the path to settings.db !
You wrote : /data/data/com.android.providers.settings/settings.db
It is : /data/data/com.android.providers.settings/databases/settings.db

I tryed it.. annd.... the same error..
if i try:
Code:
SQLiteDatabase myDB = set.this.openOrCreateDatabase("/data/data/com.android.providers.settings/databases/settings.db", MODE_PRIVATE, null);
it should normally create a new database at the dir.
when i type /data/data/.file/settings.db
there will be created the database, but at com.android.providers.settings/databases/ or all other com.* folders, it haves no permission.. :/

Try to add WRITE_SECURE_SETTINGS permission to your manifest then. Perhaps it will unlock it

Code:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
alot of permissions xD i will try it
€: nope, no permission.

Well, I think I've reached my limit ^^
I'll go with the "If you don't have and can't have the permission to touch it, then don't" and try to find an API that do the things you want.
BTW, can you explain what you want to do with this DB ?

i want to change "wifi_http_proxy" and "wifi_http_port"

Are you sure that these fields even exist ?
I can find http_proxy, but no wifi_http_proxy nor wifi_http_port :/

which android do you have? 2.1? or 2.2?

2.2, but I'm using the official SDK website as a reference (and Google, obviously ^^)

can you change proxy settings manually?
Virtual Device:
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
My Phone:

Yes, I have the same screen as yours (2nd one).

hmm.. have you ever tryed to change the settings? try it to change, and then open the database /data/data/com.android.providers.settings/databases/settings.db -> system and then look for "wifi_http_proxy" and "wifi_http_port"

I'll try it once I get home. I'm at work now, and they locked the possibility to connect something with USB :/
I'll tell you what I'll see.

Related

[Q] Commands for Hardware controll

Hello,
i just starting with C# dev. and now i search the "commands" or the "way" to controll the Mobile phone.
i use a HTC Leo WinMo 6.5.3 and VB2010 or VB2008. the first little "hello world" app runs great, bit i want to controll the Hardware, like enable or disable the Camera LED or something link that.
other phones like the Sonim xp3 have a "Developer Readme" and list the complet commands for hardware access.
i search for the HTC Leo the same, but i found only the "Microsoft WinMo Dev." side with the standart commands.
give it a "Dev HowTo" from HTC for Leo or something like that?
thank you
I'd go with a bit of IDA (or PE Explorer, if it can show DLL entrypoints) and try disassembling the camera.dll or HTCCameraUtility.dll files from OEMDrivers/camera packages. I bet there will be one entrypoint named something like EnableLight and DisableLight.
As OndraSter said, disassembling files is the only way to learn how to control hardware.
CreateFileW + DeviceIoControl are typically used to control leds (excluding camera's led (at least on X1, TP2, etc)).
All leds can be controlled directly using "I2C1:" device or manufacter's wrapper (on SE X1 there is "LED1:" device).
Kay, i installed the PE Explorer, i open the HTCCameraUtility.dll and the Camera.exe from the windows dir, but in both cases the PE Explorer disable the disassembling function. i try a other exe file and this works fine with pe explorer...
and now? what means "IDA" ?
IDA stands for Interactive Disassembler, which is ... disassembler of dll/exe/... for many platforms (win32, wince arm etc supported in demo version).
When I get home (tomorrow, on saturday, or the day after on sunday), I will help you with that, but I dont own any LED-flash integrated device, so I'll have to do a lot more work .
@ultrashot
I didn't realize it might be on I2C, thanks for pointing that out
- Andrew
Attention, as usual: All code below is rather device-specific. If you don't know what you do, don't use it!
Probably i2c_ functions are the same on all htc devices (at least I hope so).
On Kovsky I use these functions to control i2c devices directly:
*.h:
Code:
#define I2CMgr_WriteMultiBytes_Ioctl 0x80100024
#define I2CMgr_WriteByte_Ioctl 0x8010000C
#define I2CMgr_ReadMultiBytes_Ioctl 0x80100028
#pragma pack(1)
typedef struct
{
unsigned char device_id;
unsigned char smth1;
unsigned short address;
unsigned int inBufLength;
unsigned char *inBuf;
}I2C;
typedef struct
{
unsigned char device_id;
unsigned char address;
unsigned short data;
}I2C2;
#pragma pack()
.cpp:
Code:
int i2c_write(int device_id, int address, unsigned char *buf, int buf_size)
{
HANDLE device=CreateFileW(L"I2C1:",0xC0000000,0,0,3,0,0);
I2C i2c;
i2c.device_id=device_id;
i2c.address=address;
i2c.smth1=1;
i2c.inBufLength=buf_size;
i2c.inBuf=buf;
for (int x=0;x<3;x++)
{
if (DeviceIoControl(device,I2CMgr_WriteMultiBytes_Ioctl,&i2c,sizeof(I2C),NULL,NULL,NULL,NULL))
{
CloseHandle(device);
return S_OK;
}
DeviceIoControl(device,0x80100014,&i2c,sizeof(I2C),NULL,NULL,NULL,NULL);
Sleep(0xA);
}
CloseHandle(device);
return -1;
};
int i2c_writewbyte(int device_id, int address, unsigned short data)
{
HANDLE device=CreateFileW(L"I2C1:",0xC0000000,0,0,3,0,0);
I2C2 i2c;
i2c.device_id=device_id;
i2c.address=address;
i2c.data=data;
for (int x=0;x<3;x++)
{
if (DeviceIoControl(device,I2CMgr_WriteByte_Ioctl,&i2c,sizeof(I2C2),NULL,NULL,NULL,NULL))
{
CloseHandle(device);
return S_OK;
}
DeviceIoControl(device,0x80100014,&i2c,sizeof(I2C2),NULL,NULL,NULL,NULL);
Sleep(0xA);
}
CloseHandle(device);
return -1;
};
int i2c_read(int device_id, int address, unsigned char *outBuf, int outBufLength)
{
HANDLE device=CreateFileW(L"I2C1:",0xC0000000,0,0,3,0,0);
I2C i2c;
i2c.device_id=device_id;
i2c.address=address;
i2c.smth1=1;
i2c.inBufLength=outBufLength;
i2c.inBuf=outBuf;
for (int x=0;x<3;x++)
{
if (DeviceIoControl(device,I2CMgr_ReadMultiBytes_Ioctl,&i2c,sizeof(I2C),outBuf,outBufLength,NULL,NULL))
{
CloseHandle(device);
return S_OK;
}
DeviceIoControl(device,0x80100014,&i2c,sizeof(I2C),NULL,NULL,NULL,NULL);
Sleep(0xA);
}
CloseHandle(device);
return -1;
};
For example, I get info from Kovsky's lightsensor this way. You shouldn't use this code on other devices.
Code:
int lightsensor_read()
{
unsigned char buf[2]={0,0};
int res=i2c_read(MICROP_KLT, MICROP_KLT_ID_LIGHT_SENSOR_KOVS, buf, sizeof(buf));
if (res!=S_OK)
return -1;
int r3=buf[0];
int r2=buf[1];
r3=r3&3;
r2=r2|(r3<<8);
return r2;
};
Full code here: http://forum.xda-developers.com/showpost.php?p=7121525&postcount=231
Debugging on PPC and...
Stress test your application with UAEDT = Unrecoverable Application Error Debugging Tool.
UAE Debugging Tool (UAEDT) is a debug monitor, stress tester etc. for developers of Windows Mobile software. A great free alternative to IDA Pro: assembler/disassembler though of course not as advanced
Ultimate device/radio commander AT Commander :: use only if you know what you are doing it can brick your phone easily!!
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
[PC] ATCommander;
http://atcommander.com
The above link does not provide us with much information / links
Thus I searched some more and came up with;
http://atcommander.com/download/
Same page though not reachable via the first link. Anyway here you can download the latest .zip or .exe
Also do not forget to check this link;
http://atcommander.com/public/
Here some AT Commands reference links provided in a pdf file;
http://atcommander.com/download/AT_Command_Specification/
[PPC] ATCommander;
http://forum.xda-developers.com/showthread.php?t=375395
ChARMeD is a Windows Mobile / Pocket PC / Win CE (for ARM CPUs) Disassembler and Assembler
The name ChARMeD stands for:
Carolo's Hexadecimal ARM Editor and Disassembler
ARM Classic Processors
ARM Infocenter
Use all these applications with caution!!
o/~

Accessing full resolution photo of Lumia 1020

I thought it'll be nice to post this here, in any event that it's needed in future. So there was an app called phriz.be in Nokia Collection that was released recently, it was the first third party app that have the ability to upload full resolution photo. I gave it a try on reverse engineering it, hoping that it was an undocumented API and not a new capability.
Unfortunately, there's simply no way to do it unless the device is interop unlocked which is rather useless on Nokia Lumia 1020 when the only WP8 device that's unlocked is Samsung Ativ S.
Deploying an app with such capability will give you the following:
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Anyway.
<Capability Name="ID_CAP_MEDIALIB_PHOTO_FULL" />
Code:
private struct <getPhotos>d__2a : IAsyncStateMachine
Code:
this.<>4__this.IsPhotoLoading = true;
this.<>4__this.PhotoList.Clear();
taskAwaiter = this.<>4__this._deviceService.GetPhotos(this.<>4__this._currentAlbumName, 0, StateData.RecentMaxCount, true).GetAwaiter();
System.Collections.Generic.List<PhotoDisplay> arg_C9_0 = taskAwaiter.GetResult();
taskAwaiter = default(TaskAwaiter<System.Collections.Generic.List<PhotoDisplay>>);
System.Collections.Generic.List<PhotoDisplay> list = arg_C9_0;
this.<list>5__2b = list;
System.Collections.Generic.List<PhotoDisplay>.Enumerator enumerator = this.<list>5__2b.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
PhotoDisplay current = enumerator.Current;
this.<>4__this.PhotoList.Add(current);
}
}
finally
{
if (flag)
{
((System.IDisposable)enumerator).Dispose();
}
}
this.<>4__this.TryShowMoreLink();
this.<>4__this.RaisePropertyChanged("IsPhotoAvailable");
Code:
// Phrizbe.ViewModel.MainViewModel
private readonly IDeviceService<PhotoDisplay, DocumentDisplay, AlbumDisplay, TransferLogItem, ActivityLogItem, ActivityLog> _deviceService;
Code:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
namespace Phrizbe.Lib.Model
{
public interface IDeviceService<P, D, A, TL, ALI, AL>
{
void AddActivityLogItem(string deviceName, long deviceId, long deviceOSPlatform, string emailAddress, ALI logItem);
void AddApprovedDevice(string deviceName);
bool AddDownloadBackgroundTransfer(ALI ali, Target sender);
string AddUploadBackgroundTransfer(TransferItemDetail detail);
void ClearCachedPhotos();
void CreateTransferThumbnail(byte[] bytes, string fileName);
List<AL> GetActivityLogs();
Task<ObservableCollection<string>> GetAlbumNames();
Task<List<A>> GetAlbums();
Task<P> GetAlbumThumbnail(string albumName);
string GetCleanFileName(string fileName);
Device GetDeviceInfo();
Task<List<D>> GetDocuments(bool useCache);
Task<P> GetPhoto(string albumName, string fileName, bool useCache);
Task<List<P>> GetPhotos(string albumName, int startIndex, int returnCount, bool useCache);
Task<LocationReport> GetLocation(bool useCache);
bool IsApprovedDevice(string deviceName);
bool IsNetworkAvailable();
bool IsThumbnailDownloaded(long transferId);
long LoadDeviceId();
void RemoveActivityLogItem(string deviceName, ALI logItem);
void RemoveBackgroundTransfer(string requestId, bool forceRemove);
void RemoveActivityLog(string deviceName);
void SaveDeviceId(long deviceId);
Task<bool> SaveFile(ReceiveDataResponse response, string fileName, ActivityContentTypes contentType);
void SaveLogData();
Task<bool> SavePreviewFile(ReceiveDataResponse response, string fileName, long transferId);
void UpdateActivityLogNewCount(string deviceName, long deviceId, int count, bool saveLogData);
}
}
Task<P> GetPhoto(string albumName, string fileName, bool useCache);

[GUIDE][TUT]Remove useless alphabets from pin lockscreen

Simple Guide To make Pin Lockscreen from:
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
To​​
Requirements:
1. Knowledge of compiling/recompiling apk
2. Framework-res.apk of your phone
Steps:
1. De-compile framework-res.apk
2. After decompiling go to framework-res.apk\res\values folder and open arrays.xml
3. In arrays.xml find
Code:
<string-array name="lockscreen_num_pad_klondike">
It must be like this
Code:
<string-array name="lockscreen_num_pad_klondike">
<item></item>
<item></item>
<item>ABC</item>
<item>DEF</item>
<item>GHI</item>
<item>JKL</item>
<item>MNO</item>
<item>PQRS</item>
<item>TUV</item>
<item>WXYZ</item>
</string-array>
Simply remove all alphabets from it abc,def, so on
So that it look like this
View attachment 3098201
Save and close it.
4. In same folder open styles.xml and find
Code:
<style name="Widget.Button.NumPadKey" parent="@style/Widget.Button">
It must be something like this
Code:
<style name="Widget.Button.NumPadKey" parent="@style/Widget.Button">
<item name="textSize">34.0dip</item>
<item name="textStyle">normal</item>
<item name="textColor">#ffffffff</item>
[COLOR="Red"]<item name="gravity">left|center</item>[/COLOR]
<item name="background">?selectableItemBackground</item>
[COLOR="Red"]<item name="paddingLeft">20.0dip</item>[/COLOR]
<item name="paddingBottom">10.0dip</item>
<item name="singleLine">true</item>
<item name="fontFamily">sans-serif</item>
</style>
Simply change the red line with this
Code:
<item name="gravity">center</item>
Code:
<item name="paddingLeft">0.0dip</item>
Remeber 20.0dip we changed to 0.0dip will use it later. [maybe it is different in your case whatever it is just remember it]
So that the whole code looks like this
View attachment 3098219
We just made the keys 1,2,3 etc in center
5. Now go to framework-res.apk\res\layout folder and open keyguard_pin_view.xml
Find this line
Code:
<[COLOR="Red"]ImageButton androidprv:id="@id/key_enter"[/COLOR] androidprv:paddingRight="30.0dip" androidprv:layout_width="0.0px" androidprv:layout_height="fill_parent" androidprv:src="@drawable/sym_keyboard_return_holo" androidprv:layout_weight="1.0" androidprv:contentDescription="@string/keyboardview_keycode_enter"
style="@style/[COLOR="Red"]Widget.Button.NumPadKey[/COLOR]" />
Since we changed the style of Widget.Button.NumPadKey to fix it for enter key we will add this in the above line.
Remember the 20.0dip we changed its placed here if something else in your case put that
Code:
androidprv:paddingLeft="20.0dip"
Now new line will look like this
Code:
<ImageButton androidprv:id="@id/key_enter" [COLOR="Red"]androidprv:paddingLeft="20.0dip"[/COLOR] androidprv:paddingRight="30.0dip" androidprv:layout_width="0.0px" androidprv:layout_height="fill_parent" androidprv:src="@drawable/sym_keyboard_return_holo" androidprv:layout_weight="1.0" androidprv:contentDescription="@string/keyboardview_keycode_enter" style="@style/Widget.Button.NumPadKey" />
Since we made the keys in center then pin we enter is not above the 2 key so to make the pin in center find
Code:
<TextView androidprv:textAppearance="@style/TextAppearance.NumPadKey" androidprv:gravity="center" [COLOR="Red"]androidprv:id="@id/pinEntry"[/COLOR] androidprv:background="@null" androidprv:paddingLeft="40.0dip" androidprv:layout_width="0.0dip" androidprv:layout_height="fill_parent" androidprv:cursorVisible="false" androidprv:singleLine="true" androidprv:editable="true" androidprv:layout_weight="1.0" androidprv:imeOptions="actionDone|flagForceAscii" androidprv:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left" />
Add this in the above line
Code:
androidprv:paddingLeft="40.0dip"
Just double of 20.0dip
Now changed line will look like this
Code:
<TextView androidprv:textAppearance="@style/TextAppearance.NumPadKey" androidprv:gravity="center" androidprv:id="@id/pinEntry" androidprv:background="@null" [COLOR="Red"]androidprv:paddingLeft="40.0dip"[/COLOR] androidprv:layout_width="0.0dip" androidprv:layout_height="fill_parent" androidprv:cursorVisible="false" androidprv:singleLine="true" androidprv:editable="true" androidprv:layout_weight="1.0" androidprv:imeOptions="actionDone|flagForceAscii" androidprv:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left" />
6. Save and Recompile and replace framework-res.apk and enjoy clean beautiful lockscreen.
If you like It Hit Thanks Button

Heart Rate Sensor Problem

Hi guys, my heart rate monitor sensor is not working and the sensor doesn't even light up, which means it's not working AT ALL! And recently I even noticed Antutu and CPU-Z(Sensor Section) doesn't even detect it! (Screenshot below) What may be the cause of this?
Here is the logcat output of the BioSensor:
Code:
E/EnterpriseSharedDevicePolicy( 1132): isSharedDeviceEnabled
E/SensorService( 1132): Error activating sensor 18 (Operation not permitted)
E/SensorService( 1132): Error activating sensor 18 (Operation not permitted)
E/MaximBio( 1132): File Open Failed : /sys/class/sensors/hrm_sensor/led_current
E/MaximBio( 1132): File Open Failed : /sys/class/sensors/hrm_sensor/led_current2
E/MaximBio( 1132): File Open Failed : /sys/class/sensors/hrm_sensor/lib_ver
E/audio_hw_primary( 338): [MAXIM] setDSM_tx_Control()....dsm_enable : 0, dsm_opened : 1, adev->mode : 0
E/LocSvc_libulp( 1132): I/int ulp_msg_process_system_update(UlpSystemEvent): systemEvent:5
E/LocSvc_libulp( 1132): I/int ulp_msg_process_start_req(), at ulp state = 1
E/LocSvc_ApiV02( 1132): I/<--- void globalRespCb(locClientHandleType, uint32_t, locClientRespIndUnionType, void*) line 125 QMI_LOC_GET_BEST_AVAILABLE_POSITION_REQ_V02
E/LocSvc_libulp( 1132): I/int ulp_brain_process_zpp_position_report(loc_sess_status, LocPosTechMask, const UlpLocation*), report ZPP position to providers,report_position = 1
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Was your heart rate monitor working before? Have you tried doing a hard factory reset to see if it will help?
DarkGuyver said:
Was your heart rate monitor working before? Have you tried doing a hard factory reset to see if it will help?
Click to expand...
Click to collapse
I didn't try the heart sensor before, never really gave it much thought...
Yes, I've tried to do a Hard Reset, I even flashed new firmware via Kies and made the Soft Reset (Take of the battery, press power btn for 1 min, yadayada) and it still doesn't work... I've uploaded a logcat check 1st post.
I'd take your phone to a Samsung Service Center and ask them to fix it for you. Or take it back to the retailer for repairs as it maybe faulty.
Btw did u get the solution b/c I have same problem

[Tutorial] Learn to parse HTML Pages on Android with JSoup

Hello,
I create that thread to offer you a tutorial learning you to parse HTML pages on Android by using the JSoup Library. You can also discover this tutorial in video on Youtube :
When you make Android applications, you can have to parse HTML data or HTML pages got from the Web. One of the most known solution to make that in Java is to use JSoup Library. Like said on the official website of JSoup : "It is a Java library for working with real-world HTML. It provides a very convenient API for extracting and manipulating data, using the best of DOM, CSS, and jquery-like methods."
JSoup can be used in Android applications and we're going to study how to parse an HTML Page on Android with JSoup.
First, you need to add the JSoup dependency in your Gradle build file :
Code:
compile 'org.jsoup:jsoup:1.10.1'
For our example, we are going to download the content of the SSaurel's Blog and display all the links of the main page. To download the content of a website, JSoup offers the connect method and then a get method. This last method works synchronously. So, we should call these methods in a separated Thread. Our application will have just a simple layout with a Button to launch the download of the website and a TextView to display the links.
It will have the following form :
Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.ssaurel.jsouptut.MainActivity">
<Button
android:id="@+id/getBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get website"
android:layout_marginTop="50dp"
android:layout_centerHorizontal="true"/>
<TextView
android:id="@+id/result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Result ..."
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:layout_below="@id/getBtn"
android:textSize="17sp"/>
</RelativeLayout>
In the main Activity of the application, we are going to get instances of the Button and the TextView from our layout. Then, we set a click listener on the Button to start the download of the website when the user will click it.
In the getWebsite() method, we create a new Thread to download the content of the website. We use the connect() method of the Jsoup object to connect the application to the website, then we call the get() method to download the content. These calls return a Document object instance. We have to call the select() method of this instance with the query to get all the links of the content. This query returns an Elements instance and finally, we have just to iterate on the elements contained in this object to display the content of each link to the screen.
At the end of our separated Thread, we refresh the UI with the links got from the website. This refresh is embedded inside a runOnUiThread call because it's forbidden to refresh the UI elements inside a separated thread.
The code of the MainActivity has the following form :
Code:
package com.ssaurel.jsouptut;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
private Button getBtn;
private TextView result;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
result = (TextView) findViewById(R.id.result);
getBtn = (Button) findViewById(R.id.getBtn);
getBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getWebsite();
}
});
}
private void getWebsite() {
new Thread(new Runnable() {
@Override
public void run() {
final StringBuilder builder = new StringBuilder();
try {
Document doc = Jsoup.connect("http://www.ssaurel.com/blog").get();
String title = doc.title();
Elements links = doc.select("a[href]");
builder.append(title).append("\n");
for (Element link : links) {
builder.append("\n").append("Link : ").append(link.attr("href"))
.append("\n").append("Text : ").append(link.text());
}
} catch (IOException e) {
builder.append("Error : ").append(e.getMessage()).append("\n");
}
runOnUiThread(new Runnable() {
@Override
public void run() {
result.setText(builder.toString());
}
});
}
}).start();
}
}
Last step is to run the application and to enjoy the final result with all the links of the SSaurel's blog displayed on the screen :
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Don't hesitate to try JSoup on your Android application and give me your feedbacks on this tutorial.
Thanks.
Sylvain

Categories

Resources