Related
{
"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"
}
This thread is for the discussion, development and support of EXCT2. EXCT2 is compatible with all Energy Roms based on Windows mobile 6.5 and it is entirely possible that it will work with other stock and custom windows mobile roms.
EXCT2 is the continuation of a project i started last year which can be found here. It was born out of a hatred for the hours it took to configure a new rom install.
EXCT2 expands on EXCT by adding a basic User Interface and allowing for a large amount of automation for settings gathering from the system registry. No registry editors required, no Third party XML file writers needed. EXCT2 will detect exchange server settings, audio manager storage paths, Windows Live and palringo settings and so much more all at the touch of a button and export them in the appropriate file type in the folder of your choosing for XDA_UC (or possibly Sashimi) to import.
Requirements:
Windows Mobile 6.5 or 6.5.x (it may work with 6.0 and 6.1 as well but this has only been tested in the SDK's emulator and may not work as expected)
.Net Compact Framework 3.5
XDA_UC (it may well work with other settings importers like sashimi)
Some patience
Known Bugs:
All known Bugs have been squished for now
Download:
All downloads will be hosted here and new builds will also be hosted on XDA. Hosting the newest version anywhere else is strictly prohibited and if you want to host mirrors of previous versions seek my permission first.
Some Fun Stuff
I have had some forum banners made up so the users can identify themselves to each other. Also so it is easier to identify the testers and myself outside of this thread. If anyone donates towards the continuation of the project you will get a special supporters banner. Below is the users banner for you to download. Thanks to Swiss420 for creating them and also for doing the program icon. Swis has also just come up with the EXCT2 Splat!
The Thank you's
Finally i should say thank you to a few people simply because they have put up with me pestering them with questions and because they have provided code. These people are XDA members Ultrashot, Stephj, Xcaliburinhand. Also Jesse Jiang and Reed Kimble the on MSDN forums have contributed greatly. Finally The testing team deserve a big thanks (even the guys that went MIA) CanjunFlavoredBob deserves the biggest thanks for sticking with it and providing some great suggestions and ideas.
The Changelog
Changelog:
18 November (RC1)
Updated Visual look
Other minor bug fixes
23 September (Beta 5)
Added CHT export (hidden and disabled till the CHTE team sort out a bug in their code)
Fixed Minor issue with twitter export
Added People tab order export
Added Manilla Tab order export
Fixed issue with Alarm 2 and alarm3 exports
15 August (Beta 4)
Added Alarm export functions
Some small UI tweaks
Improved Operation Complete and Operation Failed dialogs
Other small tweaks and fixes
24 July (Beta 3.1)
Fixed Rhodium crash (thanks to JVH3)
22 July 2011 (beta 3)
Complete UI redesign.
Added File overwrite checking
Adjusted Time elapsed check in file write success check to 10 seconds
Improved Exception handling
Added "Export all" click detection to reduce the amount of message boxes it generates
Updated xml export code to include updated error handling, file overwrite protection and Export all click detection
Added copy.mscr to cab file (Installs to "\Storage Card\XDA_UC")
Added copy2root folder detection/creation code
Various Other internal changes
10 July 2011 (beta 2):
Fixed xml file write checking code
Improved folderbrowser (thanks to stephj)
Improved combobox item description for all xml functions
Fixed Twitter function (thanks to CJB for helping with that)
Added framework for file copies. Will allow for opera settings export later
Added some basic exception handling
probably some other things i forgot to write down
30 June 2011 (beta 1):
First public release
The FAQ
1) Some misconceptions.
It has been reported this is a settings importer as well as an exporter. This is not true. EXCT2 will only export settings and only the settings it is aware of. It is also not exclusively written for the Energy roms. It will quite probably work on any rom but the only roms it has been tested with are the stock WM6.5 rom in the WM emulator and the Energy rom in my signature. I also know that CajunFlavoredBob uses EXCT2 on his own private custom rom
2) I use a program/feature in Windows Mobile that doesn't have a settings exporter in EXCT2.
Well tell me about it. As long as it is a program that many people use, IS NOT a third party app like S2U2 or any of the SPB programs etc, and you can provide me an complete example of the settings that need to be exported i will work on including it, if it is reasonable to do so.
3) EXCT2 beta 2 and newer crashes on startup
Make sure you have .Net 3.5 Compact framework installed. This can be checked by running cgacutil.exe from the windows folder on the device
4) What do i need to include when posting a problem?
When posting a problem, please include what device you are using, the exact version (including skin, windows build number and rom date) also the version of .Net you have installed. This can be found by running cgacutil.exe from the windows folder on the device. If this util reports anything less than 3.5.xxxx.xx then don't post. Instead grab .Net 3.5 from the MS download center and get NRGZ to update his rom
more to come.........
@everyone This is a pretty handy application that makes exporting settings a piece of cake. Not everything is fully functional yet, but this has HUGE potential for the entire community and deserves some support and recognition.
@M3PH Is the public beta release any different than the last alpha build I tested?
cajunflavoredbob said:
@everyone This is a pretty handy application that makes exporting settings a piece of cake. Not everything is fully functional yet, but this has HUGE potential for the entire community and deserves some support and recognition.
@M3PH Is the public beta release any different than the last alpha build I tested?
Click to expand...
Click to collapse
Yeah i fixed the things you said were broken .. well the things i could fix (the palringo function mostly). I've also spent a little time this afternoon working on the user selectable save location with stephj and we've cracked it so i'll ship that out into a new private area for the testers tomorrow because i'm gonna go have some chill time. I've been working on this for 4 weeks or so and now it's public i'm gonna go enjoy myself for few hours
I've also just sent a PM to ezthunder in the hope that he will come read the thread and post something about it on the portal. I hope he likes EXCT.
M3PH said:
Yeah i fixed the things you said were broken .. well the things i could fix (the palringo function mostly). I've also spent a little time this afternoon working on the user selectable save location with stephj and we've cracked it so i'll ship that out into a new private area for the testers tomorrow because i'm gonna go have some chill time. I've been working on this for 4 weeks or so and now it's public i'm gonna go enjoy myself for few hours
I've also just sent a PM to ezthunder in the hope that he will come read the thread and post something about it on the portal. I hope he likes EXCT.
Click to expand...
Click to collapse
He's a good one to contact. I always go through orb3000. Either way, here's hoping for some exposure.
Have yourself a beer for this little milestone.
cajunflavoredbob said:
He's a good one to contact. I always go through orb3000. Either way, here's hoping for some exposure.
Have yourself a beer for this little milestone.
Click to expand...
Click to collapse
I already am and theres gonna be a few more consumed before the evening is done
Just a couple of things for people reading this thread and thinking is it worth a try. Firstly hell yes! The more feedback i get from the curious the better because it will allow me to improve on the rough edges. I always release stuff as quickly as i can because the more people that use stuff like this the more it improves in a shorter amount of time. Secondly, if you have flashed more than just a couple of custom roms in your time you know it can be a pain to restore all your settings by hand. I remember when i was flashing updates every couple of days. It made using my phone so difficult because everytime i ran a new program i'd have to configure it. After every flash i would have go through the labourious process of reconfiguring my wifi, exchange partner and vpn settings. That's a half hour job right there and with EXCT it takes 10 seconds. Those numbers work for me and the 1500+ people that downloaded the original EXCT.
So go on, try it out, click that thanks button like you have a muscle spasm in your index finger and enjoy the brilliance that is EXCT2 (and if you really like it buy me a beer links below )
so we made it on to the portal see what egzthunder1 had to say here
Can't wait to try it, just need to know what prep is needed. I'm coming from EXCT1, so should I do anything more than backup and empty my XDA_UC folder and then run the cab?
BerMM said:
Can't wait to try it, just need to know what prep is needed. I'm coming from EXCT1, so should I do anything more than backup and empty my XDA_UC folder and then run the cab?
Click to expand...
Click to collapse
BerMM, Whazzzup!!!?
You actually need to interact with this (sorry if that sounds insulting. I've been drinking). For you, i would say all you need to do is make sure the exchange, wifi and vpn tabs are filled out and hit the export all button and prey it's doesn't crash (no exception handling in the public release yet). If it works fine you then you just need to check everything you need was exported and combine the back up with it.
There also stuff in EXCT2 that would have never got into EXCT (like Facebook and twitter settings backup). Mainly because NRGZ said he would include EXCT2 in the rom when it was up to his standards (and the sun, moon, most of the planets and the man himself all align ).
Anyway, nice to see you're still around. I never forget a pretty face... i mean... i never forget a decent supporter
P.S
If you want a copy of the testing version let me know but it means you will have to do some work and stay in touch but you do get a cool banner like CajunBob's (ok fair enough, it's not exactly a massive selling point but Swiss spent time on those)
Going to give this a shot. Watching Nrgz postings shows he is getting ready to release his first 29022 ROM tonight so this will come in handing getting all the apps configured like I want them.
Thanks.
6700Freak said:
Going to give this a shot. Watching Nrgz postings shows he is getting ready to release his first 29022 ROM tonight so this will come in handing getting all the apps configured like I want them.
Thanks.
Click to expand...
Click to collapse
Another rom, you say? Any chance someone could tell me where a changelog is for these different builds (29017 vs 29022 for example)?
back to the main subject: Great job! I haven't "export[ed] all' yet, as I don't use sense and I feared for the safety of my meticulously kept xda_uc folder, but everything I tested worked just fine.
My first suggestion would be the obvious; instead of having numbers for encryption/auth in the wifi tab, make the drop down list show the words each number represents.
I haven't HR'd yet, but looking at the Hotmail.reg, it doesn't seem to have saved the password anywhere, encrypted or not.
Additionally, it would be nice for it to have an option to add other mail accounts with a page similar to what you have for exchange.
link68759 said:
Another rom, you say? Any chance someone could tell me where a changelog is for these different builds (29017 vs 29022 for example)?
back to the main subject: Great job! I haven't "export[ed] all' yet, as I don't use sense and I feared for the safety of my meticulously kept xda_uc folder, but everything I tested worked just fine.
My first suggestion would be the obvious; instead of having numbers for encryption/auth in the wifi tab, make the drop down list show the words each number represents.
I haven't HR'd yet, but looking at the Hotmail.reg, it doesn't seem to have saved the password anywhere, encrypted or not.
Additionally, it would be nice for it to have an option to add other mail accounts with a page similar to what you have for exchange.
Click to expand...
Click to collapse
You can't lift the hotmail password from the registry. It's just plain impossible but you can lift everything else so when you run windows live all you have to do is to enter the password. There is also no provision for placing it in to a registry file so windows live knows what to do with it. So blame MS not me.
The numbers will get masked eventually. Right now it's more of a case of getting everything working before we make it look nice (and if you look at post 3 there are links that explain the numbers)
If you want extra email accounts send me an example file and when i get time i'll make up a layout and some code for it.
You guys have to understand that to write a program like this i've had to do months of reaserch to get the registry keys etc for exct1 and then i've had to learn VB, develop exchange partner detection code (i am the only person in the world to have done that) and then write 1100+ lines and counting of code. I can also only develop for what i have to hand. If i don't have say a yahoo email account syncing to my phone i'm not just magic one up to test with
M3PH said:
You can't lift the hotmail password from the registry. It's just plain impossible but you can lift everything else so when you run windows live all you have to do is to enter the password. There is also no provision for placing it in to a registry file so windows live knows what to do with it. So blame MS not me.
The numbers will get masked eventually. Right now it's more of a case of getting everything working before we make it look nice (and if you look at post 3 there are links that explain the numbers)
If you want extra email accounts send me an example file and when i get time i'll make up a layout and some code for it.
You guys have to understand that to write a program like this i've had to do months of reaserch to get the registry keys etc for exct1 and then i've had to learn VB, develop exchange partner detection code (i am the only person in the world to have done that) and then write 1100+ lines and counting of code. I can also only develop for what i have to hand. If i don't have say a yahoo email account syncing to my phone i'm not just magic one up to test with
Click to expand...
Click to collapse
I won't blame microsoft for protecting my passwords
I appreciate the significant amount of work you've put into your projects; but correct me if I'm wrong, generating the email2.xml could be done in almost exactly the same way as you have with the activesync page. You don't need to test any email accounts, since if it doesn't work AND the xml file was generated correctly, that is beyond the scope of this export project (and probably something funky going on within winmo itself, since xda_uc is only the messenger). Regardless, I would be willing to create any number of email accounts to help testing, and I'm sure others with random email domains will offer up their bug reports.
I will post a sample email2.xml later
------EDIT
It's later, here's a generic imap email config. There's probably some unnecessary unused values at the end, and I don't mean to patronize, but have you read http://msdn.microsoft.com/en-gb/bb737579 ?
Code:
<wap-provisioningdoc><characteristic type="EMAIL2">
<characteristic type="{76877040-0395-4efb-b3c6-b87c5aedce67}">
<parm name="SERVICENAME" value="Gmail" />
<parm name="SERVICETYPE" value="IMAP4" />
<parm name="INSERVER" value="imap.gmail.com" />
<parm name="OUTSERVER" value="smtp.gmail.com" />
<parm name="NAME" value="Link" />
<parm name="AUTHNAME" value="[email protected]" />
<parm name="AUTHSECRET" value="supersafepass" />
<parm name="DOMAIN" value="" />
<parm name="REPLYADDR" value="[email protected]" />
<parm name="FORMAT" value="2" />
<parm name="LINGER" value="30" />
<parm name="RETRIEVE" value="-1" />
<parm name="KEEPMAX" value="50" />
<parm name="DWNDAY" value="7" />
<characteristic type="TAGPROPS">
<parm name="8128000B" value="0"/>
<parm name="812C000B" value="1"/>
</characteristic>
<parm name="AUTHREQUIRED" value="1" />
<parm name="SMTPALTENABLED" value="0" />
<parm name="SMTPALTAUTHNAME" value="" />
<parm name="SMTPALTAUTHPASSWORD" value="" />
<parm name="SMTPALTDOMAIN" value="" />
</characteristic>
</characteristic>
</wap-provisioningdoc>
link68759 said:
I won't blame microsoft for protecting my passwords
I appreciate the significant amount of work you've put into your projects; but correct me if I'm wrong, generating the email2.xml could be done in almost exactly the same way as you have with the activesync page. You don't need to test any email accounts, since if it doesn't work AND the xml file was generated correctly, that is beyond the scope of this export project (and probably something funky going on within winmo itself, since xda_uc is only the messenger). Regardless, I would be willing to create any number of email accounts to help testing, and I'm sure others with random email domains will offer up their bug reports.
I will post a sample email2.xml later
------EDIT
It's later, here's a generic imap email config. There's probably some unnecessary unused values at the end, and I don't mean to patronize, but have you read http://msdn.microsoft.com/en-gb/bb737579 ?
Code:
<wap-provisioningdoc><characteristic type="EMAIL2">
<characteristic type="{76877040-0395-4efb-b3c6-b87c5aedce67}">
<parm name="SERVICENAME" value="Gmail" />
<parm name="SERVICETYPE" value="IMAP4" />
<parm name="INSERVER" value="imap.gmail.com" />
<parm name="OUTSERVER" value="smtp.gmail.com" />
<parm name="NAME" value="Link" />
<parm name="AUTHNAME" value="[email protected]" />
<parm name="AUTHSECRET" value="supersafepass" />
<parm name="DOMAIN" value="" />
<parm name="REPLYADDR" value="[email protected]" />
<parm name="FORMAT" value="2" />
<parm name="LINGER" value="30" />
<parm name="RETRIEVE" value="-1" />
<parm name="KEEPMAX" value="50" />
<parm name="DWNDAY" value="7" />
<characteristic type="TAGPROPS">
<parm name="8128000B" value="0"/>
<parm name="812C000B" value="1"/>
</characteristic>
<parm name="AUTHREQUIRED" value="1" />
<parm name="SMTPALTENABLED" value="0" />
<parm name="SMTPALTAUTHNAME" value="" />
<parm name="SMTPALTAUTHPASSWORD" value="" />
<parm name="SMTPALTDOMAIN" value="" />
</characteristic>
</characteristic>
</wap-provisioningdoc>
Click to expand...
Click to collapse
Cool, thanks. Can i be cheeky and as you to export the registry key for that too?
As for the coding, it is pretty similar but the problem is in the details. Although the xml writing code would be the same with out the above file i'd have no idea what the attributenames would need to be. Then there is digging the values from the registry. You need to know the name of the account and every one names them differently. So you need to have an inputbox so the user can enter the name, then you need to run a search through the registry to find the relevent key and finally convert all the registry values to something that can be used in an xml file. So, if the email2 providers aren't grouped together in the registry like the activesync partners that's gonna mean writing a custom search proceedure.
So you see how complicated it is and yes i had read that link but it doesn't tell me the things i need to know about the registry key's and values because you forget this program is supposed to be as autonomous as possible and just another xml file writer.
Right, and now for a progress update. The current testing version has an improved folderbrowser that now supports a hierarchal view. Also, i have implemented some very basic exception handling. I expect to get the new version to you guys this week but i'm not making an promises.
Ok, I see, I didn't realize the activesync page fetches values from the registry. I didn't use it, and from my glance at it, I thought you had to fill in the values yourself (which is what I thought would be done for the email2.xml).
I'll have the key for you shortly.
link68759 said:
Ok, I see, I didn't realize the activesync page fetches values from the registry. I didn't use it, and from my glance at it, I thought you had to fill in the values yourself (which is what I thought would be done for the email2.xml).
I'll have the key for you shortly.
Click to expand...
Click to collapse
Some of it comes from the registry and some of it you have to enter coz it's easier to get the user to input it than convert the value data to something the xml file can use. Ideally i would prefer it if the user never had to enter anything but that perfect world doesn't exist
The Beta2 has gone to the testing team. I'm hoping they do their thing so i can get it out today but it's very much a case of it's ready when it's ready. The preliminary changelog includes lots of crash fixes and some bug squishing and a speed improvement here and there. I also have a surprise for you but i'll keep that one quiet untill we release Beta2. Let's just say it opens the door for some really cool future features.
Also would you guys like it if i posted future versions on xda as well as hotfile so you can use the new QR Code download system? Post below and tell me what you think
I can't find the registry keys of email accounts for the life of me: where are they located?
link68759 said:
I can't find the registry keys of email accounts for the life of me: where are they located?
Click to expand...
Click to collapse
It will either be "\storage card" or "\storage card\XDA_UC" and is called either exchange.xml or hotmail.reg. It won't be anywhere else. In the testing version i implemented a folder browser so you can pick where it is saved.
Hi, I want to create an application which intercepts sent sms and shows a dialog eventually performing certain actions before allowing the message to be sent. It's pretty much like "LBE Privacy Guard", but with a different purpose.
Does anybody know how can I catch sms being sent using root and a background service? I have looked on the internet but without success.
Thanks!
Questions or Problems Should Not Be Posted in the Development Forum
Please Post in the Correct Forums & Read the Forum Rules
Moving to Q&A
All I could find was on stackoverflow, but it's functionality is limited to the stock application and perhaps a few more. It doesn't use root.
Code:
<intent-filter>
<action android:name="android.intent.action.SENDTO" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
</intent-filter>
This doesn't intercept applications that use SmsManager directly, and maybe not even then.
The default SMS Application uses android.telephony.SmsManager's method SendDataMessage() that doesn't send any broadcast.
Click to expand...
Click to collapse
http://stackoverflow.com/questions/5808577/android-listen-outgoing-sms-or-sent-box
http://stackoverflow.com/questions/8171783/how-to-do-outgoing-sms-interception-using-ndk
Nobody knows anything? Not even using root?
Hello everybody,
I am a new developer and started with Libgdx to make a simple game (Flappy Bird) an understand everything.
My English is not the best but I could understand this tutorial (tutorial) and make my "own" Flappy Bird.
To complete the tutorial I wanted to show some ads in the app but it didn't work. I used the ads from admob.
Can someone explain me how I can show ads? I think libgdx is the problem but I don't know what I did wrong.
I found this code but it doesn't work and I am getting a few errors: (Is ist correct and am I right if I do in the Android folder a new class
called BannerExample and put this code in it?
import com.google.ads.*;
public class BannerExample extends Activity {
private AdView adView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Create the adView
adView = new AdView(this, AdSize.BANNER, MY_AD_UNIT_ID);
// Lookup your LinearLayout assuming it's been given
// the attribute android:id="@+id/mainLayout"
LinearLayout layout = (LinearLayout)findViewById(R.id.mainLayout);
// Add the adView to it
layout.addView(adView);
// Initiate a generic request to load it with an ad
adView.loadAd(new AdRequest());
}
@Override
public void onDestroy() {
if (adView != null) {
adView.destroy();
}
super.onDestroy();
}
}
Click to expand...
Click to collapse
PS: Sorry for my bad English!
libGDX and AdMob
Hi,
which error messages do you get?
Which Version of libGDX do you use?
I'm not sure if it's possible make it with a class like your BannerExample.
For my app I put all the code for the ad in the AndroidLauncher class.
Additionally you should update to Google Mobile Ads because Google will stop the support of the old standalone sdk.
I think this will help you:
The Article "Google Mobile Ads in Libgdx (replaces deprecated AdMob)" in the libGDX Wiki on github.
And a sample code from "TheInvader360" on github.
I hope you find the right sites. I can't post links .
Good luck
In developing my wear watch faces I like to have the wearable vibrate when it detects connection of disconnection from the mobile. In the past I've implemented NodeApi.NodeListener and done the vibration in the onPeerConnect or onPeerDisconnect methods.
This has worked well but NodeApi has be deprecated in favor of the CapabilityApi.
Does anyone know of any simple example of how to detect connection using the CapabilityApi? None of the examples I've tried have worked at all. It should be fairly simple since I'm not trying to do downloads or anything, just detecting.
Thanks.
dlbarron said:
In developing my wear watch faces I like to have the wearable vibrate when it detects connection of disconnection from the mobile. In the past I've implemented NodeApi.NodeListener and done the vibration in the onPeerConnect or onPeerDisconnect methods.
This has worked well but NodeApi has be deprecated in favor of the CapabilityApi.
Does anyone know of any simple example of how to detect connection using the CapabilityApi? None of the examples I've tried have worked at all. It should be fairly simple since I'm not trying to do downloads or anything, just detecting.
Thanks.
Click to expand...
Click to collapse
Did you checked this http://stackoverflow.com/questions/35136881/cant-detect-node-using-the-capability-api ?
Skin1980 said:
Did you checked this http://stackoverflow.com/questions/35136881/cant-detect-node-using-the-capability-api ?
Click to expand...
Click to collapse
Yes, I've seen that one. The code is far from complete, for example, what does that class extend or implement?
Here's what I've done.
This is the entry in the manifest for the service.
<service
android:name=".MyService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<action android:name="com.google.android.gms.wearable.CAPABILITY_CHANGED" />
<action android:name="com.google.android.gms.wearable.CHANNEL_EVENT" />
</intent-filter>
</service>
And here is the code that is supposed to run
public class MyService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
private static final String TAG="MyService";
public static final long VIBRATE_TIME = 250;
@override
public void onCreate() {
super.onCreate();
Toast.makeText(this,"Starting onCreate",Toast.LENGTH_LONG).show();
Log.i(TAG,"Starting onCreate");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
ConnectionResult connectionResult = mGoogleApiClient.blockingConnect(30, TimeUnit.SECONDS);
if(!connectionResult.isSuccess()) {
Toast.makeText(this,"onCreate",Toast.LENGTH_LONG).show();
Log.i(TAG,"onCreate");
}
}
I've overridden the other methods in WearableListenerService but it doesn't matter, the onCreate isn't even called so there's no way the GoogleApiClient is ever created. Now according to what I've read I shouldn't have to do anything to start the service, it is supposed to be started in response to events, like connecting etc, but nothing.
Well, I found the solutions. I created a java class that extends WearableListenerService and in it I override the onPeerConnected and onPeerDisconnected methods. But I also had to add this to the wearable manifest:
<service
android:name=".WearListener">
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER"/>
</intent-filter>
</service>
This is odd because BIND_LISTENER is deprecated. But it works so that's all I care about.
More information like this, you can visit HUAWEI Developer Forum
Original link: https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201333021967420023&fid=0101187876626530001
HMS DEVELOPMENT
Create a Beautiful Site Tracker App with Huawei Mobile Services (HMS)
Let the friendly war begins.
Hello to you all. As you know, there is an ongoing legal battle between Google i.e USA and Huawei. And things are getting serious in the tech field as well. As you may have heard, Huawei stopped using Google Mobile Services (GMS) from a while on their mobile devices and developed its own Mobile Services which known as Huawei Mobile Services (HMS). It has all the abilities that GMS has except some minor features but those would be implemented in the near future thanks to its robust roadmap of Huawei Core team. And plus, you would get the unique features that only supported by the Huawei ecosystem and its devices. If you have GMS experience somehow, the implementation of HMS would be a piece of cake for you due to its API design is identical to GMS.
Actually, you might want to use HMS Core Toolkit Plugin for those who have GMS implementations on their apps and implement HMS with less effort and pretty UI ?. It has a Convertor feature that automatically changes all GMS package name occurrences with correct HMS mappings. This little Android Studio plugin would save you time rather than some manual labor. And also, it offers a couple of features that would make your HMS development more convenient. But this is up to you.
The number of Huawei Mobile Services aka HMS samples and articles are getting bigger and bigger each day goes by. You could find numerous samples easily and implement them into your app without effort. Different HMS articles release almost in a day such as JavaScript libraries so you will have a lot of options to choose from . So enough chit chat, let’s get into the business.
In this article, I’m gonna show you how to build a site tracker app using Huawei Mobile Services (HMS). Much precisely tracker app for health institutions who do Coronavirus testing in Turkey. For that, we‘re going to use the list of institutions provided by the Minister of Health of Turkey’s website. I named the app COVID19HIT. I know, it does not sound nice but it stands for COVID-19 Health Institutions Tracker. That was the best and simple naming I could get for an app like this one. Apparently, I’m not good at naming apps . Anyways, Before getting into the development, I would like to clarify things beforehand such as the app‘s aim, capabilities, and limitations. I would leave you with concise text that I used in my README file to answer those questions.
It’s an Android sample application that uses Huawei Mobile Services (HMS) to display and search health institutions around you that supports Coronavirus testing in Turkey. The default search radius is 10 km.
The project aims to how to use HMS in real-life applications. Our use-case is displaying all the near health institutions around you that have a certificate to test for Coronavirus. The list itself declared on the website of the Ministry of Health of Turkey. You can check the list out at the link below.
The official list of health institutions
We’re going to use Analytics + Map + Location + Site Kits and Directions API to demonstrate their usage in this use-case. The application’s architecture pattern is MVVM with modular project architecture. Currently, the project has 3 modules which are App, Base and Network modules. Their usage and role differ as modules. And lastly, it developed with everyone’s favorite Kotlin Coroutine which is the language level supported feature.
After that huge boring explanation, I’ll give you short brief information about which Kits solve which use-cases for this app. And, you could click the kit name and see what is more they offer.
Analytics Kit sends user events or properties via Analytics Kit
Map Kit provides a visual map to discover what is around you and drawing 2D shapes
Location Kit locates the user’s current location
Site Kit shows nearby health institutions around 10 KM
Directions API gets you directions based on the options that you select which are by walk, by a drive, and by bike options
Development
FYI, for the sake of the article’s goal, I would only focus on the HMS Development parts in the project. And also, you could ask me any other questions that you have in mind in the comments below.
Each HMS Integration requires the same initial steps, to begin with. You could use this link to prepare your app before implementing features into it. Please, don’t skip this part. This is a mandatory phase. HMS Kits will not work as they should be without it.
After you finish your project’s initial steps, we’re ready to rock and roll.
My DI choice for this project would be Koin which I really recommend who codes in Kotlin. It really takes away all of the boilerplate jobs that Dagger brings on the table. Therefore, we start with Koin initialization in our custom application class’s onCreate() method.
Code:
startKoin {
androidLogger()
androidContext([email protected])
modules(appModule + networkModule)
}
Our module dependencies are in the app module’s com.yektasarioglu.covid19hit.di package.
Code:
val appModule = module {
// Data Sources
single { DiskHealthInstitutionDataSource() }
single { RemoteHealthInstitutionDataSource() }
// Repositories
single { HealthInstitutionRepository(get(), get()) }
viewModel { HomeViewModel(get(), get()) }
}
val networkModule = module {
// Data Sources
single { RemoteDirectionDataSource(get()) }
// Repositories
single { DirectionsRepository(get()) }
single {
OkHttpClient().newBuilder()
.addInterceptor(HttpLoggingInterceptor().apply {
level = if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE
})
.connectTimeout(10000, TimeUnit.MILLISECONDS)
.readTimeout(10000, TimeUnit.MILLISECONDS)
.build()
}
// Services
single {
val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("https://mapapi.cloud.huawei.com/mapApi/")
.client(get())
.build()
retrofit.create(DirectionsService::class.java)
}
}
This app has only two screens Home and Splash. Our entire logic underlies in Home screen. So, we would focus there mostly. Firstly, Map Kit has two ways to display a map i.e container in our app. The first one is using MapView in our XML which I did. Secondly, you could develop with MapFragment way too. This way of using prevents to call onStart(), onStop(), onResume(), onPause(), onDestroy(), onLowMemory(), and onSaveInstanceState(Bundle outState) methods in its Activity due to Fragment is tied to its parent Activity’s lifecycle. But I chose to use MapView rather than MapFragment. So I did call those Map Kit’s lifecycle methods in HomeActivity. You could choose whatever you want based on your needs. Then, we initialize our managers and request to get location updates at HomeActivity’s onCreate() via calling initialize() method of our ViewModel which takes Activity as a parameter.
Code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initializeUIElements()
with (viewModel) {
initialize([email protected])
initializeStyle(theme = currentTheme)
isCoordinateAvailable.observe([email protected], Observer {
viewModel.moveCameraToCurrentLocation()
viewModel.drawCirclePivotalToCurrentLocation()
})
nearbyHealthInstitutionSites.observe([email protected], Observer {
Log.i("HomeActivity", "nearbyHealthInstitutionSites -> $it")
it.forEach { site->
Log.i(TAG, "site's lat and long: ${site.location.lat}, ${site.location.lng}")
viewModel.markTheSite(site = site, distanceText = resources.getString(R.string.distance))
}
viewModel.setOnMarkerClickListener { marker ->
toast("Clicked ${marker.title}")
with (binding.actionsMenu) {
root.visibility = View.VISIBLE
}
}
toast(getString(R.string.scroll_to_see_more))
})
}
mapView = binding.mapView
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(viewModel.getOnMapReadyCallback())
}
As you would notice, we use ViewModel’s OnMapReadyCallback implementation rather than directly implementing it to Activity. In this case, our ViewModel provides the implementation somewhere else. You would see why we do that just below for a couple of reasons.
Code:
fun initialize(activity: Activity) {
initializeManagers(activity)
requestLocationUpdates()
}
We are going to use Manager classes to encapsulate HMS kit implementations and call it in ViewModel. For our previous example above, ViewModel would only call the MapKitManager’s implementation of OnMapReadyCallback. This helps us to hide all the HMS implementation details in its class, enables us to make changes easily and prevents to propagate more code in HomeViewModel. This approach also suits SOLID principles, especially the Single-responsibility principle. I strongly recommend you to learn it if you don’t know what those are.
Code:
private fun initializeManagers(activity: Activity) {
analyticsManager = AnalyticsManager(activity)
locationKitManager = LocationKitManager(activity)
mapKitManager = MapKitManager()
siteKitManager = SiteKitManager(activity, BuildConfig.HMS_API_KEY)
// For testing purposes
analyticsManager?.sendEvent("XX", Bundle().apply {
putString("TestProperty1", "TestValue1")
})
}
If you run the APK. You would see that the app has two different themes which are Light(Default) and Dark. I wanted to display different map styling for Dark Theme. This custom styling feature is supported by Map Kit. You could use this reference to make your own map style. Even, there is handy Huawei style tool that generates JSON style file based on your customization choices.
Code:
private fun requestLocationUpdates() {
locationKitManager?.requestLocationUpdatesWithCallback(
locationRequest = LocationRequest().apply {
interval = 10000L
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
needAddress = true // This let you to reach the current address information.
},
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
if (locationResult != null) {
with(locationResult.lastHWLocation) {
if (!isNearbyHealthInstitutionsFetched.get()) {
if (userLocation?.city == null &&
userLocation?.country == null &&
userLocation?.state == null &&
userLocation?.coordinate == null
) {
userLocation?.city = city
userLocation?.country = countryName
userLocation?.state = state
userLocation?.coordinate = latitude to longitude
isCoordinateAvailable.value = Unit
viewModelScope.launch {
nearbyHealthInstitutionSites.value =
withContext(context = Dispatchers.Default) {
var list = listOf<Site>()
while (list.isEmpty()) {
Log.i(MTAG, "list is empty")
list = getNearbyHealthInstitutions()
}
isNearbyHealthInstitutionsFetched.set(true)
list
} as ArrayList<Site>
}
}
}
if (stepList != null)
rotateCameraToCurrentDirection(locationResult.lastLocation, stepList!!)
}
} else Log.i(MTAG, "locationResult is NULL !!")
}
})
}
requestLocationUpdatesWithCallback() method’s callback result initiates our flow. Whenever the callback first time returns, we fetch our nearby health institutions with filtered fashion.
Code:
private suspend fun getNearbyHealthInstitutions(radius: Meter = DEFAULT_KM_RADIUS): List<Site> {
return CoroutineScope(Dispatchers.IO).async {
val list = getHealthInstitutions()
val filteredList = list?.filter { it.city == userLocation?.state?.toUpperCase() }
val result = suspendCoroutine<List<Site>> { continuation ->
addNearbyHospitals(
radius = radius,
onEnd = { nearbyHealthInstitutions ->
compareHealthInstitutionLists(
officialHealthInstitutions = filteredList!!,
nearbyHealthInstitutions = nearbyHealthInstitutions
).let { found -> continuation.resume(found) }
})
}
[email protected] result
}.await()
}
Code:
getNearbyHealthInstitutions() does all the work. In a basic sense;
Get health institutions
Filter only the exact matching ones with user location’s city
Search nearby hospitals with the help of Site Kit
Compare the filtered list with the result of Site Kit
Code:
private inline fun addNearbyHospitals(radius: Float, crossinline onEnd: (nearbyHealthInstitutions: List<Site>) -> Unit) {
if (siteKitManager == null) return
val nearbyHealthInstitutions = mutableListOf<Site>()
for (i in 1..SiteKitManager.MAX_PAGE_INDEX) {
Log.i(TAG, "i is $i")
if (siteKitManager!!.isInTheRangeOfMaxResult(pageIndex = i, pageSize = 20))
siteKitManager?.searchNearby(
location = Coordinate(
userLocation?.coordinate?.first!!,
userLocation?.coordinate?.second!!
),
radius = radius,
searchLanguage = "en",
locationType = LocationType.HOSPITAL,
pageFilters = i to 20,
searchResultListener = object : SearchResultListener<NearbySearchResponse?> {
override fun onSearchResult(results: NearbySearchResponse?) {
Log.i("TAG", "Total result count is ${results?.totalCount}")
val sites = results!!.sites
if (results.totalCount <= 0 || sites == null || sites.size <= 0)
return
for (site in sites) {
Log.i("TAG", "siteId: ${site.siteId}, name: ${site.name}, distance: ${site.distance} address: ${site.address} \r\n")
}
nearbyHealthInstitutions.addAll(sites)
if (nearbyHealthInstitutions.size == SiteKitManager.MAX_RESULT)
onEnd(nearbyHealthInstitutions)
}
override fun onSearchError(status: SearchStatus) {
Log.i("TAG", "Error : " + status.errorCode + " " + status.errorMessage)
}
}
)
}
}
{
"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"
}
addNearbyHospitals() returns its result to onEnd(List<Site>) lambda parameter does the post-process after its call. This enable us to get the max result which is 60. We loop until the nearbyHealthInstitutions’ element count is 60. Checking of pageIndex x pageSize ≤ 60 formula under the isInTheRangeOfMaxResult(Int, Int) method.
Then, we compare the nearby hospital list with official health institutions. This comparison’s result is our final list that we would mark it on the map. A comparison algorithm is just a basic token comparison. It uses the Levenshtein distance method to compare two strings. Nowadays, you don’t have to be a math genius to use these methods thanks to StackOverflow. But as an enthusiast, you might go and learn how the Levenshtein distance algorithm works in the first place. Before getting into the next phase, I would like to mention about data fetching layer. Under the hood, the data fetching mechanism designed to get data from a Repository. A repository method returns a result if the data wasn’t cached. Repository Pattern is another good old design pattern that you should learn if you didn’t know. It simplifies the data fetching layer of your app. You should check this link out if you’re interested in. Data collection of the app is not so robust due to the Ministry of Health of Turkey changes its HTML so often . As you would guess, all we do is some basic web scraping. As you were reading, the Ministry of Health of Turkey might change its website’s HTML some of two. And that would lead to corrupt scraped data and cause you to see fewer health institutions or nothing at all. Unfortunately, there is no REST API for getting certified health institutions in Turkey. That is all we have for now I am afraid. If you find a stable REST API for getting certified health institutions in X country. The country does not matter as long as the data is stable, just let me know. Or you could implement it on your own and contribute it to the sample project. I would gladly accept your contribution to the project.
Our last demonstration would be how to navigate to your destination point from your current location. For that, the app only offers a simple display of directions at this moment. No fancy or complex features are supported for the sake of the simplicity of our app’s context. As you would see above, there is a compound component and each component’s action would provide 3 different routes(walking/driving/bicycling). At that point, Directions API would come to rescue from our train of thoughts about how to get directions. Then, these directions would be displayed on the map with drawing polylines till the destination point via MapKit. And that would pretty much do the job in a nutshell.
Bonus Resource
I created also Postman collections for both Directions and Matrix APIs to observe all the endpoints. All you have to do is create an empty project under my projects section in AppGallery Connect. Then use this field as your API Key like the above image to test it.
Code:
fun getRoute(`for`: RouteType, onFailed: ((errorMessage: String) -> Unit)? = null) {
val originCoordinates =
Coordinates(userLocation?.coordinate?.first!!, userLocation?.coordinate?.second!!)
val destinationCoordinates = Coordinates(
mapKitManager?.selectedMarker?.position!!.latitude,
mapKitManager?.selectedMarker?.position!!.longitude
)
val routeDirection =
RouteDirection(origin = originCoordinates, destination = destinationCoordinates)
viewModelScope.launch {
var routeResponse: RouteResponse? = null
when (`for`) {
RouteType.WALK -> {
routeResponse = directionsRepository.getWalkingRoute(routeDirection) {
onFailed?.invoke(it)
}
}
RouteType.DRIVE -> {
routeResponse = directionsRepository.getDrivingRoute(routeDirection) {
onFailed?.invoke(it)
}
}
RouteType.BICYCLE -> {
routeResponse = directionsRepository.getBicyclingRoute(routeDirection) {
onFailed?.invoke(it)
}
}
}
stepList = routeResponse?.routes?.first()?.paths?.first()?.steps
routeResponse?.let {
mapKitManager?.removePolylines()
mapKitManager?.generateRoute(it)
}
}
}
After we fill stepList variable with the response. Our code block in the onLocationResult callback method which is the below would be triggered. This code block below exists in the article as the sixth gist but in the terms of laziness, I made this as another gist. Who likes to scroll up in a long article, right ? As we know, requestLocationUpdatesWithCallback() method’s callback invokes after each x interval. That would cause a rotate camera to the current direction.
Code:
if (stepList != null)
rotateCameraToCurrentDirection(locationResult.lastLocation, stepList!!)
Github Repository
yektasarioglu/covid19hit
That is it for this article. You could search any question that comes to your mind via Huawei Developer Forum. And lastly, you could find lengthy detailed videos at Huawei Developers YouTube channel. These resources diversify learning channels and make things easy to pick and learn from a huge knowledge pool. In short, there is something for everybody in here . Stay tuned for more HMS Development resources. Thanks for reading. Be safe folks.
Nice article
What should I do if error code 6 is returned when I call APIs of Site Kit?
riteshchanchal said:
What should I do if error code 6 is returned when I call APIs of Site Kit?
Click to expand...
Click to collapse
Can you provide the screenshot or the steps you call ?