随笔 - 33, 文章 - 0, 评论 - 12, 引用 - 0
数据加载中……

android 保存图片到数据库

方法一:
Java代码 复制代码
  1. public void saveIcon(Bitmap icon) {   
  2.         if (icon == null) {   
  3.             return;   
  4.         }   
  5.   
  6.         // 最终图标要保存到浏览器的内部数据库中,系统程序均保存为SQLite格式,Browser也不例外,因为图片是二进制的所以使用字节数组存储数据库的   
  7.         // BLOB类型   
  8.         final ByteArrayOutputStream os = new ByteArrayOutputStream();   
  9.         // 将Bitmap压缩成PNG编码,质量为100%存储           
  10.         icon.compress(Bitmap.CompressFormat.PNG, 100, os);    
  11.         // 构造SQLite的Content对象,这里也可以使用raw   
  12.         ContentValues values = new ContentValues();    
  13.         // 写入数据库的Browser.BookmarkColumns.TOUCH_ICON字段   
  14.         values.put(Browser.BookmarkColumns.TOUCH_ICON, os.toByteArray());    
  15.            
  16.         DBUtil.update(....);//调用更新或者插入到数据库的方法   
  17.     } 


方法二:如果数据表入口时一个content:URI

 

Java代码 复制代码
  1. import android.provider.MediaStore.Images.Media;   
  2. import android.content.ContentValues;   
  3. import java.io.OutputStream;   
  4.   
  5. // Save the name and description of an image in a ContentValues map.     
  6. ContentValues values = new ContentValues(3);   
  7. values.put(Media.DISPLAY_NAME, "road_trip_1");   
  8. values.put(Media.DESCRIPTION, "Day 1, trip to Los Angeles");   
  9. values.put(Media.MIME_TYPE, "image/jpeg");   
  10.   
  11. // Add a new record without the bitmap, but with the values just set.   
  12. // insert() returns the URI of the new record.   
  13. Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);   
  14.   
  15. // Now get a handle to the file for that record, and save the data into it.   
  16. // Here, sourceBitmap is a Bitmap object representing the file to save to the database.   
  17. try {   
  18.     OutputStream outStream = getContentResolver().openOutputStream(uri);   
  19.     sourceBitmap.compress(Bitmap.CompressFormat.JPEG, 50, outStream);   
  20.     outStream.close();   
  21. catch (Exception e) {   
  22.     Log.e(TAG, "exception while writing image", e);   


posted @ 2011-11-17 14:09 建华 阅读(1652) | 评论 (0)编辑 收藏

代码命名

1、成员变量(全局变量)命名首字母以m开头第二个字母大写;(e.g  int mIndex = 0)                                                                                                            
2、常量全部大写                                                                                                                                                                                                           3、静态的变量命名首字母以s开头第二个字母大写;(e.g  static int sIndex = 0)          

posted @ 2011-11-04 10:03 建华 阅读(149) | 评论 (0)编辑 收藏

android混淆apk出错Proguard returned with error code 1. See console解决办法”

原文出自:http://blog.csdn.net/aa4790139/article/details/6754230 

第一种情况:
Proguard returned with error code 1. See console 
Error: C:/Documents (系统找不到指定文件) 
后来发现是因为将整个工程放到了桌面上,而桌面的目录是C:/Documents and Settings/Administrator/桌面,在这里面有空格,而proguard进行发编译的时候是不允许有空格的
如果换了正确路径还不好用的话,直接删除proguard就好了

注意:SDK和程序路径最好不要有空格符

第二种情况:

Proguard returned with error code 1. See console 
异常:

java.lang.ArrayIndexOutOfBoundsException

解决办法:将proguard.cfg中的"-dontpreverify"改成“-dontoptimize

参考文章:http://groups.google.com/group/android-developers/browse_thread/thread/eca3b0f5ce6ad00f

posted @ 2011-11-02 19:56 建华 阅读(3960) | 评论 (0)编辑 收藏

怎么建一个自己的博客

建一个自己的博客,既可以练习php,mysql,还能了解一些网站基础知识。好了现在我就吧自己建立玩站的过程写下来,供大家参考!过程是漫长的,只有自己摸索,才能不断增加经验,才能自己解决问题!

首先我们得要个空间,这个空间是用来放网页文件滴,其实网站就是一个文件夹,里面放了许多网页,在静态网页中,当你用浏览器访问这个文件时它会首先访问index.html,自己动手做过的同学肯定知道,当你把别人网站拷下来的时候体会就明显了,我就这么干的(好像很废话)。

1.我前前后后申请了N多空间,不是空间太小,就是无法登陆,或者DNS解析不上,所以我推荐用www.simplefreeweb.com,完全免费滴,等一晚上就把账号密码发过来了,后台有很多工具mysql,phpmyadmin等等(额- -!我忘了说一点,懂一点数据库和php的同学上手快一些,因为你连数据库,表都不知道,那出现问题你都不知道在哪里)。

2.注册好能登陆的前提下,再到cn.wordpress.org下载他们的wordpress(这是别人做好的玩站模板,直接可用,里面是php文件如果你自己有自信比他做的好,或者练习php,那就自己做吧)解压上传到空间,上传工具很多,我用的是filezilla,用www.simplefreeweb.com提供的ftp站好密码,上传到ftp里面的www目录下,记住上传wordpress文件下的文件,不要把wordpress文件夹一起传上去,要不然你要访问yourname.simplefreeweb.com/wordpress才能访问。

3.上传完成,用simplefreeweb给你的后台登陆网址登陆,在里面建立数据库,再向数据库添加用户的时候一定要勾选全部权限,要不然在后面wordpress安装的时候会连接出现问题!

4.建立好数据库后,登陆你的网站yourname.simplefreeweb.com,会出现wordpress安装导向,按照步骤就可以啦!

5.yourname.simplefreeweb.com这个是人家的二级域名,既不个性,有很难记,所以我们得要个自己的。网上的顶级域名很多但价格不菲,而且申请麻烦,所以我建议到http://www.dot.tk申请,很方便!

绑定域名,就是将这个域名指向你的网站,方法主要是域名解析,免费的解析商也很多,很久都没消息(我的就是,ywww.simplefreeweb.com自带的解析不给力啊)。但是,tk里面有个域名跳转,当你申请完后把你的yourname.simplefreeweb.com填进去,这样当访问你的域名,如我的www.liubos.k时候,直接跳到liubo.simplefreeweb.com。好处是方便,缺点是当别人访问非主页时,还是显示原来的网址!又等一晚上!第二天再访问自己的网站www.xxx.tk吧!说到xxx,我又邪恶了,呵呵!


posted @ 2011-10-31 11:34 建华 阅读(2370) | 评论 (6)编辑 收藏

android 使用contentobserver监听数据库内容变化

     摘要: android 使用contentobserver监听数据库内容变化在android中经常会用到改变数据库内容后再去使用数据库更新的内容,很多人会重新去query一遍,但是这样的问题就是程序会特别占内存,而且有可能会搂关cursor而导致程序内存未释放等等。其实android内部提供了一种ContentObserver的东西来监听数据库内容的变化。ContentObserver的构造函数需要一个参...  阅读全文

posted @ 2011-10-27 22:11 建华 阅读(4933) | 评论 (1)编辑 收藏

Android 彩信的发送

最近有个需求,不去调用系统界面发送彩信功能。做过发送短信功能的同学可能第一反应是这样:
不使用 StartActivity,像发短信那样,调用一个类似于发短信的方法
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneCode, null, text, null, null);
可以实现吗? 答案是否定的,因为android上根本就没有提供发送彩信的接口,如果你想发送彩信,对不起,请调用系统彩信app界面,如下
            Intent sendIntent = new Intent(Intent.ACTION_SEND,  Uri.parse("mms://"));
	    sendIntent.setType("image/jpeg");
	    String url = "file://sdcard//tmpPhoto.jpg";
	    sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(url));
	    startActivity(Intent.createChooser(sendIntent, "MMS:"));

但是这种方法往往不能满足我们的需求,能不能不调用系统界面,自己实现发送彩信呢?经过几天的努力,终于找到了解决办法。
第一步:先构造出你要发送的彩信内容,即构建一个pdu,需要用到以下几个类,这些类都是从android源码的MMS应用中mms.pdu包中copy出来的。你需要将pdu包中的所有类

都拷贝到你的工程中,然后自己酌情调通。
   final SendReq sendRequest = new SendReq();
   final PduBody pduBody = new PduBody();

final PduPart part = new PduPart();//存放附件,每个附件是一个part,如果添加多个附件,就想body中add多个part。

   pduBody.addPart(partPdu);
   sendRequest.setBody(pduBody);
   final PduComposer composer = new PduComposer(ctx, sendRequest);

final byte[] bytesToSend = composer.make(); //将彩信的内容以及主题等信息转化成byte数组,准备通过http协议发送到 ”http://mmsc.monternet.com”;

 第二步:发送彩信到彩信中心。
 构建pdu的代码:
  String subject = "测试彩信";
		    String recipient = "接收彩信的号码";//138xxxxxxx
		    final SendReq sendRequest = new SendReq();
		    final EncodedStringValue[] sub = EncodedStringValue.extract(subject);
		    if (sub != null && sub.length > 0) {
		    	sendRequest.setSubject(sub[0]);
		    }
		    final EncodedStringValue[] phoneNumbers = EncodedStringValue.extract(recipient);
		    if (phoneNumbers != null && phoneNumbers.length > 0) {
		    	sendRequest.addTo(phoneNumbers[0]);
		    }
		    final PduBody pduBody = new PduBody();
		    final PduPart part = new PduPart();
		    part.setName("sample".getBytes());
		    part.setContentType("image/png".getBytes());
		    String furl = "file://mnt/sdcard//1.jpg";
 
		    		final PduPart partPdu = new PduPart();
		    		partPdu.setCharset(CharacterSets.UTF_8);//UTF_16
		    		partPdu.setName(part.getName());
		    		partPdu.setContentType(part.getContentType());
		    		partPdu.setDataUri(Uri.parse(furl));
		    		pduBody.addPart(partPdu);   
 
		    sendRequest.setBody(pduBody);
		    final PduComposer composer = new PduComposer(ctx, sendRequest);
		    final byte[] bytesToSend = composer.make();
 
		    Thread t = new Thread(new Runnable() {
 
				@Override
				public void run() {
					try {
						HttpConnectInterface.sendMMS(ctx,  bytesToSend);
//
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			});
		    t.start();
发送pdu到彩信中心的代码:
        public static String mmscUrl = "http://mmsc.monternet.com";
//	public static String mmscUrl = "http://www.baidu.com/";
	public static String mmsProxy = "10.0.0.172";
	public static String mmsProt = "80";
 
       private static String HDR_VALUE_ACCEPT_LANGUAGE = "";
    // Definition for necessary HTTP headers.
       private static final String HDR_KEY_ACCEPT = "Accept";
       private static final String HDR_KEY_ACCEPT_LANGUAGE = "Accept-Language";
 
    private static final String HDR_VALUE_ACCEPT =
        "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic";
public static byte[] sendMMS(Context context, byte[] pdu)throws IOException{
		HDR_VALUE_ACCEPT_LANGUAGE = getHttpAcceptLanguage();
 
		if (mmscUrl == null) {
            throw new IllegalArgumentException("URL must not be null.");
        }
 
        HttpClient client = null;
        try {
	        // Make sure to use a proxy which supports CONNECT.
	        client = HttpConnector.buileClient(context);
	        HttpPost post = new HttpPost(mmscUrl);
	        //mms PUD START
	        ByteArrayEntity entity = new ByteArrayEntity(pdu);
			entity.setContentType("application/vnd.wap.mms-message");
	        post.setEntity(entity);
	        post.addHeader(HDR_KEY_ACCEPT, HDR_VALUE_ACCEPT);
	        post.addHeader(HDR_KEY_ACCEPT_LANGUAGE, HDR_VALUE_ACCEPT_LANGUAGE);
	        //mms PUD END
	        HttpParams params = client.getParams();
	        HttpProtocolParams.setContentCharset(params, "UTF-8");
	        HttpResponse response = client.execute(post);
 
			LogUtility.showLog(tag, "111");
	        StatusLine status = response.getStatusLine();
	        LogUtility.showLog(tag, "status "+status.getStatusCode());
	        if (status.getStatusCode() != 200) { // HTTP 200 is not success.
            	LogUtility.showLog(tag, "!200");
                throw new IOException("HTTP error: " + status.getReasonPhrase());
            }
	        HttpEntity resentity = response.getEntity();
            byte[] body = null;
            if (resentity != null) {
                try {
                    if (resentity.getContentLength() > 0) {
                        body = new byte[(int) resentity.getContentLength()];
                        DataInputStream dis = new DataInputStream(resentity.getContent());
                        try {
                            dis.readFully(body);
                        } finally {
                            try {
                                dis.close();
                            } catch (IOException e) {
                                Log.e(tag, "Error closing input stream: " + e.getMessage());
                            }
                        }
                    }
                } finally {
                    if (entity != null) {
                        entity.consumeContent();
                    }
                }
            }
            LogUtility.showLog(tag, "result:"+new String(body));
            return body;
		}  catch (IllegalStateException e) {
			LogUtility.showLog(tag, "",e);
//            handleHttpConnectionException(e, mmscUrl);
        } catch (IllegalArgumentException e) {
        	LogUtility.showLog(tag, "",e);
//            handleHttpConnectionException(e, mmscUrl);
        } catch (SocketException e) {
        	LogUtility.showLog(tag, "",e);
//            handleHttpConnectionException(e, mmscUrl);
        } catch (Exception e) {
        	LogUtility.showLog(tag, "",e);
        	//handleHttpConnectionException(e, mmscUrl);
        } finally {
            if (client != null) {
//                client.;
            }
        }
		return new byte[0];
	}

至此,彩信的发送算是完成了。
总结:android的彩信相关操作都是没有api的,包括彩信的读取、发送、存储。这些过程都是需要手动去完成的。想要弄懂这些过程,需要仔细阅读android源码中的mms这个app。还有就是去研究mmssms.db数据库,因为彩信的读取和存储其实都是对mmssms.db这个数据库的操作过程。而且因为这个是共享的数据库,所以只能用ContentProvider这个组件去操作db。

总之,想要研究彩信这块(包括普通短信),你就必须的研究mmssms.db的操作方法,多多了解每个表对应的哪个uri,每个uri能提供什么样的操作,那些字段代表短信的那些属性等。
最后推荐个好用的sqlite查看工具:SQLite Database Browser。


posted @ 2011-08-16 14:50 建华 阅读(4515) | 评论 (2)编辑 收藏

Activity的生命周期

注意到在Activity的API中有大量的onXXXX形式的函数定义,除了我们前面用到的onCreate以外,还有onStart,onStop以及onPause等等。从字面上看,它们是一些事件回调,那么次序又是如何的呢?其实这种事情,自己做个实验最明白不过了。在做这个实验之前,我们先得找到在Android中的Log是如何输出的。

显然,我们要用的是android.util.log类,这个类相当的简单易用,因为它提供的全是一些静态方法:
Log.v(String tag, String msg);        //VERBOSE
Log.d(String tag, String msg);       //DEBUG    
Log.i(String tag, String msg);        //INFO
Log.w(String tag, String msg);     //WARN
Log.e(String tag, String msg);      //ERROR
前面的tag是由我们定义的一个标识,一般可以用“类名_方法名“来定义。
输出的LOG信息,如果用Eclipse+ADT开发,在LogCat中就可以看到,否则用adb logcat也行,不过我是从来都依赖于IDE环境的。

好了,现在我们修改前面的HelloThree代码:
   public void onStart()
    
{
        
super.onStart();
        Log.v(TAG,
"onStart");
    }

    
public void onStop()
    
{
        
super.onStop();
        Log.v(TAG,
"onStop");
    }

    
public void onResume()
    
{
        
super.onResume();
        Log.v(TAG,
"onResume");
    }

    
public void onRestart()
    
{
        
super.onRestart();
        Log.v(TAG,
"onReStart");
    }

    
public void onPause()
    
{
        
super.onPause();
        Log.v(TAG,
"onPause");
    }

    
public void onDestroy()
    
{
        
super.onDestroy();
        Log.v(TAG,
"onDestroy");
    }

    
public void onFreeze(Bundle outState)
    
{
        
super.onFreeze(outState);
        Log.v(TAG,
"onFreeze");
    }
在HelloThreeB中也同样增加这样的代码,编译,运行一下,从logcat中分析输出的日志。
在启动第一个界面Activity One时,它的次序是:
onCreate (ONE) - onStart (ONE) - onResume(ONE) 
虽然是第一次启动,也要走一遍这个resume事件。然后,我们点goto跳到第二个Activity Two中(前一个没有关闭),这时走的次序是:
onFreeze(ONE) - onPause(ONE) - onCreate(TWO) - onStart(TWO) - onResume(TWO) - onStop(ONE)
说明,第二个Activity Two在启动前,One会经历一个:冻结、暂停的过程,在启动Two后,One才会被停止?
然后,我们再点back回到第一个界面,这时走的次序是:
onPause(TWO) - onActivityResult(ONE) - onStart(ONE) - onRestart(ONE) - onResume(ONE) - onStop(TWO) - onDestroy(TWO)
说明,返回时,Two没有经历冻结就直接暂停了,在One接收参数,重启后,Two就停止并被销毁了。
最后,我们点一下Exit退出应用,它的次序是:
onPause(ONE) - onStop(ONE) - onDestroy(ONE)
说明如果我们用了finish的话,不会有freeze,但是仍会经历pause - stop才被销毁。

这里有点疑问的是:为什么回来时先是Start才是Restart?可是文档中的图上画的却是先restart再start的啊?不过,后面的表格中的描述好象是正确的,start后面总是跟着resume(如果是第一次)或者restart(如果原来被stop掉了,这种情况会在start与resume中插一个restart)。

下面不跑例子了,看看文档吧。

1.Android用Activity Stack来管理多个Activity,所以呢,同一时刻只会有最顶上的那个Activity是处于active或者running状态。其它的Activity都被压在下面了。

2.如果非活动的Activity仍是可见的(即如果上面压着的是一个非全屏的Activity或透明的Activity),它是处于paused状态的。在系统内存不足的情况下,paused状态的Activity是有可被系统杀掉的。只是不明白,如果它被干掉了,界面上的显示又会变成什么模样?看来下回有必要研究一下这种情况了。

3.几个事件的配对可以比较清楚地理解它们的关系。Create与Destroy配成一对,叫entrie lifetime,在创建时分配资源,则在销毁时释放资源;往上一点还有Start与Stop一对,叫visible lifetime,表达的是可见与非可见这么一个过程;最顶上的就是Resume和Pause这一对了,叫foreground lifetime,表达的了是否处于激活状态的过程。

4.因此,我们实现的Activity派生类,要重载两个重要的方法:onCreate()进行初始化操作,onPause()保存当前操作的结果。

除了Activity Lifecycle以外,Android还有一个Process Lifecycle的说明:

在内存不足的时候,Android是会主动清理门户的,那它又是如何判断哪个process是可以清掉的呢?文档中也提到了它的重要性排序:

1.最容易被清掉的是empty process,空进程是指那些没有Activity与之绑定,也没有任何应用程序组件(如Services或者IntentReceiver)与之绑定的进程,也就是说在这个process中没有任何activity或者service之类的东西,它们仅仅是作为一个cache,在启动新的Activity时可以提高速度。它们是会被优先清掉的。因此建议,我们的后台操作,最好是作成Service的形式,也就是说应该在Activity中启动一个Service去执行这些操作。

2.接下来就是background activity了,也就是被stop掉了那些activity所处的process,那些不可见的Activity被清掉的确是安全的,系统维持着一个LRU列表,多个处于background的activity都在这里面,系统可以根据LRU列表判断哪些activity是可以被清掉的,以及其中哪一个应该是最先被清掉。不过,文档中提到在这个已被清掉的Activity又被重新创建的时候,它的onCreate会被调用,参数就是onFreeze时的那个Bundle。不过这里有一点不明白的是,难道这个Activity被killed时,Android会帮它保留着这个Bundle吗?

3.然后就轮到service process了,这是一个与Service绑定的进程,由startService方法启动。虽然它们不为用户所见,但一般是在处理一些长时间的操作(例如MP3的播放),系统会保护它,除非真的没有内存可用了。

4.接着又轮到那些visible activity了,或者说visible process。前面也谈到这个情况,被Paused的Activity也是有可能会被系统清掉,不过相对来说,它已经是处于一个比较安全的位置了。

5.最安全应该就是那个foreground activity了,不到迫不得已它是不会被清掉的。这种process不仅包括resume之后的activity,也包括那些onReceiveIntent之后的IntentReceiver实例。

在Android Application的生命周期的讨论中,文档也提到了一些需要注意的事项:因为Android应用程序的生存期并不是由应用本身直接控制的,而是由Android系统平台进行管理的,所以,对于我们开发者而言,需要了解不同的组件Activity、Service和IntentReceiver的生命,切记的是:如果组件的选择不当,很有可能系统会杀掉一个正在进行重要工作的进程。

posted @ 2011-08-03 15:41 建华 阅读(215) | 评论 (0)编辑 收藏

Eclipse+ADT进行Android应用程序的代码混淆和签名

启动代码混淆功能

在较新版本的Android tools和ADT,项目工程里面是带有proguard.cfg的代码混淆配置文件,但默认是没有启动这个配置的,需要手动地在default.properties里面添加指定这个配置文件:
# Project target.
target=android-3
proguard.config=proguard.cfg
然后按F5刷新当前项目工程,这时候Eclipse检测了文件的变动而重新编译!

生成签名发布apk

1.Eclipse工程中右键工程,弹出选项中选择 android工具-生成签名应用包:
右键选择
2.选择需要打包的android项目工程(注:这里会自动选择当前的Project的):
3.如果已有私钥文件,选择私钥文件 输入密码,如果没有私钥文件见 第6和7步创建私钥文件:
4.输入私钥别名和密码:
5.选择APK存储的位置,并完成设置 开始生成:
6.没有私钥文件的情况,创建私钥文件(注:这里私钥文件的Location位置最好自己选择一个新位置,便于牢记,而且最好把这个私钥文件备份到其他地方去以免丢失,因为应用程序的更新需要同一私钥文件):
7.输入私钥文件所需信息,并创建(注:这里的密码是用于Key的别名的,和上面的KeyStore文件的不同,这点可以看步骤3和4。另外下面的名字,开发者资料等是不需要全部填写的,dialog会有提示的):
这时候生成的apk,我发现是比debug版本的要小!如果你发现没有变小的话,请确认项目工程是重新编译的!但代码混淆的效果一般般,基本上还是可以看到原来的语句!

posted @ 2011-06-23 19:42 建华 阅读(1015) | 评论 (0)编辑 收藏

Android的Task和Activity相关

     摘要: android:allowTaskReparenting    用来标记Activity能否从启动的Task移动到有着affinity的Task(当这个Task进入到前台时)——“true”,表示能移动,“false”,表示它必须呆在启动时呆在的那个Task里。   ...  阅读全文

posted @ 2011-06-23 17:42 建华 阅读(12455) | 评论 (0)编辑 收藏

Android APK 签名

Apk签名首先要有一个keystore的签名用的文件.
keystore是由jdk自带的工具keytool生成的.具体生成方式参考一下:
开始->运行->cmd->cd 到你安装的jdk的目录这里我是 C:\Program Files\Java\jdk1.6.0_10\bin
然后输入:keytool -genkey -alias asaiAndroid.keystore -keyalg RSA -validity 20000 -keystore asaiAndroid.keystore
-alias 后跟的是别名这里是 asaiAndroid.keystore
-keyalg 是加密方式这里是 RSA
-validity 是有效期 这里是 20000
-keystore 就是要生成的keystore的名称 这里是 asaiAndroid.keystore
然后按回车
按回车后首先会提示你输入密码:这个在签名时要用的要记住了哦。
然后会再确认你的密码。
之后会依次叫你输入 姓名,组织单位,组织名称,城市区域,省份名称,国家代码等。
参考:
 
运行完可以在 C:\Program Files\Java\jdk1.6.0_10\bin 里找到刚才生产的keyStore文件

好现在开始给Apk签名了:
在 C:\Program Files\Java\jdk1.6.0_10\bin 还提供一个工具 jarsigner.exe
好现在可以在刚才的命令行后继续运行以下命令给APK签名:
jarsigner -verbose -keystore asaiAndroid.keystore -signedjar LotteryOnline_signed.apk LotteryOnline.apk asaiAndroid.keystore
-keystore:keystore 的名称
LotteryOnline_signed.apk  是签完名后的APK
LotteryOnline.apk 是签名前的apk
然后按回车:会要求输入刚才设置的密码,输入后按回车就开始签名了。
参考:
 
运行成功后在 C:\Program Files\Java\jdk1.6.0_10\bin 目录下会多出一个被签名的apk文件,
参考:
 

posted @ 2011-06-23 17:40 建华 阅读(825) | 评论 (0)编辑 收藏

仅列出标题
共4页: 上一页 1 2 3 4 下一页