场景
最近得一个项目中,因为没有原生安卓开发人员,只有选择用webview嵌套网页得方式来打包程序,不知道什么域名总是在微信和QQ里面被报违规,就得很频繁得更新下载得域名,后面下载通过中间页面方式解决了,居安思危,想到了之前做了一个博客还被人DDos攻击, 万一程序里面请求数据得域名无法访问了,那已下载得用户岂不是很尴尬,想来想去,也没有找到好的解决方案,后面在做IM消息推送得时候,得到了灵感,我主动获取网址可能不行,那我可以被动接受啊, 那可以借助第三方推送来实现把域名推送给安卓壳子,反正三方sdk得域名一般有专人维护,大不了交点费用, 壳子收到域名后,重新loadUrl即可。仅凭自己n年前学的安卓基础,想到了极光推送。
极光推送
- 注册账号以后进入开发者中心
- 创建应用,集成并下载整合好的sdk ,整合过程按照文档一步一步来即可。
极光推送注意几点
* 尽量不要发广播,广播每天免费只有10次机会,能用设备注册ID推送的就用ID推送
* 集成过程中最好直接把下载好的sdk全部拷贝过去,参考文档修改已有的代码。
* 如果是在已有的项目中集成,需要注意sdk中baseApplication中一些初始化的工作,我就是集成到已有项目中,一些初始化工作没有做,导致一直不成功。
嵌套webview的坑
* alert弹出框会有网址,这个是我们不希望看到的,可以选择重写也可以在js中直接自己封装一个美化版本alert
* 默认状态是不允许选择文件
* 默认状态下如果js中使用了window.location.href=进行跳转的不能跳转页面,需要重写方法才行
webview填坑代码
- 不允许选择文件
webview.setWebChromeClient(new WebChromeClient() {
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> valueCallback) {
uploadMessage = valueCallback;
openImageChooserActivity();
}
// For Android >= 3.0
public void openFileChooser(ValueCallback valueCallback, String acceptType) {
uploadMessage = valueCallback;
openImageChooserActivity();
}
//For Android >= 4.1
public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
uploadMessage = valueCallback;
openImageChooserActivity();
}
// For Android >= 5.0
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
uploadMessageAboveL = filePathCallback;
openImageChooserActivity();
return true;
}
});
- window.location跳转
webview.setWebViewClient(new WebViewClient() {
/**
* 拦截 url 跳转,在里边添加点击链接跳转或者操作
*/
public boolean shouldOverrideUrlLoading(WebView view, String url)
view.loadUrl(url);
return true;//返回true,立即跳转;返回false,打开网页有延时
}
/**
* 在开始加载网页时会回调
*/
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
//mProgressDialog.show();//加载转圈圈
}
/**
* 在结束加载网页时会回调
*/
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
//mProgressDialog.hide();//关闭转圈圈
}
});
php服务端推送域名给APP
composer安装Jpush库
-
我这里用得是thinkphp5来集成的,这个不会自动加载到框架autoload里面,而是自己有一个autoload,需要在入口里面自己手动引入才可用。
-
简单调用
use JPush\Client as JPush;
$client = new JPush($app_key, $master_secret);
//向所有人推送
$client->push()
->setPlatform('all')
->addAllAudience()
->setNotificationAlert('Hello, JPush')
->send();
//指定设备注册ID推送
$result = $client->push()
->setPlatform('android')
->addRegistrationId($id)
->androidNotification('系统有更新', ['extras' => ['host' => $host]])
->send();
动态更换域名
在调用php推送以后,在安卓端会有一个方法是
接收到字符串以后,需要转为json, 这里用的GSON转的。
获取域名以后放入缓存中,webview加载url的时候都是从缓存中读取的,没有的话就默认加载我们代码中写死的网址。
放入缓存以后,可以用广播的方式通知webview去更改加载的url 也可以直接退出程序,重新打开程序url就被更新了。
设备注册ID和用户绑定
这一点也是突发奇想来的,最近短信费用不够用了,如果能够使用推送消息的方式替换短信,就需要把设备ID和用户信息进行一个绑定,这时候就需要安卓和webview进行通信了。
这里介绍最简单的一种,直接在安卓代码中获取到设备ID,在加载页面完成以后,直接传到页面上去。
传送代码:
接收代码:
//这里的data就是传送过来的 registrationIDEncode
function javacalljswithargs(data){
//这里就可以,把data 传到后台,通过session中存储的用户,和设备注册ID进行一个绑定。
}
总结
这里只是做了最简单的demo演示,后面还有一些细节性的代码没有给出,比如集成过程中遇到的小问题,设备注册ID接收以后格式的判断,以及从android 向网页发送数据进行加密传输,APP的混淆防止别人反编译。需要代码的可以小窗我。