手机定位

有一类事件必须依赖于手机信号方能触发,如果把设备中的sim卡拔出,或者该设备本身不支持sim卡(如ipad),那么这类事件将永远不会被触发。在Android中,这类事件包括定位事件和手机信号事件。
与定位有关的类主要有:
1、定位条件器Criteria : 该类用于设置定位的前提条件,比如精度、速度、海拔、方位等等信息。
2、定位管理器LocationManager : 该类用于获取定位信息的提供者,设置监听器,并获取最近一次的位置信息。
3、定位监听器LocationListener : 该类用于监听定位信息的变化事件,如定位提供者的开关、位置信息发生变化等等。

定位条件器

Criteria的常用参数设置方法如下:
setAccuracy : 设置定位精确度。有两个取值,ACCURACY_FINE表示精度高,ACCURACY_COARSE表示精度低
setSpeedAccuracy : 设置速度的定位精确度。有两个取值,ACCURACY_HIGH表示精度高,ACCURACY_LOW表示精度低
setAltitudeRequired : 设置是否需要海拔信息。取值true表示需要,false表示不需要
setBearingRequired : 设置是否需要方位信息。取值true表示需要,false表示不需要
setCostAllowed : 设置是否允许运营商收费。取值true表示允许,false表示不允许
setPowerRequirement : 设置对电源的需求。有三个取值,POWER_LOW表示耗电低,POWER_MEDIUM表示耗电中等,POWER_HIGH表示耗电高

定位管理器

管理器类名 : LocationManager
获取管理器实例的方法:

LocationManager mLocationMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

管理器的常用方法如下:
getBestProvider : 获取最佳的定位提供者。第一个参数设置条件器Criteria,第二个参数一般取值true。返回值主要有两个:GPS定位返回gps,网络定位返回network
isProviderEnabled : 判断指定提供者是否可用
getLastKnownLocation : 获取最近一次的定位地点
requestLocationUpdates : 设置定位监听器

定位监听器

监听器类名 : LocationListener
设置监听器的方法:

requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)

其中第一个参数设置定位提供者,第二个参数设置位置更新的最小间隔时间,第三个参数设置位置更新的最小距离,第四个参数设置监听器实例。
监听器需要重写的方法:
onLocationChanged : 在位置地点发生变化时调用
onProviderDisabled : 在定位提供者被用户关闭时调用
onProviderEnabled : 在定位提供者被用户开启时调用
onStatusChanged : 在定位提供者的状态发生变化时调用。状态值有三个:OUT_OF_SERVICE表示在服务范围之外,TEMPORARILY_UNAVAILABLE表示暂时不可用,AVAILABLE表示可用

手机定位示例

手机开启GPS信号,GPS定位的截图如下:

手机关闭GPS信号,网络定位的截图如下:

定位信息获取的示例代码如下:

import com.example.exmmobile.util.Utils;import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.TextView;public class LocationActivity extends Activity {private final static String TAG = "LocationActivity";private TextView tv_location;private String mLocation="";private LocationManager mLocationMgr;private Criteria mCriteria = new Criteria();private Handler mHandler = new Handler();private boolean bLocationEnable = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_location);initWidget();initLocation();mHandler.postDelayed(mRefresh, 100);}private void initWidget() {tv_location = (TextView) findViewById(R.id.tv_location);mLocationMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);// 设置定位精确度 Criteria.ACCURACY_COARSE 比较粗略, Criteria.ACCURACY_FINE 则比较精细mCriteria.setAccuracy(Criteria.ACCURACY_FINE);// 设置是否需要海拔信息 AltitudemCriteria.setAltitudeRequired(true);// 设置是否需要方位信息 BearingmCriteria.setBearingRequired(true);// 设置是否允许运营商收费mCriteria.setCostAllowed(true);// 设置对电源的需求mCriteria.setPowerRequirement(Criteria.POWER_LOW);}private void initLocation() {String bestProvider = mLocationMgr.getBestProvider(mCriteria, true);if (bestProvider == null) {bestProvider = LocationManager.NETWORK_PROVIDER;}if (mLocationMgr.isProviderEnabled(bestProvider)) {tv_location.setText("\n正在获取"+bestProvider+"定位对象");mLocation = String.format("\n定位类型=%s", bestProvider);beginLocation(bestProvider);bLocationEnable = true;} else {tv_location.setText("\n"+bestProvider+"定位不可用");bLocationEnable = false;}}@SuppressLint("DefaultLocale")private void setLocationText(Location location) {if (location != null) {String desc = String.format("%s\n定位对象信息如下:\n\t其中时间:%s\n\t其中经度:%f\n\t其中纬度:%f\n\t其中高度:%f", mLocation, Utils.getNowDateTime(),location.getLongitude(), location.getLatitude(), location.getAltitude());Log.d(TAG, desc);tv_location.setText(desc);} else {tv_location.setText(mLocation+"\n暂未获取到定位对象");}}private void beginLocation(String method) {mLocationMgr.requestLocationUpdates(method, 300, 0, mLocationListener);Location location = mLocationMgr.getLastKnownLocation(method);setLocationText(location);}// 位置监听器private LocationListener mLocationListener = new LocationListener() {@Overridepublic void onLocationChanged(Location location) {setLocationText(location);}@Overridepublic void onProviderDisabled(String arg0) {}@Overridepublic void onProviderEnabled(String arg0) {}@Overridepublic void onStatusChanged(String arg0, int arg1, Bundle arg2) {}};private Runnable mRefresh = new Runnable() {@Overridepublic void run() {if (bLocationEnable == false) {initLocation();mHandler.postDelayed(this, 1000);}}};}

手机基站和信号

手机要能接收基站的信号,才能打电话和发短信。手机制式目前有4G、3G、2G,同样的,基站和信号也分4G、3G、2G。4G的网络是LTE,2G的网络是GSM,3G的网络在国内根据运营商划分(移动是TD,电信是CDMA,联通是WCDMA)。不过基站与信号事件在实际开发中用得不多,一般是运营商的网优业务才会用到。
与基站和信号有关的类主要有:
1、电话管理器TelephonyManager : 该类用于提供运营商信息、蜂窝网络信息、当前的基站信息等等。
2、手机状态监听器PhoneStateListener : 该类用于监听基站或者信号信息的变化事件。

电话管理器

管理器类名 : TelephonyManager
获取管理器实例的方法:

TelephonyManager mTelMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

管理器的常用方法如下:
getNetworkOperator : 获取运营商信息。返回字符串的前三位是国家代码(中国的为460),后两位是运营商代码(中国移动为0,中国联通为1,中国电信为2)
getNetworkType : 获取运营商网络类型。
getNetworkClass : 获取运营商网络类别。取值1表示2G,取值2表示3G,取值3表示4G
getCellLocation : 获取当前连接的基站信息。
getNeighboringCellInfo : 获取附近的基站信息。
getAllCellInfo : 获取可连接的所有基站信息。
listen : 设置手机状态监听器。

手机状态监听器

监听器类名 : PhoneStateListener
设置监听器的方法:

listen(PhoneStateListener listener, int events)

其中第一个参数设置手机状态监听器,第二个参数指定要监听的事件类型。
监听器需要重写的方法:
onCellLocationChanged : 在基站位置发生变化时调用,对应的监听类型是LISTEN_CELL_LOCATION
onCellInfoChanged : 在基站信息发生变化时调用,对应的监听类型是LISTEN_CELL_INFO
onSignalStrengthsChanged : 在信号强度发生变化时调用,对应的监听类型是LISTEN_SIGNAL_STRENGTHS

获取手机基站和信号的示例

手机开启4G信号,找到LTE基站和信号信息的截图如下:

手机关闭4G信号,找到TD基站和信号信息的截图如下:

基站和信号获取的示例代码如下:

import java.util.List;import com.example.exmmobile.util.Utils;import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.telephony.CellIdentityCdma;
import android.telephony.CellIdentityGsm;
import android.telephony.CellIdentityLte;
import android.telephony.CellIdentityWcdma;
import android.telephony.CellInfo;
import android.telephony.CellInfoCdma;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.CellLocation;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import android.widget.TextView;public class StationActivity extends Activity {private final static String TAG = "StationActivity";private TextView tv_station;private TextView tv_net;private String mDevice="", mStation="", mSignal="";private TelephonyManager mTelMgr;private int mCellType = Utils.TYPE_GSM;private Handler mHandler = new Handler();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_station);initWidget();mHandler.postDelayed(mRefresh, 100);}@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)private void listenCellInfo() {MyPhoneStateListener mCellInfoListener = new MyPhoneStateListener();mTelMgr.listen(mCellInfoListener, PhoneStateListener.LISTEN_CELL_INFO);}private void initWidget() {tv_station = (TextView) findViewById(R.id.tv_station);tv_net = (TextView) findViewById(R.id.tv_net);mTelMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);MyPhoneStateListener mSignalStrengthListener = new MyPhoneStateListener();mTelMgr.listen(mSignalStrengthListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);MyPhoneStateListener mCellLocationListener = new MyPhoneStateListener();mTelMgr.listen(mCellLocationListener, PhoneStateListener.LISTEN_CELL_LOCATION);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {listenCellInfo();}}private class MyPhoneStateListener extends PhoneStateListener {@Overridepublic void onSignalStrengthsChanged(SignalStrength signalStrength) {super.onSignalStrengthsChanged(signalStrength);int gsm_sign = -113+2*signalStrength.getGsmSignalStrength();int lte_sinr = 99;int lte_rsrp = 99;int lte_rsrq = 99;int lte_rssnr = 0;int lte_cqi = 0;try {lte_sinr = (Integer) signalStrength.getClass().getMethod("getLteSignalStrength").invoke(signalStrength);lte_rsrp = (Integer) signalStrength.getClass().getMethod("getLteRsrp").invoke(signalStrength);lte_rsrq = (Integer) signalStrength.getClass().getMethod("getLteRsrq").invoke(signalStrength);lte_rssnr = (Integer) signalStrength.getClass().getMethod("getLteRssnr").invoke(signalStrength);lte_cqi = (Integer) signalStrength.getClass().getMethod("getLteCqi").invoke(signalStrength);} catch (Exception e) {e.printStackTrace();return;}mSignal = "";if (mCellType == Utils.TYPE_LTE || Utils.getClassType(mTelMgr, mTelMgr.getNetworkType())==Utils.TYPE_4G) {mSignal = String.format("%s\nLTE信号更新时间=%s\n gsm_sign=%d\n lte_sinr=%d\n lte_rsrp=%d\n lte_rsrq=%d\n lte_rssnr=%d\n lte_cqi=%d", mSignal, Utils.getNowDateTime(), gsm_sign, lte_sinr, lte_rsrp, lte_rsrq, lte_rssnr, lte_cqi);} else if (mCellType == Utils.TYPE_GSM) {mSignal = String.format("%s\nGSM信号更新时间=%s\n gsm_sign=%d", mSignal, Utils.getNowDateTime(), gsm_sign);} else if (mCellType == Utils.TYPE_WCDMA) {mSignal = String.format("%s\nTD信号更新时间=%s\n td_sign=%d", mSignal, Utils.getNowDateTime(), gsm_sign);}mSignal += "\n";tv_station.setText(mStation+mSignal);}@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)@Overridepublic void onCellInfoChanged(List<CellInfo> cellList) {super.onCellInfoChanged(cellList);int count = (cellList==null)?0:cellList.size();tv_net.setText(mDevice+"\n\t\t已连接的基站个数="+count);refreshStation(cellList);}@Overridepublic void onCellLocationChanged(CellLocation location) {super.onCellLocationChanged(location);mHandler.postDelayed(mRefresh, 100);}}//    MCC,Mobile Country Code,移动国家代码(中国的为460);//   MNC,Mobile Network Code,移动网络号码(中国移动为0,中国联通为1,中国电信为2); //   LAC,Location Area Code,位置区域码;//    CID,Cell Identity,基站编号;//  BSSS,Base station signal strength,基站信号强度。@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)private void refreshStation(List<CellInfo> cellList) {if (cellList == null) {return;}GsmCellLocation location = (GsmCellLocation) mTelMgr.getCellLocation();int cid = location.getCid();boolean is_found = false;mStation = "";mCellType = Utils.TYPE_LTE;for (int i=0; i<cellList.size(); i++) {CellInfo cell = cellList.get(i);if (cell.toString().indexOf(""+cid) >= 0) {is_found = true;if ((cell instanceof CellInfoLte)) {mCellType = Utils.TYPE_LTE;CellIdentityLte cellLte = ((CellInfoLte)cell).getCellIdentity();mStation = String.format("%s\nLTE基站更新时间=%s", mStation, Utils.getNowDateTime());mStation = String.format("%s\n mcc=%d", mStation, cellLte.getMcc());mStation = String.format("%s\n mnc=%d", mStation, cellLte.getMnc());mStation = String.format("%s\n lte_tac=%d", mStation, cellLte.getTac());mStation = String.format("%s\n lte_ci=%d", mStation, cellLte.getCi());mStation = String.format("%s\n lte_pci=%d", mStation, cellLte.getPci());} else if ((cell instanceof CellInfoGsm)) {mCellType = Utils.TYPE_GSM;CellIdentityGsm cellGsm = ((CellInfoGsm)cell).getCellIdentity();mStation = String.format("%s\nGSM基站更新时间=%s", mStation, Utils.getNowDateTime());mStation = String.format("%s\n mcc=%d", mStation, cellGsm.getMcc());mStation = String.format("%s\n mnc=%d", mStation, cellGsm.getMnc());mStation = String.format("%s\n gsm_lac=%d", mStation, cellGsm.getLac());mStation = String.format("%s\n gsm_cid=%d", mStation, cellGsm.getCid());} else if ((cell instanceof CellInfoCdma)) {String operator = mTelMgr.getNetworkOperator();int mcc = Integer.parseInt(operator.substring(0, 3));int mnc = Integer.parseInt(operator.substring(3, 5));mCellType = Utils.TYPE_CDMA;CellIdentityCdma cellCdma = ((CellInfoCdma)cell).getCellIdentity();mStation = String.format("%s\nCDMA基站更新时间=%s", mStation, Utils.getNowDateTime());mStation = String.format("%s\n mcc=%d", mStation, mcc);mStation = String.format("%s\n mnc=%d", mStation, mnc);mStation = String.format("%s\n lac(network_id)=%d", mStation, cellCdma.getNetworkId());mStation = String.format("%s\n system_id=%d", mStation, cellCdma.getSystemId());mStation = String.format("%s\n cellid=%d", mStation, cellCdma.getBasestationId()/16);} else if ((cell instanceof CellInfoWcdma)) {mCellType = Utils.TYPE_WCDMA;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {refreshHigher3G(cell);} else {initLowerStation(mCellType, null);}}break;}}tv_station.setText(mStation+mSignal);if (is_found == false) {initLowerStation(0, null);}}@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)private void refreshHigher3G(CellInfo cell) {CellIdentityWcdma cellWcdma = ((CellInfoWcdma)cell).getCellIdentity();mStation = String.format("%s\nTD基站更新时间=%s", mStation, Utils.getNowDateTime());mStation = String.format("%s\n mcc=%d", mStation, cellWcdma.getMcc());mStation = String.format("%s\n mnc=%d", mStation, cellWcdma.getMnc());mStation = String.format("%s\n td_lac=%d", mStation, cellWcdma.getLac());mStation = String.format("%s\n td_ci=%d", mStation, cellWcdma.getCid());mStation = String.format("%s\n td_psc=%d", mStation, cellWcdma.getPsc());}@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)private void initHigherStation() {List<CellInfo> cell_list = mTelMgr.getAllCellInfo();int count = (cell_list==null)?0:cell_list.size();tv_net.setText(mDevice+"\n 已连接的基站个数="+count);if (Utils.getClassType(mTelMgr, mTelMgr.getNetworkType())==Utils.TYPE_4G) {if (cell_list==null || cell_list.size()==0) {initLowerStation(0, null);mHandler.postDelayed(mRefresh4G, 100);} else {refreshStation(cell_list);}} else {initLowerStation(0, null);}}private void initLowerStation(int cell_type, CellLocation location) {mStation = "";String operator = mTelMgr.getNetworkOperator();int mcc = Integer.parseInt(operator.substring(0, 3));int mnc = Integer.parseInt(operator.substring(3, 5));int lac = 0, cid = 0;if (location == null) {GsmCellLocation gsmLocation = (GsmCellLocation) mTelMgr.getCellLocation();lac = gsmLocation.getLac();cid = gsmLocation.getCid();} else {GsmCellLocation gsmLocation = (GsmCellLocation) location;lac = gsmLocation.getLac();cid = gsmLocation.getCid();}if (Utils.getNetworkTypeName(mTelMgr, mTelMgr.getNetworkType()).indexOf("CDMA")>=0) {CdmaCellLocation locationCdma = (CdmaCellLocation) mTelMgr.getCellLocation(); mCellType = Utils.TYPE_CDMA;mStation = String.format("%s\nCDMA基站更新时间=%s", mStation, Utils.getNowDateTime());mStation = String.format("%s\n mcc=%d", mStation, mcc);mStation = String.format("%s\n mnc=%d", mStation, mnc);mStation = String.format("%s\n lac(network_id)=%d", mStation, locationCdma.getNetworkId());mStation = String.format("%s\n system_id=%d", mStation, locationCdma.getSystemId());mStation = String.format("%s\n cellid=%d", mStation, locationCdma.getBaseStationId()/16);} else if (cell_type==Utils.TYPE_WCDMA || Utils.getClassType(mTelMgr, mTelMgr.getNetworkType())==Utils.TYPE_3G) {mCellType = Utils.TYPE_WCDMA;mStation = String.format("%s\nTD基站更新时间=%s", mStation, Utils.getNowDateTime());mStation = String.format("%s\n mcc=%d", mStation, mcc);mStation = String.format("%s\n mnc=%d", mStation, mnc);mStation = String.format("%s\n td_lac=%d", mStation, lac);mStation = String.format("%s\n td_ci=%d", mStation, cid);} else if (Utils.getClassType(mTelMgr, mTelMgr.getNetworkType())==Utils.TYPE_4G) {mCellType = Utils.TYPE_LTE;mStation = String.format("%s\nLTE基站更新时间=%s", mStation, Utils.getNowDateTime());mStation = String.format("%s\n mcc=%d", mStation, mcc);mStation = String.format("%s\n mnc=%d", mStation, mnc);mStation = String.format("%s\n lte_tac=%d", mStation, lac);mStation = String.format("%s\n lte_ci=%d", mStation, cid);mStation = String.format("%s\n lte_pci=%d", mStation, -1);} else {mCellType = Utils.TYPE_GSM;mStation = String.format("%s\nGSM基站更新时间=%s", mStation, Utils.getNowDateTime());mStation = String.format("%s\n mcc=%d", mStation, mcc);mStation = String.format("%s\n mnc=%d", mStation, mnc);mStation = String.format("%s\n gsm_lac=%d", mStation, lac);mStation = String.format("%s\n gsm_cid=%d", mStation, cid);}tv_station.setText(mStation+mSignal);}private void initStation() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {initHigherStation();} else {initLowerStation(0, null);}}private Runnable mRefresh4G = new Runnable() {@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)@Overridepublic void run() {List<CellInfo> cell_list = mTelMgr.getAllCellInfo();if (cell_list==null || cell_list.size()==0) {mHandler.postDelayed(this, 1000);} else {refreshStation(cell_list);}}};private Runnable mRefresh = new Runnable() {@Overridepublic void run() {if (mTelMgr.getNetworkType()==Utils.TYPE_UNKNOWN || mTelMgr.getCellLocation()==null) {mHandler.postDelayed(this, 1000);} else {mDevice = String.format("%s\n 网络类型=%s %s", "", Utils.getNetworkTypeName(mTelMgr, mTelMgr.getNetworkType()), Utils.getClassName(mTelMgr, mTelMgr.getNetworkType()));initStation();}}};}

点击下载本文用到的手机事件(包括手机定位、获取基站和信号信息)的工程代码

点此查看Android开发笔记的完整目录

Android开发笔记(四十六)手机相关事件相关推荐

  1. 【Visual C++】游戏开发笔记四十六 浅墨DirectX教程十四 模板测试与镜面特效专场

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处.   文章链接: http://blog.csdn.net/zhmxy555/article/details/8632184 作者:毛星云( ...

  2. Android开发笔记(十六)秋千摇摆动画SwingAnimation

    上节博主介绍了AlphaAnimation和淡入淡出动画的使用,其实AlphaAnimation只是四种补间动画中的一种.那么为了加深对其他补间动画的理解,我想说说旋转动画RotateAnimatio ...

  3. Android开发笔记(一百六十四)仿京东首页的下拉刷新

    上一篇文章介绍了高仿京东的沉浸式状态栏,可是跟京东首页的头部轮播图相比,依然有三处缺憾: 1.京东的头部Banner上方,除了有悬浮着的状态栏,状态栏下面还有一行悬浮工具栏,内嵌扫一扫图标.搜索框,以 ...

  4. Android开发笔记(一百六十五)利用红外发射遥控电器

    红外遥控是一种无线控制技术,它具有功耗小.成本低.易实现等诸多优点,因而被各种电子设备特别是家用电器广泛采用,像日常生活中的电视遥控器.空调遥控器等等基本都采用红外遥控技术. 不过遥控器并不都是红外遥 ...

  5. Android开发笔记(一百六十二)蓝牙设备的连接与配对

    蓝牙是一种短距离无线通信技术,它由爱立信公司于1994年创制,原本想替代连接电信设备的数据线,但是后来发现它也能用于移动设备之间的数据传输,所以蓝牙技术在手机上获得了长足发展. 因为手机内部的通讯芯片 ...

  6. Android开发笔记(一百六十九)利用BottomNavigationView实现底部标签栏

    在Android Studio上创建官方默认的首屏标签页面很方便,首先右击需要添加标签栏的模块,在弹出的右键菜单中依次选择"New"--"Activity"-- ...

  7. Android开发笔记(一百六十六)H5通过WebView录像上传

    前面的博文< Android开发笔记(一百五十二)H5通过WebView上传图片>介绍了如何拍照上传给网页,不料客户又要求再加个摄像上传给网页.既然如此,那么再探讨一下如何实现这个摄像上传 ...

  8. Android开发笔记(一百六十)休眠模式下的定时器控制

    定时器AlarmManager常常用于需要周期性处理的场合,比如闹钟提醒.任务轮询等等.并且定时器来源于系统服务,即使App已经不在运行了,也能收到定时器发出的广播而被唤醒.似此回光返照的神技,便遭到 ...

  9. Android开发笔记(一百六十八)为应用绑定通知渠道并展示消息角标

    为了分清消息通知的轻重缓急,从Android8开始新增了通知渠道,并且必须指定通知渠道才能正常推送消息.一个应用允许拥有多个通知渠道,每个渠道的重要性各不相同,有的渠道消息在通知栏被折叠成小行,有的渠 ...

  10. Android开发笔记(十四)圆弧进度动画CircleAnimation

    一个好看的APP,都有不少精致的动画效果.熟练运用各种动画技术,可让我们的APP灼灼生辉.Android在技术上把动画分为了三类,分别是帧动画FrameAnimation.补间动画TweenAnima ...

最新文章

  1. java 3维_java 二维/三维/多维数组
  2. 《Visual Studio Hacks 》(十)
  3. MYSQL 深入浅出索引(下)
  4. java宝典_JAVA宝典之_JAVA基础
  5. Nginx文档阅读笔记-Reverse Proxy vs. Load Balancer(反向代理与负载均衡)
  6. 《指针的编程艺术(第二版)》一3.8 改错题
  7. SosoApi使用手册
  8. 分享一个很好的dll查看器
  9. 十大Excel函数(一)
  10. 在安卓模拟器(mumu为例)上联调app并且用Charles抓包
  11. 详解分级基金(杠杆基金)【精华】 【转】
  12. 判断用户flash是否安装了flash以及flash的版本
  13. 达达-京东到家面试总结
  14. Linux(Ubuntu)同步互联网时间(ntpdate)
  15. Android微信支付订单支付失败的问题
  16. pyqt-窗口最大化
  17. 微型计算机三部分基本组成,微型计算机的基本组成
  18. 没分啊,下载不了东西苦逼啊~!
  19. 焦点与焦距 (focal point, focal length)
  20. Educoder计算机数据表示实验(HUST)第5关:16位海明编码电路设计

热门文章

  1. 机器学习实战(五)支持向量机SVM(Support Vector Machine)
  2. PGPool使用限制
  3. 移动安全-iOS(一)
  4. 2019PKU\THU WC题解
  5. undefined reference to symbol' pthread_create@@GLIBC_2.2.5'
  6. focal loss dice loss源码_0815——W2V的TF源码阅读
  7. HttpClient工具类 HttpClientUtils.java
  8. 48个国际音标发音图解暨口形及发音方法
  9. c语言程序设计多个文件,c语言如何单文件变多文件(2个文件),求大神帮忙!!...
  10. 泉州海事学校计算机,泉州海事学校寝室图片、校园环境好吗?