zoukankan      html  css  js  c++  java
  • 10. 社交模块

    社交模块

    邀请好友 - 推广应用

    主要就是为了实现推广流程。

    业务逻辑流程图

    客户端提供邀请好友的展示页面

    1. 用户个人中心user.html, 实现点击"邀请好友"打开邀请好友invite.html页面,代码:
    <!DOCTYPE html>
    <html>
    <head>
    	<title>用户中心</title>
    	<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    	<meta charset="utf-8">
    	<link rel="stylesheet" href="../static/css/main.css">
    	<script src="../static/js/vue.js"></script>
    	<script src="../static/js/axios.js"></script>
    	<script src="../static/js/uuid.js"></script>
    	<script src="../static/js/v-avatar-2.0.3.min.js"></script>
      <script src="../static/js/main.js"></script>
    </head>
    <body>
    	<div class="app user" id="app">
    		<div class="bg">
          <img src="../static/images/bg0.jpg">
        </div>
    		<img class="back" @click="back" src="../static/images/user_back.png" alt="">
    		<img class="setting" @click="goto_settings" src="../static/images/setting.png" alt="">
    		<div class="header">
    			<div class="info">
    				<div class="avatar">
    					<img class="avatar_bf" src="../static/images/avatar_bf.png" alt="">
    					<!-- <img class="user_avatar" :src="user_data.avatar" alt=""> -->
    					<div class="user_avatar">
    						<v-avatar v-if="user_data.avatar" :src="user_data.avatar" :size="56" :rounded="true"></v-avatar>
    						<v-avatar v-else-if="user_data.nickname" :username="user_data.nickname" :size="56" :rounded="true"></v-avatar>
    						<v-avatar v-else :username="user_data.id" :size="56" :rounded="true"></v-avatar>
    					</div>
    					<img class="avatar_border" src="../static/images/avatar_border.png" alt="">
    				</div>
    				<p class="user_name">{{user_data.nickname}}</p>
    			</div>
    			<div class="wallet">
    				<div class="balance">
    					<p class="title"><img src="../static/images/money.png" alt="">钱包</p>
    					<p class="num">{{game.money_format(user_data.money)}}</p>
    				</div>
    				<div class="balance">
    					<p class="title"><img src="../static/images/integral.png" alt="">果子</p>
    					<p class="num">{{game.money_format(user_data.credit)}}</p>
              <!-- <p class="num">99,999.00</p> -->
              <!-- <p class="num">1,999,999.00</p> -->
    				</div>
    			</div>
    			<div class="invite" @click="open_invite_page">
    				<img class="invite_btn" src="../static/images/invite.png" alt="">
    			</div>
    		</div>
    		<div class="menu">
    				<div class="item">
    					<span class="title">我的主页</span>
    					<span class="value">查看</span>
    				</div>
    				<div class="item" @click="open_friend_list">
    					<span class="title">好友列表</span>
    					<span class="value">查看</span>
    				</div>
    				<div class="item">
    					<span class="title">收益明细</span>
    					<span class="value">查看</span>
    				</div>
    				<div class="item">
    					<span class="title">实名认证</span>
    					<span class="value">未认证</span>
    				</div>
    				<div class="item">
    					<span class="title">问题反馈</span>
    					<span class="value">去反馈</span>
    				</div>
    			</ul>
    		</div>
    	</div>
    	<script>
    	apiready = function(){
        var game = new Game("../static/mp3/bg1.mp3");
        Vue.prototype.game = game;
    		new Vue({
    			el:"#app",
    			data(){
    				return {
    					user_data: {},
    				}
    			},
    			created(){
    				  let token = this.game.getfs("access_token") || this.game.getdata("access_token");
              this.user_data = this.game.get_user_by_token(token);
    					this.game.print(this.user_data);
    					this.listen();
    			},
    			methods:{
    					listen(){
    	          // 监听头像发生变化的通知
    	          this.listen_update_avatar();
    						// 监听昵称发生变化的通知
    						this.listen_update_nickname();
    	        },
    	        listen_update_avatar(){
    	          // 监听头像更新的通知
    	          api.addEventListener({
    	              name: 'update_avatar_success',
    	          }, (ret, err)=>{
    	              this.get_user_data();
    	          });
    	        },
    					listen_update_nickname(){
    						//监听昵称更新的通知
    						api.addEventListener({
    								name: 'update_nickname_success'
    						}, (ret, err)=>{
    								this.get_user_data();
    						});
    					},
    					get_user_data(){
    	          let token = this.game.getfs("access_token") || this.game.getdata("access_token");
    	          this.user_data = this.game.get_user_by_token(token);
    	          this.game.print(this.user_data);
    	        },
    				  back(){
                // 返回首页
                this.game.closeWin();
              },
    					goto_settings(){
    						// 打开配置页面
    						this.game.openFrame("settings","settings.html");
    					},
    					open_friend_list(){
    						// 打开好友列表
    						this.game.openFrame("friends","friends.html");
    						this.game.openFrame("friend_list","friend_list.html",null,{
    							x: 0,             // 左上角x轴坐标
    							y: 194,           // 左上角y轴坐标
    							w: 'auto',        // 当前帧页面的宽度, auto表示满屏
    							h: 'auto'         // 当前帧页面的高度, auto表示满屏
    						});
    					},
    					open_invite_page(){
    						// 邀请好友页面
    						this.game.openFrame("invite","invite.html",null,null,{
    	            type: "push", //动画类型(详见动画类型常量)
    	            subType: "from_top", //动画子类型(详见动画子类型常量)
    	            duration: 300 //动画过渡时间,默认300毫秒
    	          });
    					}
    			}
    		});
    	}
    	</script>
    </body>
    </html>
    
    1. 邀请好友页面html/invite.html,代码:
    <!DOCTYPE html>
    <html>
    <head>
    	<title>邀请好友</title>
    	<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    	<meta charset="utf-8">
    	<link rel="stylesheet" href="../static/css/main.css">
    	<script src="../static/js/vue.js"></script>
    	<script src="../static/js/axios.js"></script>
      <script src="../static/js/uuid.js"></script>
    	<script src="../static/js/main.js"></script>
    </head>
    <body>
    	<div class="app frame avatar" id="app">
        <div class="box">
          <p class="title">邀请好友</p>
          <img class="close" @click="back" src="../static/images/close_btn1.png" alt="">
          <div class="content">
    				<img class="invite_code" src="../static/images/code.jpg" alt="">
    			</div>
    			<p class="invite_tips">长按保存图片到相册</p>
        </div>
    	</div>
    	<script>
    	apiready = function(){
        var game = new Game("../static/mp3/bg1.mp3");
        // 在 #app 标签下渲染一个按钮组件
        Vue.prototype.game = game;
    		new Vue({
    			el:"#app",
    			data(){
    				return {
    
    				}
    			},
    			methods:{
            back(){
              this.game.closeFrame();
            },
    			}
    		});
    	}
    	</script>
    </body>
    </html>
    
    
    1. 添加代码样式: static/css/main.css,代码:
    .invite_code{
       14rem;
      height: 14rem;
      position: absolute;
      left: 7rem;
      top: 11rem;
    }
    .invite_tips{
      position: absolute;
      left: 7rem;
      top: 26.4rem;
      text-align: center;
      color: #fff;
      font-size: 1.5rem;
    }
    
    

    代码逻辑编写

    服务端提供基于二维码生成邀请码的接口

    flask-qrcode, 文档: https://marcoagner.github.io/Flask-QRcode/

    1. 安装二维码生成模块
    pip install flask-qrcode
    
    1. 项目入口文件初始化模块 ,application/__init__.py,代码:
    import os
    
    from flask import Flask
    from flask_script import Manager
    from flask_sqlalchemy import SQLAlchemy
    from flask_redis import FlaskRedis
    from flask_session import Session
    from flask_jsonrpc import JSONRPC
    from faker import Faker
    from celery import Celery
    from flask_jwt_extended import JWTManager
    from flask_admin import Admin
    from flask_babelex import Babel
    from xpinyin import Pinyin
    from flask_qrcode import QRcode
    
    from application.utils.config import init_config
    from application.utils.logger import Log
    from application.utils.commands import load_commands
    from application.utils.bluerprint import register_blueprint, path, include, api_rpc
    from application.utils import message, code
    from application.utils.unittest import BasicTestCase
    from application.utils.OssStore import OssStore
    
    # 终端脚本工具初始化
    manager = Manager()
    
    # SQLAlchemy初始化
    db = SQLAlchemy()
    
    # redis数据库初始化
    # - 1.默认缓存数据库对象,配置前缀为REDIS
    redis_cache = FlaskRedis(config_prefix='REDIS')
    # - 2.验证相关数据库对象,配置前缀为CHECK
    redis_check = FlaskRedis(config_prefix='CHECK')
    # - 3.验证相关数据库对象,配置前缀为SESSION
    redis_session = FlaskRedis(config_prefix='SESSION')
    
    # session储存配置初始化
    session_store = Session()
    
    # 自定义日志初始化
    logger = Log()
    
    # 初始化jsonrpc模块
    jsonrpc = JSONRPC()
    
    # 初始化随机生成数据模块faker
    faker = Faker(locale='zh-CN') # 指定中文
    
    # 初始化异步celery
    celery = Celery()
    
    # jwt认证模块初始化
    jwt = JWTManager()
    
    # 阿里云对象存储oss初始化
    oss = OssStore()
    
    # admin后台站点初始化
    admin = Admin()
    
    # 国际化和本地化的初始化
    babel = Babel()
    
    # 文字转拼音初始化
    pinyin = Pinyin()
    
    # 二维码生成模块初始化
    qrcode = QRcode()
    
    # 全局初始化
    def init_app(config_path):
        """全局初始化 - 需要传入加载开发或生产环境配置路径"""
        # 创建app应用对象
        app = Flask(__name__)
    
        # 当前项目根目录
        app.BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
        # 开发或生产环境加载配置
        init_config(app, config_path)
    
        # SQLAlchemy加载配置
        db.init_app(app)
    
        # redis加载配置
        redis_cache.init_app(app)
        redis_check.init_app(app)
        redis_session.init_app(app)
    
        """一定先加载默认配置,再传入APP加载session对象"""
        # session保存数据到redis时启用的链接对象
        app.config["SESSION_REDIS"] = redis_session
        # session存储对象加载配置
        session_store.init_app(app)
    
        # 为日志对象加载配置
        log = logger.init_app(app)
        app.log = log
    
        # json-rpc加载配置
        jsonrpc.init_app(app)
        # rpc访问路径入口(只有唯一一个访问路径入口),默认/api
        jsonrpc.service_url = app.config.get('JSON_SERVER_URL', '/api')
        jsonrpc.enable_web_browsable_api = app.config.get("ENABLE_WEB_BROWSABLE_API",False)
        app.jsonrpc = jsonrpc
    
        # 自动注册蓝图
        register_blueprint(app)
    
        # 加载celery配置
        celery.main = app.name
        celery.app = app
        # 更新配置
        celery.conf.update(app.config)
        # 自动注册任务
        celery.autodiscover_tasks(app.config.get('INSTALL_BLUEPRINT'))
    
        # jwt认证加载配置
        jwt.init_app(app)
    
        # faker作为app成员属性
        app.faker = faker
    
        # 注册模型,创建表
        with app.app_context():
            db.create_all()
    
        # 阿里云存储对象加载配置
        oss.init_app(app)
    
        # admin后台站点加载配置
        admin.name = app.config.get('FLASK_ADMIN_NAME') # 站点名称
        admin.template_mode = app.config.get('FLASK_TEMPLATE_MODE') # 使用的模板
        admin.init_app(app)
    
        # 国际化和本地化加载配置
        babel.init_app(app)
    
        # 二维码模块加载配置
        qrcode.init_app(app)
    
        # 终端脚本工具加载配置
        manager.app = app
    
        # 自动注册自定义命令
        load_commands(manager)
    
        return manager
    
    1. 视图提供生成二维码图片 : users/views.py,代码:
    from flask_jwt_extended import jwt_required
    from flask import make_response, current_app, request
    
    from application import qrcode
    # 引入装饰器
    from application.utils import decorator
    
    # 基于二维码模块生成邀请码
    @jwt_required()
    @decorator.get_user_object
    def invite_code(user):
        '''
        基于二维码模块生成邀请码
        :param user: 装饰器通过token获取的用户模型对象
        :return:
        '''
        # 获取用户头像,如果没有设置头像,则默认为项目配置中的默认头像
        if user.avatar:
            avatar = user.avatar
        else:
            avatar = current_app.config.get('DEFAULT_INVITE_LOGO')
    
        # 服务端访问地址,从配置文件中提取
        # 判断是否为开发环境
        if current_app.config.get('DEBUG'):
            SERVER_URL = 'DEV_SERVER_URL'
        else:
            SERVER_URL = 'SERVER_URL'
        # 获取服务端访问地址,如果没有就用请求地址
        # print(request.host_url[:-1]) # http://0.0.0.0:5000
        server_url = current_app.config.get(SERVER_URL, request.host_url[:-1])
    
        # 编写邀请码中携带的地址
        invite_url = server_url + '/users/invite?type=invite&uid=%s'%user.id
    
        # 生成二维码图片数据
        # qrcode基于mode=raw生成的图片数据格式是 BytesIO, flask返回图片需要bytes类型数据
        # 所以需要把BytesIO通过getvalue方法转成bytes
        image = qrcode.qrcode(invite_url, mode='raw', box_size=16, icon_img=avatar)
        image = image.getvalue()
    
        response = make_response(image)
        # 设置响应头类型
        response.headers['Content-Type'] = 'image/png'
    
        return response
    
    1. 开发环境配置文件 application/settings/dev.py,配置代码:
    """邀请二维码"""
    # 默认LOGO
    DEFAULT_INVITE_LOGO = "https://mofang32.oss-cn-beijing.aliyuncs.com/680cda4f-2868-4abf-95b0-6eb5240bfd39.jpeg"
    # 服务端的访问地址
    SERVER_URL = "http://www.mofang.com:5000"
    DEV_SERVER_URL = "http://192.168.19.46:5000" # 开发环境使用主机IP地址
    
    1. 路由: user/urls.py,代码:
    from application import path, api_rpc
    # 引入当前蓝图应用视图 , 引入rpc视图
    from . import views, api
    
    # 蓝图路径与函数映射列表
    urlpatterns = [
        path('invite.png', views.invite_code), # 生成邀请码,推广应用
    ]
    
    # rpc方法与函数映射列表[rpc接口列表]
    apipatterns = [
        api_rpc('check_mobile', api.check_mobile),
        api_rpc('register', api.register),
        api_rpc('login', api.login),
        api_rpc('refresh', api.refresh_token), # 刷新access_token值
        api_rpc('update_avatar', api.update_avatar), # 更新头像
        api_rpc('update_nickname', api.update_nickname), # 更新昵称
        api_rpc('update_mobile', api.update_mobile), # 更新手机号
        api_rpc('update_password', api.update_password), # 更新登录密码
        api_rpc('update_pay_password', api.update_pay_password), # 更新交易密码
        api_rpc('get_apply_friend_history', api.get_apply_friend_history), # 获取好友申请列表
        api_rpc('search_user_info', api.search_user_info), # 搜索用户信息
        api_rpc('apply_friend', api.apply_friend), # 添加用户好友申请记录
        api_rpc('add_friend', api.add_friend), # 添加用户好友关系记录
        api_rpc('cancel_apply_friend', api.cancel_apply_friend), # 用户取消自己申请的好友记录
        api_rpc('get_friend_list', api.get_friend_list), # 获取好友列表
    ]
    
    
    1. 获取好友邀请码访问地址:
    http://0.0.0.0:5000/users/invite.png?jwt=(access_token值)
    
    

    客户端获取好友邀请码

    1. 获取好友邀请码, 并且长按保存图片到相册中 ,html/invite.html,代码:
    <!DOCTYPE html>
    <html>
        <head>
            <title>邀请好友</title>
            <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
            <meta charset="utf-8">
            <link rel="stylesheet" href="../static/css/main.css">
            <script src="../static/js/vue.js"></script>
            <script src="../static/js/axios.js"></script>
            <script src="../static/js/uuid.js"></script>
            <script src="../static/js/main.js"></script>
        </head>
        <body>
            <div class="app frame avatar" id="app">
                <div class="box">
                    <p class="title">邀请好友</p>
                    <img class="close" @click="back" src="../static/images/close_btn1.png" alt="">
                    <div class="content">
                        <img class="invite_code" :src="invite_code" alt="">
                    </div>
                    <p class="invite_tips">长按保存图片到相册</p>
                </div>
            </div>
            <script>
                apiready = function(){
                    var game = new Game("../static/mp3/bg1.mp3");
                    // 在 #app 标签下渲染一个按钮组件
                    Vue.prototype.game = game;
                    new Vue({
                        el:"#app",
                        data(){
                            return {
                                invite_code: '', // 好友邀请码图片地址
                            }
                        },
                        created(){
                            this.get_invite_code(); // 获取好友邀请码地址
                            this.listen(); // 监听事件
                        },
                        methods:{
                            // 监听事件
                            listen(){
                                // 监听长按事件
                                this.listen_long_press();
                            },
    
                            // 监听长按邀请码事件
                            listen_long_press(){
                                api.addEventListener({
                                    name: 'longpress' // 监听系统长按页面事件
                                }, (ret, err)=>{
                                    // 保存图片或视频到本地相册
                                    api.saveMediaToAlbum({
                                        path: this.invite_code
                                    }, (ret, err)=>{
                                        if (ret && ret.status) {
                                            this.game.tips('保存二维码成功!')
                                        } else {
                                            this.game.tips('保存二维码失败!')
                                        }
                                    });
                                });  
                            },
    
    
                            back(){
                                this.game.closeFrame();
                            },
                            // 获取好友邀请码地址
                            get_invite_code(){
                                let self = this
                                self.game.check_user_login(self, () => {
                                    let token = self.game.getdata('access_token') || self.game.getfs('access_token')
                                    // 拼接好友邀请码地址
                                    self.invite_code = self.game.config.HTTP_SERVER + 'users/invite.png?jwt=' + token
                                })
                            },
    
    
                        }
                    });
                }
            </script>
        </body>
    </html>
    
    
    
    1. static/js/main.js中新增HTTP_SERVER(网关地址)配置项,代码:
       // 初始化配置
    	init_config(){
    		// 客户端项目的全局配置
    		this.config = {
    			// 服务端API地址
    			// API_SERVER:"http://192.168.189.138:5000/api",
    			API_SERVER:"http://192.168.19.46:5000/api",
    			// http服务端网关地址
    			HTTP_SERVER: 'http://192.168.19.46:5000/',
    			SMS_TIME_OUT: 60 , // 短信发送冷却时间/秒
    			CAPTCHA_APP_ID: "2028945858", // 防水墙验证码应用ID
    		}
    	}
    
    

    扫描识别邀请码,下载应用软件

    服务端提供对应的接口允许访问

    1. 视图提供users/views.py
    from flask import make_response, current_app, request, render_template
    
    # 根据二维码识别进入的唤醒/下载APP视图
    def invite():
        '''根据二维码识别进入的唤醒/下载APP视图'''
        # 提取二维码中隐藏链接的参数信息
        uid = request.args.get('uid') # 用户ID
        user_type = request.args.get('type') # 用途来源
    
        # 识别用户信息
        user = services.get_user_by_id(id = uid)
        # todo 用户邀请好友的奖励方法,将来方便进行奖励处理
        # services.apply_user(user)
    
        # 识别用户当前使用的访问代理(使用什么软件扫描的二维码)
        user_agent = request.headers.get('User-Agent').lower()
        if 'micromessenger' in user_agent:
            client_agent = 'weixin' # 使用微信扫描的
        elif 'alipayclient' in user_agent:
            client_agent = 'alipay' # 使用支付宝扫描的
        else:
            client_agent = 'others' # 使用其他软件扫描的
    
        # 判断用途来源
        if user_type == 'invite':
            '''邀请好友的'''
            data = {
                'uid': uid,
                'user_tpye': user_type,
                'client_agent': client_agent
            }
            # 返回模板界面
            return render_template('users/invite.html', **data)
    
        return 'hello world !'
    
    
    1. 模板目录下创建对应的html模板文件,application/templates/users/invite.html, 代码:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
        <meta >
        <title>Title</title>
        <style>
        body{
            background-color: #000;
        }
        img{
             100%;
        }
        a{
            color: #fff;
        }
        </style>
    </head>
    <body>
        {% if client_agent == "weixin" %}
            <img src="/static/openbrowser.png" alt="">
        {% else %}
            <div id="content"></div>
            <script>
            // 尝试通过打开客户端已经安装的魔方APP
            var iframe = document.createElement("iframe");
            iframe.src = "mofang://?uid={{ uid }}&user_type={{user_type}}"; // app的私有协议,在用户已经安装了app以后,可以自动唤醒APP
            iframe.hidden=true; // iframe.style.display="none";
            document.body.appendChild(iframe);
    
            // 如果等待了3秒以后,还没有切换APP
            setTimeout(function() {
              if (!document.hidden) {
                // 在3秒内如果页面出去了。说明这个时候document.hidden是true,这段代码就不执行了。
                // 就算是再切回来也是不执行的。
                // 如果你进了这个函数,没离开。。那就会在3秒后跳进这里
                alert('你还没安装魔方APP,赶紧下载吧,你的好友朋友都在等哦~');
    
                // 自动下载
                var iframe = document.createElement("iframe");
                iframe.src = "/static/app/mofang.apk"; // app所在的下载地址
                iframe.hidden=true;
                document.body.appendChild(iframe);
    
                // 让用户自己手动点击下载链接
                u = navigator.userAgent;
                let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
                let isiOS = !!u.match(/(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
                var content = document.querySelector("#content");
                if (isiOS) {
                    // 去下载ios版本的魔方APP
                    content.innerHTML = `<a href="/static/app/mofang.ipa">点击链接下载魔方APP</a>`;
                }
                if (isAndroid){
                    // 去下载安卓版本的魔方APP
                    content.innerHTML = `<a href="/static/app/mofang.apk">点击链接下载魔方APP</a>`;
                }
              }
            }, 3000);
    
            </script>
        {% endif %}
    </body>
    </html>
    
    

    (1) 把素材中的openbrowser.png图片放到静态文件中application/static/image

    (2) 把客户端编译过的APP下载包, 放置到静态文件 application/static/app 中, 方便视图调用下载

    1. 注册视图路由: ,users.urls,代码:
    from application import path, api_rpc
    # 引入当前蓝图应用视图 , 引入rpc视图
    from . import views, api
    
    # 蓝图路径与函数映射列表
    urlpatterns = [
        path('invite.png', views.invite_code), # 生成邀请码,推广应用
        path('invite', views.invite), # 唤醒或下载APP软件
    ]
    
    # rpc方法与函数映射列表[rpc接口列表]
    apipatterns = [
        api_rpc('check_mobile', api.check_mobile),
        api_rpc('register', api.register),
        api_rpc('login', api.login),
        api_rpc('refresh', api.refresh_token), # 刷新access_token值
        api_rpc('update_avatar', api.update_avatar), # 更新头像
        api_rpc('update_nickname', api.update_nickname), # 更新昵称
        api_rpc('update_mobile', api.update_mobile), # 更新手机号
        api_rpc('update_password', api.update_password), # 更新登录密码
        api_rpc('update_pay_password', api.update_pay_password), # 更新交易密码
        api_rpc('get_apply_friend_history', api.get_apply_friend_history), # 获取好友申请列表
        api_rpc('search_user_info', api.search_user_info), # 搜索用户信息
        api_rpc('apply_friend', api.apply_friend), # 添加用户好友申请记录
        api_rpc('add_friend', api.add_friend), # 添加用户好友关系记录
        api_rpc('cancel_apply_friend', api.cancel_apply_friend), # 用户取消自己申请的好友记录
        api_rpc('get_friend_list', api.get_friend_list), # 获取好友列表
    ]
    
    
    
    

    客户端

    App配置私有协议, 允许第三方应用通过私有协议唤醒魔方APP

    1. config.xml 中配置添加 <preference name="urlScheme" value="mofang" />
     <widget id="A6177994729952"  version="0.0.1">
    
        <name>mofangapp</name>
    
        <description>
    
            Example For APICloud.
    
        </description>
    
        <author email="developer@apicloud.com" href="http://www.apicloud.com">
    
            Developer
    
        </author>
    
        <content src="html/index.html" />
    
        <access origin="*" />
    
        <preference name="pageBounce" value="false"/>
    
    	<preference name="appBackground" value="rgba(0,0,0,0.0)"/>
    
    	<preference name="windowBackground" value="rgba(0,0,0,0.0)"/>
    
    	<preference name="frameBackgroundColor" value="rgba(0,0,0,0.0)"/>
    
    	<preference name="hScrollBarEnabled" value="false"/>
    
    	<preference name="vScrollBarEnabled" value="false"/>
    
    	<preference name="autoLaunch" value="true"/>
    
    	<preference name="fullScreen" value="false"/>
    
    	<preference name="autoUpdate" value="true" />
    
    	<preference name="smartUpdate" value="false" />
    
    	<preference name="debug" value="true"/>
    
    	<preference name="statusBarAppearance" value="true"/>
      <!-- 配置app私有协议, 可通过协议唤醒魔方APP软件 -->
      <preference name="urlScheme" value="mofang" />
    
    	<permission name="readPhoneState" />
    
    	<permission name="camera" />
    
    	<permission name="record" />
    
    	<permission name="location" />
    
    	<permission name="fileSystem" />
    
    	<permission name="internet" />
    
    	<permission name="bootCompleted" />
    
    	<permission name="hardware" />
    
    </widget>
    
    
    
    1. APP默认首页index.html中监听是否来自第三方应用的唤醒.并接收唤醒时附带的参数信息.

    html/index.html,代码:

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <title>首页</title>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
            <meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
            <link rel="stylesheet" href="../static/css/main.css">
            <script src="../static/js/vue.js"></script>
            <script src="../static/js/axios.js"></script>
            <script src="../static/js/uuid.js"></script>
            <script src="../static/js/main.js"></script>
        </head>
        <body>
            <div class="app" id="app">
                <img class="music" :class="music_play?'music2':''" @click="music_play=!music_play" src="../static/images/player.png">
                <div class="bg">
                    <img src="../static/images/bg0.jpg">
                </div>
                <ul>
                    <li><img class="module1" src="../static/images/image1.png"></li>
                    <li><img class="module2" src="../static/images/image2.png" @click='to_user'></li>
                    <li><img class="module3" src="../static/images/image3.png"></li>
                    <li><img class="module4" src="../static/images/image4.png" @click='to_login'></li>
                </ul>
            </div>
            <script>
                apiready = function(){
                    var game = new Game("../static/mp3/bg1.mp3");
                    Vue.prototype.game = game;
                    new Vue({
                        el:"#app",
                        data(){
                            return {
                                music_play:true,  // 默认播放背景音乐
                                prev:{name:"",url:"",params:{}}, // 上一页状态
                                current:{name:"index",url:"index.html","params":{}}, // 下一页状态
                            }
                        },
                        watch:{
                            music_play(){
                                if(this.music_play){
                                    this.game.play_music("../static/mp3/bg1.mp3");
                                }else{
                                    this.game.stop_music();
                                }
                            }
                        },
                        created(){
                            this.listen(); // 监听事件
                        },
                        methods:{
                            // 监听事件
                            listen(){
                                // 监听外部访问,唤醒app
                                this.listen_invite();
                            },
    
                            // 监听外部访问,唤醒app
                            listen_invite(){
                                // 使用系统方法appintenr监听并使用appParam接收URLScheme的路由参数
                                // 收集操作保存起来,并跳转到登陆页面.
                                api.addEventListener({
                                    name: 'appintent' // 系统方法
                                }, (ret, err)=>{
                                    // 获取路由参数,保存到本地
                                    let appParam = ret.appParam;
                                    // this.game.print(appParam,1); //{"uid":xxx,"user_type":xxx};
                                    this.game.setfs(appParam)
    
                                    // 如果是其他用户邀请注册!
                                    if(appParam.user_type == 'invite'){
                                        // 跳转到登陆页面
                                        this.game.openWin('login', 'login.html')
                                    }
                                });
                            },
    
                            // 点击签到跳转登陆页面
                            to_login(){
                                this.game.openWin('login','login.html')
                            },
                            // 点击跳转到个人中心页面
                            to_user(){
                                // 判断用户是否登陆
                                this.game.check_user_login(this,() => {
                                    this.game.openWin('user', 'user.html')
                                });
                            },
    
                        }
                    })
                }
            </script>
        </body>
    </html>
    
    
    

    编译生成apk安装包

    接下来的开发,我们不能再依赖官方提供的AppLoader进行功能测试了,所以我们使用由APICloud编辑器提供的本地编译, 编译自定义APPLoader来进行测试。

    1. 编译APP,则是生成一个独立的APP,无法进行终端调试,后续如果客户端代码更新,需要重新生成APP。
    2. 编译自定义APPLoader,则是生成一个新的调试加载器工具,可以进行终端调试,可以配置网络参数。

  • 相关阅读:
    AndroidManifest.xml文件详解(uses-feature) (转载)
    两分钟彻底让你明白Android Activity生命周期(图文)! (转载)
    android studio学习----添加项目依赖包补充---添加github上的开源项目为库
    android studio学习----添加项目依赖包总结
    android studio学习----如何创建一个库项目
    android studio学习----添加项目库
    android studio学习----通过libs来导入jar包
    android studio学习----通过gradle来导入jar包
    android studio学习----gradle配置
    android studio学习----构建(gradle )依赖时使用动态依赖的问题
  • 原文地址:https://www.cnblogs.com/jia-shu/p/14923313.html
Copyright © 2011-2022 走看看