ToolBar 修改菜单字体和颜色

# ToolBar基本使用 关于ToolBar的使用,网上已经非常多了, ** 思路决定出路 so, 思路是这样的: - 隐藏ActionBar,<strong>这里有两种设定方法** - 布局文件中声明, 没什么说的 - 代码中设定一下,没什么说的 可以参考这里学习: Android 5.x Theme 与 ToolBar 实战 Android Toolbar样式定制详解 ToolBar菜单 ToolBar使用菜单,思路长这样: ** 首先在menu/menu_main.xml去声明布局,然后重写onCreateOptionsMenu(inflate该布局)和onOptionsItemSelected(设定其点击事件)即可,当然也可以通过toolbar.setOnMenuItemClickListener实现点击menu的回调。 这里遇到个坑,我只需要有一个菜单,默认设定后颜色为黑色,和橙色的colorPrimary不搭调,然后想着设定为白色,没想到掉坑里去了,其实我不是一个人:[Android中菜单的字体太小了:设置actionbar中menu的text的size](http://www.crifan.com/android_menu_text_size_too_small/),这位大神很给力,尝试了各种方法,最后搞掂,思路清晰,粗暴但是不简单呐。 我直接从他的解决方法入手,开始搞,然而不是很靠谱,只能修改字体大小,颜色还是黑的,丑爆。 因此来到了这里:Android Toolbar样式定制详解, 方法就是<strong>`添加 ToolBar 主题`** 这个demo运行,完美解决,但是在我自己的项目里,一直出不来效果,一定是哪里出现了问题。。 没错,确实是我的问题,凡事还是多反思自己,我画蛇添足咯,多写了点东西,是什么呢,你们应该猜到了,我们来看: 首先敲定ToolBar布局,加一个theme: </android.support.v7.widget.Toolbar>" data-snippet-id="ext.563df2e6a04501bd3623452810697ad7" data-snippet-saved="false" data-codota-status="done">` &lt;span class="hljs-tag">&lt;&lt;span class="hljs-name">android.support.v7.widget.Toolbar&lt;/span> &lt;span class="hljs-attr">android:id&lt;/span>=&lt;span class="hljs-string">"@+id/toolbar"&lt;/span> &lt;span class="hljs-attr">android:layout_width&lt;/span>=&lt;span class="hljs-string">"match_parent"&lt;/span> &lt;span class="hljs-attr">android:layout_height&lt;/span>=&lt;span class="hljs-string">"?/attr/actionBarSize"&lt;/span> &lt;span class="hljs-attr">android:background&lt;/span>=&lt;span class="hljs-string">"?attr/colorPrimary"&lt;/span> &lt;span class="hljs-attr">app:theme&lt;/span>=&lt;span class="hljs-string">"@style/ToolbarTheme"&lt;/span>&gt;&lt;/span> &lt;span class="hljs-tag">&lt;/&lt;span class="hljs-name">android.support.v7.widget.Toolbar&lt;/span>&gt;&lt;/span>` 然后定义ToolBarTheme样式 注意,此处的坑较多,首先,要有个parent,然后actionMenuTextColor前面**不能有android前缀**,谁加谁怀孕,当然在values-v21/styles.xml里是需要添加android前缀的。 " data-snippet-id="ext.124cfa678dc23e56377d3d6a603f2c55" data-snippet-saved="false" data-codota-status="done"&gt;` &lt;span class="hljs-comment">&lt;!-- ToolBar菜单样式 --&gt;&lt;/span> &lt;span class="hljs-tag">&lt;&lt;span class="hljs-name">style&lt;/span> &lt;span class="hljs-attr">name&lt;/span>=&lt;span class="hljs-string">"ToolbarTheme"&lt;/span> &lt;span class="hljs-attr">parent&lt;/span>=&lt;span class="hljs-string">"@style/ThemeOverlay.AppCompat.ActionBar"&lt;/span>&gt;&lt;/span>&lt;span class="xml"> &lt;span class="hljs-tag">&lt;&lt;span class="hljs-name">item&lt;/span> &lt;span class="hljs-attr">name&lt;/span>=&lt;span class="hljs-string">"actionMenuTextColor"&lt;/span>&gt;&lt;/span>@color/white&lt;span class="hljs-tag">&lt;/&lt;span class="hljs-name">item&lt;/span>&gt;&lt;/span> &lt;span class="hljs-comment">&lt;!-- 敲定颜色--&gt;&lt;/span> &lt;span class="hljs-tag">&lt;&lt;span class="hljs-name">item&lt;/span> &lt;span class="hljs-attr">name&lt;/span>=&lt;span class="hljs-string">"android:textSize"&lt;/span>&gt;&lt;/span>18sp&lt;span class="hljs-tag">&lt;/&lt;span class="hljs-name">item&lt;/span>&gt;&lt;/span> &lt;span class="hljs-comment">&lt;!-- 搞掂字体大小--&gt; &lt;/span>&lt;/span>` &lt;item name="android:textAllCaps"&gt;false&lt;/item&gt; ` &lt;span class="hljs-tag">&lt;/&lt;span class="hljs-name">style&lt;/span>&gt;&lt;/span>` 好了,这样就可以了,ToolBar 修改菜单字体和颜色完成。 &lt;item name="android:textAllCaps"&gt;false&lt;/item&gt; 设置防止都是大写

2017年11月7日 · 1 分钟 · 天边的星星

动态更新Toolbar Menu以及Menu中同时显示文字和图标

我们经常会有这样的需求,在切换Fragment或者点击某个按钮后动态更新Toolbar上Menu项.但是onCreateOptionsMenu方法只在创建Activity的时候调用一次,以后就不再调用了,所以就不能在onCreateOptionsMenu中做处理了。 不过系统提供了另外的一个方法onPrepareOptionsMenu,我们可以在这个方法中做一些逻辑处理,然后在需要更新Menu的地方调用invalidateOptionsMenu方法。 效果图如下: 点击`管理专辑`按钮更换Menu, ![](http://images2015.cnblogs.com/blog/902237/201607/902237-20160720181845747-1609503965.png) ``` &lt;span class="fu">&lt;span class="hljs-meta">@Override&lt;/span>&lt;/span> &lt;span class="kw">&lt;span class="hljs-function">&lt;span class="hljs-keyword">public&lt;/span>&lt;/span>&lt;/span> &lt;span class="dt">&lt;span class="hljs-function">&lt;span class="hljs-keyword">boolean&lt;/span>&lt;/span>&lt;/span> &lt;span class="fu">&lt;span class="hljs-function">&lt;span class="hljs-title">onCreateOptionsMenu&lt;/span>&lt;/span>&lt;/span>&lt;span class="hljs-function">&lt;span class="hljs-params">(Menu menu)&lt;/span> &lt;/span>{ &lt;span class="fu">getMenuInflater&lt;/span>().&lt;span class="fu">inflate&lt;/span>(R.&lt;span class="fu">menu&lt;/span>.&lt;span class="fu">menu&lt;/span>, menu); &lt;span class="kw">&lt;span class="hljs-keyword">return&lt;/span>&lt;/span> &lt;span class="kw">&lt;span class="hljs-keyword">super&lt;/span>&lt;/span>.&lt;span class="fu">onCreateOptionsMenu&lt;/span>(menu); } </div> <div class="sourceCode"> <div class="top-box hide"> </div> ``` `&lt;span class="fu">&lt;span class="hljs-meta">@Override&lt;/span>&lt;/span> &lt;span class="kw">&lt;span class="hljs-function">&lt;span class="hljs-keyword">public&lt;/span>&lt;/span>&lt;/span> &lt;span class="dt">&lt;span class="hljs-function">&lt;span class="hljs-keyword">boolean&lt;/span>&lt;/span>&lt;/span> &lt;span class="fu">&lt;span class="hljs-function">&lt;span class="hljs-title">onPrepareOptionsMenu&lt;/span>&lt;/span>&lt;/span>&lt;span class="hljs-function">&lt;span class="hljs-params">(Menu menu)&lt;/span> &lt;/span>{ &lt;span class="kw">&lt;span class="hljs-keyword">if&lt;/span>&lt;/span> (mIsEditStatus) { menu.&lt;span class="fu">findItem&lt;/span>(R.&lt;span class="fu">id&lt;/span>.&lt;span class="fu">action_share&lt;/span>).&lt;span class="fu">setVisible&lt;/span>(&lt;span class="kw">&lt;span class="hljs-keyword">false&lt;/span>&lt;/span>); menu.&lt;span class="fu">findItem&lt;/span>(R.&lt;span class="fu">id&lt;/span>.&lt;span class="fu">action_edit&lt;/span>).&lt;span class="fu">setVisible&lt;/span>(&lt;span class="kw">&lt;span class="hljs-keyword">true&lt;/span>&lt;/span>); } &lt;span class="kw">&lt;span class="hljs-keyword">else&lt;/span>&lt;/span> { menu.&lt;span class="fu">findItem&lt;/span>(R.&lt;span class="fu">id&lt;/span>.&lt;span class="fu">action_share&lt;/span>).&lt;span class="fu">setVisible&lt;/span>(&lt;span class="kw">&lt;span class="hljs-keyword">true&lt;/span>&lt;/span>); menu.&lt;span class="fu">findItem&lt;/span>(R.&lt;span class="fu">id&lt;/span>.&lt;span class="fu">action_edit&lt;/span>).&lt;span class="fu">setVisible&lt;/span>(&lt;span class="kw">&lt;span class="hljs-keyword">false&lt;/span>&lt;/span>); } &lt;span class="kw">&lt;span class="hljs-keyword">return&lt;/span>&lt;/span> &lt;span class="kw">&lt;span class="hljs-keyword">super&lt;/span>&lt;/span>.&lt;span class="fu">onPrepareOptionsMenu&lt;/span>(menu); }` ``` `<span class="fu">invalidateOptionsMenu</span>(); <span class="co"><span class="hljs-comment">//重新绘制menu</span></span>` ``` 另外的一个需求是在Menu中要显示图标和文字,虽然在`menu.xml`文件中配置了图标和文字,但是在有图标的情况下文字是不会显示的,即使设置 `app:showAsAction="always|withText"` 但是我在运行的时候发现并没有显示文字,处理方法是通过另外一个属性实现`app:actionLayout`. 首先menu.xml定义如下: ...

2017年11月4日 · 3 分钟 · 天边的星星

在android studio3 问题汇总

在android studio3 下面,使用multiDexEnabled true造成导出的包缺少内容(support-v4) 如图:图一添加使用multiDexEnabled true,图二没有添加multiDexEnabled 有没有其他理想的解决方法,希望大家评论给我,谢谢 2.在build.gradle中忽略重复的引用,使用exclude(如果想在一个包忽略多个添加多行) 格式:implementation(‘引用的库’){ exclude group:’包名’,module:’模块名称(通常是包名后面和版本直接的内容)’ } 如果是 implementation project需要写成这种格式(把project扩在小括号中) implementation(project(‘……’)){ …同上 } 注意:可以单独使用group和module(推荐都写上) 例如: implementation(‘com.google.android:flexbox:0.2.3’) { exclude group: ‘com.android.support’, module: ‘appcompat-v7’ } 3. implementation 和compile 区别 (compile是被废弃了) 在AS3.0默认推荐使用implementation,如果依赖有问题使用api代替implementation, 更多参考:(自备梯子)https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html 或者:(不用梯子)https://developer.android.google.cn/studio/build/gradle-plugin-3-0-0-migration.html 4.所有项目使用指定库配置(更多请参考:http://www.jianshu.com/p/429733dbbc34) 例如: allprojects { repositories { jcenter() google() } configurations.all((Closure) { resolutionStrategy { force ‘com.android.support:support-v4:26.0.2’ // your version of support library } }) } 希望大家评论交流!!! 转自:http://www.zdltech.com/blogphp/archives/1335.html aapt2的作用说明 开启了aapt2后,资源的增量编译会加速编译速度,但是有些场景aapt2并不是很合适,因此必要的情况下,建议关闭aapt2,比如jenkins上构建时,我们并不需要增量编译,因此可以关闭,可以通过gradle参数达到关闭的效果,命令如下 1 gradle assembleRelease -Pandroid.enableAapt2=false 简单总结了几种不适合使用aapt2的场景 插件化和热修复中,需要使用public.xml的场景 构建过程,需要动态增删改资源的场景,如删除一部分线上不应该出现的资源

2017年11月3日 · 1 分钟 · 天边的星星

Android Studio3.0更新之路(遇坑必入)

序言:作为这个世界上走在最前沿的生物“猿”,怎么能对新事物一无所知呢,10月26日,随着Android 8.1 Oreo的预览版发布,Android Studio3.0正式版也发布了,作为Android开发的猿们我们应该早就知道谷歌在今年5月的开发者大会上就说了要支持Kotlin语言,所以这次更新一个比较大的点就在于支持Kotlin语言了,下面就跟着LZ的脚步来探索一下AS3.0吧 相信很多人很早就体验过谷歌爸爸放出来的体验版本了,虽然说正式版已经出了,但是很多人也不敢轻易贸然的更新,因为怕会掉进坑里出不来(真是一只胆小的猿,鉴定完毕) 安装 如果你从Android Studio内部点击更新的话,会跳转到Android的官网,没有梯子的同学可以去这个网站下载更新: ![Android Studio3.0更新之路(遇坑必入)](http://upload-images.jianshu.io/upload_images/490111-251c2b749c023786.jpg?imageMogr2/auto-orient/strip) Android Studio3.0正式版 安装过程中遇到的问题 1、Gradle Sync failed: `&lt;span class="typ">Gradle&lt;/span>&lt;span class="pln"> sync failed&lt;/span>&lt;span class="pun">:&lt;/span> &lt;span class="typ">Cause&lt;/span>&lt;span class="pun">:&lt;/span>&lt;span class="pln"> com&lt;/span>&lt;span class="pun">.&lt;/span>&lt;span class="pln">android&lt;/span>&lt;span class="pun">.&lt;/span>&lt;span class="pln">build&lt;/span>&lt;span class="pun">.&lt;/span>&lt;span class="pln">gradle&lt;/span>&lt;span class="pun">.&lt;/span>&lt;span class="pln">api&lt;/span>&lt;span class="pun">.&lt;/span>&lt;span class="typ">BaseVariant&lt;/span>&lt;span class="pun">.&lt;/span>&lt;span class="pln">getOutputs&lt;/span>&lt;span class="pun">()&lt;/span>&lt;span class="typ">Ljava&lt;/span>&lt;span class="pun">/&lt;/span>&lt;span class="pln">util&lt;/span>&lt;span class="pun">/&lt;/span>&lt;span class="typ">List&lt;/span>&lt;span class="pun">;&lt;/span> &lt;span class="typ">Consult&lt;/span>&lt;span class="pln"> IDE log &lt;/span>&lt;span class="kwd">for&lt;/span>&lt;span class="pln"> more details &lt;/span>&lt;span class="pun">(&lt;/span>&lt;span class="typ">Help&lt;/span> &lt;span class="pun">|&lt;/span> &lt;span class="typ">Show&lt;/span> &lt;span class="typ">Log&lt;/span>&lt;span class="pun">)&lt;/span> &lt;span class="pun">(&lt;/span>&lt;span class="lit">8s&lt;/span> &lt;span class="lit">123ms&lt;/span>&lt;span class="pun">)&lt;/span> ` 其实一开始不是这个错,最开始是一个redownload的一个错,后来LZ把2.3版本的给删了,缓存给清除了,然后就变成这个错了。既然有错,那就解决呗,顺手百度了一个,下面看看stackoverflow的解决方案 ...

2017年10月29日 · 2 分钟 · 天边的星星

Android USB转串口通信开发基本流程

好久没有写文章了,年前公司新开了一个项目,是和usb转串口通信相关的,需求是用安卓平板通过usb转接后与好几个外设进行通信,一直忙到最近,才慢慢闲下来,趁着这个周末不忙,记录下usb转串口通信开发的基本流程。 我们开发使用的是usb主机模式,即:安卓平板作为主机,usb外设作为从机进行数据通信。整个开发流程可以总结为以下几点: 1.发现设备 usbList = usbManager.getDeviceList();1 2 1 2 " data-snippet-id="ext.1d1481e9c3517ce217b699b6673dd389" data-snippet-saved="false" data-codota-status="done">`&lt;span class="typ">UsbManager&lt;/span>&lt;span class="pln"> usbManager &lt;/span>&lt;span class="pun">=&lt;/span> &lt;span class="pun">(&lt;/span>&lt;span class="typ">UsbManager&lt;/span>&lt;span class="pun">)&lt;/span>&lt;span class="pln"> context&lt;/span>&lt;span class="pun">.&lt;/span>&lt;span class="pln">getSystemService&lt;/span>&lt;span class="pun">(&lt;/span>&lt;span class="typ">Context&lt;/span>&lt;span class="pun">.&lt;/span>&lt;span class="pln">USB_SERVICE&lt;/span>&lt;span class="pun">);&lt;/span> &lt;span class="typ">Map&lt;/span>&lt;span class="pun">&lt;&lt;/span>&lt;span class="typ">String&lt;/span>&lt;span class="pun">,&lt;/span> &lt;span class="typ">UsbDevice&lt;/span>&lt;span class="pun">&gt;&lt;/span>&lt;span class="pln"> usbList &lt;/span>&lt;span class="pun">=&lt;/span>&lt;span class="pln"> usbManager&lt;/span>&lt;span class="pun">.&lt;/span>&lt;span class="pln">getDeviceList&lt;/span>&lt;span class="pun">();&lt;/span>` 通过UsbManager这个系统提供的类,我们可以枚举出当前连接的所有usb设备,我们主要需要的是UsbDevice对象,关于UsbDevice这个类,官方是这样注释的: `&lt;span class="typ">This&lt;/span> &lt;span class="kwd">class&lt;/span>&lt;span class="pln"> represents a USB device attached to the android device &lt;/span>&lt;span class="kwd">with&lt;/span>&lt;span class="pln"> the android device acting &lt;/span>&lt;span class="kwd">as&lt;/span>&lt;span class="pln"> the USB host&lt;/span>&lt;span class="pun">.&lt;/span>` 是的,这个类就代表了android所连接的usb设备。 ...

2017年10月19日 · 3 分钟 · 天边的星星

Android布局中的空格和占一个汉字宽度的空格的实现

在Android布局中进行使用到空格,以便实现文字的对齐。那么在android中如何表示一个空格呢? 注:下面的#160,#8201等等皆需要加上&方可实现效果 空格:#160; 窄空格:#8201; 一个汉字宽度的空格:#160;#160;#8201;,用两个空格(#160;#160;)占一个汉字的宽度时,两个空格比一个汉字略窄,三个空格(#160;#160;#160;)比一个汉字略宽 在实际使用中需要灵活使用#160;和#8201;的组合。 android:text=”真实姓名:” android:text=”身 份 证:” android:text=”姓 ‒名:” android:text=”身份证:” #8194;半个中文字更准确点, #8195;一个中文字但用起来会比中文字宽一点点。 所以中文对齐还是建议使用#8194;, 而#160; #8201;在不同机型有不同表现。 TextView实现首行缩进的方法: 在string资源文件中,在文字的前面加入”\u3000\u3000”即可实现首行缩进 在Java代码中,使用setText(“\u3000\u3000”+xxxxx); \u3000是全角空格的16进制Unicode编码。 \xa0代表 转自:http://blog.csdn.net/u014651216/article/details/52411113

2017年10月17日 · 1 分钟 · 天边的星星

android textview 自动换行 整齐排版

一、问题在哪里? textview显示长文字时会进行自动折行,如果遇到一些特殊情况,自动折行会杯具成这个样子: 上述特殊情况包括: 1)全角/半角符号混排(一般是数字、字母、汉字混排) 2)全角/半角标点符号出现在行首时,该标点符号会连同其前一个字符跳到下一行 3)英文单词不能被折成两行 4)…… 二、怎么搞? 通常有两类解决方案: 1)修改文本内容,将所有符号全角化、在标点符号前面加空格等等…… 2)保持文本内容不变,在合适的位置将文本手动分成多行 本文采用第二种方案,更加通用,也最大限度的保留了原文本。 三、开始干活 3.1 “在合适的位置将文本手动分成多行”需要知道textview的实际宽度、字体大小等信息,框架如下: ![复制代码](http://common.cnblogs.com/images/copycode.gif) 1 public class TestCActivity extends Activity { 2 private TextView mText; 3 4 @Override 5 protected void onCreate(Bundle savedInstanceState) { 6 super.onCreate(savedInstanceState); 7 8 setContentView(R.layout.testc); 9 10 mText = (TextView)findViewById(R.id.txt); 11 mText.setText("本文地址http://www.cnblogs.com/goagent/p/5159125.html本文地址啊本文。地址。啊http://www.cnblogs.com/goagent/p/5159125.html"); 12 mText.getViewTreeObserver().addOnGlobalLayoutListener(new OnTvGlobalLayoutListener()); 13 } 14 15 private class OnTvGlobalLayoutListener implements OnGlobalLayoutListener { 16 @Override 17 public void onGlobalLayout() { 18 mText.getViewTreeObserver().removeOnGlobalLayoutListener(this); 19 final String newText = autoSplitText(mText); 20 if (!TextUtils.isEmpty(newText)) { 21 mText.setText(newText); 22 } 23 } 24 } 25 26 private String autoSplitText(final TextView tv) { 27 final String rawText = tv.getText().toString(); 28 final Paint tvPaint = tv.getPaint(); 29 final int tvWidth = tv.getWidth() - tv.getPaddingLeft() - tv.getPaddingRight(); 30 31 //autoSplitText begin.... 32 String newText = rawText; 33 //autoSplitText end.... 34 35 return newText; 36 } 37 } ![复制代码](http://common.cnblogs.com/images/copycode.gif) 3.2 实现自动分割文本,简单来说就是用textview的paint逐字符测量,如果发现当前行绘制不下了,就手动加入一个换行符: ...

2017年10月16日 · 6 分钟 · 天边的星星

Android动态获取权限

前几天在网上找了找Android动态获取权限的文章和视频,自己整理了一下。几天看一位大神说真正的程序员是有着分享精神的,我这个刚刚入行的小菜鸟,也想把自己整理的东西分享给大家。 本文参考了A_si的Permission——郭霖认为最优的运行时权限方案和郭霖大神的CSDN视屏 在这之前,我们需要知道什么是权限? 权限是一种安全机制。Android权限主要用于限制应用程序内部某些具有限制性特性的功能使用以及应用程序之间的组件访问。 比如网络权限 " data-snippet-id="ext.1ecd4ff36f58d5c42638b9d887b68988" data-snippet-saved="false" data-codota-status="done">&lt;user-permission android:name="android.permission.INTERNET"/&gt;当我们的程序需要访问网络的时候,必须添加这个权限,不添加则无法访问网络。 这里还需要注意的是:在Android6.0之前,我们只需要在AndroidManifest.xml文件中直接添加权限即可,但是在Android6.0之后,我们只在AndroidManifest.xml文件中配置是不够的,还需要在Java代码中进行动态获取权限。当然这里不是所有的权限都需要动态获取,只需要获取危险权限就可以了。(毕竟Android权限100多种,要是每个都需要获取,那不累死开发人员啦) Android中的危险权限分为9组24种 ![](http://upload-images.jianshu.io/upload_images/3780051-92dda32c577e32cb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 1454742-2c2196fd438a4ed3.png 我们只需要在用这些权限的时候,才需要去动态申请,除这些之外的权限,我们只需要在AndroidManifest.xml文件种写上即可,动态申请的权限同样需要在AndroidManifest.xml文件中写。而且每一组种的权限只要有一个授权了,其他的也会自动授权 下面这张图是我们的build.gradle文件中的版本信息 ![](http://upload-images.jianshu.io/upload_images/3780051-e00a73adfc0a922a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) Image.png 1、targetSdkVersion版本号如果<= 21时,不需要动态处理权限 。但是有时候我们的应用程序会打不开。 2、如果是之前的老版本升级上来的,系统会默认开启之前所有的权限,比如之前的targetSdkVersion是21,后来升级之后变成了25,这个时候系统会自动授权。一定要记住是升级变成的25,否则还是需要授权。 Tips: 为什么SD卡读写权限是危险权限,能不能不申请权限但又能使用SD卡呢? (1)把SD权限设置为危险权限,是为了防止应用随便在用户的手机上些东西,如果不加防范,用户的SD卡就会有很多乱七八糟的东西。 (2)用户可以不申请权限而使用SD卡,但是只能使用系统提供的默认的路径。 我们可以使用Android系统提供的SDK目录。路径是Android\data\程序包名。这个目录是程序可以不需要经过 用户授权就可以直接使用,甚至不需要添加WRITE_EXTERNAL_STORAGE这个权限。 这个目录会在程序删除时也会直接删除。 如何访问这个目录呢? File file = getExternalCacheDir(); String s = file.getPath; 这个方法得到的是cache的路径,但是一般的垃圾清理软件都可以把这里面的数据清理掉 File[] files = getExternalCacheDirs(); 这个得到的是一个文件数组,要求Api最小19 如果我们不想垃圾清理软件把我们缓存的数据清理掉,则可以放在file文件下 getExternalFilesDir(“”); 这个表示所有的操作都是放在file目录下进行的 getExternalFilesDir(“mm”); 这个表示会在file目录下在见一个mm目录,然后所有的操作都会放在这个目录下。 下面我们来看如何动态获取权限!!! 先看最简单的,动态获取一个权限 比如现在要动态获取一个打电话的权限。。 首先需要在AndroidManifest.xml文件中写上这个权限 " data-snippet-id="ext.f281d8d8d9cfe2d283d570842a2b4c1e" data-snippet-saved="false" data-codota-status="done">&lt;user-permission android:name="android.premission.CALL_PHONE"/&gt; 然后在Java代码进行动态获取 请求授权的代码 ` &lt;span class="hljs-comment">/** * 请求授权 */&lt;/span> &lt;span class="hljs-function">&lt;span class="hljs-keyword">private&lt;/span> &lt;span class="hljs-keyword">void&lt;/span> &lt;span class="hljs-title">requestPermission&lt;/span>&lt;span class="hljs-params">()&lt;/span>&lt;/span>{ &lt;span class="hljs-keyword">if&lt;/span> (ContextCompat.checkSelfPermission(&lt;span class="hljs-keyword">this&lt;/span>, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED){ &lt;span class="hljs-comment">//表示未授权时&lt;/span> &lt;span class="hljs-comment">//进行授权&lt;/span> ActivityCompat.requestPermissions(&lt;span class="hljs-keyword">this&lt;/span>,&lt;span class="hljs-keyword">new&lt;/span> String[]{Manifest.permission.CALL_PHONE},&lt;span class="hljs-number">1&lt;/span>); }&lt;span class="hljs-keyword">else&lt;/span>{ &lt;span class="hljs-comment">//调用打电话的方法&lt;/span> makeCall(); } }` 请求之后,我们需要重写onRequestPermissionsResult这个方法 ...

2017年10月11日 · 8 分钟 · 天边的星星

Android apk反编译及重新打包流程

### 一、反编译代码 **1、**反编译java代码首先需要下载**dex2jar**这个工具,下载地址:[https://sourceforge.net/projects/dex2jar/files/](https://sourceforge.net/projects/dex2jar/files/) 目前最新版是2.0, 下载完后并解压缩。 2、将要反编译的apk文件重命名为zip格式并解压缩,注意其中的classes.dex文件,它存放了全部的java代码,将classes.dex文件拷贝到dex2jar解压后的根目录下。 **3、**打开cmd,进入dex2jar解压后的根目录,执行命令: ** d2j-dex2jar classes.dex 如下图: ![](http://upload-images.jianshu.io/upload_images/1633070-6fc5febd3f11a9ef.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <div class="image-caption"> dex2jar </div> 命令执行完后在对应目录下会生成<strong>classes-dex2jar.jar**文件 ![](http://upload-images.jianshu.io/upload_images/1633070-ba7fc87bb47cc64e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <div class="image-caption"> jar文件 </div> **4、**要查看java代码,还需要下载**jd-gui**这个工具,下载地址:[http://jd.benow.ca/](http://jd.benow.ca/),目前最新版是1.4.0,下载完后解压缩,并用**jd-gui.exe**打开上边反编译出来的jar文件: ![](http://upload-images.jianshu.io/upload_images/1633070-3bb77b39750f7562.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <div class="image-caption"> java code </div> 到此,已经顺利的反编译出了java代码 那资源文件呢,再回头看一下刚才apk文件对应的解压缩文件,所有的xml文件都是乱码,例如AndroidManifest.xml: ![](http://upload-images.jianshu.io/upload_images/1633070-2e019b033641d4d3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <div class="image-caption"> AndroidManifest.xml </div> 当然要还原原始的资源文件还是有办法的,继续往下看。 二、反编译资源 **1、**要反编译apk中的资源文件,就需要**apktool**这个工具了,下载地址:[http://ibotpeaches.github.io/Apktool/install/](http://ibotpeaches.github.io/Apktool/install/),进入下载页面: ![](http://upload-images.jianshu.io/upload_images/1633070-6715ef0d87edee56.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <div class="image-caption"> apktool download </div> 按照图中1、2两条的提示,下载**apktool.bat和apktool.jar**这两个文件,目前最新的apktool是2.1.1,并放到同一文件夹: ![](http://upload-images.jianshu.io/upload_images/1633070-e6e8d64f3519b021.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <div class="image-caption"> apktool </div> , **2、**将要反编译的apk文件放到apktool文件夹,打开cmd,进入apktool文件夹目录,执行命令: ...

2017年10月11日 · 2 分钟 · 天边的星星

Android java.security.NoSuchProviderException: no such provider: Crypto

由于项目的优化改进,用到AES+RSA加密传输数据。于是,在网上摘录了网友们的AES算法,如下: **public static byte**[] encrypt(**byte**[] raw, **byte**[] clear) **throws **Exception { SecretKeySpec skeySpec = **new **SecretKeySpec(raw, **"AES"**); Cipher cipher = Cipher.getInstance(**"AES"**); cipher.init(Cipher.***ENCRYPT_MODE***, skeySpec); **byte**[] encrypted = cipher.doFinal(clear); **return **encrypted; } **public static byte**[] decrypt(**byte**[] raw, **byte**[] encrypted) **throws **Exception { SecretKeySpec skeySpec = **new **SecretKeySpec(raw, **"AES"**); Cipher cipher = Cipher.getInstance(**"AES"**); cipher.init(Cipher.***DECRYPT_MODE***, skeySpec); **byte**[] decrypted = cipher.doFinal(encrypted); **return **decrypted; } **public static byte**[] getRawKey(**byte**[] seed) **throws **Exception { KeyGenerator kgen = KeyGenerator.getInstance(**"AES"**); SecureRandom sr = SecureRandom.getInstance(**"SHA1PRNG"**, **"Crypto"**); sr.setSeed(seed); kgen.init(128, sr); SecretKey skey = kgen.generateKey(); **byte**[] raw = skey.getEncoded(); **return **raw; } 一切正常的在Android 4.3-6.1的手机上加解密,但是我用 *LGE Nexus 5X (7.1.1 API 25)*上发现在Android N上 google去掉了**Crypto **provider,意味着我们将不能继续像上面那样对数据加密填充。当然,在studio里的Logcat里会提示前往关于Android N对Crypto的解决方案: http://Android-developers.blogspot.com/2016/06/security-crypto-provider-deprecated-in.html ...

2017年9月5日 · 2 分钟 · 天边的星星