I was setting up a brand new server yesterday running Cent OS 6.4 and had the need to install PSLib (PostScript) for PHP.
The initial setup commands all worked as expected:
cd /src #A good directory to install stuff in. You may need to create it first
#Install intltool (required for pslib)
yum install intltool
#Install pslib
wget http://sourceforge.net/projects/pslib/files/latest/download?source=files
tar -xzvf pslib-*.tar.gz
cd pslib-*
./configure
make
make install
cd ..
#Install pslib wrapper for php
pecl download ps
tar -xzvf ps-*.tgz
cd ps-*
phpize
./configure
make
At this point, the make failed with
/src/ps-1.3.6/ps.c:58: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘ps_functions’
After a little bit of browsing the code and a really lucky first guess, I found that changing the following fixed the problem:
In ps.c change: “ function_entry ps_functions[] = {” to “ zend_function_entry ps_functions[] = {”
Then to finish the install, just run:
make
make install
and you’re done! | Android Stuff | Yet another platform/library to learn. It never ends. |
Having recently finished my first Android project (and hopefully not last), I decided to supply some notes I took about the process.
While I am going to try and keep impressions to a minimum on the rest of this post, and keep it to tangible notes, I must first comment that trying to find out things for the Android platform was often like pulling teeth. While its typical Java reference online documentation is all there with all the classes and cross-linking, that is about all it is, very dry and virtually useless beyond a base reference. The comments on variable parameters (and many other sections) in the reference are often coarse and not descriptive at all, for example, one parameter named mask has the basic description as “this is a mask”. Some functions don’t even have descriptions at all.
Perhaps I am getting too complacent as a programmer and getting used to excellent documentation like for Python or GTK (I’ve even grown to love Microsoft documentation after having used it for long enough!). After all, most required information is just a Google away, and being a programmer is often just about finding the proper magical incantations to hook into a certain library. Unfortunately, however, even web searches were often yielding less than fruitful results when dealing with Android, as the platform is relatively new.
- Some useful tasks and some problems:
- Using the virtual (soft) keyboard without a TextView:
-
Showing the virtual keyboard:
((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE)).toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
-
Hiding the virtual keyboard:
((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(getWindow().getDecorView().getApplicationWindowToken(), 0);
Note: “getWindow().getDecorView()” can also be replaced by a View on your screen
-
Getting the keyboard input: Add the following function to the Activity that opened the keyboard:
@Override public boolean onKeyDown(int keyCode, KeyEvent msg)
Note: This will not work if you’re not using default keyboard input (like if it’s set to enter Japanese or Chinese characters).
-
Determining the physical dimensions of the screen:
This should be a trivial task using the DisplayMetrics (getWindowManager().getDefaultDisplay()) interface to get dpis and multiply by the screen dimensions getWindowManager().getDefaultDisplay().getWidth() (and .getHeight). However, it doesn’t always work as it should.
The best method to get the DPI would be to use “DisplayMetrics.xdpi” and “DisplayMetrics.ydpi”, but unfortunately, these are misreported by at least the Motorola Droid. I’ve found “DisplayMetrics.density”*160 to be pretty accurate, but if true accuracy is needed, a calibration screen might be required.
-
Inform user of touch events: Many Android widgets (Views) change their visual state (highlight) when the user presses down on them to let the user know something is going to happen if the user lifts their finger while still on the widget. Unfortunately, there seems to be no text widget or layout view that does this automatic highlighting by itself (ListViews do in groups). The following is some example code to produce this effect.
import android.view.View.OnTouchListener;
public class CLASSNAME extends Activity
{
@Override public void onCreate(Bundle savedInstanceState)
{
View HighlightView=findViewById(R.id.THE_VIEWS_ID);
HighlightView.setOnTouchListener(HighlightState);
}
private OnTouchListener HighlightState = new OnTouchListener() { public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction()==MotionEvent.ACTION_DOWN)
v.setBackgroundColor(0xFF0000FF); //Set background color to blue
else if(event.getAction()==MotionEvent.ACTION_CANCEL || event.getAction()==MotionEvent.ACTION_UP)
v.setBackgroundResource(0); //No background color
return false;
} };
}
-
Retrieving the names and IDs of all resources in a resource group:
import java.lang.reflect.Field;
Field[] FieldList=R.drawable.class.getDeclaredFields();
String[] Names=new String[FieldList.length];
int[] IDs=new int[FieldList.length];
for(int i=0;i<FieldList.length;i++)
IDs[i]=getResources().getIdentifier(Names[i]=FieldList[i].getName(), "drawable", getClass().getPackage().getName());
-
Setting a color matrix on an image: If you have 2 ImageViews that display the same resource image, and either has a color matrix set on it, the will both share one of the color matrices. If this occurs, copy the image the resource, or use a separate image resource. For kicks, here is an example of setting an inverse color matrix on an image.
((ImageView)findViewById(R.id.IMAGE_ID)).setColorFilter(new ColorMatrixColorFilter(new float[] {-1,0,0,0,255, 0,-1,0,0,255, 0,0,-1,0,255, 0,0,0,1,0}));
-
Setting to full screen:
requestWindowFeature(Window.FEATURE_NO_TITLE); //This must be called before "setContentView", and hides the title bar
getWindow().setFlags(FULLSCREEN ? WindowManager.LayoutParams.FLAG_FULLSCREEN : 0, WindowManager.LayoutParams.FLAG_FULLSCREEN); //Turns on/off the status bar
-
Starting another local activity: Instead of using Intent(String action) for Context.StartActivity, as the Reference explains, it is much easier to use Intent(Context packageContext, Class<?> cls) like the following: (called from inside an Activity)
startActivity(new Intent(this, OTHER_ACTIVITY_NAME.class);
-
Creating a timed event that updates the UI: A function running through java.util.Timer cannot interact with the GUI. One solution to make a timer is with the android.os.Handler interface.
import android.os.Handler;
public class ExampleActivity extends Activity
{
final int InitialDelay, RepeatDelay;
Handler TimedHandler=new Handler();
public void ExampleFunction()
{
TimedHandler.postDelayed(new Runnable() { public void run() {
//Do GUI stuff...
TimedHandler.postDelayed(this, RepeatDelay);
} }, InitialDelay);
}
}
Another solution is to post to a Handler from the Timer function.
- When dealing with putting on the market place:
- Getting an account to put applications on the Android Market cost $25.
- Screenshots shown on the Android Market description page are somewhat buggy, and seemingly randomly either stretch properly or crop. Viewing the full sized screenshots does seem to work properly.
-
Seeing as there are a number of applications on the market that have both a “Free” and “Full” version, you’d think this would be an easy thing to accomplish. Unfortunately, the marketplace uses an application’s package name as its unique identifier, so both versions have to have a different package name, which is again, a bit of a nuisance.
One method of remedying this is just having a recursive string replace through all the files to change the package names. However, if using eclipse, so you don’t have to reopen it, it’s quicker to update the string first in the manifest, and then renaming the package under the “src” folder by pressing F2 (rename) on it when it is selected.
Also, unfortunately, if you do this, when a person upgrades from the lite to the full version, preferences are not automatically transferred :-\.
- The publisher’s market place page is very sparse and leaves a lot to be desired. It also seems to update only once every 24 hours or so (not sure of exact times).
- If an application is put up, it WILL get downloads immediately. For example, I put up an application with a description of “This is a test, do not download this” for doing security tests that I took down within like 10 minutes. It already had 2 comments/ratings on it within that time ~.~; .
- Google Checkout: Fees. When a copy of your application is purchased, the user has 24 hours to return it. The money is not deposited into your bank account until after this time (when it’s not a weekend). If you want to give your application to someone for free, they need to purchase it through the market, and then you can cancel the purchase transaction before the 24 hours are up. Unfortunately, this has to be done every time they want to update the application. It also seems you cannot buy your own applications, as the purchase server throws an error.
- Application Protection:
You can download any Android application by default from your phone to your computer, modify them, and reinstall them back to any phone. An example use for this would be to crack a shareware application where just a single byte probably needs to be changed to make it a full version.
The applications themselves are in an .apk file (which is just a .zip file), and the source code (classes) are encoded as a “Dalvik Executable” file within it (classes.dex), which as I understand it, is optimized Java bytecode. So, AFAIK right now, there is no way to decompile the .dex file back to the original source, like you can with normal Java. However, the Android emulator, part of the Android SDK, includes a tool called dexdump, which allows you to decompile it to bytecode.
Once you have the bytecode, you can use that as reference to modify the compiled .dex file however you want, which is pretty much synonymous with assembly editing. Once that is done, the signature and checksum of the .dex file must be recalculated (Java source by Timothy Strazzere), and then the apk file must be resigned, and then it’s good to go!
The marketplace also has an option to turn on Copy Protection. When this is turned on for an application, the user cannot backup or access the applications package file. I would assume however with a rooted phone you could still grab it from “/data/app-private”, and the rest of the process should be the same. I have not tested this as rooting Android 2.1 is much more of a pain in the butt, ATM, than I want to deal with.
| This is sort of a continuation of the parseInt in JavaScript post made a few months ago.
Another minor JavaScript oddity is that it has two very similar String functions in its base library that are so similar that they can cause confusion to programmers. If a programmer only uses one of the two, and then tries to work with someone else’s code that uses the other function, things could easily get messy. These two functions are substr and substring, which w3schools defines as follows:
Function Name |
Parameters |
Description |
substr |
StartIndex, Length |
Extracts a specified number of characters in a string, from a start index |
substring |
StartIndex, EndIndex |
Extracts the characters in a string between two specified indices |
It is KIND of nice to have substring as a function for some purposes... but is it really so hard to do a...
String.substr(StartIndex, EndIndex - StartIndex)
?
I actually did something like this myself in my super awesome string library (which I have not yet released and do not know when I will...). I do not consider this hypocritical though because in my string library, I have a “substr”, like the JavaScript one, but the function that acts like JavaScript’s substring is called “mid”, after the function used in Visual Basic. I did this because I wanted the library to have “matching function names for many languages (PHP, JavaScript, VB, etc).” to make it easier on other programmers already familiar with other libraries. | We recently moved one of our important web server clients to a newly acquired server (our 12th server at ThePlanetThePlanet [Used to be called EV1Servers, and before that RackShack], one of, if not the largest, server-farm hosting company in the states). A bad problem cropped up on his site in the form of a PHP script (CaRP) that deals with parsing XML.
The problem was that whenever the XML was parsed and then returned, all XML entities (escaped XML characters like “>” “<” and “"”) were removed/deleted. I figured the problem had to do with a bad library, as the code worked perfectly on our old server, and the PHP settings on both were almost identical, but I wasn’t sure which one. After an hour or two of manipulating the code and debugging, I narrowed it down to which XML function calls had the problem, and that it was definitely not the scripts themselves. The following code demonstrates the problem.
$MyXMLData='<?xml version="1.0" encoding="iso-8859-1"?><description><img test="a"</description>';
$MyXml=xml_parser_create(strtoupper('ISO-8859-1'));
xml_parser_set_option($MyXml,XML_OPTION_TARGET_ENCODING,'ISO-8859-1');
xml_parse_into_struct($MyXml, $MyXMLData, $MyData);
print htmlentities($MyData[0]['value']);
On the server with the problem, the following was outputted:
img test=a
while it should have outputted the following:
<img test="a"
I went with a hunch at this point and figured that it might be the system’s LibXML libraries, so I repointed them away from version 2.7.1, which appears to be buggy, to an older version that was also on the system, 2.6.32. And low and behold, things were working again, yay :-D.
Technical data (This is a cPanel install): In “/opt/xml2/lib/” delete the symbolic links “libxml2.so” & “libxml2.so.2” and redirect them as symbolic links to “libxml2.so.2.6.32” instead of “libxml2.so.2.7.1”. | A very important part of programming languages is the standard library that comes with them. PHP has one of the strongest base standard libraries I’ve ever seen. It’s also great to always be able to just throw out any function call in a script and not need look up the library file that you need to include! Perl has one of the largest official library sets (not included by standard) that I know if, but I find it a pain always having to remember which libraries I have to include for all the different functions I need. Though this is probably just because I don’t use Perl that much, as I have most of the C standard include libraries memorized, heh.
To properly use any function from any library, it is important to know exactly how it is supposed to work and any idiosyncrasies. You can never know EXACTLY how a function works unless you have the source for it, but you can pretty much always guess the gist of the internals. This is one of the reasons I have always enjoyed writing my own Personal Libraries, besides that fact that I find it fun getting down in the nitty gritty of things. Not knowing the inner workings of a function is not really a problem when programming, as this is the whole point of encapsulation, and documentation is usually sufficient enough.
I ran into a problem with the parseInt (sister of parseFloat) JavaScript function a long ways back however (this topic has been written down for years to talk about). JavaScript is kind of special in that it is a language that you just kind of jump into and assume you can quickly pick up everything, as there is very very little to its base library. One would assume that the “parseInt” function would just turn anything given to it into an integer, so “parseInt('123')” would return “123” and “parseInt(1.4)” would return “1”, as expected. The gotcha comes in if you pass a 0 before an integral number in a string, in which case it assumes the number is in octal (base 8 math). I found this out by accident when parsing time strings, where minutes are always 2 digits with leading 0s. When “parseInt('09')” is called, it returns “0” because 9 is not a part of base 8 math. Oops! parseInt stops at the first character it identifies that is not part of the base it is currently parsing in. Incidentally parseInt will also parse hex[adecimal] (base 16) strings, as per standard C syntax, for example, “parseInt('0x10')” returns “16”. I would have just said standard hex syntax, but not all languages represent hex in that manner, for example, Visual Basic requires &H before a hex number instead, like “&H10” represents “16”. |
|