Я одного не понимаю, что не так с дефолтными View элементами андроида, это же криповщина, которая и в кошмарах не приснится
seen from Italy
seen from Bolivia
seen from Yemen
seen from Italy

seen from United Kingdom

seen from United States
seen from United Kingdom
seen from Pakistan

seen from United States
seen from Yemen
seen from United States

seen from United Kingdom

seen from United States
seen from United States
seen from Singapore
seen from United States
seen from United Kingdom
seen from United States

seen from Russia

seen from United Kingdom
Я одного не понимаю, что не так с дефолтными View элементами андроида, это же криповщина, которая и в кошмарах не приснится
Jenkins, signing Android builds with an entered password, and the Promoted Build plugin
Good workflow is Jenkins automatically picking up changes from git, rebuilding the app in release mode (including proguard) and running the test suite.
If it passes it becomes a Release Candidate, ready for manual testing then distribution to testers and eventually PROD. It's around this point that the .apk needs to be signed using your official Android Developer key rather than the debug key. I'm not keen on putting the password for that in build.properties.
(If you're not uploading to Google Play you can distribute manually with the auto-generated debug key, but switching keys requires your testers to uninstall then reinstall which makes them sad testers so it's best to stabilise at some point)
Jenkins has 'parameterised build' properties which prompt you for values at runtime, this includes passwords which are masked as much as possible. But this doesn't fit into the automatic build-test cycle that is triggered by git, and you don't need it for most builds during development, just ones you're ready to release to the world.
So create a job which takes the output of the release build - 'myapp-release-unsigned.apk' - prompts for the password, signs and zipaligns the .apk then copies it back to the original build's artifacts directory ready for easy picking. As this doesn't rebuild the apk we can be certain that this is the same build that just passed the tests. Maybe trigger the tests again if you like to be certain.
There's a Jenkins plugin called 'promoted builds' which seems to be for exactly this purpose. When a build has finished you can automatically or manually (I prefer to to some manual testing) mark the build as 'promoted' - this gives it a nice star. It also allows another Jenkins job to be triggered. You'd think this would be a great place to trigger a job to sign the .apk... it would, but I could not get it to present the parameterized build's input screen so there's no way to enter the password. (if you're happy to embed the password somewhere then you don't need this, do it in your normal release build).
Install the 'Promoted Builds' plugin along with the 'Copy Artifact' and 'Workspace Cleanup' plugins.
First edit the configuration of the builds you might want to sign the artifacts of, tick the 'Permission to Copy Artifact' box, enter something like 'sign-release-apk' and save.
Create a new project called 'sign-release-apk'. Tick 'This build is parameterised' and add two 'Password Parameter' fields with names 'keystore_password' and 'keyalias_password'. I tried 'Non-stored password parameter' too but that doesn't mask them in the environment so they might be available to snoopers.
At runtime you need a way of selecting which build produced the .apk you are happy with, this is where the 'Promoted Build' plugin comes in handy as it provides a picklist of just the builds you have promoted. It doesn't set your choice in the property formats we need though so some manipulation is needed - copy & pasted below. If you want the dropdown then add a 'Promoted Build Parameter' and set the Job Name.
The script below for parsing the Promoted Build parameter's value is for linux, OSX or other unixes, if you're using Windows and want to use the Promoted Build parameter you'll need to find a way to extract the job name and build number from the URL property that it sets. Maybe cygwin will be fine if you install rev, cut and sed.
If you'd rather not bother with the Promoted Build plugin and manually enter the project name and build number you'd like then that's fine too, set SIGN_PROMOTED_BUILD_NUMBER and SIGN_PROMOTED_BUILD_JOB and skip the first two build steps below. I don't recommend using 'Build selector for Copy Artifact' because it sets the property with some bespoke XML which will need to be parsed to extract the job name and build number for use by the later script.
Tick 'delete workspace before build starts' - you really don't want your builds getting mixed up.
Tick 'Inject environment variables to the build process' and in the 'Properties Content' box enter:
KEYSTORE_LOCATION=/var/lib/jenkins/my-private-keystore KEY_ALIAS=myappkey
or wherever your keystore lives. If they change or you'd like some security-via-minor-obscurity you could make them enterable parameters.
Add the build steps:
Click add build step, choose 'Execute shell' and paste the below:
echo "SETTING signing_for_job.properties:" echo "-----------------------------------" echo "pwd: `pwd`, SIGN_PROMOTED_BUILD_ABS_URL: $SIGN_PROMOTED_BUILD_ABS_URL" echo SIGN_PROMOTED_BUILD_NUMBER=$(echo "$SIGN_PROMOTED_BUILD_ABS_URL" | rev | cut -d / -f2 | rev) >signing_for_job.properties echo SIGN_PROMOTED_BUILD_JOB=$(echo "$SIGN_PROMOTED_BUILD_ABS_URL" | sed -rn 's/^.*\/job\/([^/]*)\/.*/\1/p') >>signing_for_job.properties
This parses the URL provided by the Promoted Build parameter and extracts the project name and build number into separate properties which are written into a temporary file which is loaded into Jenkins' environment in the next step.
Add a step 'Inject environment variables' and enter 'signing_for_job.properties' in the Properties file Path.
This seems a bit clunky, is there a more Jenkins-native way to parse a URL than using a shell script which writes to a property file?
Add a step 'Copy artifacts from another project', for Project Name enter:
${SIGN_PROMOTED_BUILD_JOB}
for 'Which build' enter 'Specific Build' and for 'Build number' enter:
${SIGN_PROMOTED_BUILD_NUMBER}
under 'Artifacts to copy' I've entered:
bin/*.apk
and ticked the 'Flatten directories' box below. We're not interested in storing any artifacts in this build - they'll be copied back to the original build's artifacts directory so let's keep this one as clean as possible.
Add another 'Execute shell' step and paste in:
#!/bin/bash echo "SIGNING AND ZIPALIGNING" echo "-----------------------" echo "pwd: `pwd` " echo "SIGN_PROMOTED_BUILD_ABS_URL: $SIGN_PROMOTED_BUILD_ABS_URL" echo "SIGN_PROMOTED_BUILD_JOB: $SIGN_PROMOTED_BUILD_JOB" echo "SIGN_PROMOTED_BUILD_NUMBER: $SIGN_PROMOTED_BUILD_NUMBER" echo "PROMOTED_NUMBER: $PROMOTED_NUMBER" export RELEASE_UNSIGNED_APK=$(ls *-release-unsigned.apk) export APK_BASE=$(echo $RELEASE_UNSIGNED_APK | sed -rn 's/^(.*)-release-unsigned.apk$/\1/p') echo "RELEASE_UNSIGNED_APK: $RELEASE_UNSIGNED_APK" echo "APK_BASE: $APK_BASE" jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ${KEYSTORE_LOCATION} $APK_BASE-release-unsigned.apk "${KEY_ALIAS}" -storepass $keystore_password -keypass $keyalias_password -signedjar $APK_BASE-release-signed-unaligned.apk $ANDROID_HOME/build-tools/latest/zipalign -v 4 $APK_BASE-release-signed-unaligned.apk $APK_BASE-release-signed-aligned.apk
Note $ANDROID_HOME/build-tools/latest/ probably doesn't exist for you, 'latest' is a symlink that I update to point to the latest directory as new versions are installed by the SDK downloader. Either do the same or change it to the latest one you have. Unless you'd prefer to add it to jenkins' or your system path, in which case you can leave it out and just run 'zipalign'.
Without the '#!/bin/bash' line at the top Jenkins will echo back each line of the script into the log which will include your passwords.
The above script will look for a file ending in '-release-unsigned.apk' and parse it to find the part of the name before it which it sets as APK_BASE. It uses jarsigner with KEYSTORE_LOCATION and KEY_ALIAS (that were set in Properties Content) and keystore_password and keyalias_password (that were set by masked input fields) to create a -release-signed-unaligned.apk, then zipaligns to -release-signed-aligned.apk.
The latter is the file we want to distribute, let's copy it back to the build it came from:
Add a build step 'Execute shell' and paste in:
#!/bin/bash echo "COPYING SIGNED APK BACK TO BUILD" echo "---------------------------------" echo "pwd: `pwd` " echo "SIGN_PROMOTED_BUILD_JOB: $SIGN_PROMOTED_BUILD_JOB" echo "SIGN_PROMOTED_BUILD_NUMBER: $SIGN_PROMOTED_BUILD_NUMBER" echo "APK_BASE: $APK_BASE" export TARGET_DIR=../../$SIGN_PROMOTED_BUILD_JOB/builds/$SIGN_PROMOTED_BUILD_NUMBER/archive/bin/ echo "TARGET_DIR: $TARGET_DIR" ls -l $TARGET_DIR cp -va *-release-signed-aligned.apk $TARGET_DIR/ ls -l $TARGET_DIR
That's it! I'm archiving the artifacts purely for debugging purposes, there's no need to do so as the only thing you're interested in is the final apk and that will have been copied back to your original build directory.
Run it, enter your build, check the log, then if all looks OK check the artifacts on your original build for the new -release-signed-aligned.apk file.
What's next?
Fingerprinting Is fingerprinting useful? If your signed apk is depended on by other projects then it probably is. It won't be covered by fingerprinting in the main job because it has no idea about this -signed .apk. Fingerprinting in the sign-release-apk job will work but I'm not sure if the trail will be intact if it is referenced under the main job. It might be.
Re-testing You could kick off your test suite again but this time using the signed .apk, just add a post-build action to the signing project.
Versioning This job could edit the AndroidManifest.xml in the .apk before it is signed and change the version number from an internal-test-build-number to a publicly-facing-release-number. Is this safe? Probably, as long as you're very careful to ONLY edit the version string in the manifest, anything else could result in application-level changes that will mean you've not run the package you're distributing through your test process.
If it manages to mess up the XML then the resulting .apk will won't install so there's an easy test for that. Maybe trigger a re-test and have the test suite check the package version number.
Auto-deploy Auto-upload to Google Play, Amazon Appstore and anywhere else? Probably doable. I'm not sure I'd be that comfortable about it without a quick manual test inbetween, maybe another job similar to this one could do the deployment when manually triggered?
Tag source code Add a tag to git to state you've made a release build. Mention the version number, especially if you changed it as suggested above. If the original build was triggered by SCM then it will have the revision it built from, if not then it's a good idea to store that somewhere in the build's artifacts. I include it in the (development) .apk filename.
Quick tip: copying material-design-icons around in the linux GUI
There's a lot of stuff in this zip: black/white/grey versions of each, 18/24/36/48dp versions of each, hdpi/mdpi/xhdpi/etc versions of each, all categorised into folders by use case. It's quite laborious to find, pick and copy the ones you want into the matching drawable dirs in your project.
In the Dolphin file manager (you don't have to use the KDE desktop) set 'details view mode', browse to the root 'material-design-icons' directory, then expand (in the tree) every folder inside and every drawable-??? folder inside that. Start at the bottom and work up to minimise scrolling.
Then enable the filter - Tools -> Show Filter Bar, and in the filter bar enter what you're after. For example, 'search_white_24' will then just show you the 24dp search icons in white cascaded under their hdpi/mdpi etc folders, regardless of which category they are in. Open your project in another Dolphin window and ctrl-drag each file to copy.
If you're not sure what dp you're after and would like to check icon sizes open the info panel (View -> Panels -> Information) which will show you the px of each image when you click on it.
To see all image sizes at-a-glance try adding the Image Size column to Dolphin - View -> Additional Information -> Image -> Image Size. Unfortunately this doesn't work for me so I can't tell you how long it takes to scan that entire tree, maybe it'll work for you! Might have something to do with enabling one of the KDE indexing services.
Admob Integration
This is a very simple process of integrating admob.
Create a new ad unit
First up, log into your admob account and on the home page click Monetize new app. You will then see this page:
Select Add your app manually and fill in the form, type the name of the and select the platform (in this case, android).
After you have added your app, you will be asked to choose an ad format
Right now we will go with the banner. Give the unit a name and save. You will then see you ad unit's ID. Hit done and you are ready to start coding.
Import Google Play Services Library
Go to android-sdk\extras\google in your computer and copy the google_play_services folder in another the directory and then import the libproject inside the folder into your workspace. Make sure the Is Library is checked and add the library to your project. To do this go to the project properties (right click on project) then select android from the left menu.
Then add this library to your project.
Android Manifest
Add these inside the application tag:
And add this permission outside the application tag:
Java File
Go to the AppActivity.java and modify it as following:
Resolve the import errors if you need to, just hover over the error and you will be able to fix it by importing the missing class.
If you face problem in @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) then set a higher android build api for the project.
Add your ad unit ID (starts with "ca-app-pub-") in the strings.xml file in res->values.
To add a test device run the application on the device and open logcat. You will see this line:
add the test device ID (the part I obscured inside the brackets) to the AdRequest.Builder().
Run the application
Admob integration is done. Now to control when to show the ads and when to hide them.
Controlling Ad visibility
Add the following methods in your AppActivity.java file:
Helper Class
Create a c++ helper class for admob to communicate between java and c++. You might want to change the perspective in eclipse to C/C++.
Don't forget to add the new class to the android.mk file in jni.
Add the following to the AdmobHelper.h file (inside the class):
And add the following to the AdmobHelper.cpp file:
Now it's time to test if this works, head over to the HelloWorldScene.cpp and add the two menu items:
Add the callbacks in the header file:
Implement the callback methods in the c++ file:
Run the application
Congratulations! You have successfully integrated admob into your Cocos2d-x android game!
Get the project source here.
Menus
Menus in cocos2d-x are very simple to implement and use.
Only MenuItems can be added to Menus and the MenuItems can be images or texts.
When a new project is created there is a Menu added by default and it has a button which calls the method "menuCloseCallback" which is used to terminate the application.
As the names suggest, the first parameter is the image of the MenuItem when not selected, the second one is the image of the button when it is selected and the third one is the method called when the button is released.
The menuCloseCallback method needs to be declared in the header file:
The method in the cpp file is as follows:
When the button is pressed the app will terminate.
To create a menu with a text item:
The closeItem is then added to the menu the same way as the MenuItem image.
A MenuItem can also be created from a label, the label is created from either TTF or BMFont then added to a MenuItemLabel as the first parameter of create.
This is the simplest form of implementing menus in a game. There are a lot more functionality of the menu object in cocos2d-x. For instance I combine labels and images in one menu to form the UI of my games. The image below shows the game over scene from the game Save The Baby:
Everything on this UI is added to a single menu, some are labels and some are images. The labels which have no functionality have been disabled. This way I am able to use any action such as moveTo to give a transition effect to the entire menu.
Getting started with Cocos2d-x Android
This tutorial will cover the prerequisites and requirements of Cocos2d-x and how to set up an android project in eclipse on your computer.
What is R.layout.simple_list_item_1
defines how an item in the ListView should look like. It is actually a TextView,
Reference: stackoverflow, source code
Notes on Changing an Android MAC address
I started investigating how to change MAC addresses on Android devices because things like in-store tracking and massive distributed tracking of mobile devices, and by extension their owners, is probably only going to become more common and more robust.
While this does not address the issue of spewing SSIDs all over the place that might identify a device, it is a step in the direction of more control over unique information devices vomit out into the public space.
So far I have found that I can change the MAC address with commands like ip link set address ... but have run into issues connecting to WPA2 secured access points after performing this command. From a number of packet captures my best guess is Android is still using the burned-in MAC address to calculate a few values for the WPA2 handshake, but sending the actual packets from the spoofed MAC address. This freaks out the access point, as it should, and triggers a deauthentication packet. This is further supported by the fact that I can get the device to connect to an open network after spoofing the MAC. I have not done any testing with WEP.
Other notes; the MAC address never appears to change in the WiFi > Advanced screen. Turning WiFi off and on again resets the MAC address back to the burned in MAC. Running ifconfig down;ifconfig up; appears to have the same affect. All testing was done on a Nexus S 4G.
I've rolled this into MacSpin; a very simple Android application that I hope to get to a point of working with WPA2 networks. As you might expect this requires a rooted Android device.