星期日, 八月 31, 2014

GIMP 2.8不能编辑GIF和png图片问题

GIF和png颜色空间都是indexed,所以无法编辑。

如果想编辑必须首先转换颜色空间,这个非常容易,只要在image/颜色菜单里
选择mode(模式)即可转换




星期三, 八月 27, 2014

如何在Android里使用最新的Apache Httpclient

注意:Android最早使用的Apache HttpClient 4.0-beta的一个包,后来基本
不再维护,所以如果有更多的新的HTTP 特性,基本不再支持,
而且,Android推荐大家使用系统标准的java标准包:HttpURLConnection 
但是HttpURLConnection比较底层,使用起来非常的不便,尤其是在
    类似提交Form和服务器传送数据的时候;所以最近有okHttp就封装了HttpURLConnction
给开发人员提供了较好的API.但是使用起来依然不如HttpRequest爽快.
尤其是在目前稍微严肃的应用都会基于HTTPS/SSL的基础之上,大量的验证
模式支持就是以前的4.0版本不支持的。没有现成的方案。所以使用
  最新的httpclient包是必须的了。
但是由于httpclient是基于标准JDK的,有许多牵涉到版权的API比如
misc.sun之类的包不能在Android上使用,所以这个处理工作还是比较繁琐的。
幸运的是apache提供了Android移植包:
参考,写本文时的最新版本4.3.5:
http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html
  
可以在www.mvnrepository.com上 输入httpclient-android来寻找最新的
jar包Android移植版本并下载即可。
当然有些类不可避免的原始的类的功能不同并有扩展,这个时候,就要使用
类名带HC4结尾的类来使用最新的功能特性了
 
但是如果我们在Android Activity调用Async或者Thread调用最基本的:
CloseableHttpClient httpclient = HttpClients.createDefault();
立即出现异常:
 java.lang.IllegalArgumentException: Item may not be null
  
查看代码则是:
  org.apache.http.config.RegistryBuilder.java
的  Args.notNull(item, "Item");造成了错误。
阅读代码发现,这是因为SocketFactory为空造成的,所以
必须首先初始化,SocketFactory

 SSLContext sslContext = SSLContexts.createSystemDefault();
   SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
         sslContext,
         SSLConnectionSocketFactory.STRICT_HOSTNAME_VERIFIER);
 CloseableHttpClient  httpclient= HttpClientBuilder.create()
      .setSSLSocketFactory(sslsf)
      .build();

或者使用定制的方法:

 ConnectionSocketFactory plainsf = <...>  LayeredConnectionSocketFactory sslsf = <...>  Registry<ConnectionSocketFactory> r = RegistryBuilder.<ConnectionSocketFactory>create()          .register("http", plainsf)          .register("https", sslsf)          .build();    HttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(r);  HttpClients.custom()          .setConnectionManager(cm)          .build();

这个都可以从hc.apache.org对应版本的tutorial章节,看到详细的代码

注意在android使用需要在AndroidManifest.xml里加入权限:
<uses-permission android:name="android.permission.INTERNET"/>
  这个httpclient-android-4.3.5.jar在Android Studio和Eclipse ADT
里如何打包到最后的apk里步骤不同,使用的时候注意即可。

星期四, 八月 21, 2014

Button 实现淡入淡出动画

布局文件:
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.buttonana.MainActivity" >
  <Button
      android:layout_marginTop="50dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"     
      android:id="@+id/animationid"
      android:text="fade out"/>

  <Button
      android:id="@+id/mainbtn"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_alignLeft="@+id/animationid"
      android:layout_alignParentTop="true"
      android:layout_marginTop="170dp"
      android:text="Click Me" />

</RelativeLayout>

关键语句:
      amt.setFillAfter(true);//important.

package com.example.buttonana;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;

public class MainActivity extends Activity {

    Button mainbtn;
    Button animationbtn;
   
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mainbtn=(Button)this.findViewById(R.id.mainbtn);
        animationbtn=(Button)this.findViewById(R.id.animationid);
        mainbtn.setOnClickListener(new View.OnClickListener() {
           
            @Override
            public void onClick(View v) {
                Log.d("BUTTON","enter.........................................................");
                Animation t =getAnimation();
                animationbtn.clearAnimation();
                animationbtn.setAnimation(t);
                t.startNow();
            }
        });
       
    }
  public Animation getAnimation()
  {
      Animation amt=new AlphaAnimation(1.0f,0.01f);
      amt.setDuration(4*1000);
      amt.setFillAfter(true);//important.
      return amt;
     
  }

}

星期二, 八月 05, 2014

gradle 调用另外一个gradle 脚本文件

gradle 0.9 之后,支持apply from: "addiontal.gradle"语法。

星期日, 八月 03, 2014

Android Studio Beta 打包源代码和build.gradle 脚本到一个zip文件

在build.gradle脚本里加入脚本:

task srcZip2(type: Zip) {
    classifier = 'src'
    from projectDir
    include 'src/**/*'
    include 'build.gradle'
    destinationDir file('.')
    archiveName "src.zip"
}


tasks.whenTaskAdded { task ->
    if (task.name == 'generateReleaseBuildConfig' || task.name == 'generateDebugBuildConfig') {
        task.dependsOn 'srcZip2'
    }
}


最后就在当前 app目录下建立了src.zip文件。

如何在Android Studio beta 版本里加入Build versionNumber的脚本。

利用AndroidManifest.xml里的android:versionCode"整数",
android:versionName为字符串,格式为"0.0.1"的格式。

将一下代码复制到build.gradle里,最后空白的地方,sync之后即可:
这是在build project的时候,即更新AndroidManifest.xml里的
这两个字段

task('increaseVersionCode') << {
    def manifestFile = file(android.sourceSets.main.manifest.srcFile)
    def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcher = pattern.matcher(manifestText)
    matcher.find()
    def versionCode = Integer.parseInt(matcher.group(1))
    versionCode= versionCode+1
    def manifestContent = matcher.replaceAll("versionCode=\"" + versionCode + "\"")
    manifestFile.write(manifestContent)
    println  "versionCode is:"+versionCode

}

task('incrementVersionName') << {
    def manifestFile = file(android.sourceSets.main.manifest.srcFile)
    def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
    matcherVersionNumber.find()
    def majorVersion = Integer.parseInt(matcherVersionNumber.group(1))
    def minorVersion = Integer.parseInt(matcherVersionNumber.group(2))
    def buildVersion = Integer.parseInt(matcherVersionNumber.group(3))
    def mNextVersionName = majorVersion + "." + minorVersion + "." +  + (buildVersion + 1)
    def manifestContent = matcherVersionNumber.replaceAll("versionName=\"" + mNextVersionName + "\"")
    println  "build number is:"+mNextVersionName
    manifestFile.write(manifestContent)
}

tasks.whenTaskAdded { task ->
    if (task.name == 'generateReleaseBuildConfig' || task.name == 'generateDebugBuildConfig') {
        task.dependsOn 'increaseVersionCode'
        task.dependsOn 'incrementVersionName'
    }
}