APP出海--Firebase中云消息传递(FCM)接入和处理

Publish: April 15, 2021 Category: 编程 No Comments

0x00 FCM简介

消息类型
使用 FCM,您可以向客户端发送两种类型的消息:

  • 通知消息,有时被称为“显示消息”。此类消息由 FCM SDK 自动处理。
  • 数据消息,由客户端应用处理。

通知消息包含一组预定义的用户可见的键。 与其相对,数据消息只包含用户定义的自定义键值对。通知消息可以包含可选的数据载荷。两种消息类型的载荷上限均为 4KB,但从 Firebase 控制台发送消息时会强制执行 1024 个字符的限制。
使用情景 如何发送
通知消息 FCM 代表客户端应用自动向最终用户设备显示消息。通知消息包含一组预定义的用户可见键以及自定义键值对的可选数据载荷。 在可信环境(例如 Cloud Functions 或应用服务器中),使用 Admin SDK 或者 FCM 服务器协议:设置 notification 键。可能包含可选的数据载荷。 一律可折叠。请参阅一些显示通知示例并发送请求载荷。使用 Notifications Composer:输入消息文本、标题等,然后发送。 通过提供自定义数据添加可选的数据载荷。
数据消息 客户端应用负责处理数据消息。数据消息仅包含自定义键值对,没有保留键名(请参阅下文)。 在可信环境(例如 Cloud Functions 或应用服务器中),使用 Admin SDK 或者 FCM 服务器协议:仅设置 data 键。

0x01 FCM中几个重要凭据说明:

根据要实现的 FCM 功能的不同,您可能需要下列来自 Firebase 项目的凭据:
项目 ID 您的 Firebase 项目的唯一标识符,用于向 FCM v1 HTTP 端点发出请求。您可以在 Firebase 控制台设置窗格中找到该值。
注册令牌 用于标识每个客户端应用实例的唯一令牌字符串。 单一设备消息传递和设备组消息传递需要注册令牌。请注意,注册令牌必须保密。
发送者 ID 您在创建 Firebase 项目时系统创建的唯一数字值,可在 Firebase 控制台设置窗格的 Cloud Messaging 标签页找到。发送者 ID 用于标识可以向客户端应用发送消息的每个发送者。

访问令牌 一个只在短时间内有效的 OAuth 2.0 令牌,用于对发送到 HTTP v1 API 的请求进行授权。此令牌与属于您的 Firebase 项目的服务帐号相关联。如需创建和轮替访问令牌,请按照向发送请求提供授权中所述的步骤操作。
服务器密钥(用于旧版协议) 用于授权您的应用服务器访问 Google 服务(包括通过 Firebase Cloud Messaging 传递旧版协议发送消息)的服务器密钥。您在创建 Firebase 项目时获取服务器密钥。您可以在 Firebase 控制台设置窗格的 Cloud Messaging 标签页查看此密钥。重要提示:切勿在客户端代码中的任何位置包含服务器密钥。另外,请确保在为您的应用服务器授权时仅使用服务器密钥。Android 密钥、iOS 密钥和浏览器密钥会被 FCM 拒绝。









阅读剩余部分...

APP出海--Android 接入Firebase笔记

Publish: April 15, 2021 Category: 编程 No Comments

0x00 创建Firebase应用

进入Firebase控制台(https://console.firebase.google.com/) 创建应用,这里选择创建一个Android应用,注意自己的包名是否匹配。创建成功之后会给一个google-service.json的配置文件,将文件复制到app项目目录下。

阅读剩余部分...

GStreamer Android 教程(一)在Android程序中使用GStreamer

Publish: March 4, 2021 Category: 编程 No Comments

0 目标演示

在APP中显示一个GStreamer版本。

这第一篇 Android 教程非常简单:它只是检索 GStreamer 版本并将其显示在屏幕上。演示如何从Java访问GStreamer C代码,并验证了没有任何链接问题。

1 Hello GStreamer (Java 代码)

教程代码在tutorials/android-tutorial-1子目录下的gst-docs中。这个目录包含通常的Android NDK结构:一个src文件夹用于Java代码,一个jni文件夹用于C代码,一个res文件夹用于UI资源。
我们建议你在Eclipse中打开这个项目(正如在安装Android开发中所解释的那样),这样你就可以很容易地看到所有的部分是如何结合在一起的。
让我们先介绍一下Java代码,然后是C代码,最后是允许GStreamer集成的makefile。

//src/org/freedesktop/gstreamer/tutorials/tutorial_1/Tutorial1.java
package org.freedesktop.gstreamer.tutorials.tutorial_1;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

import org.freedesktop.gstreamer.GStreamer;

public class Tutorial1 extends Activity {
    private native String nativeGetGStreamerInfo();

    // Called when the activity is first created.
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        try {
            GStreamer.init(this);
        } catch (Exception e) {
            Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
            finish();
            return;
        }

        setContentView(R.layout.main);

        TextView tv = (TextView)findViewById(R.id.textview_info);
        tv.setText("Welcome to " + nativeGetGStreamerInfo() + " !");
    }

    static {
        System.loadLibrary("gstreamer_android");
        System.loadLibrary("tutorial-1");
    }

}

上面的代码中演示了声明一个从Java中调用C本地方法,就是这个方法

private native String nativeGetGStreamerInfo();

表示,告诉Java程序该方法已经存在,编译器可以继续编译,并且保证在运行时可调用。具体的实现会在后面说明。
第一个被实际执行的代码是类的静态初始化类。

static {
    System.loadLibrary("gstreamer_android");
    System.loadLibrary("tutorial-1");
}

此处声明表示加载libgstreamer_android.so和libtutorial-1.so两个库,前者包含GStreamer的全部方法,后者是本示例中所用到的方法,后面会说明。
在加载时,这些库的JNI_OnLoad()方法都会被执行。它基本上注册了这些库所公开的本地方法。GStreamer库只暴露了一个init()方法,它初始化了GStreamer,并注册了所有的插件(教程库将在后面解释)。

try {
    GStreamer.init(this);
} catch (Exception e) {
    Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
    finish();
    return;
}

接下来,在Activity的OnCreate()方法中,我们实际上是通过调用GStreamer.init()来初始化GStreamer。这个方法需要一个Context,所以不能从静态初始化器中调用,但是多次调用它并没有危险,因为除了第一次之外,所有的调用都会被忽略。
如果初始化失败,init()方法将抛出一个由GStreamer库提供异常详情的Exception。

TextView tv = (TextView)findViewById(R.id.textview_info);
tv.setText("Welcome to " + nativeGetGStreamerInfo() + " !");

然后,调用本地方法nativeGetGStreamerInfo(),并获取一个字符串,用来格式化UI中TextView的内容。
本教程的UI部分到此结束。我们来看看C代码。







阅读剩余部分...

Android 无线隔空调试,扔掉烦人的数据线

Publish: January 19, 2021 Category: 编程 No Comments

Ios的无线调试是真的好用,几乎可以不用数据线的情况下完成大部分任务。那Android是否也可以使用无线调试呢?当然可以!

第一步
保证计算机网络和手机网络在同一网络下。将手机使用数据线连接上计算机USB,打开USB调试模式。等待驱动等各种准备工作完成,使用如下命令查看是否连接成功。

adb devices
#如果成功会返回如下内容
C:\Users\yinli>adb devices
adb server version (31) doesn't match this client (41); killing...
* daemon started successfully
List of devices attached
931c9033        device

阅读剩余部分...

联通蜂窝物联网卡平台对接指导

Publish: January 6, 2021 Category: 编程 No Comments

联通物联网卡平台提供了大部分管理能力。以新的“连接管理--蜂窝安全为例”,可以实现订单、设备、短信、通讯计划、账单用量、账户和资费计划管理。具体接口地址如下:

接口名    URL    
API轮询APN    https://gwapi.10646.cn/api/wsGetPollApn/V1/1Main/vV1.1    
API账单查询    https://gwapi.10646.cn/api/wsGetInvoice/V1/1Main/vV1.1    
API设备用量查询    https://gwapi.10646.cn/api/wsGetTerminalUsage/V1/1Main/vV1.1    
API短信查询    https://gwapi.10646.cn/api/wsQuerySMS/V1/1Main/vV1.1    
API短信详情查询    https://gwapi.10646.cn/api/wsQuerySMSDetail/V1/1Main/vV1.1    
查询指定设备可用事件资费计划    https://gwapi.10646.cn/api/wsGetAvailableEvents/V1/1Main/vV1.1    
API安吉星查询设备实时信息    https://gwapi.10646.cn/api/wsGetDeviceRealTimeInfo/V1/1Main/vV1.1    
查询给定日期和时间后发生修改的设备    https://gwapi.10646.cn/api/wsGetModifiedTerminals/V1/1Main/vV1.1    
返回一个或多个设备的通信计划    https://gwapi.10646.cn/api/wsGetNetworkAccessconfig/V1/1Main/vV1.1    
查询设备最近某种属性的修改结果    https://gwapi.10646.cn/api/wsGetProvisioningStatus/V1/1Main/vV1.1    
查询一个或多个设备的当前会话信息    https://gwapi.10646.cn/api/wsGetSessionInfo/V1/1Main/vV1.1    
查询一个设备的变更记录详情    https://gwapi.10646.cn/api/wsGetTerminalAuditTrail/V1/1Main/vV1.1    
查询指定设备关联的事件资费计划    https://gwapi.10646.cn/api/wsGetTerminalEvents/V1/1Main/vV1.1    
返回给定设备的当前基本资费计划和所有排队资费计划    https://gwapi.10646.cn/api/wsGetTerminalRating/V1/1Main/vV1.1    
返回与给定的一组设备IMSI对应的ICCID列表    https://gwapi.10646.cn/api/wsGetTerminalsByImsi/V1/1Main/vV1.1    
返回与给定的一组设备MSISDN对应的ICCID列表    https://gwapi.10646.cn/api/wsGetTerminalsByMsisdn/V1/1Main/vV1.1    
API返回给定设备在一个特定计费周期内发生的所有流量会话的相关信息    https://gwapi.10646.cn/api/wsGetTerminalUsageDataDetails/V1/1Main/vV1.1    
API返回一个设备在某个特定计费周期内接到或拨打的所有通话呼叫的相关信息    https://gwapi.10646.cn/api/wsGetTerminalUsageGsmDetails/V1/1Main/vV1.1    
API返回一个设备在某个特定计费周期内发出或收到的所有短信的相关信息    https://gwapi.10646.cn/api/wsGetTerminalUsageSmsDetails/V1/1Main/vV1.1    
API查询设备最近某种属性的修改结果    https://gwapi.10646.cn/api/wsStatus/V1/1Main/vV1.1    
修改迁移卡状态    https://gwapi.10646.cn/api/wsUpdateStatusMigrationSim/V1/1Main/vV1.1    
API新建APN    https://gwapi.10646.cn/api/wsCreateNewApn/V1/1Main/vV1.1    
Japan离线计费APN维护接口    https://gwapi.10646.cn/api/wsUpdateJasperOfflineCharingAPN/V1/1Main/vV1.1    
修改订单信息    https://gwapi.10646.cn/api/wsUpdateOrderInfo/V1/1Main/vV1.1    
更新订单状态(更新参数)    https://gwapi.10646.cn/api/wsUpdateOrderStatus/V1/1Main/vV1.1    
API通过SIM卡ID批量发送短信    https://gwapi.10646.cn/api/wsSendBulkSms/V1/1Main/vV1.1    
API通过MSISDN批量发送短信    https://gwapi.10646.cn/api/wsSendBulkSmsToMsisdn/V1/1Main/vV1.1    
API通过SIM卡ID发送短信    https://gwapi.10646.cn/api/wsSendSms/V1/1Main/vV1.1    
API通过MSISDN发送短信    https://gwapi.10646.cn/api/wsSendSmsToMsisdn/V1/1Main/vV1.1    
为设备分配事件资费计划    https://gwapi.10646.cn/api/wsActivateTerminalEvent/V1/1Main/vV1.1    
向设备队列的开头添加一个资费计划    https://gwapi.10646.cn/api/wsAddPlanInBeginQueue/V1/1Main/vV1.1    
向设备队列的末尾添加一个资费计划    https://gwapi.10646.cn/api/wsAddPlanInLastQueue/V1/1Main/vV1.1    
为特定设备取消预定事件    https://gwapi.10646.cn/api/wsDeleteTerminalEvent/V1/1Main/vV1.1    
更改与给定设备相关联的通信计划    https://gwapi.10646.cn/api/wsEditNetworkAccessConfig/V1/1Main/vV1.1    
为给定设备更改单个属性的值    https://gwapi.10646.cn/api/wsEditTerminal/V1/1Main/vV1.1    
查询一个或多个设备详情    https://gwapi.10646.cn/api/wsGetTerminalDetails/V1/1Main/vV1.1    
从设备队列中删除指定资费计划    https://gwapi.10646.cn/api/wsRemoveRatePlanFromQueue/V1/1Main/vV1.1    
强制设备断开网络    https://gwapi.10646.cn/api/wsSendCancelLocation/V1/1Main/vV1.1    
更改给定设备IP地址    https://gwapi.10646.cn/api/wsUpdateIpAddress/V1/1Main/vV1.1    
API订单新建    https://gwapi.10646.cn/api/wsCreateOrderApi/V1/1Main/vV1.1    
API新建或删除    https://gwapi.10646.cn/api/wsInsertOrDeleteAPI/V1/1Main/vV1.1    
API查询测试    https://gwapi.10646.cn/api/wsSelectAPI/V1/1Main/vV1.1    
编辑账户    https://gwapi.10646.cn/api/wsEditAcct/V1/1Main/vV1.1    
新建账户    https://gwapi.10646.cn/api/wsNewAcct/V1/1Main/vV1.1    
查询账户详情    https://gwapi.10646.cn/api/wsQueryAcctDet/V1/1Main/vV1.1    
查询账户列表    https://gwapi.10646.cn/api/wsQueryAcctTable/V1/1Main/vV1.1    
根据账户名查询账户ID    https://gwapi.10646.cn/api/wsQueryIdbyName/V1/1Main/vV1.1    
根据运营商账户名查询账户ID    https://gwapi.10646.cn/api/wsQueryIdbyServiceProCode/V1/1Main/vV1.1    
API可用事件资费计划查询    /api/query/eventplan/available/V1/1Main/vV1.1    
API关联事件资费计划查询    /api/query/eventplan/terminal/V1/1Main/vV1.1    
API分配事件资费计划    /api/operate/eventplan/activate/V1/1Main/vV1.1    
API删除事件资费计划    /api/operate/eventplan/delete/V1/1Main/vV1.1

联通蜂窝网络物联网卡平台对接签名,PHP版本的签名算法
token签名,参与签名字段只有app_id timestamp trans_id
物联网卡签名算法描述

1.蜂窝安全API接口时参数分为鉴权参数和业务负载参数,
2.鉴权权参数各个接口相同,包括appid,timestamp,trans_id,token四个参数,
  其中app_id为开通API功能时提供给企业用户,timestamp和trans_id的值由用户自行指定,token为签名字段,
  其值是根据app_id,timestamp,trans_id三个参数的值,再加上提供给企业客户的app_secret值,四个值经过
  加密算法计算得出,具体请参考《能力使用者接入指引 V2.7》中的sdk代码实现
{
"app_id":"XXXXXX",
"timestamp":"2018-12-05 10:23:35 649",
"trans_id":"XXXXXX",
"token":"XXXXXXXXXXXXXXXXXXXXXXXXX",
"data" :{
        "messageId": "134536",
        "openId": "xxxxxxxxxx",
        "version": "1.0",
        "iccids":["89860919720022503597"]
    }
}
4.data中为业务负载参数,格式参考各个接口的接口文档


阅读剩余部分...