禁用自动更新

你可以在Android Studio的设置中禁用自动检查更新的功能。路径是 File > Settings > Appearance & Behavior > System Settings > Updates,然后取消勾选 Automatically check updates for

  1. 打开Android Studio,并点击顶部菜单中的“Help”选项。
  2. 在下拉菜单中选择“Edit Custom VM Options”。
  3. 在弹出的对话框中添加以下代码:
-DdisableAutomaticUpdate=true

这行代码的作用是告诉Android Studio禁用自动更新功能。

  1. 保存并关闭配置文件,然后重启Android Studio。

无法启动 Emulator

The emulator process for AVD Nexus_4_API_25 has terminated.

"C:\Users\joychen\AppData\Local\Google\AndroidStudio2021.1\log\idea.log"

尝试用命令调起模拟器

D:\worktools\Android\sdk\emulator\emulator.exe -netdelay none -netspeed full -avd 720pAPI27

其中 D:\worktools\Android\sdk\为SDK路径
720pAPI27 为模拟器的name。

提示 找不到 VCRUNTIME140_1.dll 。需要安装VC++ 2015.

控制台中文乱码

在help中找到Edit Custom VM Options… 并打开文件,在文件中添加-Dfile.encoding=UTF-8

去掉默认的标题栏

全部取消主题:
我们先在已建立的项目下找到main/res/values/style.xml,打开style.xml文件
然后我们将看到项目引用的Theme,其中parent="Theme.AppCompat.Light.DarkActionBar",这里显示了主题的继承。
改为parent="Theme.AppCompat.Light.NoActionBar"

themes.xml:

<style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar.Bridge">

单个取消主题:
就是在<activity 便签中同样存在android:theme="",里面的值同上

在代码中取消标题,在android studio中使用:

//请将以下代码写在 setContentView() 前面
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);

也可以自己写style进行引用

<style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>

</style>

在eclipse中使用:

requestWindowFeature(Window.FEATURE_NO_TITLE);

附带取消头部状态栏代码,状态栏为最上面的小黑条,显示着时间,电量什么的,手指按住可以下拉,eclipse下同

//同样写在setContentView()之上
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

在eclipse中使用:

android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

暂停

执行某个方法后,想停顿3秒,然后去执行另外一个 方法:

        //主代码
        new Thread() {
            public void run() {
                try {
                    Thread.sleep(5000);

                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                //停顿后执行代码写在这里
                //startActivity(new Intent("com.joychen.LoginActivity"));

            }

        }.start();

创建多个Activity

pass

Android MarginLeft与MarginStart的区别

在写layout布局的时候,我们会发现有这样几个比较相似的属性:

MarginStart MarginLeft

MarginEnd MarginRight

这些属性的区别是什么? 根据api注释,我们得知MarginStart指的是控件距离开头View部分的间距大小,MarginLeft则指的是控件距离左边View部分的间距大小,MarginEnd和MarginRight同理。

一般情况下,View开始部分就是左边,但是有的语言目前为止还是按照从右往左的顺序来书写的,例如阿拉伯语,在Android 4.2系统之后,Google在Android中引入了RTL布局,更好了支持了由右到左文字布局的显示,为了更好的兼容RTL布局,google推荐使用MarginStart和MarginEnd来替代MarginLeft和MarginRight,这样应用可以在正常的屏幕和由右到左显示文字的屏幕上都保持一致的用户体验。

以下内容摘自他人翻译的中文Android 4.2API:

Android 4.2引入了由右到左文字的全面本地支持布局。在本地RTL支持下,您可以为所有用户带来完美的应用体验,不论他们的文字书写方向是由左至右还是由右至左。

当用户切换系统语言到由右至左书写方式时,系统提供自动的应用UI布局和所有可视组件的镜像,包括文字元素的显示和输入。

您的应用仅需极少改变即可支持RTL布局镜像。如果您的应用支持这一特性,只要在您应用的manifest文件中将所有的”left/right”布局属性改变为对应的”start/end”即可。系统就会根据需要处理您UI了。

android布局

Android fill_parent、wrap_content和match_parent的区别

三个属性都用来适应视图的水平或垂直大小,一个以视图的内容或尺寸为基础的布局比精确地指定视图范围更加方便。

1)fill_parent

设置一个构件的布局为fill_parent将强制性地使构件扩展,以填充布局单元内尽可能多的空间。这跟Windows控件的dockstyle属性大体一致。设置一个顶部布局或控件为fill_parent将强制性让它布满整个屏幕。

2) wrap_content

设置一个视图的尺寸为wrap_content将强制性地使视图扩展以显示全部内容。以TextView和ImageView控件为例,设置为wrap_content将完整显示其内部的文本和图像。布局元素将根据内容更改大小。设置一个视图的尺寸为wrap_content大体等同于设置Windows控件的Autosize属性为True。

3)match_parent
Android2.2中match_parent和fill_parent是一个意思 .两个参数意思一样,match_parent更贴切,于是从2.2开始两个词都可以用。那么如果考虑低版本的使用情况你就需要用fill_parent了

Activity/Context转换

在 Android 中,ActivityContext 的子类,因此你可以在大多数情况下将 Activity 当作 Context 来使用。但是,有时候你需要明确地将 Context 转换为 Activity 类型,以便在 Activity 中使用特定的方法。

在转换 ContextActivity 类型时,你需要确保 Context 实际上是一个 Activity 的实例,否则会抛出 ClassCastException 异常。

Activity activity =(Activity) context;
TextView tv_tips = activity.findViewById(R.id.tv_tips);

Android 5.0系统默认颜色

伴随着 Android5.0 的发布也更新了support-v7-appcompat 到 V21,其中增加了 ToolBar、recyclerview、cardview 等控件。

Android5.0 对改变 APP 样式下了不小的功夫,写法也和以前不一样了,下面先简单介绍一下colorAccent,colorPrimary,colorPrimaryDark …… 的作用:

img

\1. colorPrimary:应用的主要色调,ActionBar 默认使用该颜色,Toolbar 导航栏的底色;

\2. colorPrimaryDark:应用的主要暗色调,statusBarColor默认使用该颜色;

\3. statusBarColor:状态栏颜色,默认使用colorPrimaryDark;

\4. windowBackground:窗口背景颜色;

\5. navigationBarColor:底部栏颜色;

\6. colorForeground:应用的前景色,ListView 的分割线,switch 滑动区默认使用该颜色;

\7. colorBackground:应用的背景色,popMenu 的背景默认使用该颜色;

\8. colorAccent:CheckBox,RadioButton,SwitchCompat 等一般控件的选中效果默认采用该颜色;

\9. colorControlNormal:CheckBox,RadioButton,SwitchCompat 等默认状态的颜色;

\10. colorControlHighlight:控件按压时的色调;

\11. colorControlActivated:控件选中时的颜色,默认使用 colorAccent;

\12. colorButtonNormal:默认按钮的背景颜色;

\13. editTextColor:默认EditView输入框字体的颜色;

\14. textColor:Button,TextView 的文字颜色;

\15. textColorPrimaryDisableOnly: RadioButton、Checkbox 等控件的文字;

\16. textColorPrimary:应用的主要文字颜色,ActionBar 的标题文字默认使用该颜色;

\17. colorSwitchThumbNormal: switch thumbs 默认状态的颜色 (switch off)。

Uri/PATH转换

String imagePath = "/storage/emulated/0/Download/example.jpg";
Uri uri = Uri.parse(imagePath);


Uri uri = Uri.parse("content://com.example.provider/files/example.jpg");
String filePath = uri.getPath();

这里的 uri 是文件的 URI,可以是来自任何来源,例如 FileProvider、MediaStore 等。然后,我们使用 getPath() 方法从 URI 中获取文件的路径。

需要注意的是,并非所有的 URI 都有一个对应的路径,特别是对于 content:// 类型的 URI,它们可能是由 ContentProvider 提供的虚拟 URI,而不是实际的文件路径。在这种情况下,您可能需要通过 ContentResolver 查询相关信息来获取文件的实际路径。

常用的定时器和延时方法

cp7719 于 2015-12-01 18:41:10 发布

通过实际项目的练习,掌握了几种android基本定时器和延时的用法,这里我想总结一下作为自己的收获,下面列出的是比较简洁的模式,方便简单地在程序中直接调用。
一、三种常用的定时器
1.Handler类的postDelayed方法:

写法1:
             Handler handler = new Handler();
                 Runnable runnable = new Runnable() {

                    @Override
                    public void run() {
                            //do something
                    }
                };


主线程中调用:  handler.postDelayed(runnable, 100);//延时100毫秒


写法2:
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                /**
                 *要执行的操作
                 */

                TextView tv = findViewById(R.id.tv);
                tv.setText("你好世界!");
            }
        }, 3000);//3秒后执行Runnable中的run方法

2.用handler+timer+timeTask方法:

      Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1){
                //do something
            }
            super.handleMessage(msg);
        }
    };

    Timer timer = new Timer();
    TimerTask timerTask = new TimerTask() {
        @Override
        public void run() {
            Message message = new Message();
            message.what = 1;
            handler.sendMessage(message);
        }
    };
 主线程中调用:timer.schedule(timerTask,1000,500);//延时1s,每隔500毫秒执行一次run方法

3.Thread+handler方法:

 Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1){
                //do something
            }
            super.handleMessage(msg);

        }
    };

    class MyThread extends Thread {//这里也可用Runnable接口实现
        @Override
        public void run() {
            while (true){
                try {
                    Thread.sleep(1000);//每隔1s执行一次
                    Message msg = new Message();
                    msg.what = 1;
                    handler.sendMessage(msg);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
    }
主线程中调用:new Thread(new MyThread()).start();

二、三种延时的快捷方法:
1.Handler的postDelayed方法:

new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
              //do something
          }
       }, 1000);    //延时1s执行

2.timer + TimerTask方法:

                 timer = new Timer();
                 timer.schedule(new TimerTask() {                   
                    @Override
                    public void run() {
                          //do something
                    }
                },1000);//延时1s执行

3.Thread方法:

        new Thread(new MyThread()).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);//延时1s
                    //do something
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

以上部分,都是实际项目中使用过的,同时这也是第一次写博客,如果有错误的地方,请大神们指正。准备写博客,是想把这块知识进行总结,同时也能加深自己对这部分的理解,希望以后能有更多的内容同大家分享。

颜色大全

使用方法:

将color.xml文件拷到res/values目录下后我们只需要R.xml文件名称.name名称就可以调用了(例如:R.color.red)

img

customer_colors.xml

使用技巧(快捷键)

自动补全代码

转载

实用设置

1、布局跳到代码:选中布局+Ctrl+B
2、清除无用包:Ctrl+Alt+O
3、自动整理代码格式:Ctrl+Alt+L
4、代码补全快捷键设置:File->Settings->Keymap->Main menu->Code->Completion:设置Basic为你想要自动补代码的快捷键
5、代码提示设置:File->Settings->Editor->General->Code Completion:Match case去掉勾选
6、代码提示快捷键设置:File->Settings->Keymap->Other->Class Name Completion:设置快捷键

必备快捷键

Alt+回车 导入包,自动修正

Ctrl+N 查找类

Ctrl+Shift+N 查找文件

Ctrl+Alt+L 格式化代码

Ctrl+Alt+O 优化导入的类和包

Alt+Insert 生成代码(如get,set方法,构造函数等)

Ctrl+E或者Alt+Shift+C 最近更改的代码

Ctrl+R 替换文本

Ctrl+F 查找文本

Ctrl+Shift+Space 自动补全代码

Ctrl+空格 代码提示

Ctrl+Alt+Space 类名或接口名提示

Ctrl+P 方法参数提示

Ctrl+Shift+Alt+N 查找类中的方法或变量

Alt+Shift+C 对比最近修改的代码

Shift+F6 重构-重命名

Ctrl+Shift+先上键

Ctrl+X 删除行

Ctrl+D 复制行

Ctrl+/ 或 Ctrl+Shift+/ 注释(// 或者 )

Ctrl+J 自动代码

Ctrl+E 最近打开的文件

Ctrl+H 显示类结构图

Ctrl+Q 显示注释文档

Alt+F1 查找代码所在位置

Alt+1 快速打开或隐藏工程面板

Ctrl+Alt+ left/right 返回至上次浏览的位置

Alt+ left/right 切换代码视图

Alt+ Up/Down 在方法间快速移动定位

Ctrl+Shift+Up/Down 代码向上/下移动。

F2 或Shift+F2 高亮错误或警告快速定位

代码标签输入完成后,按Tab,生成代码。

选中文本,按Ctrl+Shift+F7 ,高亮显示所有该文本,按Esc高亮消失。

Ctrl+W 选中代码,连续按会有其他效果

选中文本,按Alt+F3 ,逐个往下查找相同文本,并高亮显示。

Ctrl+Up/Down 光标跳转到第一行或最后一行下

Ctrl+B 快速打开光标处的类或方法

常用快捷键

1.Ctrl+E,可以显示最近编辑的文件列表

2.Shift+Click可以关闭文件

3.Ctrl+[或]可以跳到大括号的开头结尾

4.Ctrl+Shift+Backspace可以跳转到上次编辑的地方

5.Ctrl+F12,可以显示当前文件的结构

6.Ctrl+F7可以查询当前元素在当前文件中的引用,然后按F3可以选择

7.Ctrl+N,可以快速打开类

8.Ctrl+Shift+N,可以快速打开文件

9.Alt+Q可以看到当前方法的声明

10.Ctrl+W可以选择单词继而语句继而行继而函数

11.Alt+F1可以将正在编辑的元素在各个面板中定位

12.Ctrl+P,可以显示参数信息

13.Ctrl+Shift+Insert可以选择剪贴板内容并插入

14.Alt+Insert可以生成构造器/Getter/Setter等

15.Ctrl+Alt+V 可以引入变量。例如把括号内的SQL赋成一个变量

16.Ctrl+Alt+T可以把代码包在一块内,例如try/catch

17.Alt+Up and Alt+Down可在方法间快速移动

IntelliJ IDEA使用技巧一览表

在使用 InelliJ IDEA 的过程中,通过查找资料以及一些自己的摸索,发现这个众多 Java 程序员喜欢的 IDE 里有许多值得一提的小窍门,如果能熟练的将它们应用于实际开发过程中,相信它会大大节省你的开发时间,而且随之而来的还会有那么一点点成就感:) Try it !

1 、写代码时用 Alt-Insert ( Code|Generate… )可以创建类里面任何字段的 getter 与 setter 方法。

2 、右键点击断点标记(在文本的左边栏里)激活速查菜单,你可以快速设置 enable/disable 断点或者条件它的属性。

3 、 CodeCompletion (代码完成)属性里的一个特殊的变量是,激活 Ctrl-Alt-Space 可以完成在或不在当前文件里的类名。如果类没有引入则 import 标志会自动创建。

4 、使用 Ctrl-Shift-V 快捷键可以将最近使用的剪贴板内容选择插入到文本。使用时系统会弹出一个含有剪贴内容的对话框,从中你可以选择你要粘贴的部分。

5 、利用 CodeCompletion (代码完成)属性可以快速地在代码中完成各种不同地语句,方法是先键入一个类名地前几个字母然后再用 Ctrl-Space 完成全称。如果有多个选项,它们会列在速查列表里。

6 、用 Ctrl-/ 与 Ctrl-Shift-/ 来注释 / 反注释代码行与代码块。

-/ 用单行注释标记(“ //… ”)来注释 / 反注释当前行或者选择地代码块。而 Ctrl-Shift-/ 则可以用块注释标记(“ ”)把所选块包围起来。要反注释一个代码块就在块中任何一个地方按 Ctrl-Shift-/ 即可。

7 、按 Alt-Q ( View|Context Info )可以不需要移动代码就能查看当前方法地声明。连续按两次会显示当前所编辑的类名。

8 、使用 Refactor|Copy Class… 可以创建一个所选择的类的“副本”。这一点很有用,比如,在你想要创建一个大部分内容都和已存在类相同的类时。

9 、在编辑器里 Ctrl-D 可以复制选择的块或者没有所选块是的当前行。

10 、 Ctrl-W (选择字)在编辑器里的功能是先选择脱字符处的单词,然后选择源代码的扩展区域。举例来说,先选择一个方法名,然后是调用这个方法的表达式,然后是整个语句,然后包容块,等等。

11 、如果你不想让指示事件细节的“亮球”图标在编辑器上显示,通过按 Alt-Enter 组合键打开所有事件列表然后用鼠标点击它就可以把这个事件文本附件的亮球置成非活动状态。

这样以后就不会有指示特殊事件的亮球出现了,但是你仍然可以用 Alt-Enter 快捷键使用它。

12 、在使用 CodeCompletion 时,可以用逗点( . )字符,逗号(,)分号(;),空格和其它字符输入弹出列表里的当前高亮部分。选择的名字会随着输入的字符自动输入到编辑器里。

13 、在任何工具窗口里使用 Escape 键都可以把焦点移到编辑器上。

Shift-Escape 不仅可以把焦点移到编辑器上而且还可以隐藏当前(或最后活动的)工具窗口。

F12 键把焦点从编辑器移到最近使用的工具窗口。

14 、在调试程序时查看任何表达式值的一个容易的方法就是在编辑器中选择文本(可以按几次 Ctrl-W 组合键更有效地执行这个操作)然后按 Alt-F8 。

15 、要打开编辑器脱字符处使用的类或者方法 Java 文档的浏览器,就按 Shift-F1 (右键菜单的 External JavaDoc )。
要使用这个功能须要把加入浏览器的路径,在“ General ”选项中设置( Options | IDE Settings ),另外还要把创建的 Java 文档加入到工程中( File | Project Properties )。

16 、用 Ctrl-F12 ( View | File Structure Popup )键你可以在当前编辑的文件中快速导航。
这时它会显示当前类的成员列表。选中一个要导航的元素然后按 Enter 键或 F4 键。要轻松地定位到列表中的一个条目,只需键入它的名字即可。

17 、在代码中把光标置于标记符或者它的检查点上再按 Alt-F7 (右键菜单中的 Find Usages… )会很快地查找到在整个工程中使用地某一个类、方法或者变量的位置。

18 、按 Ctrl-N ( Go to | Class… )再键入类的名字可以快速地在编辑器里打开任何一个类。从显示出来的下拉列表里选择类。
同样的方法你可以通过使用 Ctrl-Shift-N ( Go to | File… )打开工程中的非 Java 文件。

19 、要导航代码中一些地方使用到的类、方法或者变量的声明,把光标放在查看项上再按 Ctrl-B 即可。也可以通过按 Ctrl 键的同时在查看点上单击鼠标键调转到声明处。

20 、把光标放到查看点上再按 Ctrl-Alt-B 可以导航到一个抽象方法的实现代码。

21 、要看一个所选择的类的继承层次,按 Ctrl-H ( Browse Type Hierarchy )即可。也可以激活编辑器中的继承关系视图查看当前编辑类的继承关系。22 、使用 Ctrl-Shift-F7 ( Search | Highlight Usages in File )可以快速高亮显示当前文件中某一变量的使用地方。按 Escape 清除高亮显示。

23 、用 Alt-F3 ( Search | Incremental Search )在编辑器中实现快速查查找功能。

在“ Search for: ”提示工具里输入字符,使用箭头键朝前和朝后搜索。按 Escape 退出。

24 、按 Ctrl-J 组合键来执行一些你记不起来的 Live Template 缩写。比如,键“ it ”然后按 Ctrl-J 看看有什么发生。

25 、 Introduce Variable 整合帮助你简化代码中复杂的声明。举个例子,在下面的代码片断里,在代码中选择一个表达式:然后按 Ctrl-Alt-V 。

26 、 Ctrl-Shift-J 快捷键把两行合成一行并把不必要的空格去掉以匹配你的代码格式。

27 、 Ctrl-Shift-Backspace ( Go to | Last Edit Location )让你调转到代码中所做改变的最后一个地方。

多按几次 Ctrl-Shift-Backspace 查看更深的修改历史。

28 、用 Tools | Reformat Code… 根据你的代码样式参考(查看 Options | IDE Setting | Code Style )格式化代码。

使用 Tools | Optimize Imports… 可以根据设置(查看 Options | IDE Setting | Code Style | Imports )自动“优化” imports (清除无用的 imports 等)。

29 、使用 IDEA 的 Live Templates | Live Templates 让你在眨眼间创建许多典型代码。比如,在一个方法里键入

再按 Tab 键看有什么事情发生了。

用 Tab 键在不同的模板域内移动。查看 Options | Live Templates 获取更多的细节。

30 、要查看一个文件中修改的本地历史,激活右键菜单里的 Local VCS | Show History… 。也许你可以导航不同的文件版本,看看它们的不同之处再回滚到以前的任何一个版本吧。

使用同样的右键菜单条目还可以看到一个目录里修改的历史。有了这个特性你就不会丢失任何代码了。

31 、如果要了解主菜单里每一个条目的用途,把鼠标指针移到菜单条目上再应用程序框架的底部的状态栏里就会显示它们的一些简短描述,也许会对你有帮助。

32 、要在编辑器里显示方法间的分隔线,打开 Options | IDE Settings | Editor ,选中“ Show method separators ”检查盒( checkbox )。

33 、用 Alt-Up 和 Alt-Down 键可以在编辑器里不同的方法之间快速移动。

34 、用 F2/Shift-F2 键在高亮显示的语法错误间跳转。

用 Ctrl-Alt-Down/Ctrl-Alt-Up 快捷键则可以在编译器错误信息或者查找操作结果间跳转。

35 、通过按 Ctrl-O ( Code | Override Methods… )可以很容易地重载基本类地方法。

要完成当前类 implements 的(或者抽象基本类的)接口的方法,就使用 Ctrl-I ( Code | Implement Methods… )。

36 、如果光标置于一个方法调用的括号间,按 Ctrl-P 会显示一个可用参数的列表。

37 、要快速查看编辑器脱字符处使用的类或方法的 Java 文档,按 Ctrl-Q (在弹出菜单的 Show Quick JavaDoc 里)即可。

38 、像 Ctrl-Q ( Show Quick JavaDoc 显示简洁 Java 文档), Ctrl-P ( Show Parameter Info 显示参数信息), Ctrl-B ( Go to Declaration 跳转到声明), Shift-F1 ( External JavaDoc 外部 Java 文档)以及其它一些快捷键不仅可以在编辑器里使用,也可以应用在代码完成右键列表里。

39 、 Ctrl-E ( View | Recent Files )弹出最近访问的文件右键列表。选中文件按 Enter 键打开。

40 、在 IDEA 中可以很容易地对你的类,方法以及变量进行重命名并在所有使用到它们的地方自动更正。

试一下,把编辑器脱字符置于任何一个变量名字上然后按 Shift-F6 ( Refactor | Rename… )。在对话框里键入要显示地新名字再按 Enter 。你会浏览到使用这个变量地所有地方然后按“ Do Refactor ”按钮结束重命名操作。

41 、要在任何视图( Project View 工程视图, Structure View 结构视图或者其它视图)里快速

选择当前编辑地部分(类,文件,方法或者字段),按 Alt-F1 ( View | Select in… )。

42 、在“ new ”字符后实例化一个已知类型对象时也许你会用到 SmartType 代码完成这个特性。比如,键入

再按 Ctrl-Shift-Space :

43 、通过使用 SmartType 代码完成,在 IDEA 中创建接口的整个匿名 implementation 也是非常容易的,比如,对于一些 listener (监听器),可以键入

Component component;  
component.addMouseListener(  
  new 
);1.2.3.4.

然后再按 Ctrl-Shift-Space 看看有什么发生了。

44 、在你需要设置一个已知类型的表达式的值时用 SmartType 代码完成也很有帮助。比如,键入

String s = (1.

再按 Ctrl-Shift-Space 看看会有什么出现。

45 、在所有视图里都提供了速查功能:在树里只需键入字符就可以快速定位到一个条目。

46 、当你想用代码片断捕捉异常时,在编辑器里选中这个片断,按 Ctrl-Alt-T ( Code | Surround with… )然后选择“ try/catch ”。它会自动产生代码片断中抛出的所有异常的捕捉块。在 Options | File Templates | Code tab 中你还可以自己定制产生捕捉块的模板。

用列表中的其它项可以包围别的一些结构。

47 、在使用代码完成时,用 Tab 键可以输入弹出列表里的高亮显示部分。

不像用 Enter 键接受输入,这个选中的名字会覆盖掉脱字符右边名字的其它部分。这一点在用一个方法或者变量名替换另一个时特别有用。

48 、在声明一个变量时代码完成特性会给你显示一个建议名。比如,开始键入“ private FileOutputStream ”然后按 Ctrl-Space。

返回主页

Android 读取手机短信

获取android手机短信需要在AndroidManifest.xml加权限:

<uses-permission android:name="android.permission.READ_SMS" />

检查是否已经获得了读取短信的权限。如果权限已经被授予(即返回值为 PackageManager.PERMISSION_GRANTED),我们可以执行读取短信的操作;否则,我们使用 ActivityCompat.requestPermissions() 方法向用户请求权限。

    // 需要在类中声明 REQUEST_CODE_READ_SMS 变量。
    private static final int REQUEST_CODE_READ_SMS = 123; // 添加此行

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
            // 如果没有权限,则向用户请求权限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, REQUEST_CODE_READ_SMS);
        }

获取短信只需要得到ContentResolver就行了,它的URI主要有:

content://sms/        所有短信
content://sms/inbox    收件箱
content://sms/sent      已发送
content://sms/draft     草稿
content://sms/outbox   发件箱
content://sms/failed    发送失败
content://sms/queued  待发送列表

SMS数据库中的字段如下:

_id 一个自增字段,从1开始
thread_id 序号,同一发信人的id相同
address 发件人手机号码
person 联系人列表里的序号,陌生人为null
date 发件日期
protocol 协议,分为: 0 SMS_RPOTO, 1 MMS_PROTO
read 是否阅读 0未读, 1已读
status 状态 -1接收,0 complete, 64 pending, 128 failed
type ALL = 0;INBOX = 1;SENT = 2;DRAFT = 3;OUTBOX = 4;FAILED = 5; QUEUED = 6;
body 短信内容
service_center 短信服务中心号码编号。如+8613800755500
subject 短信的主题
reply_path_present TP-Reply-Path
locked

DEMO

package com.lmy.sms;

import android.Manifest;
import android.content.pm.PackageManager;

import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.ScrollView;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

public class SmsReadActivity extends AppCompatActivity {

    private static final int REQUEST_CODE_READ_SMS = 123; // 添加此行

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
            // 如果没有权限,则向用户请求权限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, REQUEST_CODE_READ_SMS);
        }

        TextView tv = new TextView(this);
        tv.setText(getSmsInPhone());

        ScrollView sv = new ScrollView(this);
        sv.addView(tv);

        setContentView(sv);
    }

    public String getSmsInPhone() {
        final String SMS_URI_ALL = "content://sms/"; // 所有短信
        final String SMS_URI_INBOX = "content://sms/inbox"; // 收件箱
        final String SMS_URI_SEND = "content://sms/sent"; // 已发送
        final String SMS_URI_DRAFT = "content://sms/draft"; // 草稿
        final String SMS_URI_OUTBOX = "content://sms/outbox"; // 发件箱
        final String SMS_URI_FAILED = "content://sms/failed"; // 发送失败
        final String SMS_URI_QUEUED = "content://sms/queued"; // 待发送列表

        StringBuilder smsBuilder = new StringBuilder();

        Map<Integer, String> map = new HashMap<>();

        // 向Map中添加键值对
        map.put(1, "接收");
        map.put(2, "发送");
        map.put(3, "草稿");
        map.put(4, "发件箱");
        map.put(5, "发送失败");
        map.put(6, "待发送");
        map.put(0, "所有短信");

        try {
            Uri uri = Uri.parse(SMS_URI_INBOX);
            String[] projection = new String[] { "_id", "address", "person","body", "date", "type", };
            Cursor cur = getContentResolver().query(uri, projection, null,
                    null, "date desc"); // 获取手机内部短信
            // 获取短信中最新的未读短信
            // Cursor cur = getContentResolver().query(uri, projection,
            // "read = ?", new String[]{"0"}, "date desc");
            if (cur.moveToFirst()) {
                int index_Address = cur.getColumnIndex("address");
                int index_Person = cur.getColumnIndex("person");
                int index_Body = cur.getColumnIndex("body");
                int index_Date = cur.getColumnIndex("date");
                int index_Type = cur.getColumnIndex("type");

                do {
                    String strAddress = cur.getString(index_Address);
                    int intPerson = cur.getInt(index_Person);
                    String strbody = cur.getString(index_Body);
                    long longDate = cur.getLong(index_Date);
                    int intType = cur.getInt(index_Type);

                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    Date d = new Date(longDate);
                    String strDate = dateFormat.format(d);

                    smsBuilder.append("[ ");
                    smsBuilder.append(strAddress + ", ");
                    smsBuilder.append(intPerson + ", ");
                    smsBuilder.append(strbody + ", ");
                    smsBuilder.append(strDate + ", ");
                    smsBuilder.append(map.get(intType));
                    smsBuilder.append(" ]\n\n");
                } while (cur.moveToNext());

                if (!cur.isClosed()) {
                    cur.close();
                    cur = null;
                }
            } else {
                smsBuilder.append("no result!");
            }

            smsBuilder.append("getSmsInPhone has executed!");

        } catch (SQLiteException ex) {
            Log.d("SQLiteException in getSmsInPhone", ex.getMessage());
        }

        return smsBuilder.toString();
    }
}