这两天按项目进度接入了第三方的一些东西。本来感觉太简单了了,因为原来的项目都接入过,但是老项目代码代码弄过来直接用那叫一个崩溃。这三个没有一个能行的,搞不懂为什么老项目中农用并且没出现问题,但是新项目不行。烦躁的我一咬牙索性从官网直接撸一遍,特此记录,希望对有相同需求的有帮助。
极光推送
在这给大家衷心的提醒,按照官网最新的文档来集成,原因很简单:相对于原来去除了很多冗余,最重要的是“能用!!!”
1、首先,清单列表配置起来感觉比原来爽多了(这里我是用的是自动配置) ,只需要定义好你自己receive及添加所需的权限即可,其他的极光帮你自动配置了(这里我把项目所有所需权限都贴出来,包括项目所需)
<uses-permission android:name="com.hkzr.liangquan.permission.JPUSH_MESSAGE" />
<!-- 获取网络信息状态,如当前的网络连接是否有效 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 允许程序获取当前或最近运行的应用 -->
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission
android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
tools:ignore="ProtectedPermissions" />
<!-- 改变WiFi状态 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
<!-- 允许程序写入外部存储,如SD卡上写文件 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.WRITE_MEDIA_STORAGE"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 允许读写系统设置项 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- 允许程序调用killBackgroundProcesses(String).方法结束后台进程 -->
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<!-- 允许访问闪光灯 -->
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
<!-- 挂载、反挂载外部文件系统 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- 允许程序在手机屏幕关闭后后台进程仍然运行 -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- 许程序从非系统拨号器里输入电话号码 -->
<uses-permission android:name="android.permission.CALL_PHONE" />
<!-- 通过WiFi或移动基站的方式获取用户错略的经纬度信息,定位精度大概误差在30~1500米 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 通过GPS芯片接收卫星的定位信息,定位精度达10米以内 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 修改声音设置信息 -->
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<!-- 录制声音通过手机或耳机的麦克 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 改变网络状态如是否能联网 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<!-- 访问电话状态 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 读取系统底层日志 -->
<uses-permission android:name="android.permission.READ_LOGS" />
<!-- 允许程序开机自动运行 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- 允许程序访问额外的定位提供者指令 -->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<!-- 极光推送 -->
<!-- User defined. 用户自定义的广播接收器 -->
<receiver
android:name="你定义的receiver"
android:enabled="true">
<intent-filter>
<!-- Required 用户注册SDK的intent -->
<action android:name="cn.jpush.android.intent.REGISTRATION" />
<!-- Required 用户接收SDK消息的intent -->
<action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED" />
<!-- Required 用户接收SDK通知栏信息的intent -->
<action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED" />
<!-- Required 用户打开自定义通知栏的intent -->
<action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED" />
<!-- 接收网络变化 连接/断开 since 1.6.3 -->
<action android:name="cn.jpush.android.intent.CONNECTION" />
<category android:name="你的包名" />
</intent-filter>
</receiver>
<!-- 极光推送END -->
这个是自定义的receiver
public class MyReceiver extends BroadcastReceiver {
private static final String TAG = "JPush";
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Log.d(TAG, "[MyReceiver] onReceive - " + intent.getAction() + ", extras: " + printBundle(bundle));
// if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
// String regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID);
// Log.d(TAG, "[MyReceiver] 接收Registration Id : " + regId);
// //send the Registration Id to your server...
//
// } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
// Log.d(TAG, "[MyReceiver] 接收到推送下来的自定义消息: " + bundle.getString(JPushInterface.EXTRA_MESSAGE));
// processCustomMessage(context, bundle);
//
// } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {
// Log.d(TAG, "[MyReceiver] 接收到推送下来的通知");
// int notifactionId = bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);
// Log.d(TAG, "[MyReceiver] 接收到推送下来的通知的ID: " + notifactionId);
//
// } else
if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
// Log.d(TAG, "[MyReceiver] 用户点击打开了通知");
String string = bundle.getString(JPushInterface.EXTRA_EXTRA);
JPushBean jPushBean = GsonInstance.gson().fromJson(string, JPushBean.class);
// TODO: 2018/8/3 页面跳转等相应处理
}
}
// 打印所有的 intent type 数据
private static String printBundle(Bundle bundle) {
StringBuilder sb = new StringBuilder();
for (String key : bundle.keySet()) {
if (key.equals(JPushInterface.EXTRA_NOTIFICATION_ID)) {
sb.append("\nkey:" + key + ", value:" + bundle.getInt(key));
} else if (key.equals(JPushInterface.EXTRA_CONNECTION_CHANGE)) {
sb.append("\nkey:" + key + ", value:" + bundle.getBoolean(key));
} else if (key.equals(JPushInterface.EXTRA_EXTRA)) {
if (TextUtils.isEmpty(bundle.getString(JPushInterface.EXTRA_EXTRA))) {
Log.i(TAG, "This message has no Extra data");
continue;
}
try {
JSONObject json = new JSONObject(bundle.getString(JPushInterface.EXTRA_EXTRA));
Iterator<String> it = json.keys();
while (it.hasNext()) {
String myKey = it.next().toString();
sb.append("\nkey:" + key + ", value: [" +
myKey + " - " + json.optString(myKey) + "]");
}
} catch (JSONException e) {
Log.e(TAG, "Get message type JSON error!");
}
} else {
sb.append("\nkey:" + key + ", value:" + bundle.getString(key));
}
}
return sb.toString();
}
2、其次为build文件配置
确保根目录的gradle文件
allprojects {
repositories {
jcenter()
...
}
}
app给gradle文件
defaultConfig {
applicationId "你的包名"
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
manifestPlaceholders = [
JPUSH_PKGNAME: applicationId,
JPUSH_APPKEY : "自己的appkey", //JPush上注册的包名对应的appkey.
JPUSH_CHANNEL: "developer-default", //暂时填写默认值即可.
]
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation rootProject.ext.supportDeps["appcompatv7"]
implementation rootProject.ext.supportDeps["recyclerview"]
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
...
// jpush
compile 'cn.jiguang.sdk:jpush:3.1.1' // 最新版下载不下来,这里已这个版本为例
compile 'cn.jiguang.sdk:jcore:1.1.9'
}
3、自定义application初始化
/**
* 初始极光推送,只需要在application中初始化一次即可
*/
private void initJpush() {
JPushInterface.setDebugMode(false); //todo 开启极光推送debug模式,上线后需关闭
JPushInterface.init(this);
}
4、最激动的一步到了,绑定--推送
请根据公司业务选择,我这里使用的按别名推送
JPushInterface.setAlias(context, "你和后台定义的用户唯一标识",null);
大功告成!!!
友盟第三方登录
友盟更恶心,用老版本的代码及配置有时候行,有时候崩溃!!!而且每次崩的都不一样。
1、去下载jar包及一些资源文件等等(凑合看吧,就这两个圈)
这里资源文件没有给贴出来大家注意,粘过来就完事了
2、清单列表配置(加绒8.0,我这里根据项目要求只有qq和微信)
<!-- 友盟appkey -->
<meta-data
android:name="UMENG_APPKEY"
android:value="你申请的友盟appkey" />
<!-- 微信 -->
<activity
android:name=".wxapi.WXEntryActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<!-- QQ -->
<activity
android:name="com.tencent.tauth.AuthActivity"
android:launchMode="singleTask"
android:noHistory="true">
<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="可改成你平台申请的也可以不动" />
</intent-filter>
</activity>
<activity
android:name="com.tencent.connect.common.AssistActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
3、Applicaion中初始化
/**
* 初始化友盟分享,只需要在application中初始化一次即可
*
* @param appContext
*/
public static void initUMShare(Context appContext) {
mShareAPI = UMShareAPI.get(appContext);
initPlatForm(appContext);
}
/**
* 初始化平台分享key
* @param appContext
*/
private static void initPlatForm(Context appContext) {
UMConfigure.init(appContext,"你的友盟key",
"umeng",UMConfigure.DEVICE_TYPE_PHONE,"");
PlatformConfig.setWeixin("微信平台申请的key", "value");
PlatformConfig.setQQZone("qq平台申请的key", "value");
}
4、好了,现在就可以使用了,终于搞定两个了,好兴奋!!!
我简单封装的方法
/*获取用户信息*/
private static void getUserInfo(SHARE_MEDIA type, final OnGetUser onGetUser) {
App.getShareAPI().getPlatformInfo(activity, type, new UMAuthListener() {
@Override
public void onStart(SHARE_MEDIA share_media) {
}
@Override
public void onComplete(SHARE_MEDIA share_media, int i, Map<String, String> map) {
Set<String> strings = map.keySet();
for (String s : strings) {
Log.e("key", s);
Log.e("value", map.get(s));
}
onGetUser.onGetUser(map.get("screen_name"), map.get("iconurl"), map.get("unionid"), map.get("openid"));
activity = null;
}
@Override
public void onError(SHARE_MEDIA share_media, int i, Throwable throwable) {
onGetUser.onErrorr();
activity = null;
}
@Override
public void onCancel(SHARE_MEDIA share_media, int i) {
onGetUser.onCannel();
activity = null;
}
});
}
科大讯飞语音转文字
跟大厂比起来这家的文档显得有些不尽人意。。。
1、去官网下载一些资源(.so文件不要忘记下载,不然直接崩)
2、Application初始化
/**
* 初始科大讯飞,只需要在application中初始化一次即可
*/
private void initSpeechUtility() {
// 请勿在“=”与appid之间添加任何空字符或者转义符
SpeechUtility.createUtility(this, SpeechConstant.APPID + "=你申请的appkey");
}
3、对的,现在就可以使用了
// 1、首先设置参数
// 初始化
private val mIat: SpeechRecognizer by lazy { SpeechRecognizer.createRecognizer(activity, mInitListener) }
/**
* 初始化监听器。
*/
private val mInitListener = InitListener { code ->
if (code != ErrorCode.SUCCESS) {
toast("语音转文字功能初始化失败")
}
}
fun setParam() {
// 清空参数
mIat.setParameter(SpeechConstant.PARAMS, null)
// 设置听写引擎
mIat.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType)
// 设置返回结果格式
mIat.setParameter(SpeechConstant.RESULT_TYPE, "json")
// 设置语言
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn")
// 设置语言区域
mIat.setParameter(SpeechConstant.ACCENT, "mandarin")
}
//2、开始录音(这里使用的自己的ui动画)
ret = mIat.startListening(mRecognizerListener)
//得到结果
private val mRecognizerListener = object : RecognizerListener {
override fun onBeginOfSpeech() {
// 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入
}
override fun onError(error: SpeechError?) {
Log.e("liulu", error?.errorDescription)
}
override fun onEndOfSpeech() {
// 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
}
override fun onResult(results: RecognizerResult?, isLast: Boolean) {
if (remindDialog != null) {
remindDialog.dismiss()
}
val text = JsonParser.parseIatResult(results?.resultString)
var sn: String? = null
// 读取json结果中的sn字段
try {
val resultJson = JSONObject(results?.resultString)
sn = resultJson.optString("sn")
} catch (e: JSONException) {
e.printStackTrace()
}
mIatResults[sn] = text
val resultBuffer = StringBuffer()
for (key in mIatResults.keys) {
resultBuffer.append(mIatResults.get(key))
}
if (isLast) {
// TODO 最后的结果
// todo 添加到列表
val speak = resultBuffer.toString()
// todo 处理自己的逻辑
}
}
override fun onVolumeChanged(volume: Int, data: ByteArray?) {}
override fun onEvent(eventType: Int, arg1: Int, arg2: Int, obj: Bundle?) {
// 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查
询会话日志,定位出错原因
// 若使用本地能力,会话id为null
// if (SpeechEvent.EVENT_SESSION_ID == eventType) {
// String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
// Log.d(TAG, "session id =" + sid);
// }
}
}
//3、中途可通知录音顶拿到结果
mIat.stopListening()
/**
* Json结果解析类
*/
public class JsonParser {
public static String parseIatResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
// 转写结果词,默认使用第一个结果
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
JSONObject obj = items.getJSONObject(0);
ret.append(obj.getString("w"));
// 如果需要多候选结果,解析数组其他字段
// for(int j = 0; j < items.length(); j++)
// {
// JSONObject obj = items.getJSONObject(j);
// ret.append(obj.getString("w"));
// }
}
} catch (Exception e) {
e.printStackTrace();
}
return ret.toString();
}
public static String parseGrammarResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
for(int j = 0; j < items.length(); j++)
{
JSONObject obj = items.getJSONObject(j);
if(obj.getString("w").contains("nomatch"))
{
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append("【结果】" + obj.getString("w"));
ret.append("【置信度】" + obj.getInt("sc"));
ret.append("\n");
}
}
} catch (Exception e) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
return ret.toString();
}
public static String parseLocalGrammarResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
for(int j = 0; j < items.length(); j++)
{
JSONObject obj = items.getJSONObject(j);
if(obj.getString("w").contains("nomatch"))
{
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append("【结果】" + obj.getString("w"));
ret.append("\n");
}
}
ret.append("【置信度】" + joResult.optInt("sc"));
} catch (Exception e) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
return ret.toString();
}
public static String parseTransResult(String json,String key) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
String errorCode = joResult.optString("ret");
if(!errorCode.equals("0")) {
return joResult.optString("errmsg");
}
JSONObject transResult = joResult.optJSONObject("trans_result");
ret.append(transResult.optString(key));
/*JSONArray words = joResult.getJSONArray("results");
for (int i = 0; i < words.length(); i++) {
JSONObject obj = words.getJSONObject(i);
ret.append(obj.getString(key));
}*/
} catch (Exception e) {
e.printStackTrace();
}
return ret.toString();
}
}