android连接https web service忽略证书的方法

如果直接连接https,都会出现报证书的错误,如果是正式用的话一定要添加证书,但是测试用的话,直接忽略掉证书,然后就可以继续连接上去。

解决方法如下:

在使用web service之前调用allowAllSSL()就行了。

public static void allowAllSSL() {  
javax.net.ssl.HttpsURLConnection  
        .setDefaultHostnameVerifier(new HostnameVerifier() {  
            public boolean verify(String hostname, SSLSession session) {  
                return true;  
            }  
        });  

javax.net.ssl.SSLContext context = null;  

if (trustManagers == null) {  
    trustManagers = new javax.net.ssl.TrustManager[] { new _FakeX509TrustManager() };  
}  

try {  
    context = javax.net.ssl.SSLContext.getInstance("TLS");  
    context.init(null, trustManagers, new SecureRandom());  
} catch (NoSuchAlgorithmException e) {  
    Log.e("allowAllSSL", e.toString());  
} catch (KeyManagementException e) {  
    Log.e("allowAllSSL", e.toString());  
}  
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(context  
        .getSocketFactory());  

}`

android里面使用linux命令的时候报permission.INTERACT_ACROSS_USERS_FULL

在adb 打命令 am broadcast 发广播的时候,正常返回数据。
但是android里面使用Runtime.getRuntime().exec()运行命令的时候,发现报错了,如下

Permission Denial: broadcast asks to run as user -1 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL or android.permission.INTERACT_ACROSS_USERS_

解决方案:
在命令里面加个参数 - - user 0,即 am broadcast - - user 0,此时在android里面就可以正常返回了。

mac下如何通过vpn连接公司的svn

window下通过vpn连接到公司的svn很轻松,但是mac怎么搞都不行。最后终于找到了解决方法。

1、了解公司内网的svn部署的内网ip地址,然后记下来,例如是10.11.12.2。

2、先sudo -i(如果mac没有root,建议先开启root,具体教程自行百度),然后转到/etc/ppp这个目录下。用vi编辑(创建)一个叫ip-up的文件。在里面加入下面的命令。

3、

#!/bin/sh
/sbin/route add -net x.x.x -interface ppp0

注:ppp0不要修改它,上述例子中需要将x.x.x替换成10.11.12

4、试试打开公司svn的外网地址,是不是可以访问了。

编译android4.3

环境 :
ubuntu16.04
oracle jdk1.6
make3.82
百度云下载android的7z源码,从window复制到linux,再解压缩。
7z x file.7z 解压缩7z

android5.1.1
. build/envsetup.sh
lunch / lunch full-eng
openjdk1.7

make clean
make update-api
make
cp /usr/bin/ld.gold prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6/x86_64-linux/bin/ld

 【开发笔记】 如何将svn 回滚old revision到head revision

背景需求: 有些时候错误地提交了代码到trunk head revision上,后面需要将这个错误的revision回滚掉,把正确的代码重新放到head revision上。

解决方案:

1.checkout ,project update
2.找到head revision版本号
3.找到目标revision 版本号
4.在当前project里执行 “ svn merge -r 10551:10197 ./ “
注:(10551是head revision,10197是需要回滚的目标revision ./是当前workplace copy)(这步做完多了diff)
5.commit

参考链接

http://blog.sina.com.cn/s/blog_5432f2730100vmz4.h

【开发笔记】使用gson对一个json实体会出现object或者array不规则返回的处理

背景:聚合网址的免费天气,当有数据的时候是object,没数据的时候是array,对于这种情况,习惯于使用retrofit来说都是很痛苦的。通常我们习惯于接口数据必须是规则的,要么只是object,要么只是array。对于这种不规则的返回,还是有办法去解决的,在使用gson的条件下。解决的核心代码在最后面。

调用

主要看 testApple这个类,会有几种不同的值。

  1. { } object型

  2. [] array型

    Gson gson = new GsonBuilder().registerTypeAdapter(TestPeople.class, new MyDeserializer()).create();
    String ssArray = “{"name":"333","id":"18","testPeople":{"name":"222","testApple":[]}}”;
    System.out.println(ssArray);
    String ssArray2 = “{"name":"333","id":"18","testPeople":{"name":"222","testApple":[{"name":"111","id":"9"}]}}”;
    System.out.println(ssArray2);
    String ssObject = “{"name":"333","id":"18","testPeople":{"name":"222","testApple":{"name":"111","id":"9"}}}”;
    System.out.println(ssObject);
    TestHouse testHouseArray = gson.fromJson(ssArray, TestHouse.class);
    TestHouse testHouseArray2 = gson.fromJson(ssArray2, TestHouse.class);
    TestHouse testHouseObject = gson.fromJson(ssObject, TestHouse.class);
    System.out.println(“result=” + testHouseArray.toString());
    System.out.println(“result=” + testHouseArray2.toString());
    System.out.println(“result=” + testHouseObject.toString());

输出内容

根据testApple可以看到,确实可以根据不同的输入正确解析出来。

{"name":"333","id":"18","testPeople":{"name":"222","testApple":[]}}
{"name":"333","id":"18","testPeople":{"name":"222","testApple":[{"name":"111","id":"9"}]}}
{"name":"333","id":"18","testPeople":{"name":"222","testApple":{"name":"111","id":"9"}}}
result=TestHouse{name='333', id='18', testPeople=TestPeople{name='222', testApple=null}}
result=TestHouse{name='333', id='18', testPeople=TestPeople{name='222', testApple=TestApple{name='111', id='9'}}}
result=TestHouse{name='333', id='18', testPeople=TestPeople{name='222', testApple=TestApple{name='111', id='9'}}}

最外层实体

为了演示用,构造了一个最外层的实体。

public class TestHouse {
    private String name;
    private String id;
    private TestPeople testPeople;

    public TestHouse(String name, String id, TestPeople testPeople) {
        this.name = name;
        this.id = id;
        this.testPeople = testPeople;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public TestPeople getTestPeople() {
        return testPeople;
    }

    public void setTestPeople(TestPeople testPeople) {
        this.testPeople = testPeople;
    }

    @Override
    public String toString() {
        return "TestHouse{" +
                "name='" + name + '\'' +
                ", id='" + id + '\'' +
                ", testPeople=" + testPeople +
                '}';
    }
}

第二层实体

为了演示用,构造了一个第二层的实体。这里就直接涉及到不规则实体的容器了。

public class TestPeople {
    private String name;
    private TestApple testApple;

    public TestPeople() {
    }

    public TestPeople(String name, TestApple testApple) {
        this.name = name;
        this.testApple = testApple;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public TestApple getTestApple() {
        return testApple;
    }

    public void setTestApple(TestApple testApple) {
        this.testApple = testApple;
    }

    @Override
    public String toString() {
        return "TestPeople{" +
                "name='" + name + '\'' +
                ", testApple=" + testApple +
                '}';
    }
}

最内层实体

不规则值的实体,有可能是object,也有可能是array。

public class TestApple {
    private String name;
    private String id;


    public TestApple(String name, String id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "TestApple{" +
                "name='" + name + '\'' +
                ", id='" + id + '\'' +
                '}';
    }
}

自定义的JsonDeserializer

主要是为了解析有争议的实体,针对不同的情况去做相关的处理,最后输出同一个最外层实体。

public class MyDeserializer implements JsonDeserializer<TestPeople> {
    @Override
    public TestPeople deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
        JsonElement jsonElementApple = jsonElement.getAsJsonObject().get("testApple");
        if (jsonElementApple == null) {
            return null;
        }
        if (jsonElementApple.isJsonObject()) {
            return new Gson().fromJson(jsonElement, TestPeople.class);
        } else {
            List<TestApple> testApple = jsonDeserializationContext.deserialize(jsonElementApple, new TypeToken<List<TestApple>>() {}.getType());
            Gson gson = new Gson();
            Map map = jsonDeserializationContext.deserialize(jsonElement, Map.class);
            if (map.containsKey("testApple")) {
                map.remove("testApple");
            }
            JsonElement jsonElementMixed = gson.toJsonTree(map);
            TestPeople testPeople = gson.fromJson(jsonElementMixed, TestPeople.class);
            if (testApple.size() > 0) {
                testPeople.setTestApple(testApple.get(0));
            }
            return testPeople;
        }
    }
}

【开发笔记】高德地图在fragment使用时切换时会黑屏

背景:fragment,使用FrameLayout作为容器,切换fragment的时候使用fragmentTransaction.replace(int, fragment); 切换的时候黑屏,看样子是高德的bug,mapView在fragment的摧毁的时候释放时间太久,导致ui部分黑屏了。

解决方案:

1.使用两个FrameLayout

在activity里使用两个FrameLayout容器,一个叫地图FrameLayout,一个叫普通FrameLayout,有map view的放到地图FrameLayout里面去,统一管理。
每次切换的时候先fragment所在的FrameLayout容器先gone掉,再去remove 掉具体的fragment。这时,耗时的ui操作在后台进行,所以就不会看到黑屏的存在,但是,还是有点耗时的时间存在,导致屏幕会有点卡顿。
结果是良好的,fragment的生命周期不变。

BaseFragment mLastBaseFragment;
// 根据fragment实例去切换activity里的fragment
public void changeFragment(BaseFragment fragment) {
    FragmentTransaction fragmentTransaction = fm.beginTransaction();
    if (mLastBaseFragment != fragment) {
        if (fragment instanceof MapFragment) { // 区别是不是地图fragment单独处理
            frameLayout.setVisibility(View.GONE);
            mapFrameLayout.setVisibility(View.VISIBLE);
            fragmentTransaction.replace(R.id.mapFrameLayout, fragment);
        } else {
            frameLayout.setVisibility(View.VISIBLE);
            mapFrameLayout.setVisibility(View.GONE);
            fragmentTransaction.replace(R.id.frameLayout, fragment);
        }
        if (mLastBaseFragment != null) {
            fragmentTransaction.remove(mLastBaseFragment);
        }
        fragmentTransaction.commit();
        mLastBaseFragment = fragment;
    }
}

2.将fragment的切换从replace环城show和hide

使用show和hide,黑屏不见了,原理就是这时fragment不会每次都被重新创建了。但是fragment的生命周期就乱了,具体表现为没有onResume和onPause,这时使用手动的方式模拟这两个fragment.setUserVisibleHint(true), 实际上setUserVisibleHint在fragment与view pager共用的时候才会被调用。

FragmentTransaction fragmentTransaction = fm.beginTransaction();
Fragment fragment = fm.findFragmentByTag(type + "");
if (mCurFragment != null) {
    fragmentTransaction.hide(mCurFragment);
    mCurFragment.setUserVisibleHint(false);
}
if (fragment == null) {
    fragmentTransaction.add(R.id.frameLayout, list.get(type), type + "");
} else {
    fragmentTransaction.show(fragment);
}
fragment.setUserVisibleHint(true);
mCurFragment = list.get(type);
fragmentTransaction.commit();