Android炫酷应用300例读书笔记八

第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对联系人进行操作
https://www.jianshu.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 表
https://www.jianshu.com/p/93e25bb2ffe7

236.使用ContentResolver改变屏幕亮度值
237.使用ContentResolver设置屏幕亮度值
236和237综合一下。
参考链接:
Android设置屏幕亮度
https://www.jianshu.com/p/75815fb86f15

238.使用ContentResolver检测旋转屏幕功能

Settings.System.getInt(context.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION);

其实是判断自动旋转开关是否开启。这个只是获取一次,可能需求是需要监听。
参考链接:
Android只支持横屏旋转,监听自动旋转开关
https://www.jianshu.com/p/57e9e3bb3e5d

最后,ContentResolver大致总结可以看这篇。虽然部分内容过时了。

Android:关于ContentProvider的知识都在这里了!
https://www.jianshu.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实现分享功能
https://www.jianshu.com/p/612f569f5599
获取被禁用的应用
https://www.jianshu.com/p/08100e091142
PackageManager使用
https://www.cnblogs.com/xingfuzzhd/p/3374504.html

250.使用WifiManager开启或关闭WiFi信号
参考链接:
Android-WIFI功能-状态判断/开启/关闭
https://www.jianshu.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地址
https://www.jianshu.com/p/d98519faf7b6

252.使用ConnectivityManager判断网络状态
参考链接:
Android获取网络连接状态类型
https://www.jianshu.com/p/b4d4432b0633

253.使用BluetoothAdapter打开或关闭蓝牙
参考链接:
Android中蓝牙的基本使用----BluetoothAdapter类简介
https://blog.csdn.net/qinjuning/article/details/7726093
254.使用LocationListener获取当前经纬度值
Android中通过GPS或NetWork获取当前位置的经纬度
https://www.jianshu.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监听靠近听筒,音频播放切换听筒和外放
https://www.jianshu.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 横竖屏切换总结
https://www.jianshu.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,所以还是使用书上的例子。


image.png

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(震动器)的总结
https://www.jianshu.com/p/0b9f915f56bd

266.使用SurfaceView实现照相机的预览功能
267.使用Camera实现缩小和放大预览画面
268.使用Camera实现预览时摄像头手动对焦
android相机方面的开发都可以当一个专题去学了。因此这3个小节跳过。

269.从相册中选择图像并设置为手机壁纸
2个知识点,1.打开相册选中图像 2.设置手机壁纸,组合一下就可以了。
参考链接:
android从相册选择图片和拍照选择图片
https://www.jianshu.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 倒计时的五种实现方式
https://www.jianshu.com/p/e3c055a39e47
Android仿活动时分秒倒计时效果
https://www.jb51.net/article/134765.htm

272.使用Runtime执行系统命令静默安装应用包
本小节太过受限于root权限,而且现在设备也很难root,可能就应用于定制的设备,而且随着android版本的更新代码也可能会失效(个人猜测),因此跳过本小节。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,271评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,725评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,252评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,634评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,549评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,985评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,471评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,128评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,257评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,233评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,235评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,940评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,528评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,623评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,858评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,245评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,790评论 2 339

推荐阅读更多精彩内容