星期四, 十一月 15, 2012

正则表达式发现不包含某个特定字符串的表达

^((?!ExcludeString).)*$ 这个可以处理只包含ExcludeString的行
而以下pattern则无法处理包含ExcludeString的独立行
^(.(?!stringToExclude))*$

星期四, 十一月 08, 2012

正则表达式的例子

grep -P "\d{7}(\s+|:)(\d\d[\s+-]?){7}"  可以工作,但可以修改为

更加精简的pattern.

grep -P "\d{7}.(\d\d).{7}"


用来搜索同一个文本内的如下格式的数据:

2012083:04-09-14-15-26-33-04                               
2012084:02-10-20-26-28-29-14                               
2012103 11 14 32 33 02 09 04 14 11 33 32 364812438 452814888

Re: 正则表达一点例子.

grep -P "\d{7}(\s+|:)(\d\d[\s+-]?){7}"  可以工作,但可以修改为
更加精简的pattern.
grep -P "\d{7}.(\d\d).{7}"

用来搜索同一个文本内的如下格式的数据:

2012083:04-09-14-15-26-33-04                               
2012084:02-10-20-26-28-29-14                               
2012103 11 14 32 33 02 09 04 14 11 33 32 364812438 452814888



2012/11/8 凯幄解 <javacave@gmail.com>
grep -P "\d{7}(\s+|:)(\d\d[\s+-]?){7}"

用来搜索同一个文本内的如下格式的数据:

2012083:04-09-14-15-26-33-04                               
2012084:02-10-20-26-28-29-14                               
2012103 11 14 32 33 02 09 04 14 11 33 32 364812438 452814888

正则表达一点例子.

grep -P "\d{7}(\s+|:)(\d\d[\s+-]?){7}"

用来搜索同一个文本内的如下格式的数据:

2012083:04-09-14-15-26-33-04                               
2012084:02-10-20-26-28-29-14                               
2012103 11 14 32 33 02 09 04 14 11 33 32 364812438 452814888

星期三, 十一月 07, 2012

规则表达一些概念

正则表达式中的贪婪(greedy)、勉强(reluctant)和侵占(possessive)

贪婪(greedy)

一般默认情况下,正则的量词是贪婪的,也就是“尽可能多地匹配”,符号通常是:* + ? {num,num}
举个例子说,比如"a+"这个正则,对于"aaaaaab"这个字符串,它就会匹配到6个a,这是最常见的情况

勉强(reluctant)[也叫懒惰(lazy)]

勉强与贪婪正好是相对的,它“尽可能少地匹配”,它会用最小的努力,去完成(应付)正则的匹配要求,所以很懒。符号是贪婪量词后面加上问号:*? +? ?? {num,num}?
回到前面的那个例子,如果正则换成了“勉强”的,"a+?",对于目标字符串还是"aaaaaab",那么这个正则就只会匹配一个a,因为"+"量词的意思是“一个或一个以上”,匹配一个a就能满足要求,它就不再去尝试了(不像贪婪的"a+"那样,不遗余力将所有符合要求的都匹配了)
 
“勉强”的量词在实际的使用中也是比较常见的,例如引号配对之类的问题,例如有这么一个字符串,"A says, 'bb'.",想要用正则将单引号里面的bb匹配出来,可以用正则'.*',这种情况下默认的贪婪量词也是能适用的,但如果这个字符串变成了 "A says, 'bb', and C says, 'ddddd'.",如果还是用'.*',由于贪婪,它匹配到的并不是你想要的'bb', and C says, 'ddddd',中间的.(点元字符)代表任何字符,当然也包括单引号,所以'.*'会将两个单引号中间的所有内容都匹配,不管是不是含有单引号。显然这不是我们想要的结果。如果用“勉强”的量词,'.*?',加一个问号,那么它就会尽最小的能力去完成,只要下一个字符是单引号,.*?就停止尝试,结果它就只会匹配'bb',不会将后面的, and ....那些都纳进来。
 
侵占(possessive)

这个用得很少,侵占量词在很多语言的正则中都没有被支持,它的符号是在贪婪量词后面加上一个加号:*+ ++ ?+ {num,num}+
侵占量词有个特点,它前面的子表达式作为一个整体,不记录回溯点(关于回溯方面的问题,建议你去看一看《精通正则表达式》这本书,讲得比较详细),通常是可以利用这个特点,对正则的匹配效率进行优化。其实它是和固化分组等价的,不支持侵占量词的语言中可以用固化分组的形式来代替。固化分组的写法:(?>)
有个例子可以帮助理解侵占量词的特点,但这个例子并不实用:
对于字符串"abbbbbbc",如果用普通的(贪婪)正则"a.*c"来匹配的话,它可以匹配整个字符串,因为.*可以匹配任何数量的任何字符,它是可以匹配bbbbbbc的,但它会发现正则后面还有一个c需要匹配,否则不能匹配成功,所以.*就“退回”一个字符c,使得整个正则能够成功匹配(回溯),所以贪婪即使是“贪”,它还是会顾全大局,退回一些必要的字符。
换侵占量词就不同了,"a.*+c"是一个侵占式的,它并不能成功匹配,因为.*+太霸道,占着最后的那个c不肯放回(不回溯),所以a.*+前面就已经匹配了整个字符串abbbbbbc,a.*+正则后面的c发现没有字符可以匹配了,前面的又不肯吐出一个来,所以整个正则以匹配失败结束。(这个"a.*+c"可以用固化分组改写成:"a(?>.*)c")
 

星期二, 十一月 06, 2012

Android 2.3.3 以上通用Notification 生成 代码.使用NotificationCompat.Builder

//notification unique id 
//The IDs must be unique only within the namespace of your .apk's package nam
//这个ID只需要在你自己的app 空间里唯一即可,不是整个系统唯一
public void setupNotification(Context ctx)
    {
        Intent notificationIntent = new Intent(ctx, StartGateActivity.class);
        PendingIntent contentIntent = PendingIntent.getActivity(ctx,
                0, notificationIntent,
                0);

        NotificationManager nm = (NotificationManager) ctx
                .getSystemService(Context.NOTIFICATION_SERVICE);
        nm.cancel(100);
        Resources res = ctx.getResources();
        CharSequence text = res.getString(R.string.nf_text);
        CharSequence contentTitle = res.getString(R.string.nf_title);
        CharSequence ticket = res.getString(R.string.nf_ticket);
        NotificationCompat.Builder builder= new NotificationCompat.Builder(ctx);

        builder.setContentTitle(contentTitle)
        .setContentText(text)
        .setSmallIcon(R.drawable.ic_launcher)
        .setOngoing(true) //this flag notification record  can't be clear
        .setAutoCancel(true)
        .setWhen(System.currentTimeMillis())
        .setTicker(ticket)
        .setContentIntent(contentIntent);
        Notification nf = builder.build();       
        nm.notify(100, nf);
    }

星期一, 十一月 05, 2012

如何在app中3.0 API LEVEL 11后加入notification.

public void setupViews(Context ctx)
{
    Intent notificationIntent = new Intent(ctx, LifeDemo.class);
    PendingIntent contentIntent = PendingIntent.getActivity(ctx,
            0, notificationIntent,
            PendingIntent.FLAG_CANCEL_CURRENT);

    NotificationManager nm = (NotificationManager) ctx
            .getSystemService(Context.NOTIFICATION_SERVICE);

    Resources res = ctx.getResources();
    Notification.Builder builder = new Notification.Builder(ctx);

    builder.setContentIntent(contentIntent)
                .setSmallIcon(R.drawable.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
                .setTicker("Demo Show")
                .setWhen(System.currentTimeMillis())
                .setAutoCancel(true)
                .setContentTitle("Demo Show 1")
                .setContentText("Demo Show2");
    Notification n = builder.build();

    nm.notify(1, n);
}

星期四, 十一月 01, 2012

如何给手机刷CMW Mod

adb reboot bootloader
fastboot boot recovery-clockwork-touch-6.0.1.4-maguro.img
#永久刷新
fastboot flash recovery recovery-clockwork-touch-6.0.1.4-maguro.img
adb reboot

发布一个apk的准备工作.

准备发布一个Android app
1.keytool -genkey -v -keystore debug.keystore -alias wxkdebugkey -keyalg RSA-validity 14000
  跟随提示回答问题.
2.Jarsigner -verbose -keystore debug.keystore yourapk.apk wxkdebugkey
3.jarsigner -verify yourapk.apk
4.zipalign -v 4 yourapk.apk lastname.apk
5.start a avd
   tools\android.bat list avd
                Available Android Virtual Devices:
                    Name: AVD233
                    Path: d:\temp\.android\avd\AVD233.avd
                  Target: Android 2.3.3 (API level 10)
                     ABI: armeabi
                    Skin: WVGA800
                ---------
                    Name: avd411
                    Path: d:\temp\.android\avd\avd411.avd
                  Target: Android 4.1 (API level 16)
                     ABI: armeabi-v7a
                    Skin: WVGA800
                  Sdcard: 512M
                Snapshot: true   
   emulator -avd AVD233 启动
5.adb devices
adb -e install lastname.apk

Android 产生key

keytool -genkey -v -keystore debug.keystore -alias wxkdebugkey -keyalg RSA-validity 14000

JDK 7.0 Display MD5 key

JDK 1.7 默认现在显示 RSA 的签名字符串了,用选项-v可以显示出MD5的签名。

keytool -v -list -alias wxkdebugkey -keystore my-release-key.keystore

星期二, 十月 23, 2012

比如屏幕旋转90度,Configuration Changes

Configuration Changes

If the configuration of the device (as defined by the Resources.Configuration class) changes, then anything displaying a user interface will need to update to match that configuration. Because Activity is the primary mechanism for interacting with the user, it includes special support for handling configuration changes.

Unless you specify otherwise, a configuration change (such as a change in screen orientation, language, input devices, etc) will cause your current activity to be destroyed, going through the normal activity lifecycle process of onPause(), onStop(), and onDestroy() as appropriate. If the activity had been in the foreground or visible to the user, once onDestroy() is called in that instance then a new instance of the activity will be created, with whatever savedInstanceState the previous instance had generated from onSaveInstanceState(Bundle).

This is done because any application resource, including layout files, can change based on any configuration value. Thus the only safe way to handle a configuration change is to re-retrieve all resources, including layouts, drawables, and strings. Because activities must already know how to save their state and re-create themselves from that state, this is a convenient way to have an activity restart itself with a new configuration.

In some special cases, you may want to bypass restarting of your activity based on one or more types of configuration changes. This is done with the android:configChanges attribute in its manifest. For any types of configuration changes you say that you handle there, you will receive a call to your current activity's onConfigurationChanged(Configuration) method instead of being restarted. If a configuration change involves any that you do not handle, however, the activity will still be restarted and onConfigurationChanged(Configuration) will not be called.




Because of this, some developers decide to handle the configuration changes (like screen orientation changes) themselves.  This is done by adding the "configChanges" attribute to the Activity declaration in AndroidManifest.xml
?
1
2
3
4
5
6
7
<activity android:name=".SomeActivity" android:label="@string/app_name"
  android:configChanges="orientation">
 <intent-filter>
  <action android:name="android.intent.action.MAIN"/>
  <category android:name="android.intent.category.LAUNCHER"/>
 </intent-filter>
</activity>

The "configChanges" attribute tells Android Platform that, some of the config changes will be handled by the activity by themselves. Platform does not need to do any special handling for these.

Android Configuration change.

http://developer.android.com/guide/topics/resources/runtime-changes.html

In Android, a configuration change causes the current activity to go away and be recreated.
The application itself keeps on running, but it has the opportunity to change
how the activity is displayed in response to the configuration change.

use onSaveInstanceState(Bundle) to keep state or other runtime data.


root Jelly Bean 4.1.2

root JB 4.1.2

首先必须安装了Android sdk和对应手机的USB驱动。
 android sdk: http://developer.android.com/sdk/index.html
  需要一些工具
 
1.download cmw(ClockworkMod) recover 工具.

 http://www.clockworkmod.com/rommanager
查找对应的设备后面的文件。
Galaxy Nexus 就要下载:
http://download2.clockworkmod.com/recoveries/recovery-clockwork-touch-6.0.1.0-maguro.img

2. download superuser packagae
 http://androidsu.com/superuser/
 下载 Superuser-3.1.3-arm-signed.zip
 
3.连接手机USB,设置为debug模式
   用adb push  Superuser-3.1.3-arm-signed.zip /sdcard/Superuser-3.1.3-arm-
signed.zip
    传送到手机上

4.临时进入cmw recover 并安装superuser 包
 进入window 命令行状态 cmd,进入android sdk安装目录下的android-sdk-windows\
platform-tools目录.
 
  adb reboot bootloader
  fastboot boot recovery-clockwork-touch-6.0.
1.0-maguro.img
 等待3秒出现,安装CMW 安装界面,如果是touch版本,则用手势滚动屏幕,选择安装
  select install zip from sdcard.
  否则用音量上下键移动,电源键确认来选择。
 
 安装完成后,用adb reboot 启动手机即可。

星期四, 九月 20, 2012

Fwd: OSWORKFLOW on JBOSS 4.22 Config.

1.download osworkflow 2.8,2006年以后已不再维护。
   http://java.net/downloads/osworkflow/

2.将osworkflow-2.8.0-example.war展开到jboss 422/server/default/deploy/osworkflow-2.8.0-example.war 目录下。

3.在MYSQL 上建立一个osworkflow的database,并运行osworkflow-2.8.0\src\etc\deployment\jdbc
 \mysql.sql,建立其需要使用的表格.
4.配置JBOSS 数据源
   在
jboss 422/server/default/deploy/mysql-ds.xml里加入数据源:
   <!-- add for osworkflow datasorce -->
  <local-tx-datasource>
    <jndi-name>osworkflow</jndi-name>
   <connection-url>jdbc:mysql://192.1.1.100:3306/osworkflow?autoReconnect=true&amp;useUnicode=TRUE&amp;characterEncoding=utf-8</connection-url>
    <driver-class>com.mysql.jdbc.Driver</driver-class>
    <user-name>root</user-name>
    <password></password>
    <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
        <min-pool-size>5</min-pool-size>
        <max-pool-size>10</max-pool-size>
        <idle-timeout-minutes>1</idle-timeout-minutes>
    <metadata>
       <type-mapping>mySQL</type-mapping>
    </metadata>
  </local-tx-datasource>


5.进入
jboss 422/server/default/deploy/osworkflow-2.8.0-example.war/WEB-INF/classes下修改配置,加入数据源说明.
  注意Linux table name 有大小写的问题。

  osuser.xml:
<opensymphony-user>
   <provider class="com.opensymphony.user.provider.jdbc.JDBCAccessProvider">
  <property name="user.table">OS_USER</property>
  <property name="group.table">OS_GROUP</property>
  <property name="membership.table">OS_MEMBERSHIP</property>
  <property name="user.name" >username</property>
  <property name="user.password">passwordhash</property>
  <property name="group.name">groupname</property>
  <property name="membership.userName" >username</property>
  <property name="membership.groupName">groupname</property>
  <property name="datasource">java:/osworkflow</property>
</provider>

<provider class="com.opensymphony.user.provider.jdbc.JDBCCredentialsProvider">
 <property name="user.table">OS_USER</property>
  <property name="group.table">OS_GROUP</property>
  <property name="membership.table">OS_MEMBERSHIP</property>
<property name="user.name" >username</property>
  <property name="user.password">passwordhash</property>
  <property name="group.name">groupname</property>
  <property name="membership.userName" >username</property>
  <property name="membership.groupName">groupname</property>
  <property name="datasource">java:/osworkflow</property>
 </provider>

    <provider class="com.opensymphony.user.provider.jdbc.JDBCProfileProvider">
 <property name="user.table">OS_USER</property>
  <property name="group.table">OS_GROUP</property>
  <property name="membership.table">OS_MEMBERSHIP</property>
<property name="user.name" >username</property>
  <property name="user.password">passwordhash</property>
  <property name="group.name">groupname</property>
  <property name="membership.userName" >username</property>
  <property name="membership.groupName">groupname</property>
  <property name="datasource">java:/osworkflow</property>
 </provider>

 <authenticator class="com.opensymphony.user.authenticator.SmartAuthenticator" />

</opensymphony-user>

osworkflow.xml:
<osworkflow>
    <!--persistence class="com.opensymphony.workflow.spi.memory.MemoryWorkflowStore"/-->
    <persistence class="com.opensymphony.workflow.spi.jdbc.MySQLWorkflowStore">
 <property key="datasource" value="java:/osworkflow"/>
<property key="entry.sequence"
                      value="SELECT max(id)+1 FROM OS_WFENTRY"/>
 <property key="entry.table" value="OS_WFENTRY"/>
 <property key="entry.id" value="ID"/>
 <property key="entry.name" value="NAME"/>
 <property key="entry.state" value="STATE"/>
 <property key="step.sequence"  value="SELECT max(ID)+1 FROM OS_STEPIDS"/>

 <property key="step.sequence.increment"    value="INSERT INTO OS_STEPIDS (ID) values (null)"/>
 <property key="step.sequence.retrieve"   value="SELECT max(ID) FROM OS_STEPIDS"/>
 <property key="entry.sequence.increment" value="INSERT INTO OS_ENTRYIDS (ID) values (null)"/>
 <property key="entry.sequence.retrieve" value="SELECT max(ID) FROM OS_ENTRYIDS"/>

 <property key="history.table" value="OS_HISTORYSTEP"/>
 <property key="current.table" value="OS_CURRENTSTEP"/>
 <property key="historyPrev.table" value="OS_HISTORYSTEP_PREV"/>
 <property key="currentPrev.table" value="OS_CURRENTSTEP_PREV"/>
 <property key="step.id" value="ID"/>
 <property key="step.entryId" value="ENTRY_ID"/>
 <property key="step.stepId" value="STEP_ID"/>
 <property key="step.actionId" value="ACTION_ID"/>
 <property key="step.owner" value="OWNER"/>
 <property key="step.caller" value="CALLER"/>
 <property key="step.startDate" value="START_DATE"/>
 <property key="step.finishDate" value="FINISH_DATE"/>
 <property key="step.dueDate" value="DUE_DATE"/>
 <property key="step.status" value="STATUS"/>
 <property key="step.previousId" value="PREVIOUS_ID"/>
</persistence>
    <factory class="com.opensymphony.workflow.loader.XMLWorkflowFactory">
        <property key="resource" value="workflows.xml" />
    </factory>
</osworkflow>

 propertyset.xml:
<propertysets>
 <propertyset name="jdbc" class="com.opensymphony.module.propertyset.database.JDBCPropertySet">
  <arg name="table.name" value="OS_PROPERTYENTRY"/>
  <arg name="col.globalKey" value="GLOBAL_KEY"/>
  <arg name="col.itemKey" value="ITEM_KEY"/>
  <arg name="col.itemType" value="ITEM_TYPE"/>
  <arg name="col.string" value="STRING_VALUE"/>
  <arg name="col.date" value="DATE_VALUE"/>
  <arg name="col.data" value="DATA_VALUE"/>
  <arg name="col.float" value="FLOAT_VALUE"/>
  <arg name="col.number" value="NUMBER_VALUE"/>
  <arg name="datasource" value="java:/osworkflow"/>
  <arg name="" value=""/>
 </propertyset>
</propertysets>


至此配置完成,启动JBOSS,从浏览器输入:
http://192.168.1.1:8080/osworkflow-2.8.0-example/

即可查看.



星期二, 九月 18, 2012

Android如何确认一个Intent是否存在呢?


 /**
     * Indicates whether the specified action can be used as an intent. This
     * method queries the package manager for installed packages that can
     * respond to an intent with the specified action. If no suitable package is
     * found, this method returns false.
     *
     * @param context The application's environment.
     * @param action The Intent action to check for availability.
     *
     * @return True if an Intent with the specified action can be sent and
     * responded to, false otherwise.
     *  Example:isIntentAvailable(getApplicationContext(),Intent.ACTION_WEB_SEARCH)
     */
    public static boolean isIntentAvailable(Context context, String action) {
    final PackageManager packageManager = context.getPackageManager();
    final Intent intent = new Intent(action);
    List<ResolveInfo> list =
    packageManager.queryIntentActivities(intent,
    PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() > 0;
    }

星期四, 九月 13, 2012

Android动态改变语言并自动刷新菜单.

Locale locale=null;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String languageToLoad  = "zh";
         locale = new Locale(languageToLoad);
        Locale.setDefault(locale);
        Configuration config = new Configuration();
        config.locale = locale;
        getBaseContext().getResources().updateConfiguration(config, null);
        //getBaseContext().getResources().getDisplayMetrics()
        Log.v("log:","local is changed!");
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        setContentView(R.layout.activity_main);
         }

星期二, 九月 11, 2012

Andorid xml is binary format in .apk package

All of the resource XML files are compiled to a binary format by aapt at build time.
只有一个例外就是 res/raw下的文件是原始文件,没有做任何处理。

Activity的getString和Activity.getResource().getString的区别是什么呢?

activity的getString下的说明如此:
 localized string from the application's package's default string table

Resource的getString说明如下:
Returns the string value associated with a particular resource ID. It will be stripped of any styled text information

但是查看源代码,发现activity的getString如下:
    public final String getString(int resId) {
        return getResources().getString(resId);
    }

其实是一回事。真不明白为什么说明差异如此之大。

Android classpath access external resource.

Resources.getSystem().getString(android.R.string.somecommonstuff)