首页> 搜索结果页
"apilevel 21" 检索
共 1186 条结果
android 名称 版本 Api
android 名称 版本 Api **name version api*** Q 10 API level 29 Pie 9 API level 28 Oreo 8.1.0 API level 27 Oreo 8.0.0 API level 26 Nougat 7.1 API level 25 Nougat 7.0 API level 24 Marshmallow 6.0 API level 23 Lollipop 5.1 API level 22 Lollipop 5.0 API level 21 KitKat 4.4 - 4.4.4 API level 19 Jelly Bea 4.3.x API level 18 Jelly Bean 4.2.x API level 17 Jelly Bean 4.1.x API level 16
文章
API  ·  Android开发
2022-10-11
Android中的 targetsdkversioin
对于Android初学开发者来说, 可能会好奇 targetsdkversioin这个配置是用来干嘛的。 也有很多一两年开发经验的 Android码农会在面试中被问到这个问题。 Api Level是个什么东西? Android的api在版本间变化可能非常大, 有时候一个 api在低版本支持,到了高版本就被删除了。 可以在 develop网站上看到 api level对应的 Android版本, xxx.jpg 举个例子,Activity.getActionBar() xxxx.jpg 可以看到 api level 11,也就是说3.0之前是没有这个api的, 3.0之前的机器运行不了用了这个api的app。 targetsdkversioin 以上面 getActionBar()的例子来说, 我们的app现在可以指定 targetsdkversioin = 11, 这意味着安装时会通知系统,开发者已经在 3.0系统上测试过没问题, 如果安装的系统 api level高于11,则会开启兼容模式来运行app。 就像 Android 6.0引入的动态权限申请, 如果你把 targetsdkversioin定位比6.0低的 api level的话, 其实是不需要动态去申请权限, 在app安装时,系统会以兼容模式默认开启这些权限。 然而问题在于, 设定 targetsdkversioin = 21(比如5.0对应的 api level 21), 意味着向系统表明我们只在 5.0系统测试过, 如果是运行在6.0的机器而用户手动关掉所需要的权限的话, 我们的应用是会崩溃的,系统并不会帮我们处理掉兼容性的问题。 @TargetApi 和 targetsdkversioin相对应的还有 @TargetApi这个注解, 还是以上  getActionBar()为例子来说明 如果我们预期app可以运行在 api level < 11的机器上, 而因为UI设计或者其他原因,非要用 getActionBar()方法的时候, @TargetApi就有作用了 对于这种情况, 通常会在代码中用 Build.VERSION.SDK_INIT 来判断,比如下面的代码, if(Build.VERSION.SDK_INIT > 10) {    ....    goWithActionBar(); } else {    .... } @TargetApi(11) public void goWithActionBar(){    .... } 这意味着 goWithActionBar()这个方法是在 api level以上可以使用的, 不加这个注解的话,编译系统会提示兼容性错误而导致编译不过, 因此 @TargetApi主要是用来抑制编译时的兼容性问题的。 更多Android进阶技术,面试资料系统整理分享,职业生涯规划,产品,思维,行业观察,谈天说地。可以加Android架构师群;701740775。
文章
测试技术  ·  API  ·  Android开发
2018-12-05
Android API Level 与SDK版本对照表
原文:https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels Platform Version API Level VERSION_CODE Android 7.0 24 N Android 6.0 23 M Android 5.1 22 LOLLIPOP_MR1 Android 5.0 21 LOLLIPOP Android 4.4W 20 KITKAT_WATCH Android 4.2,4.2.2 19 KITKAT Android 4.3 18 JELLY_BEAN_MR2 Android 7.0 17 JELLY_BEAN_MR1 Android 7.0 16 JELLY_BEAN Android 7.0 15 ICE_CREAM_SANDWICH_MR1 Android 7.0 14 ICE_CREAM_SANDWICH
文章
API  ·  开发工具  ·  Android开发
2016-11-16
Kubernetes云容器技术专题—k8s之apiserver部署
1. hdss7-21安装apiserver[root@hdss7-21 certs]# cd /opt/src/ [root@hdss7-21 src]# rz [root@hdss7-21 src]# tar xf kubernetes-server-linux-amd64-v1.15.2.tar.gz -C /opt/ [root@hdss7-21 src]# cd .. [root@hdss7-21 opt]# mv kubernetes/ kubernetes-v1.15.2 [root@hdss7-21 opt]# ln -s /opt/kubernetes-v1.15.2/ /opt/kubernetes [root@hdss7-21 opt]# cd kubernetes [root@hdss7-21 kubernetes]# rm -rf kubernetes-src.tar.gz [root@hdss7-21 kubernetes]# cd server/bin/ [root@hdss7-21 bin]# rm -rf *.tar [root@hdss7-21 bin]# rm -rf *_tag 签发apiserver-client证书:apiserver与etc通信用的证书。apiserver是客户端,etcd是服务端 运维主机HDSS-200.host.com上 [root@hdss7-21 bin]# cd /opt/kubernetes/server/bin/ [root@hdss7-21 bin]# mkdir cert [root@hdss7-21 bin]# cd cert/ [root@hdss7-21 cert]# ls [root@hdss7-21 cert]# scp hdss7-200:/opt/certs/ca.pem . root@hdss7-200's password: ca.pem 100% 1334 505.1KB/s 00:00 [root@hdss7-21 cert]# scp hdss7-200:/opt/certs/apiserver.pem ./ root@hdss7-200's password: apiserver.pem 100% 1586 913.6KB/s 00:00 [root@hdss7-21 cert]# scp hdss7-200:/opt/certs/apiserver-key.pem ./ root@hdss7-200's password: apiserver-key.pem 100% 1675 711.1KB/s 00:00 [root@hdss7-21 cert]# scp hdss7-200:/opt/certs/ca-key.pem ./ root@hdss7-200's password: ca-key.pem 100% 1679 1.3MB/s 00:00 [root@hdss7-21 cert]# scp hdss7-200:/opt/certs/client-key.pem ./ root@hdss7-200's password: client-key.pem 100% 1679 749.7KB/s 00:00 [root@hdss7-21 cert]# scp hdss7-200:/opt/certs/client.pem ./ root@hdss7-200's password: client.pem [root@hdss7-21 bin]# mkdir conf [root@hdss7-21 bin]# cd /opt/kubernetes/server/bin/conf [root@hdss7-21 conf]# vi audit.yaml [root@hdss7-21 conf]# cat audit.yaml apiVersion: audit.k8s.io/v1beta1 # This is required. kind: Policy # Don't generate audit events for all requests in RequestReceived stage. omitStages: - "RequestReceived" rules: # Log pod changes at RequestResponse level - level: RequestResponse resources: - group: "" # Resource "pods" doesn't match requests to any subresource of pods, # which is consistent with the RBAC policy. resources: ["pods"] # Log "pods/log", "pods/status" at Metadata level - level: Metadata resources: - group: "" resources: ["pods/log", "pods/status"] # Don't log requests to a configmap called "controller-leader" - level: None resources: - group: "" resources: ["configmaps"] resourceNames: ["controller-leader"] # Don't log watch requests by the "system:kube-proxy" on endpoints or services - level: None users: ["system:kube-proxy"] verbs: ["watch"] resources: - group: "" # core API group resources: ["endpoints", "services"] # Don't log authenticated requests to certain non-resource URL paths. - level: None userGroups: ["system:authenticated"] nonResourceURLs: - "/api*" # Wildcard matching. - "/version" # Log the request body of configmap changes in kube-system. - level: Request resources: - group: "" # core API group resources: ["configmaps"] # This rule only applies to resources in the "kube-system" namespace. # The empty string "" can be used to select non-namespaced resources. namespaces: ["kube-system"] # Log configmap and secret changes in all other namespaces at the Metadata level. - level: Metadata resources: - group: "" # core API group resources: ["secrets", "configmaps"] # Log all other resources in core and extensions at the Request level. - level: Request resources: - group: "" # core API group - group: "extensions" # Version of group should NOT be included. # A catch-all rule to log all other requests at the Metadata level. - level: Metadata # Long-running requests like watches that fall under this rule will not # generate an audit event in RequestReceived. omitStages: - "RequestReceived" [root@hdss7-21 conf]# [root@hdss7-21 conf]# cat /opt/kubernetes/server/bin/kube-apiserver.sh #!/bin/bash ./kube-apiserver \ --apiserver-count 2 \ --audit-log-path /data/logs/kubernetes/kube-apiserver/audit-log \ --audit-policy-file ./conf/audit.yaml \ --authorization-mode RBAC \ --client-ca-file ./cert/ca.pem \ --requestheader-client-ca-file ./cert/ca.pem \ --enable-admission-plugins NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota \ --etcd-cafile ./cert/ca.pem \ --etcd-certfile ./cert/client.pem \ --etcd-keyfile ./cert/client-key.pem \ --etcd-servers https://192.168.12.12:2379,https://192.168.12.21:2379,https://192.168.12.22:2379 \ --service-account-key-file ./cert/ca-key.pem \ --service-cluster-ip-range 192.168.0.0/16 \ --service-node-port-range 3000-29999 \ --target-ram-mb=1024 \ --kubelet-client-certificate ./cert/client.pem \ --kubelet-client-key ./cert/client-key.pem \ --log-dir /data/logs/kubernetes/kube-apiserver \ --tls-cert-file ./cert/apiserver.pem \ --tls-private-key-file ./cert/apiserver-key.pem \ --v 2 [root@hdss7-21 conf]# chmod +x /opt/kubernetes/server/bin/kube-apiserver.sh [root@hdss7-21 conf]# vi /etc/supervisord.d/kube-apiserver.ini [root@hdss7-21 conf]# cat /etc/supervisord.d/kube-apiserver.ini [program:kube-apiserver-7-21] command=/opt/kubernetes/server/bin/kube-apiserver.sh ; the program (relative uses PATH, can take args) numprocs=1 ; number of processes copies to start (def 1) directory=/opt/kubernetes/server/bin ; directory to cwd to before exec (def no cwd) autostart=true ; start at supervisord start (default: true) autorestart=true ; retstart at unexpected quit (default: true) startsecs=30 ; number of secs prog must stay running (def. 1) startretries=3 ; max # of serial start failures (default 3) exitcodes=0,2 ; 'expected' exit codes for process (default 0,2) stopsignal=QUIT ; signal used to kill process (default TERM) stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10) user=root ; setuid to this UNIX account to run the program redirect_stderr=true ; redirect proc stderr to stdout (default false) stdout_logfile=/data/logs/kubernetes/kube-apiserver/apiserver.stdout.log ; stderr log path, NONE for none; default AUTO stdout_logfile_maxbytes=64MB ; max # logfile bytes b4 rotation (default 50MB) stdout_logfile_backups=4 ; # of stdout logfile backups (default 10) stdout_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0) stdout_events_enabled=false ; emit events on stdout writes (default false) [root@hdss7-21 conf]# mkdir -p /data/logs/kubernetes/kube-apiserver [root@hdss7-21 conf]# supervisorctl update kube-apiserver-7-21: added process group [root@hdss7-21 conf]# supervisorctl status etcd-server-7-21 RUNNING pid 2753, uptime 0:53:15 kube-apiserver-7-21 RUNNING pid 2873, uptime 0:00:48 2.运维主机HDSS-200.host.com[root@hdss7-200 certs]# cd /opt/certs/ [root@hdss7-200 certs]# ll total 36 -rw-r--r-- 1 root root 840 Jun 6 13:03 ca-config.json -rw-r--r-- 1 root root 989 Jun 6 11:19 ca.csr -rw-r--r-- 1 root root 334 Jun 6 11:18 ca-csr.json -rw------- 1 root root 1679 Jun 6 11:19 ca-key.pem -rw-r--r-- 1 root root 1334 Jun 6 11:19 ca.pem -rw-r--r-- 1 root root 1062 Jun 6 13:04 etcd-peer.csr -rw-r--r-- 1 root root 379 Jun 6 13:04 etcd-peer-csr.json -rw------- 1 root root 1679 Jun 6 13:04 etcd-peer-key.pem -rw-r--r-- 1 root root 1424 Jun 6 13:04 etcd-peer.pem [root@hdss7-200 certs]# vi /opt/certs/client-csr.json { "CN": "k8s-node", "hosts": [ ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "beijing", "L": "beijing", "O": "od", "OU": "ops" } ] } [root@hdss7-200 certs]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client-csr.json |cfssl-json -bare client [root@hdss7-200 certs]# vi apiserver-csr.json { "CN": "k8s-apiserver", "hosts": [ "127.0.0.1", "192.254.0.1", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster", "kubernetes.default.svc.cluster.local", "192.168.12.21", "192.168.12.21", "192.168.12.23" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "beijing", "L": "beijing", "O": "od", "OU": "ops" } ] } [root@hdss7-200 certs]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server apiserver-csr.json |cfssl-json -bare apiserver 3 hdss7-22安装apiserver[root@hdss7-22 src]# tar xf kubernetes-server-linux-amd64-v1.15.2.tar.gz -C /opt/ [root@hdss7-22 src]# cd .. [root@hdss7-22 opt]# ls containerd etcd etcd-v3.1.20 kubernetes src [root@hdss7-22 opt]# mv kubernetes/ kubernetes-v1.15.2 [root@hdss7-22 opt]# ln -s /opt/kubernetes-v1.15.2/ /opt/kubernetes [root@hdss7-22 opt]# mkdir /opt/kubernetes/server/bin/cert /opt/kubernetes/server/bin/conf [root@hdss7-22 opt]# cd /opt/kubernetes/server/bin/cert [root@hdss7-22 cert]# scp hdss7-200:/opt/certs/ca.pem ./ root@hdss7-200's password: ca.pem 100% 1334 2.5KB/s 00:00 [root@hdss7-22 cert]# scp hdss7-200:/opt/certs/apiserver.pem ./ root@hdss7-200's password: apiserver.pem 100% 1586 752.4KB/s 00:00 [root@hdss7-22 cert]# ls apiserver.pem ca.pem [root@hdss7-22 cert]# scp hdss7-200:/opt/certs/apiserver-key.pem ./ root@hdss7-200's password: apiserver-key.pem 100% 1675 1.2MB/s 00:00 [root@hdss7-22 cert]# scp hdss7-200:/opt/certs/ca-key.pem ./ root@hdss7-200's password: ca-key.pem 100% 1679 1.3MB/s 00:00 [root@hdss7-22 cert]# scp hdss7-200:/opt/certs/client-key.pem ./ root@hdss7-200's password: client-key.pem 100% 1679 728.4KB/s 00:00 [root@hdss7-22 cert]# scp hdss7-200:/opt/certs/client.pem ./ root@hdss7-200's password: client.pem [root@hdss7-22 conf]# vim audit.yaml apiVersion: audit.k8s.io/v1beta1 # This is required. kind: Policy # Don't generate audit events for all requests in RequestReceived stage. omitStages: - "RequestReceived" rules: # Log pod changes at RequestResponse level - level: RequestResponse resources: - group: "" # Resource "pods" doesn't match requests to any subresource of pods, # which is consistent with the RBAC policy. resources: ["pods"] # Log "pods/log", "pods/status" at Metadata level - level: Metadata resources: - group: "" resources: ["pods/log", "pods/status"] # Don't log requests to a configmap called "controller-leader" - level: None resources: - group: "" resources: ["configmaps"] resourceNames: ["controller-leader"] # Don't log watch requests by the "system:kube-proxy" on endpoints or services - level: None users: ["system:kube-proxy"] verbs: ["watch"] resources: - group: "" # core API group resources: ["endpoints", "services"] # Don't log authenticated requests to certain non-resource URL paths. - level: None userGroups: ["system:authenticated"] nonResourceURLs: - "/api*" # Wildcard matching. - "/version" # Log the request body of configmap changes in kube-system. - level: Request resources: - group: "" # core API group resources: ["configmaps"] # This rule only applies to resources in the "kube-system" namespace. # The empty string "" can be used to select non-namespaced resources. namespaces: ["kube-system"] # Log configmap and secret changes in all other namespaces at the Metadata level. - level: Metadata resources: - group: "" # core API group resources: ["secrets", "configmaps"] # Log all other resources in core and extensions at the Request level. - level: Request resources: - group: "" # core API group - group: "extensions" # Version of group should NOT be included. # A catch-all rule to log all other requests at the Metadata level. - level: Metadata # Long-running requests like watches that fall under this rule will not # generate an audit event in RequestReceived. omitStages: - "RequestReceived" [root@hdss7-22 conf]# vi /opt/kubernetes/server/bin/kube-apiserver.sh #!/bin/bash ./kube-apiserver \ --apiserver-count 2 \ --audit-log-path /data/logs/kubernetes/kube-apiserver/audit-log \ --audit-policy-file ./conf/audit.yaml \ --authorization-mode RBAC \ --client-ca-file ./cert/ca.pem \ --requestheader-client-ca-file ./cert/ca.pem \ --enable-admission-plugins NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota \ --etcd-cafile ./cert/ca.pem \ --etcd-certfile ./cert/client.pem \ --etcd-keyfile ./cert/client-key.pem \ --etcd-servers https://192.168.12.12:2379,https://192.168.12.21:2379,https://192.168.12.22:2379 \ --service-account-key-file ./cert/ca-key.pem \ --service-cluster-ip-range 192.168.0.0/16 \ --service-node-port-range 3000-29999 \ --target-ram-mb=1024 \ --kubelet-client-certificate ./cert/client.pem \ --kubelet-client-key ./cert/client-key.pem \ --log-dir /data/logs/kubernetes/kube-apiserver \ --tls-cert-file ./cert/apiserver.pem \ --tls-private-key-file ./cert/apiserver-key.pem \ --v 2 [root@hdss7-22 conf]# vi /etc/supervisord.d/kube-apiserver.ini [root@hdss7-22 conf]# chmod +x /opt/kubernetes/server/bin/kube-apiserver.sh [program:kube-apiserver-7-22] command=/opt/kubernetes/server/bin/kube-apiserver.sh ; the program (relative uses PATH, can take args) numprocs=1 ; number of processes copies to start (def 1) directory=/opt/kubernetes/server/bin ; directory to cwd to before exec (def no cwd) autostart=true ; start at supervisord start (default: true) autorestart=true ; retstart at unexpected quit (default: true) startsecs=30 ; number of secs prog must stay running (def. 1) startretries=3 ; max # of serial start failures (default 3) exitcodes=0,2 ; 'expected' exit codes for process (default 0,2) stopsignal=QUIT ; signal used to kill process (default TERM) stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10) user=root ; setuid to this UNIX account to run the program redirect_stderr=true ; redirect proc stderr to stdout (default false) stdout_logfile=/data/logs/kubernetes/kube-apiserver/apiserver.stdout.log ; stderr log path, NONE for none; default AUTO stdout_logfile_maxbytes=64MB ; max # logfile bytes b4 rotation (default 50MB) stdout_logfile_backups=4 ; # of stdout logfile backups (default 10) stdout_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0) stdout_events_enabled=false ; emit events on stdout writes (default false) [root@hdss7-22 conf]# mkdir -p /data/logs/kubernetes/kube-apiserver [root@hdss7-22 conf]# supervisorctl update [root@hdss7-22 conf]# supervisorctl status etcd-server-7-22 RUNNING pid 4264, uptime 0:51:18 kube-apiserver-7-22 RUNNING pid 4400, uptime 0:02:53 4 hdss7-11上部署nginx[root@hdss7-11 opt]# yum install nginx -y nginx四层负载,必须与http同级: [root@hdss7-11 opt]# cat /etc/nginx/nginx.conf stream { upstream kube-apiserver { server 192.168.12.21:6443 max_fails=3 fail_timeout=30s; server 192.168.12.22:6443 max_fails=3 fail_timeout=30s; } server { listen 7443; proxy_connect_timeout 2s; proxy_timeout 900s; proxy_pass kube-apiserver; } } [root@hdss7-11 opt]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@hdss7-11 opt]# systemctl restart nginx [root@hdss7-11 opt]# systemctl enable nginx 5.hdss7-12安装nginx[root@hdss7-12 certs]# yum install nginx -y [root@hdss7-12 certs]# vim /etc/nginx/nginx.conf stream { upstream kube-apiserver { server 192.168.12.21:6443 max_fails=3 fail_timeout=30s; server 192.168.12.22:6443 max_fails=3 fail_timeout=30s; } server { listen 7443; proxy_connect_timeout 2s; proxy_timeout 900s; proxy_pass kube-apiserver; } } [root@hdss7-12 certs]# [root@hdss7-12 certs]# [root@hdss7-12 certs]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@hdss7-12 certs]# systemctl start nginx [root@hdss7-12 certs]# systemctl enable nginx 6.实现keep高可用[root@hdss7-11 opt]# yum install keepalived -y [root@hdss7-11 opt]# cat /etc/keepalived/check_port.sh #!/bin/bash CHK_PORT=$1 if [ -n "$CHK_PORT" ];then PORT_PROCESS=`ss -lnt|grep $CHK_PORT|wc -l` if [ $PORT_PROCESS -eq 0 ];then echo "Port $CHK_PORT Is Not Used,End." exit 1 fi else echo "Check Port Cant Be Empty!" fi [root@hdss7-11 opt]# chmod +x /etc/keepalived/check_port.sh [root@hdss7-11 opt]# cat /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id 192.168.12.11 } vrrp_script chk_nginx { script "/etc/keepalived/check_port.sh 7443" interval 2 weight -20 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 251 priority 100 advert_int 1 mcast_src_ip 192.168.12.11 nopreempt authentication { auth_type PASS auth_pass 11111111 } track_script { chk_nginx } virtual_ipaddress { 192.168.12.10 } } [root@hdss7-11 opt]# systemctl start keepalived [root@hdss7-11 opt]# systemctl enable keepalived [root@hdss7-12 certs]# yum install keepalived -y [root@hdss7-12 certs]# cat /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id 192.168.12.11 } vrrp_script chk_nginx { script "/etc/keepalived/check_port.sh 7443" interval 2 weight -20 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 251 priority 100 advert_int 1 mcast_src_ip 192.168.12.11 nopreempt authentication { auth_type PASS auth_pass 11111111 } track_script { chk_nginx } virtual_ipaddress { 192.168.12.10 } } [root@hdss7-12 certs]# cat /etc/keepalived/check_port.sh #!/bin/bash CHK_PORT=$1 if [ -n "$CHK_PORT" ];then PORT_PROCESS=`ss -lnt|grep $CHK_PORT|wc -l` if [ $PORT_PROCESS -eq 0 ];then echo "Port $CHK_PORT Is Not Used,End." exit 1 fi else echo "Check Port Cant Be Empty!" fi [root@hdss7-12 certs]# chmod +x /etc/keepalived/check_port.sh [root@hdss7-12 certs]# systemctl start keepalived [root@hdss7-12 certs]# systemctl enable keepalived
文章
运维  ·  负载均衡  ·  Kubernetes  ·  应用服务中间件  ·  nginx  ·  容器
2021-12-10
Android适配全面总结(二)----版本适配
版权声明:本文为博主原创文章(部分引用他人博文,已加上引用说明),未经博主允许不得转载。https://www.jianshu.com/p/49fa8ebc0105 转载请标明出处:https://www.jianshu.com/p/49fa8ebc0105 本文出自 AWeiLoveAndroid的博客 上一篇文章讲了 屏幕适配 http://www.jianshu.com/p/7aa34434ad4d 这一篇文章讲一下 版本适配 https://www.jianshu.com/p/49fa8ebc0105 下一篇文章讲一下 ROM适配 https://www.jianshu.com/p/f9c67a4b908e 在我们的开发中,会对不同安卓版本做适配,比如我之前做过的项目中最低兼容到4.4,最高兼容是最新的系统7.1,由于不同版本的系统中部分API版本也不同,我就要对这些API做特殊处理。新的平台有一些API不能使用旧的API,旧的平台也使用不了新的API。所以这就要考验我们开发人员的能力了。我这里简单给出几点我开发中使用过的一些方式,仅供参考: 一、同一个api在不同版本都存在,只是api的一些接口方法有变更。 这种情况是最好处理的,只要对版本号做判断,对应的系统版本用相应的api方法就好了。为了好维护,建议做一个简单的封装。 举例说明如下: 比如Notification在不同版本的兼容,举例如下: 首先打开谷歌官方文档,看看文档里面的一些说明: Notification官方文档 1.Notification这个类是added in API level 1,一直都有,只是具体某些方法有变更。继续往下看。 2.这个类有个说明,意思是Notification.Builder是新增的一个内部类,用它创建通知更方便。接着往下看。 A class that represents how a persistent notification is to be presented to the user using the NotificationManager. The Notification.Builder has been added to make it easier to construct Notifications. 3.Public constructors公共的构造方法,其中有3个参数的这个在api 11过时,它被Notification.Builder替代了。 Notification(int icon, CharSequence tickerText, long when) This constructor was deprecated in API level 11. Use Notification.Builder instead. 4.常量 EXTRA_LARGE_ICON This constant was deprecated in API level 26. Use getLargeIcon(), which supports a wider variety of icon sources.(在API级别26中已弃用。使用getLargeIcon(),它支持更多种图标源。) EXTRA_SMALL_ICON This constant was deprecated in API level 26. Use getSmallIcon(), which supports a wider variety of icon sources.(在API级别26中已弃用。使用getSmallIcon(),它支持更多种图标源。) FLAG_HIGH_PRIORITY This constant was deprecated in API level 16. Use priority with a positive value.(在api16被弃用,请使用正数priority值替代) FLAG_SHOW_LIGHTS This constant was deprecated in API level 26. use shouldShowLights().(在API级别26中已弃用。请使用 shouldShowLights() 替代) PRIORITY_DEFAULT This constant was deprecated in API level 26. use IMPORTANCE_DEFAULT instead.(在API级别26中已弃用。请使用 IMPORTANCE_DEFAULT 替代) PRIORITY_HIGH This constant was deprecated in API level 26. use IMPORTANCE_HIGH instead.(在API级别26中已弃用。请使用 IMPORTANCE_HIGH 替代) PRIORITY_LOW This constant was deprecated in API level 26. use IMPORTANCE_LOW instead.(在API级别26中已弃用。请使用 IMPORTANCE_LOW 替代) PRIORITY_MAX This constant was deprecated in API level 26. use IMPORTANCE_HIGH instead.(在API级别26中已弃用。请使用 IMPORTANCE_HIGH 替代) PRIORITY_MIN This constant was deprecated in API level 26. use IMPORTANCE_MIN instead.(在API级别26中已弃用。请使用 IMPORTANCE_MIN 替代) STREAM_DEFAULT This constant was deprecated in API level 21. Use getAudioAttributes() instead.(在API级别21中已弃用。请使用 getAudioAttributes() 替代) 5.字段Fields audioAttributes 在api 26弃用. 使用 getAudioAttributes() 替代. audioStreamType 在api 21弃用. 使用 audioAttributes 替代. defaults 此字段在API 26弃用。使用getSound() 和 shouldShowLights()和shouldVibrate()。 icon 此字段已在API级别26中弃用。使用setSmallIcon(Icon)替代。 largeIcon This field was deprecated in API level 23. Use `setLargeIcon(Icon) instead. ledARGB This field was deprecated in API level 26. use `shouldShowLights(). ledOffMS This field was deprecated in API level 26. use `shouldShowLights(). ledOnMS This field was deprecated in API level 26. use shouldShowLights(). priority This field was deprecated in API level 26. use getImportance() instead. sound This field was deprecated in API level 26. use getSound() instead. vibrate This field was deprecated in API level 26. use getVibrationPattern(). 二、Android6.0的动态权限介绍 因为Android6.0(API23)开始需要动态申请权限,需要手动申请的权限有8组(短信、电话、联系人、存储、位置、麦克风、日历、相机),共24个,如下所示: 所属权限组 权限 短信 SEND_SMS 短信 RECEIVE_SMS 短信 READ_SMS 短信 RECEIVE_WAP_PUSH 短信 RECEIVE_MMS 电话 READ_PHONE_STATE 电话 CALL_PHONE 电话 READ_CALL_LOG 电话 WRITE_CALL_LOG 电话 ADD_VOICEMAIL 电话 USE_SIP 电话 PROCESS_OUTGOING_CALLS 联系人 READ_CONTACTS 联系人 WRITE_CONTACTS 联系人 GET_ACCOUNTS 存储 READ_EXTERNAL_STORAGE 存储 WRITE_EXTERNAL_STORAGE 位置 ACCESS_FINE_LOCATION 位置 ACCESS_COARSE_LOCATION 麦克风 RECORD_AUDIO 日历 READ_CALENDAR 日历 WRITE_CALENDAR 相机 CAMERA 传感器 BODY_SENSORS 注意:如果应用程序请求在AndroidManifest中列出的危险权限,并且应用程序已经在同一权限组中具有另一个危险权限,系统会立即授予权限,而不会与用户进行任何交互。 例如,如果一个应用程序先前已经请求并被授予READ_CONTACTS权限,然后它请求WRITE_CONTACTS(同属于联系人一组),系统会立即授予该权限,不会再弹出权限授予询问的对话框。 三、Android6.0如何申请动态权限 开发中经常会遇到拍照的权限申请,这里就讲一下如何动态设置拍照权限: //别忘记在清单文件也加上CAMERA权限 //<uses-permission android:name="android.permission.CAMERA" /> // 定义识别码 public static final int CAMERA_OK = 1; //动态申请拍照权限 if (Build.VERSION.SDK_INT>22){ if (ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){ //先判断有没有权限 ,没有就在这里进行权限的申请 requestPermissions(new String[]{Manifest.permission.CAMERA}, CAMERA_OK); }else { //说明已经获取到摄像头权限了,可以去选择照片或者拍照了。 toSelectPhotoOrOpenCamera(); } }else { //这个说明系统版本在6.0之下,不需要动态获取权限,直接去选择照片或者拍照。 toSelectPhotoOrOpenCamera(); } //在Activity中重写权限获取方法: /** * 权限操作结果处理 */ @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case CAMERA_OK: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //用户已授权 toSelectPhotoOrOpenCamera(); } else { //用户拒绝权限 ToastUtils.show(this, "缺少相机权限,暂时无法提供扫描功能,请尝试在设置中打开相机权限!", Toast.LENGTH_LONG); } break; } } } 四、Android7.0对文件权限进一步升级,提出了新的类FileProvider来获取文件。所以适配的时候一定要注意这一点api的变化。 FileProvider是ContentProvider的子类,把原来文件共享的 file://uri 换成了 content://uri 。一个Uri允许你获取临时权限去读写文件,当使用含有Uri的Intent,可以使用Intent.setFlags来添加临时权限。 下面来看看调用系统相机拍摄照片有如何变化,大致步骤如下所示: (一)在manifest中添加Provider <manifest> ... <application> ... <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.lzw.demo.fileprovider" android:exported="false" android:grantUriPermissions="true"> ... </provider> ... </application> </manifest> (二)配置你要获取的文件所在的文件夹 --> 创建一个xml文件,比如file_demo.xml,文件内容如下: <paths xmlns:android="http://schemas.android.com/apk/res/android"> <files-path name="my_images" path="images/"/> ... </paths> 路径说明: <files-path name="name" path="path/" /> <!--等同于Context.getFilesDir()下面的path文件夹的所有文件--> <cache-path name="name" path="path/" /> <!--等同于Context.getCacheDir()下面的path文件夹--> <external-path name="name" path="path/" /> <!--等同于Environment.getExternalStorageDirectory()下面的path文件夹--> <external-files-path name="name" path="path/" /> <!--等同于 Context#getExternalFilesDir(String)下面子文件path文件夹--> <external-cache-path name="name" path="path/" /> <!--相当于 Context.getExternalCacheDir()下边的path文件夹--> (三)添加路径信息到provier <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.lzw.demo.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_demo" /> </provider> (四)现在可以去拍照了。(由于Android6.0开始要动态申请权限,所以别忘了,这里就不写了,主要讲FileProvider的使用) //适配7.0的fileprovider,imgfile是图片文件路径 public void TakePhotoAdaption(File imgFile){ Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //适配android7.0 手机拍照取uri的处理 if(Build.VERSION.SDK_INT<24){ //7.0如果用会Uri.fromFile(XXX)会闪退,所以这里要特别做一个判断。 //imgfile是图片文件路径 uri = Uri.fromFile(imgFile); cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); }else{ //7.0+使用FileProvider.getUriForFile这个api uri=FileProvider.getUriForFile(DemoActivity.this, "com.lzw.demo.fileprovider",imgFile); cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); //添加这一句表示对目标应用临时授权该Uri所代表的文件 cameraIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION ); } startActivityForResult(cameraIntent, FLAG_CHOOSE_CAMERA); } 想看到拍照、选择照片、裁剪等完整流程的描述,可以参考这篇博客 解决安卓7.0拍照,相册选择崩溃的问题(包括压缩图片在内) 五、关于Android7.0相机闪退以及相册获取不到图片问题 1、没有动态申请权限,按照上述思路去做就好了。 2、华为手机的一些特殊处理方式,详情参见 ROM适配 https://www.jianshu.com/p/f9c67a4b908e 六、Android 8.0适配报错:Only fullscreen opaque activities can request orientation解决方案: 出现的原因:绝大多数都是因为我们为了提高用户体验,手动取消App启动白屏或者黑屏的时候,将Splash界面设为了透明,然后这个时候又设置了方向为垂直,从而导致了这个问题。 解决方案: 1.找到你设置透明的Activity,然后在他的theme中将android:windowIsTranslucent改为false <item name="android:windowIsTranslucent">false</item> 2.再加入下面这行代码就搞定了。 <item name="android:windowDisablePreview">true</item> 这个坑来自于博客: https://www.jianshu.com/p/d0d907754603 七、Android8.0版本更新相关api适配 创建通知渠道 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); NotificationChannel mChannel = new NotificationChannel("channel_01", "消息推送", NotificationManager.IMPORTANCE_DEFAULT); manager.createNotificationChannel(mChannel); } 创建Notification Context context = DJApplication.getInstance(); Notification.Builder builder = new Notification.Builder(context); builder.setTicker("开始下载"); builder.setSmallIcon(R.mipmap.ic_launcher); builder.setLargeIcon(BitmapFactory.decodeResource(DJApplication.getInstance().getResources(), R.mipmap.ic_launcher)); builder.setAutoCancel(true); PendingIntent pIntent = PendingIntent.getActivity(context, 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT); builder.setContentTitle("下载中"); builder.setContentIntent(pIntent); builder.setContentText(text); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { builder.setChannelId("channel_01");//设置有效的通知渠道 ID,这个ID要和之前创建时候的Channel_ID相同 } manager.notify(1, builder.build()); 安装apk权限 在 Android 8.0 中,安装未知应用权限提高了安装未知来源应用时的安全性。此权限与其他运行时权限一样,会与应用绑定,在安装时进行提示,确保用户授予使用安装来源的权限后,此权限才会提示用户安装应用。在运行 Android 8.0 或更高版本的设备上使用此权限时,恶意下载程序将无法骗取用户安装未获得预先授权的应用,所以我们需要加入安装apk文件的权限。 <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> 这个坑来自微信公众号“代码集中营”。 【好消息】我的微信公众号正式开通了,关注一下吧! 关注一下我的公众号吧
文章
存储  ·  API  ·  Android开发
2017-11-15
Android版本和API Level对应关系
  http://developer.android.com/guide/topics/manifest/uses-sdk-element.html    Platform Version               API Level               VERSION_CODE                       Android 6.0 23 M     Android 5.1 22 LOLLIPOP_MR1     Android 5.0 21 LOLLIPOP     Android 4.4W 20 KITKAT_WATCH     Android 4.4 19 KITKAT     Android 4.3 18 JELLY_BEAN_MR2     Android 4.2, 4.2.2 17 JELLY_BEAN_MR1     Android 4.1, 4.1.1 16 JELLY_BEAN     Android 4.0.3, 4.0.4 15 ICE_CREAM_SANDWICH_MR1         Android 3.2 13 HONEYCOMB_MR2     Android 3.1.x 12 HONEYCOMB_MR1     Android 3.0.x  11 HONEYCOMB
文章
API  ·  Android开发
2017-05-16
Android关于buildToolVersion与CompileSdkVersion的区别
StackOverFlow中对这个问题进行了详细的讨论:http://stackoverflow.com/questions/24521017/android-gradle-buildtoolsversion-vs-compilesdkversion 【问题的结论】就是: 1、CompileSdkVersion是你SDK的版本号,也就是API Level,例如API-19、API-20、API-21等等。 2、buildeToolVersion是你构建工具的版本,其中包括了打包工具aapt、dx等等。这个工具的目录位于..your_sdk_path/build-tools/XX.XX.XX 这个版本号一般是API-LEVEL.0.0。 例如I/O2014大会上发布了API20对应的build-tool的版本就是20.0.0 在这之间可能有小版本,例如20.0.1等等。 3、在ecplise的project.properties中可以设置sdk.buildtools=17.0.0。也可以不设置,不设置的话就是指定最新版本。而在android studio中是必须在build.gradle中设置。例如 compileSdkVersion   22  buildToolsVersion "22.0.1" 4、你可以用高版本的build-tool去构建一个低版本的sdk工程,例如build-tool的版本为20,去构建一个sdk版本为18的 例如:compileSdkVersion 18   buildToolsVersion "22.0.1"这样也是OK的。 【Android SDK 功能解析】 先来看一下SDK的目录 其中比较重要的目录包括【build-tools】【platforms】【platform-tools】【tools】 【build-tools】里面是不同版本(例如21.1.1)的build工具,这些工具包括了aapt打包工具、dx.bat、aidl.exe等等 【platform】是存放不同API-level版本SDK目录的地方 【platform-tools】是一些android平台相关的工具,adb、fastboot等 【tools】是指的安卓开发相关的工具,例如android.bat、ddms.bat(Dalvik debug Monitor Service)、draw9patch.bat等等 课外阅读: http://4byte.cn/question/47017/android-sdk-build-tools.html Android中build target,minSdkVersion,targetSdkVersion,maxSdkVersion概念区分
文章
API  ·  开发工具  ·  Android开发
2017-10-09
xamarin之 安装工具介绍
原文:xamarin之 安装工具介绍   思考:   1,  一定要按照顺序安装吗?   先装JDK,再装Android SDK 原因:Android SDK采用了Java语言   先装Android SDK,再装Android NDk 原因:NDK只是在SDK基础上开发的原生工具包,用于编写和编译一些c/c++的代码   先装Xamarin,再装Xamarin for Visual Studio 原因:Xamarin 是一个开发移动程序的IDE,而Xamarin for Visual Studio是Xamarin针对Visual Studio提供的插件。有了这个插件,就可以直接在Visual Studio中开发移动应用程序了     2,  为什么要安装这几个工具?   把上面(1)中按装顺序倒着推,你就明白了“开发xamarian程序,为什么要装这几个工具?”   3,  Xamarin Studio 和 Xamarin for Studio 的区别和联系?   Xamarin Studio        是个IDE Xamarin for Studio 是个插件   Xamarin Studio可以直接开发移动应用程序 Visual Studio只有装了Xamarin for Studio这个插件,才能在Visual Studio中开发移动应用程序   4,  为什么要进行环境配置?   设置Path 在cmd命令行里要启动一个应用程序时,系统会先在当前目录下查找,如果没有则在系统变量Path指定的路径去查找   设置CLASSPATH 设置CLASSPATH 的目的,在于告诉Java执行环境,在哪些目录下可以找到你所要执行的Java程序所需要的类或者包。     5,  Android SDK 与 Xamarin Studio通过什么建立连接   如果使用Eclipse开发: 需要给Eclipse装adt (Android Development Tools)插件,这样Eclipse就可以和android sdk建立连接,可以在Eclipse中启动android模拟器进行程序调试等   但Xamarin Studio 与Android SDK是如何建立连接,不清楚   6,  JDK,Android SDK,Android NDK,Xamarin,Xamarin for VS,它们之间的架构关系?   以上5点,已经回答了这个问题   一, JDK   1,  什么是SDK   前奏:什么是SDK SDK是软件开发工具包(Software Development Kit),它为某种程序语言提供应用程序接口API的一些文件     2,  什么是JDK   JDK    是Java语言的软件开发工具包(SDK) 没有JDK的话,无法编译Java程序,如果只运行Java程序,要确保已安装相应 的JRE       JRE             对应         .NET平台 JVM            对应         CLR     3,  组成   javac – 编译器,将源程序转成字节码 jar – 打包工具,将相关的类文件打包成一个文件(类似于Windows中的DLL) java – 运行编译后的java程序(.class后缀的) jdb – java调试器 appletviewer –小程序浏览器,一种执行HTML文件上的Java小程序的Java浏览器     4,  版本   版本 发行日期 JDK 1.1.4 1997-09-12 JDK 1.1.5 1997-12-13 JDK 1.1.6 1998-04-24 JDK 1.1.7 1998-09-28 JDK 1.1.8 1999-04-08                     5,  下载   http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html             6,  环境配置   JAVA_HOME = C:\Program Files\Java\jdk1.8.0_20 PATH = %JAVA_HOME%\bin; %JAVA_HOME%\jre\binset CLASSPATH =.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar       二,Android SDK   1,  什么是Android   Android,中文名“安卓”,是Google公司开发的一款用于手机和平板的操作系统 开发语言:C/C++(底层) Java等(应用层)   Android结构,如下图     从架构图看,Android分为四个层,从高层到低层分别是:   应用程序层 应用程序框架层 系统运行库层 Linux内核层     2,  Android应用程序开发,体现在哪几个方面(很重要)   Android开发四大组件:   活动(Activity): 用于表现功能            1个活动 对应         1个屏幕          1个屏幕 相当         1个网页   服务(Service): 后台运行服务,不提供界面呈现   开始         播放音乐 然后         玩QQ 发现         音乐继续播放   其实这个播放就是由播放音乐的Service进行控制   广播接收器(BroadcastReceiver):用于接收广播   Broadcast是一种广泛运用在应用程序之间传输信息的机制。而 BroadcastReceiver 是对发送出来的Broadcast进行过滤接受并响应的一类组件   例如: 当电话呼入这个外部事件到来的时候,可以利用BroadcastReceiver 进行处理。   当下载一个程序成功完成的时候,仍然可以利用BroadcastReceiver 进行处理     内容提供商(Content Provider): 支持在多个应用中存储和读取数据,相当于数据库   在Android 中,对数据的保护是很严密的,除了放在SD卡中的数据, 一个应用所持有的数据库、文件等内容,都是不允许其他直接访问的。 Andorid当然不会真的把每个应用都做成一座孤岛,它为所有应用都准备了一扇窗, 这就是Content Provider           3,  Android后缀   APK是安卓应用的后缀,是AndroidPackage的缩写,即Android安装包(apk) APK是类似Symbian Sis或Sisx的文件格式。通过将APK文件直接传到Android模拟器或Android手机中执行即可安装。 apk文件和sis一样,把android sdk编译的工程打包成一个安装程序文件,格式为apk。 APK文件其实是zip格式,但后缀名被修改为apk, 通过UnZip解压后,可以看到Dex文件, Dex是Dalvik VM executes的全称,即Android Dalvik执行程序,并非Java ME的字节码而是Dalvik字节码   4,  什么是Android SDK   Android SDK      指Android专属的软件开发工具包   Android SDK提供了开发Android应用程序所需的API库和构建、测试和调试Android应用程序所需的开发工具     5,  版本       6,  下载   https://developer.android.com/sdk/installing/index.html         7,  安装   先装JDK5.0以上版本,再装Android SDK        原因:Android SDK采用了Java语言 Android SDK不用安装,下载后,直接解压即可   8,  Android SDK Manage   负责下载或更新不同版本的SDK包 使用它下载,需要先对Google进行FQ   a,,FQ:            (1)在本机host文件中,加入                             203.208.46.146 dl.google.com 203.208.46.146 dl-ssl.google.com   (2)勾选下图中的选项       b,下载相关的Android SDK包         c,创建一个AVD,运行一下         9,  后续   如果使用Eclipse开发: 需要给Eclipse装adt (Android Development Tools)插件,这样Eclipse就可以和android sdk建立连接,可以在Eclipse中启动android模拟器进行程序调试等 10,Android SDK 与 Visual Studio通过什么建立连接     三, Android NDK   1,  什么是NDK   NDK  原生开发工具包(Native Development Kit)   是一种基于原生程序接口的开发工具 通过此工具开发的程序直接以本地语言运行,而非虚拟机。因此只有java等基于虚拟机运行的语言的程序才会有原生开发工具包   原理: 基于java的软件NDK通过JNI进行调度,由于java语言支持调用C/C++动态链接库,因此可以令java 的程序执行部分C语言代码,这为NDK的使用提供了可能   2,  什么是Android NDK   Android的SDK是基于Java实现,但Google的虚拟机Dalvik支持JNI编程方式 Android NDK使得Android平台支持C/C++开发   通过这个开发包的工具才能将android jni 的C/C++的代码编译成so库 并且,将so和java应用一起打包成apk     3,  版本   Code name Version API level Lollipop 5.1 API level 22 Lollipop 5.0 API level 21 KitKat 4.4 - 4.4.4 API level 19 Jelly Bean 4.3.x API level 18 Jelly Bean 4.2.x API level 17 Jelly Bean 4.1.x API level 16 Ice Cream Sandwich 4.0.3 - 4.0.4 API level 15, NDK 8 Ice Cream Sandwich 4.0.1 - 4.0.2 API level 14, NDK 7 Honeycomb 3.2.x API level 13 Honeycomb 3.1 API level 12, NDK 6 Honeycomb 3.0 API level 11 Gingerbread 2.3.3 - 2.3.7 API level 10 Gingerbread 2.3 - 2.3.2 API level 9, NDK 5 Froyo 2.2.x API level 8, NDK 4 Eclair 2.1 API level 7, NDK 3 Eclair 2.0.1 API level 6 Eclair 2.0 API level 5 Donut 1.6 API level 4, NDK 2 Cupcake 1.5 API level 3, NDK 1 (no code name) 1.1 API level 2 (no code name) 1.0 API level 1     4,  下载   http://developer.android.com/tools/sdk/ndk/index.html       5,  安装   下载后,直接解压即可 但是最后,需要在visual studio中进行配置ndk的path位置       四, GTK#   1,  什么是GTK#   GTK#          全称Graphical User Interface Toolkit   Gtk#是个.NET的库, 是对流行的跨平台图形用户界面库(GUI)GTK+ 的包装   GTK# 的运行类似于 Windows 窗体和 WPF,在 GTK# 中,窗口是基于 Gtk.Window 的,小插件(widgets,相当于控件)是基于 Gtk.Widget 类的   GTK# 是随 Mono 项目一同发布的,因此,想使用它的最好方法是安装 Mono(http://www.go-mono.com/mono-downloads/download.html)         2,  下载   http://www.mono-project.com/download/#download-win         五, Xamarin Studio   1,  什么是Xamarin Studio Xamarin Studio        是一个开发移动应用程序的IDE         2,  版本 3,  下载 http://xamarin.com/download                 六, Xamarin for Visual Studio   1,  什么是Xamarin for Visual Studio   Xamarin for Stududio  是Visual Studio的插件,包括Android 和IOS. 它是Xamarin针对Visual Studio提供的附挂套件     七,XamarinInstaller   XamarinInstall只是一个下载安装器,并不是软件包   InstallationManifest.xml 这是Xamarin的安装配置文件,里面记录了所需的安装包下载地址及版本 http://xamarin.com/installer_assets/v3/Windows/Universal//InstallationManifest.xml     八,破解   下载破解包:http://pan.baidu.com/s/1bnlc2vX 密码:43dg,里面有破解步骤        九,  配置   1,  环境变量   为JDK配置环境变量Path和CLASSPATH       2,  Visual Studio的配置 在Visual Studio中要指定Android SDK和Android NDK的Path路径       3,  Android SDK Manager调试运行     记得在Visual Studio项目中,要何持Android的版本与上图配置相同         4,  思考为什么要进行以上配置       十,Xamarin简介   Xamarin是基于Mono的平台,目前主要有以下产品(更具体请见:http://xamarin.com/products): Xamarin Studio:IDE,是从原来的MonoDevelop改名而来。现在从MonoDevelop官方网站下载的其实也是Xamarin Studio:http://monodevelop.com/。 (话说MonoDevelop也是SharpDevelop的一个分支发展而来) Xamarin.iOS:原名MonoTouch,用于开发iOS应用程序,并且可以发布到app store上。 Xamarin.Mac:用于开发mac os x应用程序,类似于windows 桌面应用。 Xamarin.Android:原名MonoDroid/Mono for Android,用于开发Android应用程序。 Xamarin for Visual Studio:Visual Studio的插件,包括iOS和Android,不过目前只支持vs2010/vs2012。 Xamarin Test Cloud:测试云,可以把你的应用程序发布到Xamarin的云上面测试,它可以自动帮你在数百种设备上测试你的应用程序。 Component Store:组件商店,上面有各种收费/免费的控件提供下载。           参考:   五步搞定Android开发环境部署——非常详细的Android开发环境搭建教程 http://www.cnblogs.com/zoupeiyang/p/4034517.html#1   Android之NDK开发 http://www.cnblogs.com/devinzhang/archive/2012/02/29/2373729.html   介绍 GTK# http://blog.csdn.net/hadstj/article/details/25161261   Xamarin 手动安装步骤+破解 http://www.tuicool.com/articles/eIvIra     ——
文章
Web App开发  ·  Java  ·  API  ·  开发工具  ·  Android开发
2015-05-07
[Android问答] 如何获得手机屏幕分辨率?
[Android问答] 如何获得手机屏幕分辨率? 这个问题并不复杂,但是问的人实在很多,所以还是集中回答一下。 从Android 3.2(API Level 13)开始,在Activity里使用下面的方法来获取屏幕分辨率(单位是像素): Display display = getWindowManager().getDefaultDisplay(); //Activity#getWindowManager() Point size = new Point(); display.getSize(size); int width = size.x; int height = size.y; 如果代码不是写在Activity里,用下面的方法(通过WINDOW_SERVICE获取display对象): WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); display.getSize(size); int width = size.x; int height = size.y; 如果Android版本小于3.2,那么因为Display对象还没有getSize()方法,应该用下面的方法获取屏幕分辨率: Display display = getWindowManager().getDefaultDisplay(); int width = display.getWidth(); int height = display.getHeight(); 最后,附Android系统版本与API Level对照表(官方文档在这里,如果打不开,也可以在android源文件的android.os.Build里找到这些对应关系): Platform Version API Level VERSION_CODE Notes Android 5.0 21 LOLLIPOP (正式的名称)   21 L (暂时使用的名称) Android 4.4W 20 KITKAT_WATCH   Android 4.4 19 KITKAT   Android 4.3 18 JELLY_BEAN_MR2   Android 4.2 17 JELLY_BEAN_MR1   Android 4.1, 4.1.1 16 JELLY_BEAN Platform Highlights Android 4.0.3, 4.0.4 15 ICE_CREAM_SANDWICH_MR1 Platform Highlights Android 4.0, 4.0.1, 4.0.2 14 ICE_CREAM_SANDWICH Android 3.2 13 HONEYCOMB_MR2 Android 3.1.x 12 HONEYCOMB_MR1 Platform Highlights Android 3.0.x 11 HONEYCOMB Platform Highlights Android 2.3.4 Android 2.3.3 10 GINGERBREAD_MR1 Platform Highlights Android 2.3.2 Android 2.3.1 Android 2.3 9 GINGERBREAD Android 2.2.x 8 FROYO Platform Highlights Android 2.1.x 7 ECLAIR_MR1 Platform Highlights Android 2.0.1 6 ECLAIR_0_1 Android 2.0 5 ECLAIR Android 1.6 4 DONUT Platform Highlights Android 1.5 3 CUPCAKE Platform Highlights Android 1.1 2 BASE_1_1   Android 1.0 1 BASE   参考资料 Display | Android Developers Android: How to get screen dimensions What is API Level? 本文转自博客园八进制的博客,原文链接:[Android问答] 如何获得手机屏幕分辨率?,如需转载请自行联系原博主。
文章
编解码  ·  API  ·  Android开发
2017-12-05
Android系统版本号和Android API level对应表
终于建了一个自己个人小站:https://huangtianyu.gitee.io,以后优先更新小站博客,欢迎进站,O(∩_∩)O~~       平时总会去查 Android系统版本号和Android API level对应关系,有时候上不了Google,网上搜的又不全。这里翻译记录下,顺便给出原文网址:https://developer.android.com/guide/topics/manifest/uses-sdk-element.html  平台版本         API 级别        VERSION_CODE 备注 Android 7.0 24 N 平台亮点 Android 6.0 23 M 平台亮点 Android 5.1 22 LOLLIPOP_MR1 平台亮点 Android 5.0 21 LOLLIPOP Android 4.4W 20 KITKAT_WATCH 仅限 KitKat for Wearables Android 4.4 19 KITKAT 平台亮点 Android 4.3 18 JELLY_BEAN_MR2 平台亮点 Android 4.2、4.2.2 17 JELLY_BEAN_MR1 平台亮点 Android 4.1、4.1.1 16 JELLY_BEAN 平台亮点 Android 4.0.3、4.0.4 15 ICE_CREAM_SANDWICH_MR1 平台亮点 Android 4.0、4.0.1、4.0.2 14 ICE_CREAM_SANDWICH Android 3.2 13 HONEYCOMB_MR2 Android 3.1.x 12 HONEYCOMB_MR1 平台亮点 Android 3.0.x 11 HONEYCOMB 平台亮点 Android 2.3.4Android 2.3.3 10 GINGERBREAD_MR1 平台亮点 Android 2.3.2Android 2.3.1Android 2.3 9 GINGERBREAD Android 2.2.x 8 FROYO 平台亮点 Android 2.1.x 7 ECLAIR_MR1 平台亮点 Android 2.0.1 6 ECLAIR_0_1 Android 2.0 5 ECLAIR Android 1.6 4 DONUT 平台亮点 Android 1.5 3 CUPCAKE 平台亮点 Android 1.1 2 BASE_1_1 Android 1.0 1 BASE
文章
API  ·  Android开发
2018-02-07
...
跳转至:
开发与运维
5638 人关注 | 131545 讨论 | 304219 内容
+ 订阅
  • C语言入门(八)——数组(二)
  • JavaScript小试牛刀之猜数字
  • 一起来学SpringCloud之整合Nacos配置中心与注册中心
查看更多 >
人工智能
2800 人关注 | 11411 讨论 | 97756 内容
+ 订阅
  • C语言入门(八)——数组(二)
  • 【评测】pandoc 安装与测评
  • C语言入门(八)——数组(一)
查看更多 >
云原生
234024 人关注 | 11362 讨论 | 45589 内容
+ 订阅
  • JavaScript小试牛刀之猜数字
  • 一起来学SpringCloud之整合Nacos配置中心与注册中心
  • SpringBoot进阶之服务部署
查看更多 >
云计算
21788 人关注 | 59387 讨论 | 56047 内容
+ 订阅
  • 国际阿里云账号OSS购买了资源包为何仍会欠费?
  • 一起来学SpringCloud之微服务概述
  • Spring Cloud Zuul 基础搭建
查看更多 >