移动开发

Android实现暗透明背景的页面

项目要求做一个对话框样式的页面,仅页面上的文字和按钮可见,背景效果和对话框类似。下面看看怎么实现: 方案一: 首先实现一个继承自对话框样式的主题: @android:color/transparent的值为#00000000。前两个00表示透明度,后6位为RGB值。#00000000表示全透明的黑色。 然后把这个主题应用到activity: <activity android:name=".activity.TestActivity" android:theme="@style/DarkTransParent" /> 这个activity不用做别的设置,布局文件里仅包含一个TextView和一个Button。 如果在布局文件里给它们设置了背景色,则背景色也会显示出来。 效果如下: 但是这个方法有缺点: 1. 页面布局会被自动调整,不易控制。 2. 背景的暗色不好改。 所以尝试了一种新的方案: 方案二: 继承系统的透明主题,然后自定义windowBackground属性: <style name="DarkTransParent" parent="android:style/Theme.Translucent"> <item name="android:windowBackground">@color/lock_bg style> 看下Theme.Translucent的定义: 然后,lock_bg即为我们想要设置的背景的颜色,我们可以在colors.xml中自定义其值: <color name="lock_bg">#cc000000 然后把这个主题应用到activity即可: <activity android:name=".activity.TestActivity" android:theme="@style/DarkTransParent" />

Glide结合高斯模糊使用

最近在做毕业设计,想做一个跟网易音乐播放界面差不多的,在做到播放详情界面的时候用到Glide加载网络图片作为整个布局的背景,但是背景太明显反而显得不好看,上网查了查,找到了高斯模糊感觉还行,接下来我就说一下使用流程。 第一步肯定是在build中加入依赖库 //加载图片 compile 'com.github.bumptech.glide:glide:3.7.0' //高斯模糊 compile 'jp.wasabeef:glide-transformations:2.0.1' transformations库里面还有好多其他转换形式,具体github地址glide转换库 第二步 加载一张图片的话比较简单,Gilde做的非常好了,不会的自己去搜。 //加载背景,也是加载专辑封面 Glide.with(MusicPlayerActivity.this) .load(service.getImageUri()) .dontAnimate() .error(R.drawable.no_music_rotate_img) .into(allBg); 第三部就是在上面代码中加一句话就可以了。 // "14":模糊度;"3":图片缩放3倍后再进行模糊,缩放3-5倍个人感觉比较好。 .bitmapTransform(new BlurTransformation(this, 14, 3)) 完整的代码 //加载背景, Glide.with(MusicPlayerActivity.this) .load(service.getImageUri()) .dontAnimate() .error(R.drawable.no_music_rotate_img) // 设置高斯模糊 .bitmapTransform(new BlurTransformation(this, 14, 3)) .into(allBg); 完整代码点这里 在MusicPlayerActivity中使用到

Deeplink:web唤醒app

在Android平台URI主要分五个部分:scheme, authority, path, queryParameter, queryString。其中authority又分为host和port。格式如下:(url的所有字母命名只能为小写) scheme://host:port/path?qureyParameter=queryString 例如:myscheme://www.febmaple.com:80/mypath?key=mykey 在Android的Manifest配置文件中,在要启动的activity下配置项中有配置。 其中包含内容有: <data android:host="" android:mimeType="" android:path="" android:pathPattern="" android:pathPrefix="" android:port="" android:scheme="" android:ssp="" android:sspPattern="" android:sspPrefix=""/> 1、web端html里写入 Click 2、android端在menifest的响应activity的intentfilter下配置,一般只需配置scheme和host即可。 3、这样手机系统自带浏览器碰到不能处理的scheme之后会发送intent给能处理的应用,因为我们的app可以处理该scheme,所以我的app得到启动。(ps:如果用webview加载html,webview碰到处理不了的scheme并不会发送intent找app处理,而系统自带浏览器是可以的,当然我们的需求就是用系统自带浏览器触发)。 Show u my code: 一、跳到app首页:新建一个app工程用webview加载所写的html,用以触发目标app。(实际需求是直接在系统浏览器里触发目标app) 1、建立html放到工程的main/assets目录下 </span> <html> <body> <h1>Test Schemeh1> <a href="myscheme://www.febmaple.com:80/mypath?key=mykey">Clicka> body> html> 2、webview加载本地html内容来触发目标app wvUrl.loadUrl("file:///android_asset/test.html"); 3、在app manifeset的**欢迎**activity添加intent-filter配置data标签. <activity android:name=".ui.launching.DemoLaunchingActivity" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:scheme="myscheme"/> intent-filter> activity> 4、在配置好的Activity里即可获取外部跳转的参数信息。 @Override protected void onCreate(Bundle savedInstanceState) { super.

沉浸式状态栏(修改状态栏)颜色的简单实现

Google 推出MaterialDesign后,可以说极大的美化了Android的UI,开发者只需按照MaterialDesign的相关标准就能设计出炫酷的界面。 自从5.0推出后,Android就开始支持修改状态栏的颜色,从QQ、网易云音乐等主流的App都可以看到这一特性使得Android界面更加一体化。 网络上关于修改状态栏的方法更多,也有很多开源库,今天讲一种简单的实现方式。 1、在Java代码中设置状态栏为透明 if (Build.VERSION.SDK_INT >= 21) { View decorView = getWindow().getDecorView(); int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; decorView.setSystemUiVisibility(option); getWindow().setStatusBarColor(Color.TRANSPARENT); } 2、在布局文件中添加下面的属性:android:paddingTop=”28dp”,笔者经测试,28dp是比较合适的,大家也可以根据需要调整。 ...... 下面是效果图:

解决ProGuard混淆代码时出现的java.lang.NoSuchFieldException: xxx…异常

用Android Studio写小Demo的时候,由于需要混淆代码,所以把build.gradle文件里的minifyEnabled false改成了true。 然后编译成release发布版本,就会发现apk包小了不少,说明混淆成功。 这对一般的小项目倒是没什么影响,混淆后程序运行仍然正常,但如果用到了Java的反射机制,就没那么轻松了。 下面是我程序中的一段代码: Class<RecyclerView> recyclerViewClass = RecyclerView.class; try { Field declaredField = recyclerViewClass.getDeclaredField("mRecycler"); declaredField.setAccessible(true); Method declaredMethod = Class.forName(RecyclerView.Recycler.class.getName()).getDeclaredMethod("clear"); declaredMethod.setAccessible(true); declaredMethod.invoke(declaredField.get(activeRecyclerView)); RecyclerView.RecycledViewPool recycledViewPool = activeRecyclerView.getRecycledViewPool(); recycledViewPool.clear(); } catch (Exception e) { e.printStackTrace(); } 在Build时就会报类似下面的错: java.lang.NoSuchFieldException: No field mRecycler in class Landroid/support/v7/widget/RecyclerView; (declaration of ‘android.support.v7.widget.RecyclerView’ appears in /data/app/com.xxx…… 还有: java.lang.NoSuchMethodException: clear [] 报错提示找不到相应的域和方法。 看最开始的代码我们知道用到了反射,大致的原理是根据字符串去寻找方法,然而代码经过ProGuard混淆后一些方法名都变成了无意义的短字符了(比如a、b、c这种), 但是经过反编译可以发现,代码中的字符串是不会被混淆修改的。 所以程序运行时就无法映射到相应的方法了。 解决办法: ProGuard官方文档也是建议了大家不要混淆反射所涉及的类方法,因此我们需要自定义配置项目中的proguard-rules.pro文件。 第一个报错解决办法就是保留RecyclerView类不被混淆即可,文件中添加: -keep class android.support.v7.widget.RecyclerView {*;} 第二个报错,阅读了很多文档,我做了很多尝试,由于技艺不精,还是无法通过配置rules文件来消除混淆对clear()方法的影响,反编译代码后我发现clear()方法名还是被混淆改成了a()。 最后我就干脆把最开始原始代码里的字符串“clear”改成了“a”,然后成功消除报错。 其实这不是很好的解决办法,因为你需要得知相应的方法名被混淆成了什么,而且修改项目源代码去应付混淆也非上策,如果有大神知道如何配置rules文件来保证反射的正常运行,欢迎评论留言,交流指点。 (这里可以通过查看项目下面的 \build\outputs\mapping\release\mapping.txt 映射文件去查看相应的方法名被混淆成了什么,或者简单粗暴一点的,直接查看反编译apk后的代码也能得知)

百度地图开发时:只显示灰色的网格而不显示具体地图信息的解决办法

最近在开发百度地图时遇到只显示灰色的框框,不显示具体的地图信息: 查阅资料后,自己的解决办法是: 1、百度地图API key的申请 在申请key的时候需要注意的是安全码的设置,安全码的组成为:数字签名+;+包名,其中数字签名不是随便给出就行的,获取数字签名的方法: 方法一:如果使用adt 22,可以在eclipse中直接查看:winows -> preferance -> Android -> build,然后在该页面中有个SHA1 fingerprint值,这个值就是上面的数字签名; 方法二:如果使用的是adt21及以下的,可以在default debug keystore项目里找到该文件,然后运行cmd命令: keytool -list -v -keystoreC:Usersuser.androiddebug.keystore 然后输入密码,这里密码一般为空,直接按回车就行。即可看到sha1码! 包名可以是你任意给出的包名(但是你一定要记者这个包名),在新建功能的时候,自己创建的工程包名就必须和这个包名一致了。也就是说该key只能在该包位置下使用。(PS:在不同的工程下如果给出相同的包名,这种情况我就没有试验了,但是我想应该也是可以的,因为在申请key的时候只给定了包名,而没有限定你的项目工程名) 1、创建工程工程部分目录如下: 如图中包名和上面百度key值申请时候所定义的包名一致。另外,有些人新建了工程后,刚开始建的包名和百度key申请时的包名不一致的时候,有些人将包名改过来,但是却忘记了一件事,那就是AndroidManifest.xml文件中还有个需要改的地方,如图:要将该包名同样修改一下。 到此,问题应该可以解决

SystemUI状态条下拉视图显示过程

super_status_bar.xml中的brightness_mirror是状态条上面亮度调节的控件。panel_holder是下面包括所有控件的一个容器。在status_bar_expanded_header.xml中system_icons_super_container为状态条下拉时候显示的顶层布局。split_clock_view.xml用来绘制下拉菜单左边的时间日期。状态条控件的显示是用的PanelBar.java。 顶上的状态条被下拉首先被处理的是触摸事件,也就是PhoneStatusBar里面的interceptTouchEvent函数,当状态条被下拉出来之后就会执行PanelBar里面的onTouchEvent函数,它会根据触摸的位置选择被触摸的panel,然后执行startOpeningPanel()就是用来初始化panel的状态,调用除NotificationPanelView以外其他视图的collapse函数,然后调用被触摸panel的onTouchEvent函数里面的ACTION_MOVE分支,执行setExpandedHeightInternal根据手指移动的距离刷新panel的高度并更新状态条的状态指示当前被扩展的状态,如果被完全下拉下来,则不会在更新状态条视图,否则不断调用NotificationPanelView里面的onHeightUpdated函数来更新该状态条的里面的内容。因此在PhoneStatusBar里面的onInterceptKeyEvent中的最后加入if(SystemProperties.get(“persist.sys.sysui.config”)){return true;}使得状态条不能被下拉下来。setprop persist.sys.sysui.config命令需要被写入init.rc文件里面,该文件会被编译成boot.img,所以要替换掉boot.img,之后在使用setprop命令就会在data/local目录下生成该 persist.sys.sysui.config目录,所以重启之后该属性值还生效。//1612001724 yah1826

Android简单联网获取网页

一门语言,联网编程都是非常重要,所以我们来简单的实现以下android开发如何写联网程序。 Http请求分为: GET:明文传参,在地址栏上可以看到参数,调用简单没,不安全。 POST:暗文传参,在地址栏上看不到参数,调用稍微复杂,安全。 android上发送Http请求的方式有两种: HttpURLConnection类:是java的标准指定网站发送GET请求、POST请求类,使用相对简单,并且易于扩展,推荐使用。 HttpClient类:是android SDK提供的请求方式,对HTTP协议全面支持,但是在android6.0(API23)中,Google已经移除了该相关的类,因此不在赘述使用该类的使用。 这次我们使用GET方式进行获取数据,步骤: 1.创建URL对象。 2.通过 URL对象调用openConnection()方法获取HttpURLConnection对象。 3.设置相关属性。 4.HttpURLConnection对象通过getInputStream()方法获得输入流。 5.读取输入流,转成字符串。 效果图: **其实很简单,列举一个例子: 假如从水库引水,首先要找到水库的位置,第二步将水引到工厂后建立一个阀门来控制水,第三步建立水道将水引到蓄水池,在水道口放上网来过滤鱼虾蟹,然后用小水桶把渔网的鱼一点一点的捞起来放到大水桶,最后晒网。** 代码演示: 布局文件: <RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.httpdemo.MainActivity" > <Button android:id="@+id/a12" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="获取" android:onClick="aaa" /> <ScrollView android:layout_below="@id/a12" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/a" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> ScrollView> RelativeLayout> MainActivity: package com.example.httpdemo; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import android.

【Android休眠】之Android休眠机制

http://blog.csdn.net/u013686019/article/details/53645646 一、休眠概述 休眠,简而言之就是设备在不需要工作的时候把一些部件、外设关掉(掉电或让它进入低功耗模式)。 为什么要休眠呢?一言以蔽之:省电。 休眠分主动休眠和被动休眠。主动休眠:比如我电脑不用了,就通过设置让系统进入休眠模式;被动休眠:系统检测到自己闲的慌,为了节约故,自己就休眠去了。 废话不叙。 二、Android休眠 休眠是内核的核心工作,而Android是基于Linux内核的,所以Android休眠和内核有着千丝万缕的联系;由于Android的特殊应用场景:移动设备,所以Android休眠和内核又有着特别的需求。 1、联系: Android设备停止使用,系统没有什么事情可做,进入休眠状态的功能最终是由内核去实现的;每一类硬件都有自己的驱动,具体的驱动决定怎么进入休眠以及处于何种层次的休眠。比如:对于platform_device,就按照platform_driver定义的规则,在suspend调用的时候,去做上面提到的事情: struct platform_driver { int (*probe)(struct platform_device *); int (*remove)(struct platform_device *); void (*shutdown)(struct platform_device *); int (*suspend)(struct platform_device *, pm_message_t state); int (*resume)(struct platform_device *); struct device_driver driver; const struct platform_device_id *id_table; }; 2、Android的特别需求: 比如对于自己的电脑,不用让它休眠好了;但是对于我们形影不离的手机,在休眠的时候还要睁一只眼:来电了要通知你,QQ啊微信啊什么的由信息了也要通知你,所以Android在Linux内核休眠机制之上,提出了“Opportunistic Suspend”。 三、休眠实践 絮絮叨叨这么多,下面让我们切切实实体验下休眠。 1、休眠模式 休眠是分好几种模式的,不同模式实现方式、耗电量不同,以下来自Documentation/power/states.txt: The kernel supports four power management states generically, though one is generic and the other three are dependent on platform support code to implement the low-level details for each state.