Using GmailProvider.apk - Android Software Development

Hi,
I try to make a widget for gmail in order to have the number of unread messages in my gmail box (the only existing app I found is not free and for a such basic feature, that's a shame!). To manage it, I thought about using the GmailProvider package, especially the android.provider.Gmail.LabelCursor class, you can find its documentation here.
I use dynamic loading because I don't have the source code so I can't do a regular import statement (see here).
But I can't manage loading the class in my application, always get an ClassNotFoundException...
Code:
final String apkFile = "/system/app/Gmail.apk:/system/app/GmailProvider.apk";
[...]
dalvik.system.PathClassLoader clsLoader =
new dalvik.system.PathClassLoader(apkFile,ClassLoader.getSystemClassLoader());
Class<?> gmailProviderHandler =
Class.forName("android.provider.Gmail.LabelCursor", true, clsLoader);
Method m = gmailProviderHandler.getDeclaredMethod("getNumConversations", (Class[])null);
int nbConv = ((Integer)m.invoke(gmailProviderHandler, (Object[])null)).intValue();
Any idea ?
An other solution would be to use the atom feed, but using this package seems nicer to me.
Alternatively, is there a way I can get the source of this package, maybe the class name has changed since the javadoc (not official) has been written ???
Thanks,
LTourist

It's me again...
Nobody can help me ?
On my side, I've made some progress : I finally get some classes from the package. I did a dexdump on the package in xml, and it seems that the classes names do not match the ones in the package... That's kind of strange...
But now, I'm facing another problem... Whatever I do, I'm facing a NullException when I'm calling gmailProviderHandler.NewInstance((Class[]) null), and just for information, gmailProviderHandler seems to be not null, as an equals(null) is false...
Any idea from where this could be coming from ???

Related

Simple Programming Question embedded VC++

I'm currently doing some programs myself with the free MS embedded VC++.. and I'm finding it comfortable to do a simple dialog-based programs for PPC. I think I can have most of the background code going, and I've just got the GUI .. alright.
Now the question, how do I do a copy/paste to/from clipboard? I had most of the stuff done using the included MFC Wizard. I can get and send data to/from an EditBox (TextBox, whatever you call it). However, the click-hold thing on PPC doesn't seems to work on my EditBox, and hence I'm thinking what's needed to enable a simple Copy/Paste on an EditBox.
Currently, I'm using the simple
Code:
m_editBox = _T("the message I want to show");
UpdateData(FALSE); //send it to the EditBox
Any guide from here would be appreciated. However, I'm thinking there may not be an easy way to do that, hence I've also tried adding a 'Copy' and 'Paste' button to do the job, but I've tried things like
Code:
SetClipboardData(x, x)
GetClipboardData(x)
None works.
I have also tried
Code:
COleDataObject DataObject;
and with the handle etc etc .. but I can't seems to find this COleDataObject , is that in some other environment (e.g. not PPC env)?
Help
Fast solution:
http://www.pocketpcdn.com/articles/sip.html
(this shows/hides sip on get/lost focus in edit controls and add the context menu too)
and this is a simple example how to copy datas into clipboard
if(OpenClipboard(NULL))
{
EmptyClipboard();
HLOCAL clipbuffer = LocalAlloc(0, 100);
wcscpy((WCHAR*) clipbuffer, (WCHAR*) (vtNumber.bstrVal));
SetClipboardData(CF_UNICODETEXT, clipbuffer);
CloseClipboard();
free(szMsg);
LocalFree(clipbuffer);
}
I hope this help u
bye
Thanks for your respond.. things work.. a bit
Code:
//put a test char
char *test;
test = (char*) malloc(100);
strcpy(test, "blah blah blah");
//codes you've given
if(OpenClipboard()) //OpenClipboard(NULL) gives me error
{
EmptyClipboard();
HLOCAL clipbuffer = LocalAlloc(0, 100);
wcscpy((WCHAR*) clipbuffer, (WCHAR*) test);
SetClipboardData(CF_UNICODETEXT, clipbuffer);
CloseClipboard();
//free(szMsg); //not sure what 'szMsg' is
LocalFree(clipbuffer);
}
Things somewhat works. I'm not really sure which part I've got wrong. I'm suspecting some memory allocation is giving me problems. The thing is, if I were to use 'CF_UNICODETEXT' on the 'SetClipboardData(x,x)' line, I get something to paste on other programs (PPC Notes). BUT, the thing pasted is some funny stuff (e.g. letters that cannot be rendered, hence I get the little squares). If I were to use 'CF_TEXT', I don't seems to able to send my stuff to the clipboard or it made it invalid for (PPC Notes) pasting (e.g. I'm not able to paste it in PPC Notes).
Thanks.
BTW, if you are in the mood, can you give me a Paste function as well. Thanks a bunch.
Hi hanmin.
Odd I didn't notice this thread sooner.
Any way if you still having problems with this code here is the solution:
You are working with char and strcpy so your text is in ASCII (each letter one byte).
But you are calling SetClipboardData with CF_UNICODETEXT so it expects WCHAR (UNICODE) where each letter is two bytes.
The strange letters are the result of two consecutive bytes being interpreted as a single letter (probably lends you in Chinese or Japanese region of the Unicode table)
Windows mobile doesn't usually work with ASCII so the text you get from the edit box will already be in Unicode and won't give you any trouble.
The code should look like this:
Code:
//put a test char
CString test; //since you are working with MFC save your self the trouble of memory allocation
test = L"The text I want on clipboard"; //The L makes the string Unicode
//codes you've given
if(OpenClipboard()) //OpenClipboard(NULL) gives me error
{
EmptyClipboard();
//not sure why you need to copy it again, but here goes:
HLOCAL clipbuffer = LocalAlloc(0, test.GetLength() * 2); //remember: every letter 2 bytes long!
wcscpy((WCHAR*) clipbuffer, (WCHAR*)(LPCTSTR)test); //LPCTSTR is an overloaded operator for CString
SetClipboardData(CF_UNICODETEXT, clipbuffer);
CloseClipboard();
//szMsg probably belongs to some larger application and is irrelevant
LocalFree(clipbuffer);
}
I never used the clipboard APIs my self so I can't guide you farther but this code should work.
Hope this helps.
Wooo hooo.. Thanks levenum. I'm back on business!
You code works wonderfully.. just the final code "LocalFree(clipbuffer);" seems to cause problems. Without that, it works. I'm not sure if it will cause a memory leak.. but that's not much of my concern now
Now my Paste also works, and it seems that the magic code is the "LPCTSTR", which I have NO idea what it is (I'm more of a pure C person and.. a Java person ) Thanks again.
Glad I could help.
I am working from Ubuntu right know (Linux distro in case you didn't know) so I do not have access to my off-line MSDN files, but I recommend you check out the documentation for SetClipboardData.
It is possible it releases the memory it self so when you call LocalFree the handle is no longer valid.
That could also be the reason why you need to allocate memory instead of passing it the string directly.
As for LPCTSTR it is simple and not C++ related:
#define const* WCHAR LPCTSTR
Its M$ way of saying Long Pointer to Constant STRing
T changes meaning based on what you are working with:
If you work with ASCII TCHAR is char
If you work with Unicode TCHAR is WCHAR
Basically these are just all redefinitions of variable types so you can distinguish what they are used for.
In C++ you can overload operators. For example you can have a function which changes the way ++ works with certain types of variables.
In our case CString class has a function which determines what happens when you try to cast (convert) it to a pointer to string.
Thats all the "magi" code.
Good luck with your app.
Small update:
Since I had to go in to XP anyway (to change PDAMobiz ROM which kept hanging at random and didn't let me use BT to latest PDAViet which for now seem very good) I took a quick peek at the help files.
Here is why you should not release the memory:
After SetClipboardData is called, the system owns the object identified by the hMem parameter. The application can read the data, but must not free the handle or leave it locked. If the hMem parameter identifies a memory object, the object must have been allocated using the LocalAlloc function
Click to expand...
Click to collapse
levenum, thanks. You've got me almost there. There are several stuff I need to polish up though. Attach is a pre-mature version of what I wanted to do. There are several issues (including the fact that, only the 4 characters of the password are effectively used, which can be easily fix, I think. Just need to find the bug and squash it) that I like to polish up. They are sorted in order of importance (to me):
[1] Keyboard (SIP) pop up.
For this, I digged around and got to know that the function
"SHSipPreference( HWND, SIP_UP)" is the one to used. However, it never did what it suppose to do. I have had it put inside the "OnSetfocusConfirmPasswordEdit()" of the edit box, which should be called when it is set focus. I suspect that is I haven't set the HWND correctly. I have tried "NULL" and also tried using the "CWnd* pParent" from my dialog constructor (generated code my MFC Wizard). None of them worked.
[2] Editbox focusing.
For some reason, the focus on my main-dialog is correct on the editbox of the 'message'. However, on the dialog which is to confirm the password (which I called using
Code:
CConfirmPasswordDlg confirmPasswordDlg;
int nResponse = confirmPasswordDlg.DoModal();
is focusing on the 'Ok' button. What I like it to do is to focus on the 'confirmPasswordEdit' box, and it ought to automatically pop up the keyboard (SIP).
[3]Reduced size pop up dialog
I was trying to make the 2nd confirm password dialog smaller, something like a pop up in the PPC rather than something that take up the whole screen without much contents in it. How would you go about doing that? Is it not possible in PPC? E.g, if you were to use Total Commander, and start copying files around, they do have a pop up that does take up the entire screen. I'm suspecting I shouldn't do a "confirmPasswordDlg.DoModal()", and should some what do something myself. I have tried, SetVisible(1) thing, but that doesn't work. Or it shouldn't meant to work because my 1st screen is a dialog screen?
[4]Timer?
I would like to have a function of which after a certain period of idle time, it will clear off the clipboard and close itself. How would I go about doing this? Some sort of background thread thing?
Anyone can shine a light on my issues above? On MS-embedded Visual C++ (free), with Pocket PC 2003 SDK (free)
Attached the Blender-XXTea edition
Works on PPC2005 and WM5 (should work on WM6)
Does not require .NET framework
VERY small (54K)
hanmin said:
[2] Editbox focusing.
For some reason, the focus on my main-dialog is correct on the editbox of the 'message'. However, on the dialog which is to confirm the password (which I called using
Code:
CConfirmPasswordDlg confirmPasswordDlg;
int nResponse = confirmPasswordDlg.DoModal();
is focusing on the 'Ok' button. What I like it to do is to focus on the 'confirmPasswordEdit' box, and it ought to automatically pop up the keyboard (SIP).
Click to expand...
Click to collapse
In your CConfirmPasswordDlg::OnInitDialog handler, call GetDlgItem(confirmPasswordEdit).SetFocus() and return FALSE. That should handle the focus and possibly the SIP popup.
3waygeek said:
In your CConfirmPasswordDlg::OnInitDialog handler, call GetDlgItem(confirmPasswordEdit).SetFocus() and return FALSE. That should handle the focus and possibly the SIP popup.
Click to expand...
Click to collapse
HEY! The focus works! The working code is
Code:
((CWnd*) CConfirmPasswordDlg::GetDlgItem(IDC_CONFIRM_PASSWORD_EDIT))->SetFocus();
BTW, I'm wondering, whats the effect of a return TRUE/FALSE on a 'OnInitDialog()'?
Anyway, the keyboard pop up is still not working. I'm using the command
Code:
void CConfirmPasswordDlg::OnSetfocusConfirmPasswordEdit() {
SHSipPreference( (HWND)g_pParent, SIP_UP);//
}
which I suspect the 'g_pParent' is NULL. If it is NULL, would it work?
Ok, I haven't used MFC for a while and almost not at all on PPC but I will give this a shot:
1) MFC forces dialogs to be full-screen. Here is a detailed explanation on how to change that. Note that for some reason this will work only once if you use the same variable (object) to create the dialog several times.
If you use a local variable in say a button handler thats not a problem because the object is destroyed when you exit the function.
2) There is a simple SetTimer API. You can give it a window handle and then add an OnTimer message handler to that window. Or you could give it a separate function which will be called (say TimerProc). In that case you can give it NULL as window handle.
Note that CWnd objects have a member function with the same name (SetTimer) which sets the timer with that window handle (so that window will receive WM_TIMER message). If you want the raw API call ::SetTimer.
Also note that the timer will continue to send messages / call your special function every x milliseconds until you call KillTimer.
3) I am not sure what the problem with the SIP is. CWnd and derived classes like CDialog have a function called GetSafeHwnd (or GetSafeHandle, I don't remember exact name). Try passing that to SHSipPreference.
If that does not work here is an article with an alternate solution.
WOHO!! Everything works NOW!!.. MUAHAHHAHA.. wait til you see my release version
Non maximized windows works using the code suggested at the page. Although I still do not understand where the heck this '.m_bFullScreen' property came from. It is not anywhere obvious to be seen.
Code:
CNfsDlg dlg;
dlg.m_bFullScreen = FALSE;
dlg.DoModal();
Timer works using the
Code:
xx{
//your code...
CBlenderDlg::SetTimer(1, 5000, 0); //event 1, 5 seconds, something
//your code...
}
void CBlenderDlg::OnTimer(UINT nIDEvent){
//do something here for the timer
}
although somehow, the OnTimer() only works if I went to the MFC class wizard to add the WM_TIMER function. Doesn't work when I add in the OnTimer() myself. Must be something else that I've missed. Anyway.
Keyboard issue solved using
Code:
SHSipPreference( CBlenderDlg::GetSafeHwnd(), SIP_UP);
Glad its working out for you.
Couple of comments:
1) Somewhere at the top of the cpp file, if I am not mistaking there is something called a message map. It's a bunch of macros that lets MFC know what window messages it handles. An entry there is what was missing when you added the function manually.
2) m_bFullScreen is just another among many undocumented features. M$ likes to keep developers in the dark. For instance WM 2003 and up have an API called SHLoadImage which can load bmp, gif, jpg and some other formats and return HBITMAP which all the usual GDI functions use.
This API was undocumented until WM 5 came out and even then they said it only works for gif...
hanmin said:
BTW, I'm wondering, whats the effect of a return TRUE/FALSE on a 'OnInitDialog()'?
Click to expand...
Click to collapse
The return value indicates whether or not the standard dialog handler (which calls your OnInitDialog) should handle setting the focus. As a rule, OnInitDialog should return TRUE, unless you change the focus within the handler (or you're doing an OCX property page on big Windows).
I haven't done much WinMob/CE development -- I've been doing big Windows for 15+ years, so window message handling is pretty much second nature. I started doing Windows development back in the days when you didn't have C++ or MFC boilerplate; you had to implement your own DialogProc, crack the messages yourself, etc. It's a lot easier now.
CommandBar / MenuBar
I'm back.. with more questions
Not much of a major issue, but rather an annoying thing I've found. Probably that's what evc/mfc/m$ intended to do that.
Anyway, I'm starting my way of getting around CommandBar. I created a MFC skeleton, studied the code, and that's what I've found, after I've created a CommandBar/MenuBar on evc and putting it in
Code:
if(!m_mainMenuBar.Create(this) ||
!m_mainMenuBar.InsertMenuBar(IDR_MAINMENUBAR) ||
!m_mainMenuBar.AddAdornments() ||
!m_mainMenuBar.LoadToolBar(IDR_MAINMENUBAR))
{
TRACE0("Failed to create IDR_MAINMENUBAR\n");
return -1; // fail to create
}
where I have the variable 'CCeCommandBar m_mainMenuBar' and I have created a MenuBar on evc with the Id 'IDR_MAINMENUBAR'. The menu bar works flawlessly on my dialog based application, when I have the 1st level as a pop up. Example
MenuBar --> 'File' --> 'New', 'Save'
Where 'File' is a folder-like thing that pop-ups and show the contents (i.e. in this example, 'New', and 'Save'). However, given the SAME code to load the CommandBar/MenuBar, it will not work, if I were to put the actual command at 1st level. Example, this will not work
MenuBar -> 'New', 'Save'
where there isn't any folder-like pop-up to store the commands 'New', and 'Save'.
I know that I can have buttons for these commands, and probably works. But, what I'm trying to do is to utilize the bottom-left-right softkey in WM5/6. If I were to have the 'File'->'New','Save' structure, it works fine with WM5, showing it as a softkey. But, if I were to do just 'New','Save' it will not show up in both WM2003 emulator and WM5.
As a matter of fact, even if I have (say) File->New,Load, and I added a new command (i.e. not folder-like-pop-up), example 'Help' on the CommandBar/MenuBar, the File->New,Load will not show up too. It seems like the 1st level command (ie. without a folder-pop-up), causes some problems and stop it from loading further.
Guys, ring any bell?
two bytes more
levenum said:
Hi hanmin.
Odd I didn't notice this thread sooner.
Any way if you still having problems with this code here is the solution:
You are working with char and strcpy so your text is in ASCII (each letter one byte).
But you are calling SetClipboardData with CF_UNICODETEXT so it expects WCHAR (UNICODE) where each letter is two bytes.
The strange letters are the result of two consecutive bytes being interpreted as a single letter (probably lends you in Chinese or Japanese region of the Unicode table)
Windows mobile doesn't usually work with ASCII so the text you get from the edit box will already be in Unicode and won't give you any trouble.
The code should look like this:
Code:
//put a test char
CString test; //since you are working with MFC save your self the trouble of memory allocation
test = L"The text I want on clipboard"; //The L makes the string Unicode
//codes you've given
if(OpenClipboard()) //OpenClipboard(NULL) gives me error
{
EmptyClipboard();
//not sure why you need to copy it again, but here goes:
HLOCAL clipbuffer = LocalAlloc(0, test.GetLength() * 2); //remember: every letter 2 bytes long!
wcscpy((WCHAR*) clipbuffer, (WCHAR*)(LPCTSTR)test); //LPCTSTR is an overloaded operator for CString
SetClipboardData(CF_UNICODETEXT, clipbuffer);
CloseClipboard();
//szMsg probably belongs to some larger application and is irrelevant
LocalFree(clipbuffer);
}
I never used the clipboard APIs my self so I can't guide you farther but this code should work.
Hope this helps.
Click to expand...
Click to collapse
I know it is a bit late! But there is a mistake the code snippet:
HLOCAL clipbuffer = LocalAlloc(0, test.GetLength() * 2); //remember: every letter 2 bytes long!
needs to be
HLOCAL clipbuffer = LocalAlloc(0, test.GetLength() * 2+2);
the terminating 0 is als 2 bytes long!
Those errors are sometimes fatal, with very less chance to find them!
ms64o

dynamically setting image resources

greetings
was referred to this forum from someone at androidcommunity.com regarding this...
i searched the forum but couldnt find any relevant posts - can anyone point me in the right direction for doing this properly?
specifically how could one set an image resource based on a string variable being used for part of the image's file name
i tried this based on a post i saw elsewhere:
myContext.getResources().getIdentifier(myStringVariable + "_thumbnail", "drawable", myContext.getPackageName()));
but it returnes a string(or an integer?) of numbers (the resource id?) that setImageResource couldnt use unless i just wasnt doing it properly.
is there perhaps a way to get the resource name based on that id number or whatever it is that im getting?
apreesh
33 views
dang
getIdentifier() returns int and yes, it could be used in setImageResource() method.
But why you want to set resources from strings?
because the image being set is based on user selection and is not just one image its several associated images so there is a number sequence to the image file names as well that i did not show in the snippet i posted.
but i went back and plugged some of those returned values (resources ids?) from getIdentifier() into setImageResource() and it does indeed work so thanks for that - i have an idea what i was doing wrong before but for the sake of moving on im using a different solution now - in short i am now defining each group of images as a separate class member int[] and i will probably use a switch case to plug the correct one into the gridview. its ugly, but i currently only have 11 different groups and no more than 16 images per group so it will work for now until i can study the resource object more and figure out a way to get counts of associated image resources based on a part of the resource name, like with a regular expression or something, because thats the next problem i will have to deal with if i am not pre-defining all of these arrays.
if you know of a way to do that that would be awesome but ill will probably look into it more myself once i get this app closed up and can go back and fix stuff. im pressed for time right now.
thanks
It's really bad thing to use getIdentifier() method, we should always use R class. I think your problem resides somewhere before, you try to do something, that you shouldn't
How do you get these strings? You mentioned they are from user, but he doesn't write them by hand, right? If this is some selectable list, etc., they should be ints, enums, or some objects from the beginning. Not strings. Parsing strings is always ugly.
Ahh and if you have group of many small images, it is usually better to concatenate them into one big image - it's more efficient and you don't have to use 200 R constants in your code.
the string comes from the tag associated with a clickable imageView selected from the previous screen - a menu item if you will. the string will serve several purposes, retrieving related data, etc, but the first thing i needed to work out was retrieving the correct images and displaying them. i dont know how i could concatenate the images into one big image because each one needs to be clickable itself and handle certain events associated with itself.
i will go ahead and admit this is my first app so im basically figuring stuff out as i go. and learning most of my oop from flash has probably handicapped me
i appreciate your help dude
Brut.all said:
it's more efficient and you don't have to use 200 R constants in your code.
Click to expand...
Click to collapse
the only other thing i could think of trying was creating an xml doc to group the associated resource names together and figure out how to read from that to know which images to set
i dont see any methods in the R class i could use for sorting, grouping and then retrieving certain resources based on user interaction
switch cant eval string types...!?
kadmos said:
switch cant eval string types...!?
Click to expand...
Click to collapse
Nope
As I said, strings aren't good for identifying things - regardless of the language used. This is why people created int constants and/or enums.
And no, I doubt there are some mechanisms of grouping resources, etc. It must be simple, you are trying to complicate everything
I have a strong feeling that you should change your app architecture and get rid of strings. But here quick general fix (not a good solution! but just works).
Map your strings to R ints:
Code:
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("button_normal", R.drawable.button_normal);
map.put("button_pressed", R.drawable.button_pressed);
// etc
Accessing will be done:
Code:
map.get("button_" + state); // Return int id, use as you need.
This is a bad practice, but it will work. Consider re-archirecturing your app.
@Brut.all: do you have any plans on updating apktool with 2.2 support?
@kadmos
Full example:
Code:
public static enum Planet {
MERCURY(R.string.planet_mercury, R.drawable.planet_mercury),
VENUS(R.string.planet_venus, R.drawable.planet_venus),
EARTH(R.string.planet_earth, R.drawable.planet_earth),
MARS(R.string.planet_mars, R.drawable.planet_mars);
public final int nameResId;
public final int imageResId;
public static Planet findByNameResId(int nameResId) {
for (Planet p : values()) {
if (p.nameResId == nameResId) {
return p;
}
}
return null;
}
private Planet(int nameResId, int imageResId) {
this.nameResId = nameResId;
this.imageResId = imageResId;
}
}
You have enum of planets, each of them has its name and image. Then you could do something like:
Code:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
for (Planet planet : Planet.values()) {
menu.add(0, planet.nameResId, 0, planet.nameResId);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Planet planet = Planet.findByNameResId(item.getItemId());
doSomethingWithPlanetImage(planet.imageResId);
return true;
}
You identifies planets by ints (nameResId in this example - of course it must be unique), not by strings. Operations on ints are several times faster, than on strings, this is why Google decided to identify all things: resources, menu items, etc. just by ints.
Ahh and no, writing switch-cases to do something depending on given object isn't true OOP. OOP is above: enums know, which drawable is connected to them, there is no need for switches.
AuxLV said:
@Brut.all: do you have any plans on updating apktool with 2.2 support?
Click to expand...
Click to collapse
Yeah, of course, I want to work on apktool this weekend. Unfortunately baksmali doesn't support Froyo yet, so I can't support it fully neither.
@Brut.all:
Ha, I recognise that example It's from the Java Trail/tutorial on enums isn't it? Except they used gravity rather than drawable references.
@kadmos:
Are all the images known from the beginning? In other words, is the user creating them at runtime or are you including them with your app? If they are included with your APK then normally, as Brut said, you should be able to use the identifiers directly.
Concatenating the images all into one isn't hard to do, as you can still draw the specific bitmaps out using the Bitmap.create(bitmapToGetAPartOutOf, ....) method. You can then make those individual bitmaps into ImageViews and only have to remember the 'grid reference' for where they came out of the big image. That said, you'd have to balance the added complexity of creating the big images against the ease of not having loads of R constants. I can't really say anymore because I'm not fully following what you're trying to achieve.
Steven__ said:
@Brut.all:
Ha, I recognise that example It's from the Java Trail/tutorial on enums isn't it? Except they used gravity rather than drawable references.
Click to expand...
Click to collapse
I took planets example, because it's good, but everything was written from scratch
Steven__ said:
Concatenating the images (...)
Click to expand...
Click to collapse
I'm pretty sure I saw this concatenating approach somewhere in official Android's guidelines for performance, but now I can't find it :-/ Also I don't have much experience in Android development, so if no one else suggest this approach, then I think kadmos could forget about it.
Brut.all said:
You identifies planets by ints (nameResId in this example - of course it must be unique), not by strings. Operations on ints are several times faster, than on strings, this is why Google decided to identify all things: resources, menu items, etc. just by ints.
Ahh and no, writing switch-cases to do something depending on given object isn't true OOP. OOP is above: enums know, which drawable is connected to them, there is no need for switches.
Click to expand...
Click to collapse
i know its not true oop i didnt want to have to do that but i have not yet seen a way to pass any value from a selected item into a method that could use that value to retrieve x amount of associated resources (images in this case).
Steven__ said:
Are all the images known from the beginning? In other words, is the user creating them at runtime or are you including them with your app? If they are included with your APK then normally, as Brut said, you should be able to use the identifiers directly.
...I can't really say anymore because I'm not fully following what you're trying to achieve.
Click to expand...
Click to collapse
using the planets example, say i had x (varying) amount of pics of each planet's surface in my drawables and wanted only those planet's pics to display in a grid view when a user selects whichever planet. thats really all this is. being new to this i just dont know the most efficient way to do it. if this was Flash i could just group all the images file names/paths in an external xml doc and use that to load them from whatever folder at runtime - i wouldnt need any of those 200 or so images declared as anything or even as assets in my library (and i would only need the xml because flash cant access a file system on its own to see and filter files that it would or wouldnt need based on, say, a string comparison - though there is third party software like Zinc that gives Flash that capability.)
so i did get this to work by passing a number as a tag (string) in a bundle though an imageView click event and then casting the string as an int to use in the switch - which as of now leads to one of 11 different int arrays of resources names (images) ive got declared in my ImageAdapter class to populate my gridView.
the way i wished i could made this work would have been to use a string (like a planet name) ,passed from whatever planet image/menu item/whatever was clicked, and use that string to compare and determine which and how many images in drawables were associated with that planet and then use that to create my gridView at runtime.
kadmos said:
so i did get this to work by passing a number as a tag (string) in a bundle though an imageView click event and then casting the string as an int to use in the switch - which as of now leads to one of 11 different int arrays of resources names (images) ive got declared in my ImageAdapter class to populate my gridView.
Click to expand...
Click to collapse
I see what you're saying, that makes sense. Just as a quick note though, if you're declaring your ImageViews programmatically, you don't have to use a string object for the tag. You can directly give the integer and then cast it back when you get the tag. Just remember to use (Integer) as the tag is actually just an unspecified object.
kadmos said:
the way i wished i could made this work would have been to use a string (like a planet name) ,passed from whatever planet image/menu item/whatever was clicked, and use that string to compare and determine which and how many images in drawables were associated with that planet and then use that to create my gridView at runtime.
Click to expand...
Click to collapse
Yes, I can see why you'd want to do it this way. Your current problem is that if you add more images, you have to manually update your arrays. Unfortunately I can't think of a better, 'clean' way of doing it.
@kadmos
Now I have problems understanding you ;-) But if you don't want to declare all images in sources, but in XMLs, then you could use XML arrays.
Code:
<resources>
<string-array name="planet_names">
<item>mercury</item>
<item>venus</item>
<item>earth</item>
<item>mars</item>
</string-array>
<integer-array name="planet_images">
<item>@array/mercury_images</item>
<item>@array/venus_images</item>
<item>@array/earth_images</item>
<item>@array/mars_images</item>
</integer-array>
<integer-array name="mercury_images">
<item>@drawable/mercury_0</item>
<item>@drawable/mercury_1</item>
<item>@drawable/mercury_2</item>
</integer-array>
<integer-array name="venus_images">
<item>@drawable/venus_0</item>
<item>@drawable/venus_1</item>
<item>@drawable/venus_2</item>
</integer-array>
<integer-array name="earth_images">
<item>@drawable/earth_0</item>
<item>@drawable/earth_1</item>
<item>@drawable/earth_2</item>
</integer-array>
<integer-array name="mars_images">
<item>@drawable/mars_0</item>
<item>@drawable/mars_1</item>
<item>@drawable/mars_2</item>
</integer-array>
</resources>
When user will open planet selector, you will iterate through contents of R.array.planet_names array, each item (planet) in this selector will have itemId set to array index. When user will click on something, you will get itemId of clicked item, then you will find array of its images as R.array.planet_images[itemId] (not exactly - it's conceptual example).
You will be able to add new images or even planets through XML editing.
Steven__ said:
Yes, I can see why you'd want to do it this way. Your current problem is that if you add more images, you have to manually update your arrays. Unfortunately I can't think of a better, 'clean' way of doing it.
Click to expand...
Click to collapse
Brut.all said:
But if you don't want to declare all images in sources, but in XMLs, then you could use XML arrays...
...You will be able to add new images or even planets through XML editing.
Click to expand...
Click to collapse
as i posted earlier this was the idea that i had - i havent tried it yet because i wanted to get some feedback from you guys just to see if i was completely off base. so right now its coming down to what would make for the more memory efficient final product - declaring all these images as class array constants (which i already have working) or using xml and coding the operations for parsing, counting, filtering, assigning, etc?
again thank you guys for your time and help
kadmos said:
or using xml and coding the operations for parsing, counting, filtering, assigning, etc?
Click to expand...
Click to collapse
Do you mean parsing XMLs? My example above uses standard Android resources. You don't have to parse these XMLs, you will get them as arrays And yes, it's super efficient, because they are compiled to easy-to-read form
ok then im going to go ahead and try it
be back soon
i hope

[Q] Linkify vs TextView vs setMovementMethod

hi,
I'm loading a standard HTML code into a text view and would like to see the links to be possible to click and call the browser (web intent)
from all my readings the following code was supposed to work:
Code:
TextView tx = new TextView(this);
tx.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
tx.setText(Html.fromHtml(item.get_text()));
tx.setMovementMethod(LinkMovementMethod.getInstance());
mLayout.addView(tx);
but the fact is.. it does not work!
according to google API example link.java
Code:
TextView t3 = (TextView) findViewById(R.id.text3);
t3.setText(
Html.fromHtml(
"<b>text3:</b> Text with a " +
"link " +
"created in the Java source code using HTML."));
t3.setMovementMethod(LinkMovementMethod.getInstance());
it was supposed to be that simple, in it's declaration text3 have no special tags.
I tried several options using Linkify(tx, Lkinkify.ALL); tx.setClickable(true); tx.setLinksClickable(true); setAutoLinkMask(Linkify.ALL) and regardless of what combination I tried I cannot make those HTML links clickable!
important to note that every time I use setMovementMethod the underline on the links disappear from the TextView
any help please??
Have you tried just putting the html from their example in the fromHTML method? It shouldnt be any different but when stuff doesn't work its good to simplify.
Maybe your item.getText is wonky
From something awesome
Just to "close" the post.
at the end I guess was just some mixed binaries floating in my phones flash.. cause after I unistall the app, re-copy the code from the examples and tried it just worked... go figure.
in case anywant fancy.. the final code is:
Code:
TextView tx = new TextView(this);
tx.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
tx.setTextColor(getResources().getColor(R.color.txt));
tx.setLinkTextColor(getResources().getColor(R.color.txt));
tx.setMaxWidth((int) (getResources().getDisplayMetrics().density * 360));
tx.setText(Html.fromHtml(item.text));
tx.setMovementMethod(LinkMovementMethod.getInstance());
TextLayout.addView(tx);
if any forum moderator sees this feel free to close the thread.

DataManagement Library for Easy Android Database Storage

Storing objects to a Database for an Android application should be fast and easy as:
Code:
dm.add(new StorableClass());
DataManagement is a new open source library that allows you to do just that.
DataManagement is a Java Android library designed to help easily and efficiently store aggregate classes to an SQLite database. It eliminates the need to write separate classes to manage database – object interactions and allows developers to use simple methods to store, query, update, and delete objects. The library is capable of storing all objects of classes whose instance variables are either primitive data types or are themselves objects of another storable class. The DataManagement Library condenses many standard database features into several simple methods. It is fully open source and the code can be found at http://epsilonlabsllc.github.com/DataManagement
Examples:
Creating a Storable Class:
Code:
public class StorableClass{
@Id
private int ident;
private int num1;
private double num2;
private String num3;
private boolean num4;
public static final int num5 = 3;
private OtherStorableClass[] ds2;
}
A storable class must meet two requirements. First, the class must have a private instance variable of type int that will be used as the id number of the object. This variable may be read by the application, but the application should not have the capability to write to or change this variable in anyway. This variable is identified by the system with an @Id annotation. In addition, the class should not have any instance variables that are not either primitive types, strings, or other storable objects.
Instantiating a DataManager Object:
Code:
DataManager dm = new DataManager(context);
The open method accepts the calling Context that is going to use the database. Usually this should be the calling Activity.
Opening a Database for Use:
Code:
dm.open();
This method must be called before the database is used in any way.
Closing a Database After Use:
Code:
dm.close();
This method should be called after all database operations have been performed.
Adding an Object to the Database:
Code:
int id = dm.add(new StorableClass());
The add method accepts an object of a storable class as its only parameter and adds it to the database. It returns its id in the database for future use.
Retrieving a Specific Item from the Database by ID:
Code:
StorableClass storableObject = dm.get(StorableClass.class, id);
The get method accepts two parameters: the data type of the stored object and the Id number of the object (the return value of the add method).
Retrieving All Objects of a Given Type Stored in the Database as a Collection:
Code:
storableObjectCollection = dm.getAll(StorableClass.class);
The getAll method’s only parameter is the class of the objects that should be retrieved.
Retrieving a Collection of Storable Objects that match a given criteria:
Code:
Collection<StorableClass> storableObjectCollection = dm.find(StorableClass.class, 5, "num1");
The find method accepts three parameters: the data type of the stored object, the value that is being searched for, and the name of the instance variable as a string. This method is overloaded in such a way that the second parameter may be any primitive value or a string.
Updating an Object in the Database:
Code:
dm.update(id, updatedObject);
The update method accepts two parameters: The id number of the object being updated and the updated object that will replace the existing one I the database. If the id number of the new object and the id number given as the first parameter do not match, the object’s id will be overwritten.
Deleting an Object by its Id number:
Code:
dm.delete(StorableClass.class, id);
The delete method accepts two parameters: The data type and id number of the object to be deleted.
Additional Notes:
Id numbers are used by the database to ensure that objects are put in the correct place and to allow the program to access these objects. It is important that programs using this library do not attempt to set these variables as they will be initialized and managed by the library. These id numbers are unique for objects of a given type; objects of different types may have the same id number. In addition, if objects are deleted from the database their id numbers are left empty and are not reused.
Licensing:
DataManagement is Currently Licensed under the GNU General Public License, version 3 (GPL-3.0). It is intended for open source use by anyone who would like to use it.
This is awesome!!
Tried it out for an app today-- incredibly simple! For those looking-- this library essentially replaces loads of SQL helper classes and queries with an interface that's similar to ArrayList.
Definitely going to use this for everything in the future!
Thanks
Did you change the license or something? The repo is no longer on github.
regaw_leinad said:
Did you change the license or something? The repo is no longer on github.
Click to expand...
Click to collapse
After a quick search on github, it looks like it's been moved here
https://github.com/epsilonlabsllc/DataManagement
cmike21 said:
After a quick search on github, it looks like it's been moved here
https://github.com/epsilonlabsllc/DataManagement
Click to expand...
Click to collapse
Thanks. I forgot to change it. I just edited my post with the correct url.
Sounds awesome! Great work.
Gonna try it this evening.
Anyone compared the performance with db4o?
are there any performance test with other DB libraries for android? and what about the this lib vs contentproviders?
activeandroid.com
code.google.com/p/orm-droid]orm-droid
satyan.github.com/sugar/
will definitly be using this once i learn some app development! thanks for this!
Just in time...
Hello,
I'm trying to build a simple project the test and learn how this lib works, but I'me quite new in programming and I have some difficulties to understand how to use dm.
The project will be a simple song database with edittexts for song and artist. I created the storableClass as the example, but I cannot understand how to connect it with the main activity, so I can use the output of the editTexts.
1st question is: do I need to have the String variables as private? I'm thinking that must have them as public, so I can connect them with the editTexts output.
2nd: question: all these methods needed to be called from storableClass, or from main activity, after I connected the storableClass with main activity? And how I do this?
Probably with the use of context you descibed, but I cannot understand how to do it. I tried sometimes but always get errors and a specific one "The constructor DataManager(Context) is not visible".
Is there any example project' source code which use this lib to get an Idea, or can you explain the context step more extensively?
Thanks in advance and sorry for noob questions.
dancer_69 said:
Hello,
I'm trying to build a simple project the test and learn how this lib works, but I'me quite new in programming and I have some difficulties to understand how to use dm.
The project will be a simple song database with edittexts for song and artist. I created the storableClass as the example, but I cannot understand how to connect it with the main activity, so I can use the output of the editTexts.
1st question is: do I need to have the String variables as private? I'm thinking that must have them as public, so I can connect them with the editTexts output.
2nd: question: all these methods needed to be called from storableClass, or from main activity, after I connected the storableClass with main activity? And how I do this?
Probably with the use of context you descibed, but I cannot understand how to do it. I tried sometimes but always get errors and a specific one "The constructor DataManager(Context) is not visible".
Is there any example project' source code which use this lib to get an Idea, or can you explain the context step more extensively?
Thanks in advance and sorry for noob questions.
Click to expand...
Click to collapse
Here is a sample project: https://github.com/epsilonlabsllc/D.../net/epsilonlabs/datamanagementefficient/test
(It's in the github project.)
You can set the strings on private, because you can grab the values of the edittext on your layout. Eclipse should generate your set/ get methods if you create your private strings. The methods. Take the values and insert them into your db, Look at the sample:
Code:
public DataSample(){
num1 = 3;
numderp = 3.0;
num3 = "three";
num4 = true;
ds2depier = new ArrayList<DataSample2>();
ds2depier.add(new DataSample2());
ds2depier.add(new DataSample2());
}
That is the basic constructor of the DataSample class. If you do an insert like
int id = dm.add(new StorableClass());
Click to expand...
Click to collapse
The basic constructor will be called and it sets your values for example the num1 =3. You could overwrite the basic constructor with your costum constructor to insert your values.
You activity call:
dm.add(DataSample(sSong,sTitle));
Click to expand...
Click to collapse
The constructor could be something like this:
public DataSample(String sSong, String sTitle){
sYourTitleDataBaseColumnCaption = sTitle;
sYourSongDataBaseColumnCaption = sSong;
}
Click to expand...
Click to collapse
Or use the set/get methods, my custom constructor are just an idea to show you an example. Just take a closer look at the github sample and it should work for you.
Thanks, I think I can figure it out now.
How to is very outdated. I can't initialize via new DataManager() but via getInstance(), also delete and update method doesn't have Id argument anymore.
Also,
I can't get this to work. I can't even add a member to collection because it needs to use db.add(new MyClass()); but i already have MyClass() initialized with their members. I have tried to do something like copy the Id from add, update into my other instance of this class and run a db.update() but it throws a RuntimeException.
Not usable at this time.
Sounds good!
I'll give it a try as soon as I start a new project that requires data storage ...
I really hate SQLiteOpenHelper, cursor and all this strange syntax ...
The idea is good, but it can't be compared to db4o, specially when talking about documentation.
Hello mate,
I'd like to use your library and backup the data with Google/Dropbox Sync... can you tell me the name of the file on which you save data?
Thanks,
Tiwiz

Registering devices with GCM error

Hello everybody,
I'm experimenting with Google Cloud Messaging and I was following the tutorial at https :// github. com/ GoogleCloudPlatform/gradle-appengine-templates/blob/master/GcmEndpoints/README.md (I beg pardon but I can't post links). Unfortunately I spent the last two days struggling with solving all the dependencies but I still miss one.
In this code (taken from the tutorial at point 2.2) I cannot resolve the class "Registration"; I've been trying looking for it but given such a vague name I got back millions results that had little to do with my problem.
I also tried to add to my project all the suggested libraries but none of them contained the class I need.
Code:
public GcmRegistrationAsyncTask() {
Registration.Builder builder = new Registration.Builder(AndroidHttp.newCompatibleTransport(), new AndroidJsonFactory(), null)
// Need setRootUrl and setGoogleClientRequestInitializer only for local testing, otherwise they can be skipped
.setRootUrl("h t t p : / / 10.0.2.2:8080/_ah/api/")
.setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
@Override
public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest) throws IOException {
abstractGoogleClientRequest.setDisableGZipContent(true);
}
});
// end of optional local run code
regService = builder.build();
}
Could somebody point me in the right direction?
Thanks in advance for the help!
Bye
Mario
I was just following the same instructions today and I am experiencing the same problem unfortunately.
thvranken said:
I was just following the same instructions today and I am experiencing the same problem unfortunately.
Click to expand...
Click to collapse
Well, at least it means probably we are not dumb
At any rate if I should find something I'll post it here so it's available to whoever needs it and pls do the same...
Hmm.. I couldn't find a "Registration" class or import anywhere in their source code so it may be included in one of the dependencies, try checking your build.gradle files against the one given in their source code to check for the correct dependencies.
In any case, their method is (IMO) an extremely weird and complicated way of doing something very simple, if you haven't found the solution by Monday (when I should have more free time) I'll put together a package (including the html/php/MySQL server back-end files) with how I managed to do GCM messaging (which includes multicast messages)
Jonny said:
Hmm.. I couldn't find a "Registration" class or import anywhere in their source code so it may be included in one of the dependencies, try checking your build.gradle files against the one given in their source code to check for the correct dependencies.
In any case, their method is (IMO) an extremely weird and complicated way of doing something very simple, if you haven't found the solution by Monday (when I should have more free time) I'll put together a package (including the html/php/MySQL server back-end files) with how I managed to do GCM messaging (which includes multicast messages)
Click to expand...
Click to collapse
Hi Jonny, tnx for taking time and having a look! I checked the gradle file but it seemed everything in order...
At any rate I started studying better the code (I should have done it earlier actually) and noted that in the backend Android Studio created before a class with the methods I invoke in the app and before the declaration there is annotation:
Code:
@Api(name = "registration", version = "v1", namespace = @ApiNamespace(ownerDomain = "backend.rtalert.rt_finance.com", ownerName = "backend.rtalert.rt_finance.com", packagePath=""))
public class RegistrationEndpoint {
private static final Logger log = Logger.getLogger(RegistrationEndpoint.class.getName());
Now, searching on the web seems like I would somehow need to compile the backend module and import it as a lib into my app (despite is all within the same project). I imported both the zip file and the discovery one and then synced gradle, but still nothing.
Tomorrow after a few hours sleep I'll try again...
Good night
Mario
Ok apologies for being a bit late, life's been busier than I was expecting over the last few days...
Anyway, the web server files are all located in the following zip file >>> http://darkforest-roms.co.uk/Misc/AndroidGoogleColudMessaging.zip
There is also a table.txt file that contains the MySQL database base table I'm using - the setup is for an app for my school where the staff can send messages to individual year groups or to all year groups.
Assuming whatever webhosting service you are using has phpMyAdmin or similar you can just change the table columns in the table.txt file and import it. Then you need to go through register.php, update.php, possibly unregister.php and index.php to modify the website code to your specific application.
You will also need to edit the parameters in config.php for your Google API key and database name, user and password.
Thats it for the website side code, give me a couple of days to sort out the app-side java code, I need to modify some stuff in my current code before uploading it
Jonny said:
Ok apologies for being a bit late, life's been busier than I was expecting over the last few days...
Anyway, the web server files are all located in the following zip file >>> [
There is also a table.txt file that contains the MySQL database base table I'm using - the setup is for an app for my school where the staff can send messages to individual year groups or to all year groups.
Assuming whatever webhosting service you are using has phpMyAdmin or similar you can just change the table columns in the table.txt file and import it. Then you need to go through register.php, update.php, possibly unregister.php and index.php to modify the website code to your specific application.
You will also need to edit the parameters in config.php for your Google API key and database name, user and password.
Thats it for the website side code, give me a couple of days to sort out the app-side java code, I need to modify some stuff in my current code before uploading it
Click to expand...
Click to collapse
Hi Jonny, don't worry, I was quite busy these days myself, plus I really appeciate your help... In the weekend I'll set it up so I can test it and let you know...
Thanks again
Mario

Categories

Resources