第8章系统和设备
227.使用QuickContactBadge访问联系人
参考链接:
Android界面编程之QuickContactBadge(一幅图片关联到手机上的一个联系人)
https://blog.csdn.net/feiqinbushizheng/article/details/78822713
QuickContactBadge
https://developer.android.google.cn/reference/android/widget/QuickContactBadge.html?hl=en
QuickContactBadge这个类用的还是比较少的。
228.使用ContentProviderOperation增加联系人
229.使用ContentProviderOperation修改联系人
230.使用ContentProviderOperation删除联系人
228,229和230可以综合成使用ContentProviderOperation对联系人进行操作
参考链接:
Android利用ContentProvider对联系人进行操作
//www.greatytc.com/p/f63333fde0ba
231.使用ContentResolver检测飞行模式的状态
参考链接:
Android飞行模式的开启和状态获取
https://blog.csdn.net/cshoney/article/details/89524644
232.使用ContentResolver检测手机的时间格式
ContentResolver cv = this.getContentResolver();
String strTimeFormat = android.provider.Settings.System.getString(cv,
android.provider.Settings.System.TIME_12_24);
参考链接:
android.provider.Settings.System.TIME_12_24,有可能是三种,有一种是NULL
233.使用ContentResolver获取所有短信
234.使用ContentResolver获取通话记录
233和234合并一下。
参考链接:
使用ContentResolver读取通话记录与短信记录
https://blog.csdn.net/sinat_35238857/article/details/51945800
235.使用ContentResolver获取SD卡的文件
这里有2个知识点,一个是使用ContentResolver读取外部sd卡文件,一个是使用ContentResolver查询指定文件时所需mimeType。
Cursor cursor = resolver.query(MediaStore.Files.getContentUri("external"),null,"mime_type=\"text/plain\"", null, null);
需要查找txt后缀文件时传入text/plain,需要查找png后缀文件时传入image/png。
使用ContentResolver查询SD卡中特定的文件
https://blog.csdn.net/qq_33667176/article/details/68065710
常用mimeType 表
//www.greatytc.com/p/93e25bb2ffe7
236.使用ContentResolver改变屏幕亮度值
237.使用ContentResolver设置屏幕亮度值
236和237综合一下。
参考链接:
Android设置屏幕亮度
//www.greatytc.com/p/75815fb86f15
238.使用ContentResolver检测旋转屏幕功能
Settings.System.getInt(context.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION);
其实是判断自动旋转开关是否开启。这个只是获取一次,可能需求是需要监听。
参考链接:
Android只支持横屏旋转,监听自动旋转开关
//www.greatytc.com/p/57e9e3bb3e5d
最后,ContentResolver大致总结可以看这篇。虽然部分内容过时了。
Android:关于ContentProvider的知识都在这里了!
//www.greatytc.com/p/ea8bc4aaf057
239.使用BroadcastReceiver监听来电电话号码
这里2个知识点,一个是BroadcastReceiver的使用,另一个通过是TelephonyManager获取incoming number。
//获取number
TelephonyManager.EXTRA_INCOMING_NUMBER
参考链接:
Android Manager之TelephonyManager(电话管理器)
https://blog.csdn.net/weixin_37730482/article/details/80536756
BroadCastReceiver(广播接收者的静态注册)简单使用例子
https://my.oschina.net/u/2542711/blog/615908
240.使用BroadcastReceiver判断手机电池是否正在充电
参考链接:
Android 判断电池是否为充电状态的方法
https://blog.csdn.net/su749520/article/details/83580829
241.使用BroadcastReceiver监听屏幕开启或关闭
参考链接:
通过广播来监听屏幕点亮和关闭状态
242.自定义BroadcastReceiver实现短信拦截
参考链接:
Android的BroadcastReceiver 广播 短信拦截
243.使用RingtoneManager设置手机闹钟铃声
244.使用RingtoneManager设置手机通知铃声
243和244合并一下。
参考链接:
Android RingtoneManager 铃声管理
245.使用AlarmManager以指定时间执行操作
参考链接:
定时任务,AlarmManager使用
https://blog.csdn.net/wei_chong_chong/article/details/51258336
246.使用AudioManager获取和设置音量
参考链接:
调节音量的各个方法——AudioManager的使用
247.使用PowerManager实现屏幕一直亮着
书上的方式,官方其实已经不推荐使用了。推荐使用在Window设置flag
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
参考链接:
Android让屏幕保持常亮的三种方法
https://blog.csdn.net/superxlcr/article/details/78822544
248.使用WallpaperManager设置壁纸
参考链接:
WallpaperManager(壁纸管理器)
https://www.runoob.com/w3cnote/android-tutorial-wallpapermanager.html
249.使用PackageManager获取支持分享的应用
2个知识点,判断应用支持分享和PackageManager.queryIntentActivities获取符合条件的应用。
使用PackageManager.COMPONENT_ENABLED_STATE_DEFAULT会提示有问题,所以我用0代替了。
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(Intent.ACTION_SEND,null);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setType("text/plain");
PackageManager packageManager = getPackageManager();
List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent,0);
for (int i = 0; i < resolveInfoList.size(); i++){
Log.d("MainActivity"," packageName = " + resolveInfoList.get(i).activityInfo.packageName);
}
}
}
运行结果如下所示。
09-30 10:53:45.009 16472-16472/? D/MainActivity: packageName = com.android.bluetooth
09-30 10:53:45.009 16472-16472/? D/MainActivity: packageName = com.android.email
09-30 10:53:45.009 16472-16472/? D/MainActivity: packageName = com.android.mms
09-30 10:53:45.009 16472-16472/? D/MainActivity: packageName = com.miui.notes
09-30 10:53:45.009 16472-16472/? D/MainActivity: packageName = com.miui.personalassistant
09-30 10:53:45.010 16472-16472/? D/MainActivity: packageName = com.autonavi.minimap
09-30 10:53:45.010 16472-16472/? D/MainActivity: packageName = com.tencent.mm
09-30 10:53:45.010 16472-16472/? D/MainActivity: packageName = com.tencent.mm
参考链接:
Android利用intent实现分享功能
//www.greatytc.com/p/612f569f5599
获取被禁用的应用
//www.greatytc.com/p/08100e091142
PackageManager使用
https://www.cnblogs.com/xingfuzzhd/p/3374504.html
250.使用WifiManager开启或关闭WiFi信号
参考链接:
Android-WIFI功能-状态判断/开启/关闭
//www.greatytc.com/p/48d30c890ae4
251.使用WifiManager获取IP地址
public class IpUtils {
public static String getIPAddress(Context context) {
NetworkInfo info = ((ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
if (info != null && info.isConnected()) {
if (info.getType() == ConnectivityManager.TYPE_MOBILE) { // 当前使用2G/3G/4G网络
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
return inetAddress.getHostAddress();
}
}
}
} catch (SocketException e) {
e.printStackTrace();
}
} else if (info.getType() == ConnectivityManager.TYPE_WIFI) { // 当前使用无线网络
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
String ipAddress = intIP2StringIP(wifiInfo.getIpAddress()); // 得到IPV4地址
return ipAddress;
}
} else {
// 当前无网络连接,请在设置中打开网络
}
return null;
}
/**
* 将得到的int类型的IP转换为String类型
*
* @param ip
* @return
*/
public static String intIP2StringIP(int ip) {
return (ip & 0xFF) + "." +
((ip >> 8) & 0xFF) + "." +
((ip >> 16) & 0xFF) + "." +
(ip >> 24 & 0xFF);
}
}
参考链接:
安卓手机获取IP地址
//www.greatytc.com/p/d98519faf7b6
252.使用ConnectivityManager判断网络状态
参考链接:
Android获取网络连接状态类型
//www.greatytc.com/p/b4d4432b0633
253.使用BluetoothAdapter打开或关闭蓝牙
参考链接:
Android中蓝牙的基本使用----BluetoothAdapter类简介
https://blog.csdn.net/qinjuning/article/details/7726093
254.使用LocationListener获取当前经纬度值
Android中通过GPS或NetWork获取当前位置的经纬度
//www.greatytc.com/p/05f85f2f74c1
255.使用SensorManager获取传感器信息
参考链接:
Android学习笔记--获取传感器信息https://www.cnblogs.com/gnivor/p/4736103.html
256.使用传感器监测耳朵与手机听筒的距离
简单使用:
传感器Sensor的使用-距离感应(听筒模式)https://www.cnblogs.com/xiayexingkong/p/3986043.html
延伸:
Android监听靠近听筒,音频播放切换听筒和外放
//www.greatytc.com/p/39f6368b23ca
257.使用加速度传感器监听手机的三维变化
258.通过传感器实现自动进行横屏和竖屏切换
参考链接:
Android开发之传感器(加速度传感器、方向传感器)
https://blog.csdn.net/yaojie5519/article/details/81027909
259.使用setRequestedOrientation()实现横屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//横屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏
参考链接:
Android 横竖屏切换总结
//www.greatytc.com/p/52aa3a2c0417
260.根据手机是横屏或是竖屏进行控件布局
这里的书中介绍的知识点是onConfigurationChanged函数中判断横屏还是竖屏。
Configuration.ORIENTATION_LANDSCAPE。横屏
Configuration.ORIENTATION_PORTRAIT。竖屏
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
String screen = newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE?"横屏":"竖屏";
Toast.makeText(MainActivity.this, "系统屏幕方向发生改变 \n 修改后的方向为" + screen, Toast.LENGTH_SHORT).show();
}
参考链接:
响应系统设置的事件(Configuration类)
261.使用FLAG_FULLSCREEN标志实现全屏显示
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//去除标题
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
//全屏显示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
}
}
参考链接:
requestWindowFeature(Window.FEATURE_NO_TITLE)无效解决方法
https://blog.csdn.net/gaara_lee/article/details/51915710
262.使用Display获取屏幕宽度和高度
public class MainActivity extends AppCompatActivity{
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
int height = dm.heightPixels;
Log.d(TAG,"width = " + width + ",height = " + height);
}
}
263.使用StatFs获取内部总空间和可用空间大小
参考链接:
Android获取外部和内部存储空间总大小和可用大小
https://blog.csdn.net/pathfinder163/article/details/5941382
264.使用GestureDetector实现纵向滑动切换
参考链接是横向的,书上是纵向的,差别就是一个取y轴坐标,一个取x轴坐标去进行判断。
参考链接:
利用GestureDetector快速实现页面切换滑动效果
https://blog.csdn.net/linxi7/article/details/51124050
265.自定义手机振动器(Vibrator)的振动模式
public void vibrate(long[] pattern, int repeat)废弃了。书上的例子在android 8及以上不能用。但是由于我现在运行环境是android7,所以还是使用书上的例子。
manifest中先加入权限。
<uses-permission android:name="android.permission.VIBRATE"/>
public class MainActivity extends AppCompatActivity{
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
long[] pattern = {3000,1000,2000,5000,3000,1000};
vibrator.vibrate(pattern,-1);
}
}
pattern 表示的含义是 等待3s后,震动1s,再等待2s,震动5s,再等待3s,震动1s。
VibrationEffect使用具体使用看这里。
参考链接:
Vibraotr(震动器)的总结
//www.greatytc.com/p/0b9f915f56bd
266.使用SurfaceView实现照相机的预览功能
267.使用Camera实现缩小和放大预览画面
268.使用Camera实现预览时摄像头手动对焦
android相机方面的开发都可以当一个专题去学了。因此这3个小节跳过。
269.从相册中选择图像并设置为手机壁纸
2个知识点,1.打开相册选中图像 2.设置手机壁纸,组合一下就可以了。
参考链接:
android从相册选择图片和拍照选择图片
//www.greatytc.com/p/f13dfd5a823e
WallpaperManager(壁纸管理器)
https://www.runoob.com/w3cnote/android-tutorial-wallpapermanager.html
270.使用Runnable间隔执行重复的任务
书中的例子类似于下面的链接中的第二种方法:通过Handler和Runnable实现循环
参考链接:
学习如何每隔一段时间定时重复执行任务
https://blog.csdn.net/violetjack0808/article/details/50982604
271.使用Timer实现促销活动的倒计时功能
<LinearLayout 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:gravity="center"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="离结束时间为:"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<TextView
android:id="@+id/text_view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/text_view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/text_view3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
利用Runnable 和Handler 如下所示。
public class MainActivity extends AppCompatActivity{
private static final String TAG = "MainActivity";
private TextView mTextView1,mTextView2,mTextView3;
private long time = 600;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView1 = (TextView) findViewById(R.id.text_view1);
mTextView2 = (TextView) findViewById(R.id.text_view2);
mTextView3 = (TextView) findViewById(R.id.text_view3);
handler.postDelayed(runnable, 1000);
}
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
time--;
String formatLongToTimeStr = formatLongToTimeStr(time);
String[] split = formatLongToTimeStr.split(":");
for (int i = 0; i < split.length; i++) {
if(i==0){
mTextView1.setText(split[0]+"小时");
}
if(i==1){
mTextView2.setText(split[1]+"分钟");
}
if(i==2){
mTextView3.setText(split[2]+"秒");
}
}
if(time>0){
handler.postDelayed(this, 1000);
}
}
};
public String formatLongToTimeStr(Long l) {
int hour = 0;
int minute = 0;
int second = 0;
second = l.intValue() ;
if (second > 60) {
minute = second / 60; //取整
second = second % 60; //取余
}
if (minute > 60) {
hour = minute / 60;
minute = minute % 60;
}
String strTime = hour+":"+minute+":"+second;
return strTime;
}
}
利用Timer 如下所示。
public class MainActivity extends AppCompatActivity{
private static final String TAG = "MainActivity";
private TextView mTextView1,mTextView2,mTextView3;
private long time = 600;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView1 = (TextView) findViewById(R.id.text_view1);
mTextView2 = (TextView) findViewById(R.id.text_view2);
mTextView3 = (TextView) findViewById(R.id.text_view3);
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
time--;
String formatLongToTimeStr = formatLongToTimeStr(time);
String[] split = formatLongToTimeStr.split(":");
for (int i = 0; i < split.length; i++) {
if(i==0){
mTextView1.setText(split[0]+"小时");
}
if(i==1){
mTextView2.setText(split[1]+"分钟");
}
if(i==2){
mTextView3.setText(split[2]+"秒");
}
}
if (time <= 0){
timer.cancel();
}
}
});
}
},1000,1000);
}
public String formatLongToTimeStr(Long l) {
int hour = 0;
int minute = 0;
int second = 0;
second = l.intValue() ;
if (second > 60) {
minute = second / 60; //取整
second = second % 60; //取余
}
if (minute > 60) {
hour = minute / 60;
minute = minute % 60;
}
String strTime = hour+":"+minute+":"+second;
return strTime;
}
}
参考链接:
Android 倒计时的五种实现方式
//www.greatytc.com/p/e3c055a39e47
Android仿活动时分秒倒计时效果
https://www.jb51.net/article/134765.htm
272.使用Runtime执行系统命令静默安装应用包
本小节太过受限于root权限,而且现在设备也很难root,可能就应用于定制的设备,而且随着android版本的更新代码也可能会失效(个人猜测),因此跳过本小节。