首先,你需要下载的MiniGUI 的包:
http://www.minigui.com/download/libminigui-1.3.3.tar.gz
http://www.minigui.com/download/minigui-res-1.3.3.tar.gz
这两个包的下载需要你在www.minigui.com 上注册过才可以下载,免费注册的,自己去下吧
http://www.minigui.com/downloads/minigui13/mde-1.3.0.tar.gz图形界面程序
http://www.minigui.com/downloads/minigui13/mg-samples-1.3.0.tar.gz 一些小例子
在/home/下创建新的工作目录
[user]# mkdir -p /home/minigui
把 libminigui-1.3.3.tar.gz 解开
[user]# tar zxf libminigui-1.3.3.tar.gz
[user]# tar zxf minigui-res-1.3.3.tar.gz
编译 libminigui ,这个是 minigui 运行所必需的库文件,必须编译成功
[user]# cd libminigui-1.3.3
[user]# ./configure //最简单的编译方式,让它自己去配置 ,这里采用缺省的Thread 模式而不是Lite模式,因为这种方式在 PC 机上使用最方便,后面移到板子上再改成 Lite 模式即可
注意屏幕上的输出,特别是下面几条
checking for FrameBuffer console support... yes
checking for pthread library... yes
checking for TT_FreeType_Version in -lttf... yes
checking for T1_InitLib in -lt1... no
checking for jpeg_std_error in -ljpeg... yes
checking for png_check_sig in -lpng... yes
其中 –lttf –lpng 必须是 yes,不然后面你的程序肯定会有问题,如果这里不是 yes的话,那么就可能是相应的库没有安装。
注:如果库已经正确安装,依然显示为no,例如有checking for png_check_sig in -lpng... no
解决办法:通过vi进入configure文件,查找png,在如下所注黑体处修改
if test "x$build_png_support" != "xno"; then
echo "$as_me:$LINENO: checking for png_check_sig in -lpng" >&5
echo $ECHO_N "checking for png_check_sig in -lpng... $ECHO_C" >&6
if test "${ac_cv_lib_png_png_check_sig+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
#I modified the below line
#LIBS="-lpng -lm $LIBS"
LIBS="-lpng -lm -lz $LIBS"
其中 ttf 库是对 TrueType字体的支持,png库是对 png图形的支持,jpeg库是对jpeng图形的支持,MiniGui里都需要这两个,在后面为板子交叉编译的时候也需要这两个,不然你的程序跑不起来。
如果./configure 结果中显示yes通过了,下面是编译了,执行如下命令。
# make
# make install
如果./configure 结果中显示的是no,则需要手动添加这些库了:
安装zlib库
zlib 库是后面的库的编译基础。首先需要安装这个库。
安装包:zlib-1.2.3.tar.gz
# tar zxf zlib-1.2.3.tar.gz
# cd zlib-1.2.3
# ./configure
# make
# make install
安装freetype库
解压步骤一致。
在make的时候可能出现以下错误:
1、错误一:
X11/Xlib.h:No such file or directory
解决方法:
sudo apt-get install libx11-dev
2、错误二:
ftdump.c:172:1: pasting "." and "glyph_object" does not give a valid preprocessing token
ftdump.c:182:1: pasting "." and "first_instance" does not give a valid preprocessing token
ftdump.c:191:1: pasting "." and "second_instance" does not give a valid preprocessing token
ftdump.c:201:1: pasting "." and "face_object" does not give a valid preprocessing token
ftdump.c:202:1: pasting "." and "glyph_object" does not give a valid preprocessing token
ftdump.c:203:1: pasting "." and "second_instance" does not give a valid preprocessing token
ftdump.c:863:1: pasting "." and "initial_overhead" does not give a valid preprocessing token
ftdump.c:882:1: pasting "." and "face_object" does not give a valid preprocessing token
make[1]: *** [ftdump.o] Error 1
make[1]: Leaving directory `/software/freetype-1.3.1/test'
make: *** [tttest] Error 2
解决方法:
修改Makefile:
1. 去掉all: ttlib tttest ttpo中的tttest
2. 删除
install:
cd $(FTLIBDIR); $(MAKE) -f $(MAKEFILE) install
cd $(FTTESTDIR); $(MAKE) -f $(MAKEFILE) install
cd $(FTPODIR); $(MAKE) uninstall
中的 cd $(FTTESTDIR); $(MAKE) -f $(MAKEFILE) install
安装png库
安装包:libpng-1.0.10rc1.tar.gz
Libpng 不提供有效的 configure 脚本,所以只好自己动手改 Makefile 文件了
# cp scripts/makefile.linux Makefile //把 Scripts 下的一个 makefile 拷出来自己动手改,在ubuntu中一般不需要修改
# make
# make install
安装jpeg库
安装包:jpegsrc.v6b.tar.gz
# cd jpeg-6b
# ./configure –perfix=/usr/local –enable-shared
# make
# make install
重新安装libminigui
在安装完成了所有的支持库以后,重新进入libminigui文件夹,运行configure命令后,应该所安装的支持库都显示yes
#./configure
checking for FrameBuffer console support... yes
checking for pthread library... yes
checking for TT_FreeType_Version in -lttf... yes
checking for T1_InitLib in -lt1... no
checking for jpeg_std_error in -ljpeg... yes
checking for png_check_sig in -lpng... yes
#make
在编译的过程中还可能出现以下的错误
……
freetype.c:47:41: freetype1/freetype/freetype.h: No such file or directory
freetype.c:48:40: freetype1/freetype/ftxkern.h: No such file or directory
freetype.c:49:41: freetype1/freetype/ftnameid.h: No such file or directory
freetype.c:50:40: freetype1/freetype/ftxcmap.h: No such file or directory
freetype.c:51:41: freetype1/freetype/ftxwidth.h: No such file or directory
……
make[3]: *** [freetype.lo] Error 1
make[3]: Leaving directory `/root/Minigui/libminigui-1.3.3/src/font'
make[2]: *** [install-recursive] Error 1
make[2]: Leaving directory `/root/Minigui/libminigui-1.3.3/src/font'
make[1]: *** [install-recursive] Error 1
make[1]: Leaving directory `/root/Minigui/libminigui-1.3.3/src'
make: *** [install-recursive] Error 1
解决方法:
freetype是用来支持字体显示的,如TrueType。是版本不一样。 这个错误的意思是说找不到库文件。
大漠孤狼的文章里提到了一个freetype软件,先安装,我是安装到/usr/local/include里了。找到它们,做成“freetype1/freetype/freetype.h”的样子,再拷贝到/usr/include里面,执行make clean之后再make就行了。
具体方法:
# cd /home/minigui/freetype-1.3.1
# mkdir -p /opt/cross/libttf/extend // 自己另外建立一个目录
# cp ./lib/* ./lib/arch/ansi/* /opt/cross/libttf/ //把有用的东西拷出来
# cp ./lib/extend/* /opt/cross/libttf/extend/ //把 extend 目录下的文件也拷出来
注意 cp 命令不要用 –r 选项,因为会把一些没用的东西出拷出来的
拷贝完成了,现在来自己手动编译了
# cd /opt/cross/libttf //就是上面新建的一个目录
# gcc -c -fPIC -O2 freetype.c //只要编译这一个 .c 文件,因为它包括了其它所有的 .c 文件了,你可以自己查看它的内容
# gcc -c -fPIC -O2 -I./ extend/*.c //把 extend 下所有的 .c 文件全部编译,注意-I./ 中是大写的i
# gcc --shared -o libttf.so *.o //生成最后的动态链接库,OK了
# mkdir -p /usr/include/freetype1/freetype
# cp *.h extend/*.h /usr/include/freetype1/freetype
# cp libttf.so /usr/local/lib
解决了这个问题之后,应该可以正确编译了。接着安装编译结果
# make install
安装minigui资源
安装包:minigui-res-1.3.3.tar.gz
# cd /home/minigui/minigui-res-1.3.3
# make install
相关的配置设置
首先,修改你的 /etc/ld.so.conf 文件,在里面最后新加入一行 /usr/local/lib
然后执行
# ldconfig
# vi /usr/local/etc/MiniGUI.cfg
在里面找到
[system]
# GAL engine
#gal_engine=fbcon
gal_engine=qvfb //这里修改
# IAL engine
#ial_engine=console
ial_engine=qvfb //这里修改
mdev=/dev/mouse
mtype=IMPS2
[fbcon]
defaultmode=1024x768-16bpp
[qvfb]
defaultmode=640x480-16bpp //这里修改
display=0
qvfb的安装
如果系统里还没有安装话qvfb,那么需要安装一个 qvfb ,
# cd /home/minigui1.3.3-arm/qvfb-1.0
# ./configure
# make
# make install
注:有可能编译时候,有错误cheching for Qt...configure:error: Qt(>= Qt 3.0.3)(headers and libraries)not found.please check your installation!
解决办法:安装 libqt3-mt-dev 包,执行命令apt-get install libqt3-mt-dev ,或者找到相应包进行受到安装。(再不行分别装上libqt3-headers libqt3-mt libqt3-mt-dev包试一下),另外在执行./configure 可以同时加上参数 LDFLAGS和CPPFLAGS指定库文件和头文件所在的目录。至于 ./configure的用法可以在./configure --help查询
--with-qt-dir=/usr/lib/qt-3.3
or
--with-qt-includes=/usr/lib/qt-3.3/include
--with-qt-libraries=/usr/lib/qt-3.3/lib
试验的测试
mg-samples-1.3.0.tar.gz 这个包就是一些例子,现在试试:
# tar zxf mg-samples-1.3.0.tar.gz
# ./configure
# make
# cd src
看看 src 目录下是不是已经编译出可执行文件来了
Cd sr
执行例子程序:
[user]# qvfb & //在图形界面下执行
在 qvfb 中选 File Configure 640x480 VGA 16bit ,这样看起来舒服
[user]# cd /home/minigui1.3.3-arm/mg-samples-1.3.0/src
[user]# ./helloword
效果如下图所示:
OK ,这个时候你应该可以看到在 qvfb 中的执行效果了吧,记住:一定要先运行 qvfb ,并且设置 qvfb ,然后再运行你的程序,而且qvfb 每重启一次就需要重新设置一下
public static final int MESSAGE_TYPE_ALL = 0; public static final int MESSAGE_TYPE_INBOX = 1; public static final int MESSAGE_TYPE_SENT = 2; public static final int MESSAGE_TYPE_DRAFT = 3; public static final int MESSAGE_TYPE_OUTBOX = 4; public static final int MESSAGE_TYPE_FAILED = 5; // for failed outgoing messages public static final int MESSAGE_TYPE_QUEUED = 6; // for messages to send later public static final int MESSAGE_TYPE_INBOX_SUB1 = 7; public static final int MESSAGE_TYPE_INBOX_SUB2 = 8;看到这你有莫有感悟了,大家请看时序图的第三步,讲需要发送的短信保存到quen队列中去,下面请看如下代码:
private boolean queueMessage(long token) throws MmsException { if ((mMessageText == null) || (mNumberOfDests == 0)) { // Don't try to send an empty message. throw new MmsException("Null message body or dest."); } SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext); boolean requestDeliveryReport = prefs.getBoolean( MessagingPreferenceActivity.SMS_DELIVERY_REPORT_MODE, DEFAULT_DELIVERY_REPORT_MODE); for (int i = 0; i < mNumberOfDests; i++) { try { log("updating Database with sub = " + mSubscription); Sms.addMessageToUri(mContext.getContentResolver(), Uri.parse("content://sms/queued"), mDests[i], mMessageText, null, mTimestamp, true /* read */, requestDeliveryReport, mThreadId, mSubscription); } catch (SQLiteException e) { SqliteWrapper.checkSQLiteException(mContext, e); } } // Notify the SmsReceiverService to send the message out Intent intent = new Intent(SmsReceiverService.ACTION_SEND_MESSAGE, null, mContext, SmsReceiver.class); intent.putExtra(SUBSCRIPTION, mSubscription); mContext.sendBroadcast(intent); return false; }在for循环里面,将对应短信的内容加入到content://sms/queued中去,大家可能看到这糊涂了,为了不让大家都糊涂下面简单介绍SmsProvider的insert()方法,
String where = Sms.SUB_ID + "=" + subscription; Cursor c = SqliteWrapper.query(this, resolver, uri, SEND_PROJECTION, where, null, "date ASC"); // date ASC so we send out in // same order the user tried // to send messages. if (c != null) { try { if (c.moveToFirst()) { String msgText = c.getString(SEND_COLUMN_BODY); String address = c.getString(SEND_COLUMN_ADDRESS); int threadId = c.getInt(SEND_COLUMN_THREAD_ID); int status = c.getInt(SEND_COLUMN_STATUS); int msgId = c.getInt(SEND_COLUMN_ID); Uri msgUri = ContentUris.withAppendedId(Sms.CONTENT_URI, msgId);这段代码没有太多复杂的逻辑可以看出取出第一条中的各个数据 ;
然后调用SmsSingleRecipentSender的sendMessage方法发送
sender = new SmsSingleRecipientSender(this, address, msgText, threadId, status == Sms.STATUS_PENDING, msgUri, subscription); sender.sendMessage(SendingProgressTokenManager.NO_TOKEN);;关于
public boolean sendMessage(long token) throws MmsException { SmsManager smsManager = SmsManager.getDefault(); ArrayList<String> messages = null; if ((MmsConfig.getEmailGateway() != null) && (Mms.isEmailAddress(mDest) || MessageUtils.isAlias(mDest))) { String msgText; msgText = mDest + " " + mMessageText; mDest = MmsConfig.getEmailGateway(); messages = smsManager.divideMessage(msgText); } else { messages = smsManager.divideMessage(mMessageText); // remove spaces from destination number (e.g. "801 555 1212" -> "8015551212") mDest = mDest.replaceAll(" ", ""); } int messageCount = messages.size(); if (messageCount == 0) { // Don't try to send an empty message. throw new MmsException("SmsMessageSender.sendMessage: divideMessage returned " + "empty messages. Original message is \"" + mMessageText + "\""); } boolean moved = Sms.moveMessageToFolder(mContext, mUri, Sms.MESSAGE_TYPE_OUTBOX, 0); if (!moved) { throw new MmsException("SmsMessageSender.sendMessage: couldn't move message " + "to outbox: " + mUri); } ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>(messageCount); ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>(messageCount); for (int i = 0; i < messageCount; i++) { if (mRequestDeliveryReport) { // TODO: Fix: It should not be necessary to // specify the class in this intent. Doing that // unnecessarily limits customizability. deliveryIntents.add(PendingIntent.getBroadcast( mContext, 0, new Intent( MessageStatusReceiver.MESSAGE_STATUS_RECEIVED_ACTION, mUri, mContext, MessageStatusReceiver.class), 0)); } Intent intent = new Intent(SmsReceiverService.MESSAGE_SENT_ACTION, mUri, mContext, SmsReceiver.class); int requestCode = 0; if (i == messageCount -1) { // Changing the requestCode so that a different pending intent // is created for the last fragment with // EXTRA_MESSAGE_SENT_SEND_NEXT set to true. requestCode = 1; intent.putExtra(SmsReceiverService.EXTRA_MESSAGE_SENT_SEND_NEXT, true); intent.putExtra(SUBSCRIPTION, mSubscription); } sentIntents.add(PendingIntent.getBroadcast(mContext, requestCode, intent, 0)); } smsManager.sendMultipartTextMessage(mDest, mServiceCenter, messages, sentIntents, deliveryIntents, mSubscription); return false; }该方法会做4件事情:
Intent sendNext = new Intent(); sendNext.putExtra(SEND_NEXT_MSG_EXTRA, true); sentIntent.send(mContext, Activity.RESULT_OK, sendNext);可以看在应用层声明sentintent:
Intent intent = new Intent(SmsReceiverService.MESSAGE_SENT_ACTION, mUri, mContext, SmsReceiver.class); int requestCode = 0; if (i == messageCount -1) { // Changing the requestCode so that a different pending intent // is created for the last fragment with // EXTRA_MESSAGE_SENT_SEND_NEXT set to true. requestCode = 1; intent.putExtra(SmsReceiverService.EXTRA_MESSAGE_SENT_SEND_NEXT, true); intent.putExtra(SUBSCRIPTION, mSubscription); } sentIntents.add(PendingIntent.getBroadcast(mContext, requestCode, intent, 0))这样的话,在Mms中有注册com.android.mms.transaction.MESSAGE_SENT这个广播的接收器就有且仅有SmsReceiver
boolean sendNextMsg = intent.getBooleanExtra(EXTRA_MESSAGE_SENT_SEND_NEXT, false); if (mResultCode == Activity.RESULT_OK) { if (!Sms.moveMessageToFolder(this, uri, Sms.MESSAGE_TYPE_SENT, error)) { Log.e(TAG, "handleSmsSent: failed to move message " + uri + " to sent folder"); } if (sendNextMsg) { if (TelephonyManager.isMultiSimEnabled()) { sendFirstQueuedMessage(intent.getIntExtra(SUBSCRIPTION , 0)); } else { sendFirstQueuedMessage(); } }我想看到这,你肯定会恍然大悟吧,首先会获取sendNextMsg前面有提到该值,这里会去根据该值来发送下一条信息,调用的方法仍然是前面提到的sendFirstQueuedMessage方法,该方法会去获取当前数据库中是否有需要发送的短信,如果有继续发送第一条,如果没有直接返回。注意这里有一个Sms.moveMessageToFolder(this, uri, Sms.MESSAGE_TYPE_SENT, error)这样的操作,这里仍然是前面提到的更新sms表中type字段,会将其值设置成2,表示已发送成功,这时界面会将正在发送改成已发送状态,界面的实现是监听了数据库,那一旦数据库有改变就会更新界面,这里就不累述了,在短信的接收里有提到。
从http://libgdx.badlogicgames.com/nightlies/dist/gdx-setup-ui.jar下载gdx-setup-ui.jar
下载完成后直接双击此文件或在命令行里执行
java -jar gdx-setup-ui.jar
即可打开LibGDX创建工程的窗口,也可以通过这个程序来下载LibGDX的开发包。
如图,如果左侧"LibGDX"为红色,说明程序还没有关联到LibGDX开发包。
点击红框中的那个按钮即可在线下载开发包。
下载完成后就可以创建工程了,非常方便。