Android APP&NDK总结

NDK

CMake NDK 编译

#!/bin/bash

export NDK=$HOME/utilsset/env/bin/android-ndk-r21d
export API_LEVEL="29"
export ANDROID_STL="c++_static"
#export ANDROID_ABI="arm64-v8a"
export ANDROID_ABI=armeabi-v7a
export CFLAGS="-D__ANDROID_API__=$API_LEVEL"

mkdir build
cd build

  cmake -DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
    -DCMAKE_ANDROID_NDK=$NDK \
    -DANDROID_NATIVE_API_LEVEL=$API_LEVEL \
    -DANDROID_ABI=$ABI \
    -DANDROID_STL=$ANDROID_STL \
    -DCMAKE_INSTALL_PREFIX=$(/bin/pwd)/build \
    ..
examples

make

issues

native 库编译以后运行正常,但函数执行结果异常,不报错

  1. 确认提交代码时的编译指定的NDK和当前编译使用的NDK版本是否一致,确保一致后再次编译运行看结果,很可能问题消失。

OkHttp

WebSocket

text/plain

String query = "{\"country_code\":\"US\",\"time_zone\":\"Etc/GMT-1\"}";
Response response = null;
try {
    OkHttpClient client = new OkHttpClient()
            .newBuilder()
            .callTimeout(20, TimeUnit.SECONDS).build();

    MediaType JSON = MediaType.parse("text/plain; charset=utf-8");
    RequestBody body = RequestBody.create(query, JSON);

    Request request = new Request.Builder().url(mServerUrl).post(body).build();
    response = client.newCall(request).execute();
} catch (Exception e) {
    e.printStackTrace();
}

application/json

String query = "{\"country_code\":\"US\",\"time_zone\":\"Etc/GMT-1\"}";
Response response = null;
try {
    OkHttpClient client = new OkHttpClient()
            .newBuilder()
            .callTimeout(20, TimeUnit.SECONDS).build();

    MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    RequestBody body = RequestBody.create(query, JSON);

    Request request = new Request.Builder().url(mServerUrl).post(body).build();
    response = client.newCall(request).execute();
} catch (Exception e) {
    e.printStackTrace();
}

example

OkHttpClient httpClient = new OkHttpClient.Builder()
        .pingInterval(PING_INTERVAL, TimeUnit.SECONDS)
        .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
        .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
        .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
        .build();

Request request = new Request.Builder().url("ws://echo.websocket.org").build();

WebSocket webSocket = httpClient.newWebSocket(request, new WebSocketListener() {
    @Override
    public void onClosed(@NotNull WebSocket webSocket, int code, @NotNull String reason) {
        super.onClosed(webSocket, code, reason);
    }

    @Override
    public void onClosing(@NotNull WebSocket webSocket, int code, @NotNull String reason) {
        super.onClosing(webSocket, code, reason);
    }

    @Override
    public void onFailure(@NotNull WebSocket webSocket, @NotNull Throwable t, @Nullable Response response) {
        super.onFailure(webSocket, t, response);
    }

    @Override
    public void onMessage(@NotNull WebSocket webSocket, @NotNull String text) {
        super.onMessage(webSocket, text);
    }

    @Override
    public void onMessage(@NotNull WebSocket webSocket, @NotNull ByteString bytes) {
        super.onMessage(webSocket, bytes);
    }

    @Override
    public void onOpen(@NotNull WebSocket webSocket, @NotNull Response response) {
        super.onOpen(webSocket, response);
    }
});

issues

onFailure callback
public void onMessage(@NotNull WebSocket webSocket, @NotNull String text);

onMessage 回调接口内处理回调内容,如果出现未被捕获的 Exception,将导致 onFailure 接口被回调,导致 websocket 连接失败。

Misc

Android获取设备唯一标识

Serial Number

public String getSerialNumber() {
    String serial = "unknown";
    try {
    	if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P) {
    	    // Starting in Android 10, apps must have the READ_PRIVILEGED_PHONE_STATE privileged permission in
    	    // order to access the device's non-resettable identifiers, which include both IMEI and serial number.
    		// Third-party apps installed from the Google Play Store cannot declare privileged permissions.
        } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P) { // 9.0 +
            serial = Build.getSerial();
        } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) { // 8.0 - 9.0
            serial = Build.SERIAL;
        } else { // < 8.0
            Class<?> c = Class.forName("android.os.SystemProperties");
            Method get = c.getMethod("get", String.class);
            serial = (String) get.invoke(c, "ro.serialno");
        }
    } catch (Exception e) {
        e.printStackTrace();
        Log.e(TAG, "failed to get serial no.");
    }

    return serial;
}

IMEI

public String getIMEICode(Context context) {
	String imei = "unknown"if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
	    // Starting in Android 10, apps must have the READ_PRIVILEGED_PHONE_STATE privileged permission in
    	// order to access the device's non-resettable identifiers, which include both IMEI and serial number.
    	// Third-party apps installed from the Google Play Store cannot declare privileged permissions.
		return imei;
	}

    int permission = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE);
    if (permission != PackageManager.PERMISSION_GRANTED) {
        Log.e(TAG, "has no permission to read IMEI");
        return imei;
    }

    TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(context.TELEPHONY_SERVICE);
    imei = telephonyManager.getDeviceId();
    
    return imei;
}

ANDROID_ID

String androidID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);

locale相关

时区

GMT & UTC

首先來說 GMT 和 UTC 是什麼,有什麼差別

  • GMT:格林威治標準時間
  • UTC:世界協調時間

它们都是世界標準時間,而 UTC 的算法更為嚴謹,所以比 GMT 更為精準,不過兩者的差異是極小的,所以基本上時間是可以看作相同的

Linux Etc/GMT 时区为何正负颠倒

當你使用 Linux 設定時區時 ,若是選用 Etc 底下的 GMT 時區,可能會發現設定的結果與你預想的不同,當你想設定台北的時區 (GMT+8) ,但設定完後,系統時間卻是 -8 的時區,和台北時間相差 16 小時,原因是因為 Etc 底下的 GMT 時區是以 格林威治 以西為正,以東為負,剛好與我們現實生活的認知相反

而原因只是因為當初 Unix 多為西方人使用,便以西為正

因此在設定的時候需要選擇正負相反的選項

国家码

ZipCode - CountryName map

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="CountryCodes">
    <item>93,AF</item>
    <item>355,AL</item>
    <item>213,DZ</item>
    <item>376,AD</item>
    <item>244,AO</item>
    <item>672,AQ</item>
    <item>54,AR</item>
    <item>374,AM</item>
    <item>297,AW</item>
    <item>61,AU</item>
    <item>43,AT</item>
    <item>994,AZ</item>
    <item>973,BH</item>
    <item>880,BD</item>
    <item>375,BY</item>
    <item>32,BE</item>
    <item>501,BZ</item>
    <item>229,BJ</item>
    <item>975,BT</item>
    <item>591,BO</item>
    <item>387,BA</item>
    <item>267,BW</item>
    <item>55,BR</item>
    <item>673,BN</item>
    <item>359,BG</item>
    <item>226,BF</item>
    <item>95,MM</item>
    <item>257,BI</item>
    <item>855,KH</item>
    <item>237,CM</item>
    <item>1,CA</item>
    <item>238,CV</item>
    <item>236,CF</item>
    <item>235,TD</item>
    <item>56,CL</item>
    <item>86,CN</item>
    <item>61,CX</item>
    <item>61,CC</item>
    <item>57,CO</item>
    <item>269,KM</item>
    <item>242,CG</item>
    <item>243,CD</item>
    <item>682,CK</item>
    <item>506,CR</item>
    <item>385,HR</item>
    <item>53,CU</item>
    <item>357,CY</item>
    <item>420,CZ</item>
    <item>45,DK</item>
    <item>253,DJ</item>
    <item>670,TL</item>
    <item>593,EC</item>
    <item>20,EG</item>
    <item>503,SV</item>
    <item>240,GQ</item>
    <item>291,ER</item>
    <item>372,EE</item>
    <item>251,ET</item>
    <item>500,FK</item>
    <item>298,FO</item>
    <item>679,FJ</item>
    <item>358,FI</item>
    <item>33,FR</item>
    <item>689,PF</item>
    <item>241,GA</item>
    <item>220,GM</item>
    <item>995,GE</item>
    <item>49,DE</item>
    <item>233,GH</item>
    <item>350,GI</item>
    <item>30,GR</item>
    <item>299,GL</item>
    <item>502,GT</item>
    <item>224,GN</item>
    <item>245,GW</item>
    <item>592,GY</item>
    <item>509,HT</item>
    <item>504,HN</item>
    <item>852,HK</item>
    <item>36,HU</item>
    <item>91,IN</item>
    <item>62,ID</item>
    <item>98,IR</item>
    <item>964,IQ</item>
    <item>353,IE</item>
    <item>44,IM</item>
    <item>972,IL</item>
    <item>39,IT</item>
    <item>225,CI</item>
    <item>81,JP</item>
    <item>962,JO</item>
    <item>7,KZ</item>
    <item>254,KE</item>
    <item>686,KI</item>
    <item>965,KW</item>
    <item>996,KG</item>
    <item>856,LA</item>
    <item>371,LV</item>
    <item>961,LB</item>
    <item>266,LS</item>
    <item>231,LR</item>
    <item>218,LY</item>
    <item>423,LI</item>
    <item>370,LT</item>
    <item>352,LU</item>
    <item>853,MO</item>
    <item>389,MK</item>
    <item>261,MG</item>
    <item>265,MW</item>
    <item>60,MY</item>
    <item>960,MV</item>
    <item>223,ML</item>
    <item>356,MT</item>
    <item>692,MH</item>
    <item>222,MR</item>
    <item>230,MU</item>
    <item>262,YT</item>
    <item>52,MX</item>
    <item>691,FM</item>
    <item>373,MD</item>
    <item>377,MC</item>
    <item>976,MN</item>
    <item>382,ME</item>
    <item>212,MA</item>
    <item>258,MZ</item>
    <item>264,NA</item>
    <item>674,NR</item>
    <item>977,NP</item>
    <item>31,NL</item>
    <item>599,AN</item>
    <item>687,NC</item>
    <item>64,NZ</item>
    <item>505,NI</item>
    <item>227,NE</item>
    <item>234,NG</item>
    <item>683,NU</item>
    <item>850,KP</item>
    <item>47,NO</item>
    <item>968,OM</item>
    <item>92,PK</item>
    <item>680,PW</item>
    <item>507,PA</item>
    <item>675,PG</item>
    <item>595,PY</item>
    <item>51,PE</item>
    <item>63,PH</item>
    <item>870,PN</item>
    <item>48,PL</item>
    <item>351,PT</item>
    <item>1,PR</item>
    <item>974,QA</item>
    <item>40,RO</item>
    <item>7,RU</item>
    <item>250,RW</item>
    <item>590,BL</item>
    <item>685,WS</item>
    <item>378,SM</item>
    <item>239,ST</item>
    <item>966,SA</item>
    <item>221,SN</item>
    <item>381,RS</item>
    <item>248,SC</item>
    <item>232,SL</item>
    <item>65,SG</item>
    <item>421,SK</item>
    <item>386,SI</item>
    <item>677,SB</item>
    <item>252,SO</item>
    <item>27,ZA</item>
    <item>82,KR</item>
    <item>34,ES</item>
    <item>94,LK</item>
    <item>290,SH</item>
    <item>508,PM</item>
    <item>249,SD</item>
    <item>597,SR</item>
    <item>268,SZ</item>
    <item>46,SE</item>
    <item>41,CH</item>
    <item>963,SY</item>
    <item>886,TW</item>
    <item>992,TJ</item>
    <item>255,TZ</item>
    <item>66,TH</item>
    <item>228,TG</item>
    <item>690,TK</item>
    <item>676,TO</item>
    <item>216,TN</item>
    <item>90,TR</item>
    <item>993,TM</item>
    <item>688,TV</item>
    <item>971,AE</item>
    <item>256,UG</item>
    <item>44,GB</item>
    <item>380,UA</item>
    <item>598,UY</item>
    <item>1,US</item>
    <item>998,UZ</item>
    <item>678,VU</item>
    <item>39,VA</item>
    <item>58,VE</item>
    <item>84,VN</item>
    <item>681,WF</item>
    <item>967,YE</item>
    <item>260,ZM</item>
    <item>263,ZW</item>
    </string-array>
</resources>

获取国家码示例代码:

    public static String getCountryZipCode(Context context) {
        String countryID = "UNKNOWN";
        String countryZipCode = "UNKNOWN";
        String[] countryCodeMap = context.getResources().getStringArray(R.array.CountryCodes);
        
        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        countryID = telephonyManager.getSimCountryIso().toUpperCase();

        for (int i = 0; i < countryCodeMap.length; i++) {
            String[] zipcode_name = countryCodeMap[i].split(",");
            if (zipcode_name[1].trim().equals(countryID.trim())) {
                countryZipCode = zipcode_name[0];
                break;
            }
        }

        Log.d(TAG, "countryID: " + countryID + ", countryZipCode: " + countryZipCode);
        return countryID;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值