唤醒app_唤醒app的方法 - CSDN
精华内容
参与话题
  • html5点击唤醒app

    千次阅读 2019-02-28 10:01:58
    h5页面唤醒app,以淘宝为例子 <a onclick="openApp()">点击唤醒app</a> js <script> var download_schema = 'taobao://'; //app的协议有安卓同事提供,...

    h5页面唤醒app,以淘宝为例子

    <a onclick="openApp()">点击唤醒app</a>	

    js

    <script>
    var download_schema = 'taobao://'; //app的协议有安卓同事提供,这里是用的淘宝
    var universal_link = 'ios下载地址';//ios下载地址
    var getVersionUrl = 'Android下载地址';//Android移动端下载地址
    var u = navigator.userAgent.toLocaleLowerCase();
    //console.log(u);
    var isWeixin = u.match(/MicroMessenger/i) == 'micromessenger'; //判断是不是微信浏览器
    var isAndroid = u.indexOf('android') > -1 || u.indexOf('linux') > -1; //android终端或者uc浏览器
    var isiOS = !! u.match(/(iphone|ipod|ipad|mac)/i);
     
    function openApp() {
        //alert('1');
        //alert(isAndroid);
        //alert(isiOS);
        if (isAndroid) {
            android1();
        }
        if (isiOS) {
            ios();
        }
        //alert("调用下载失败"); //此处弹窗时,是没有version参数,如果在app中打开,是会有这个参数的
    }
     
    function android1() {
        //如果是微信,直接下载
        if (isWeixin) {
            window.location.href = "Android下载地址 "; /***Android移动端下载地址***/
        } else {
            window.location.href = download_schema; /***打开app的协议,有安卓同事提供***/
            window.setTimeout(function () {
                //window.location.href = "Android下载地址";/***Android移动端下载地址***/
                window.location.href = getVersionUrl; /***Android移动端下载地址***/
            }, 100);
        }
    }
     
    function ios() {
        window.location.href = universal_link + "?schema=" + encodeURIComponent(download_schema);
    } 
    </script>

     

     

    展开全文
  • 可以说黑色保活,可以通过网络切换,拍照,拍视频,开机,利用系统产生的广播唤醒app,接入三方的sdk也会唤醒一些app,如支付宝,微信..........这样的话,这样的话,不敢想象系统存活会给系统带来多大的负担,所以...

    安卓进程进程保活分为:

    黑色保活,白色保活,灰色保活

    黑色保活:

    可以说黑色保活,可以通过网络切换,拍照,拍视频,开机,利用系统产生的广播唤醒app,接入三方的sdk也会唤醒一些app,如支付宝,微信..........这样的话,这样的话,不敢想象系统存活会给系统带来多大的负担,所以我们的安卓手机也变得卡了,google官方可能也认识了这么一点,所以取消了

    ACTION_NEW_PICTURE(拍照),ACTION_NEW_VIDEO(拍视频),CONNECTIVITY_ACTION(网络切换)

    app也会随着做一点改变,(不过sdk的使用还是会通过一个app启动相关的一些app , 黑色保活我个人认为不推荐使用,毕竟为了我们广大安卓用户。)

    白色保活:

    白色保活手段非常简单,就是调用系统api启动一个前台的Service进程,这样会在系统的通知栏生成一个Notification,用来让用户知道有这样一个app在运行着,哪怕当前的app退到了后台。

    不过用户看到这个图标的时候,都会把它清空的。。。。

    灰色保活:

    可以说,灰色保活是用的最多,当用户不知不觉中这个app程序已经在后台运行了。

    它是利用系统的漏洞来启动一个前台的Service进程,与普通的启动方式区别在于,它不会在系统通知栏处出现一个Notification,看起来就如同运行着一个后台Service进程一样。这样做带来的好处就是,用户无法察觉到你运行着一个前台进程(因为看不到Notification),但你的进程优先级又是高于普通后台进程的。API < 18,启动前台Service时直接传入new Notification();API >= 18,同时启动两个id相同的前台Service,然后再将后启动的Service做stop处理;

    安卓app唤醒:

    其实app唤醒的介绍很好说,app唤醒就是当打开一个app的时候,另一个app里有对应刚打开那个app的属性标志,根据你想要的唤醒方式,执行不同的代码操作,这样就可以唤醒另一个没打开的app了。(代码在最下面)

    下面我展示一下这几种状态下的代码:

    这个是xml布局,主要是为了展示我所介绍的几种保活方式:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin">
    
        <Button
            android:id="@+id/mBtn_white"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="白色保活" />
    
        <Button
            android:id="@+id/mBtn_gray"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="灰色保活" />
    
        <Button
            android:id="@+id/mBtn_black"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="黑色保活(发广播)" />
    
        <Button
            android:id="@+id/mBtn_background_service"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="普通后台 Service 进程" />
    
    </LinearLayout>

    下面是主要实现类:

    WakeReceiver

    import android.app.Notification;
    import android.app.Service;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Build;
    import android.os.IBinder;
    import android.util.Log;
    
    public class WakeReceiver extends BroadcastReceiver {
        private final static String TAG = WakeReceiver.class.getSimpleName();
        private final static int WAKE_SERVICE_ID = -1111;
        /**
         * 灰色保活手段唤醒广播的action
         */
        public final static String GRAY_WAKE_ACTION = "com.wake.gray";
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (GRAY_WAKE_ACTION.equals(action)) {
                Log.i(TAG, "wake !! wake !! ");
    
                Intent wakeIntent = new Intent(context, WakeNotifyService.class);
                context.startService(wakeIntent);
            }
        }
        /**
         * 用于其他进程来唤醒UI进程用的Service
         */
        public static class WakeNotifyService extends Service {
    
            @Override
            public void onCreate() {
                Log.i(TAG, "WakeNotifyService->onCreate");
                super.onCreate();
            }
    
            @Override
            public int onStartCommand(Intent intent, int flags, int startId) {
                Log.i(TAG, "WakeNotifyService->onStartCommand");
                if (Build.VERSION.SDK_INT < 18) {
                    startForeground(WAKE_SERVICE_ID, new Notification());//API < 18 ,此方法能有效隐藏Notification上的图标
                } else {
                    Intent innerIntent = new Intent(this, WakeGrayInnerService.class);
                    startService(innerIntent);
                    startForeground(WAKE_SERVICE_ID, new Notification());
                }
                return START_STICKY;
            }
    
            @Override
            public IBinder onBind(Intent intent) {
                // TODO: Return the communication channel to the service.
                throw new UnsupportedOperationException("Not yet implemented");
            }
    
            @Override
            public void onDestroy() {
                Log.i(TAG, "WakeNotifyService->onDestroy");
                super.onDestroy();
            }
        }
    
        /**
         * 给 API >= 18 的平台上用的灰色保活手段
         */
        public static class WakeGrayInnerService extends Service {
    
            @Override
            public void onCreate() {
                Log.i(TAG, "InnerService -> onCreate");
                super.onCreate();
            }
    
            @Override
            public int onStartCommand(Intent intent, int flags, int startId) {
                Log.i(TAG, "InnerService -> onStartCommand");
                startForeground(WAKE_SERVICE_ID, new Notification());
                //stopForeground(true);
                stopSelf();
                return super.onStartCommand(intent, flags, startId);
            }
    
            @Override
            public IBinder onBind(Intent intent) {
                // TODO: Return the communication channel to the service.
                throw new UnsupportedOperationException("Not yet implemented");
            }
    
            @Override
            public void onDestroy() {
                Log.i(TAG, "InnerService -> onDestroy");
                super.onDestroy();
            }
        }
    }

    BackGroundService

    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.util.Log;
    
    /**
     * 普通的后台Service进程
     *
     * @author clock
     * @since 2016-04-12
     */
    public class BackgroundService extends Service {
    
        private final static String TAG = BackgroundService.class.getSimpleName();
    
        @Override
        public void onCreate() {
            Log.i(TAG, "onCreate");
            super.onCreate();
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
            throw new UnsupportedOperationException("Not yet implemented");
        }
    
        @Override
        public void onDestroy() {
            Log.i(TAG, "onDestroy");
            super.onDestroy();
        }
    }

    GrayService

    import android.app.AlarmManager;
    import android.app.Notification;
    import android.app.PendingIntent;
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Build;
    import android.os.IBinder;
    import android.util.Log;
    import com.example.renzheng.receiver.WakeReceiver;
    
    /**
     * 灰色保活手法创建的Service进程
     *
     * @author Clock
     * @since 2016-04-12
     */
    public class GrayService extends Service {
    
        private final static String TAG = GrayService.class.getSimpleName();
        /**
         * 定时唤醒的时间间隔,5分钟
         */
        private final static int ALARM_INTERVAL = 5 * 60 * 1000;
        private final static int WAKE_REQUEST_CODE = 6666;
    
        private final static int GRAY_SERVICE_ID = -1001;
    
        @Override
        public void onCreate() {
            Log.i(TAG, "GrayService->onCreate");
            super.onCreate();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.i(TAG, "GrayService->onStartCommand");
            if (Build.VERSION.SDK_INT < 18) {
                startForeground(GRAY_SERVICE_ID, new Notification());//API < 18 ,此方法能有效隐藏Notification上的图标
            } else {
                Intent innerIntent = new Intent(this, GrayInnerService.class);
                startService(innerIntent);
                startForeground(GRAY_SERVICE_ID, new Notification());
            }
    
            //发送唤醒广播来促使挂掉的UI进程重新启动起来
            AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            Intent alarmIntent = new Intent();
            alarmIntent.setAction(WakeReceiver.GRAY_WAKE_ACTION);
            PendingIntent operation = PendingIntent.getBroadcast(this, WAKE_REQUEST_CODE, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), ALARM_INTERVAL, operation);
    
            return START_STICKY;
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            throw new UnsupportedOperationException("Not yet implemented");
        }
    
        @Override
        public void onDestroy() {
            Log.i(TAG, "GrayService->onDestroy");
            super.onDestroy();
        }
    
        /**
         * 给 API >= 18 的平台上用的灰色保活手段
         */
        public static class GrayInnerService extends Service {
    
            @Override
            public void onCreate() {
                Log.i(TAG, "InnerService -> onCreate");
                super.onCreate();
            }
    
            @Override
            public int onStartCommand(Intent intent, int flags, int startId) {
                Log.i(TAG, "InnerService -> onStartCommand");
                startForeground(GRAY_SERVICE_ID, new Notification());
                //stopForeground(true);
                stopSelf();
                return super.onStartCommand(intent, flags, startId);
            }
    
            @Override
            public IBinder onBind(Intent intent) {
                // TODO: Return the communication channel to the service.
                throw new UnsupportedOperationException("Not yet implemented");
            }
    
            @Override
            public void onDestroy() {
                Log.i(TAG, "InnerService -> onDestroy");
                super.onDestroy();
            }
        }
    }

    WhileService

    import android.app.Notification;
    import android.app.PendingIntent;
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.support.v7.app.NotificationCompat;
    import android.util.Log;
    import com.example.renzheng.MainActivity;
    import com.example.renzheng.R;
    /**
     * 正常的系统前台进程,会在系统通知栏显示一个Notification通知图标
     *
     * @author clock
     * @since 2016-04-12
     */
    public class WhiteService extends Service {
    
        private final static String TAG = WhiteService.class.getSimpleName();
        private final static int FOREGROUND_ID = 1000;
    
        @Override
        public void onCreate() {
            Log.i(TAG, "WhiteService->onCreate");
            super.onCreate();
        }
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.i(TAG, "WhiteService->onStartCommand");
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
            builder.setSmallIcon(R.mipmap.ic_launcher);
            builder.setContentTitle("Foreground");
            builder.setContentText("I am a foreground service");
            builder.setContentInfo("Content Info");
            builder.setWhen(System.currentTimeMillis());
            Intent activityIntent = new Intent(this, MainActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, activityIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            builder.setContentIntent(pendingIntent);
            Notification notification = builder.build();
            startForeground(FOREGROUND_ID, notification);
            return super.onStartCommand(intent, flags, startId);
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
            throw new UnsupportedOperationException("Not yet implemented");
        }
    
        @Override
        public void onDestroy() {
            Log.i(TAG, "WhiteService->onDestroy");
            super.onDestroy();
        }
    }

    MainActivity

    import android.content.Intent;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import com.example.renzheng.service.BackgroundService;
    import com.example.renzheng.service.GrayService;
    import com.example.renzheng.service.WhiteService;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
        private final static String TAG = MainActivity.class.getSimpleName();
        /**
         * 黑色唤醒广播的action
         */
        private final static String BLACK_WAKE_ACTION = "com.wake.black";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            findViewById(R.id.mBtn_white).setOnClickListener(this);
            findViewById(R.id.mBtn_gray).setOnClickListener(this);
            findViewById(R.id.mBtn_black).setOnClickListener(this);
            findViewById(R.id.mBtn_background_service).setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            int viewId = v.getId();
            if (viewId == R.id.mBtn_white) { //系统正常的前台Service,白色保活手段
                Intent whiteIntent = new Intent(getApplicationContext(), WhiteService.class);
                startService(whiteIntent);
    
            } else if (viewId == R.id.mBtn_gray) {//利用系统漏洞,灰色保活手段(API < 18 和 API >= 18 两种情况)
                Intent grayIntent = new Intent(getApplicationContext(), GrayService.class);
                startService(grayIntent);
    
            } else if (viewId == R.id.mBtn_black) { //拉帮结派,黑色保活手段,利用广播唤醒队友
                Intent blackIntent = new Intent();
                blackIntent.setAction(BLACK_WAKE_ACTION);
                sendBroadcast(blackIntent);
    
            } else if (viewId == R.id.mBtn_background_service) {//普通的后台进程
                Intent bgIntent = new Intent(getApplicationContext(), BackgroundService.class);
                startService(bgIntent);
            }
        }
    }

    代码注册权限:

     

    <receiver
        android:name=".receiver.WakeReceiver"
        android:enabled="true"
        android:exported="false">
        <intent-filter>
            <action android:name="com.wake.gray" />
        </intent-filter>
    </receiver>
    
    <service
        android:name=".service.WhiteService"
        android:enabled="true"
        android:exported="false"
        android:process=":white" />
    <service
        android:name=".service.GrayService"
        android:enabled="true"
        android:exported="false"
        android:process=":gray" />
    <service
        android:name=".service.GrayService$GrayInnerService"
        android:enabled="true"
        android:exported="false"
        android:process=":gray" />
    <service
        android:name=".service.BackgroundService"
        android:enabled="true"
        android:exported="false"
        android:process=":bg" />
    <service
        android:name=".receiver.WakeReceiver$WakeNotifyService"
        android:enabled="true"
        android:exported="false" />
    
    <service
        android:name=".receiver.WakeReceiver$WakeGrayInnerService"
        android:enabled="true"
        android:exported="false" />

     

    下面是app唤醒代码:

    有2个APP,分别为A和B,当A活着的时候,试着开启B的后台服务,将原本杀死的B的后台服务程序活起来。反之也一样。

    1.先看B的代码:

    创建一个服务B,给服务添加一个process属性,设置action。

    
     
    <service
        android:name=".B"
        android:process=":test">
        <intent-filter>
            <action android:name="yangyang" />
        </intent-filter>
    </service>

    B的代码,在onStartCommand方法中弹出toast:

    public class B extends Service {
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
    
            Toast.makeText(this, "B 已经唤醒", Toast.LENGTH_SHORT).show();
            return START_STICKY;
        }
    }

    2.看A的代码,在MainActivity中点击开启B应用的B服务的代码:

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_main);
    
            Button btn = (Button) findViewById(R.id.btn);
    
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    sendService();
                }
            });
        }
    
        private void sendService() {
            boolean find = false;
    
            ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
            Intent serviceIntent = new Intent();
    
            for (ActivityManager.RunningServiceInfo runningServiceInfo : mActivityManager.getRunningServices(100)) {
                if (runningServiceInfo.process.contains(":test")) {//判断service是否在运行
                    Log.e("zhang", "process:" + runningServiceInfo.process);
                    find = true;
                }
            }
            //判断服务是否起来,如果服务没起来,就唤醒
            if (!find) {
                serviceIntent.setPackage("com.example.b);
                serviceIntent.setAction("yangyang");
                startService(serviceIntent);
                Toast.makeText(this, "开始唤醒 B", Toast.LENGTH_SHORT).show();
            }else {
                Toast.makeText(this, "B 不用唤醒", Toast.LENGTH_SHORT).show();
            }
        }
    }

    这里只是写了A启动B服务的代码,反之也是一样的。被启动应用的Servcie在AndroidMainfest.xml中注册时注意,添加process属性,和设置action匹配规则。

    展开全文
  • 安卓:从网页唤醒APP

    千次阅读 2019-05-28 10:22:59
    从网页打开APP,如果没有安装就进行下载。 安卓AndroidMainfext.xml 在要启动的activity下面添加一个intent-filter。 &lt;intent-filter&gt; &lt;action android:name="android.intent....

    前言

    现在都流行立体式的互联网,一般公司都会有自己的APP,网站,微信公众号,小程序等众多流量入口。为了更好的用户体验,也为了提高用户粘度,打通这些程序的入口,使其联动成为一体十分重要,以此达到相互引流的作用。
    APP和网页之间的联动最为常见。很多网页都有这样的功能:在网页点击某一个按钮,或者跳转到某一网页之后,就会唤醒APP,以此达到联动效果。

    分析

    我们都知道各个系统用的开发语言不尽相同,那么这种效果到底是如何做的呢?
    答案就是……scheme。
    对应到安卓中就是具体表现为 xml 中的 android:scheme 属性,通过<intent-filter> 设置data,已达到类似Intent的隐式匹配的效果。
    当然跳转之前还需要做次判断,如果手机中没有安装APP,则跳转到对应的下载网页。

    从网页打开APP,如果没有安装就进行下载。当然,也可以做别的操作处理,比如跳转应用市场一类的详情页面。在此仅提供思路,欢迎发散思维。

    网页唤醒APP,除了安卓外,ios也可以达到同样效果。不过scheme等略有不同,这就需要在网页中去判断当前设备是否是安卓设备。常见的判断方法就是通过网络请求中的UA去判断。

    UA,全称是 User Agent,中文名为用户代理,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。

    言归正传 ,我们来看一下如何实现

    实现

    安卓AndroidMainfext.xml

    首先需要指定要启动哪一个Activity,然后为该activity设置添加intent-filter。
    在要启动的activity下面添加一个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:host="splash" android:scheme="vchao" />
           </intent-filter>
    

    html 网页

    在网页中,我们这里只做了简单的处理,点击的时候进行判断跳转。

    <!doctype html>
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    
            <meta name="apple-mobile-web-app-capable" content="yes">
            <meta name="apple-mobile-web-app-status-bar-style" content="black"/>
    
            <title>唤醒APP</title>
            <meta id="viewport" name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,minimal-ui">
        </head>
        <body>
            <div>
                <a id="J-call-app" href="javascript:;" class="label">立即打开&gt;&gt;</a>
                <input id="J-download-app" type="hidden" name="storeurl" value="http://m.chanyouji.cn/apk/chanyouji-2.2.0.apk">
            </div>
    
            <script>
                (function(){
                    /*获取UA标识,并转为小写*/
                    var ua = navigator.userAgent.toLowerCase();
                    var t;
                    var config = {
                        /*scheme:必须*/
                        scheme_IOS: 'vchao://',
                        scheme_Adr: 'vchao://splash',
                        download_url: document.getElementById('J-download-app').value,
                        timeout: 600
                    };
    
                    function openclient() {
                        var startTime = Date.now();
    
                        var ifr = document.createElement('iframe');
                        
                        /*通过UA标识,判断是否是苹果系统*/
                        ifr.src = ua.indexOf('os') > 0 ? config.scheme_IOS : config.scheme_Adr;
                        ifr.style.display = 'none';
                        document.body.appendChild(ifr);
    
                        var t = setTimeout(function() {
                            var endTime = Date.now();
    
                            if (!startTime || endTime - startTime < config.timeout + 200) { 
                                window.location = config.download_url;
                            } else {
                                
                            }
                        }, config.timeout);
    
                        window.onblur = function() {
                            clearTimeout(t);
                        }
                    }
                    window.addEventListener("DOMContentLoaded", function(){
                        document.getElementById("J-call-app").addEventListener('click',openclient,false);
    
                    }, false);
                })()
            </script>
        </body>
    </html>
    

    如果需要传参数。

    在html网页中直接拼接参数。

    vchao://splash/?arg0=marc&arg1=xie
    

    在唤醒的activity页面做参数的接收。

        Uri uri = getIntent().getData();  
         if (uri != null) {  
             String test1 = uri.getQueryParameter("arg0");  
             String test2 = uri.getQueryParameter("arg1");  
             tv.setText(test1 + test2);  
         }  
    
    展开全文
  • wap页中唤醒APP

    千次阅读 2016-12-15 10:17:48
    app上这就要求前端工程师们为网页提供各种入口去打开app,今天我们就聊一聊app的打开方式(有错误的地方还请高手指正)。 常规打开 对于app打开而言最常规的打开就是通过url scheme的方式去打开你的app,...
    前言
    对于一个完备的互联网产品而言需要有app端与web端两个不同前端,对于产品而言很多都希望能够将wap页上的用户引向native app上这就要求前端工程师们为网页提供各种入口去打开app,今天我们就聊一聊app的打开方式(有错误的地方还请高手指正)。



    常规打开
    对于app打开而言最常规的打开就是通过url scheme的方式去打开你的app,如下的

    这些抛出都是以url的方式进行抛出,app捕捉到这些抛出去做相应的处理,本文对app的处理不做详细描述,app开发请自行谷歌百度。对于前端而言抛出的方式也有很多,而最理想的方式是通过iframe的src对其进行链抛出,来!说的在多都没有代码来的清晰,请看下面。
    首先我们需要有一个iframe:

    之后我们还需要一个url scheme:


    这种scheme形式的其实不是最好的,根据我们踩过的坑,觉得约定为与http协议相近可能更好一些,具体的协议需要前端人员自己去和app端人员约定。
    ok万事具备,iframe有了,urlScheme也有了,该去打开app了




    以上就是你要打开scheme的主要代码了,好吧,实际上不只是打开app,还要实现未打开的时候跳到下载页去。其中安卓实际上无论有没有打开都会跳到下载页去,而ios........好吧!按照网上的说法是浏览器失焦后会挂起脚本,呵呵,这是多老的ios版本的表现了,实际上现在的ios已经没有这么做,有些版本会跟安卓的表现一样,而有些则是直接跳转根本不会去打开,还有打开的时候那个恶心的系统弹窗是什么鬼。好吧,实际上至此你会发现,ios9.0以上的有些打不开直接跳,有些打得开还会有允许弹窗,而微信则是无论如何都打不开,实际上微信会在他的浏览器里拦截掉所有未经其允许的scheme包括app store,那么接下来我们要解决这些问题。



    通用链接

    针对ios9及以上的打不开问题,实际上ios9提供了更好的解决方案————通用链接。
    什么是Universal Links(通用链接)?
    这是iOS9推出的一项功能,如果你的应用支持Universal Links(通用链接),那么就能够方便的通过传统的HTTP链接来启动APP(如果iOS设备上已经安装了你的app,不需要额外做任何判断等),或者打开网页(iOS设备上没有安装你的app)。或许可以更简单点来说明,在iOS9之前,对于从各种从浏览器,Safari、UIWebView或者 WKWebView中唤醒APP的需求,我们通常只能使用scheme。
    以上来自网上关于通用链接的介绍,对于前端简单点讲就是你访问一个http的url,如果这个url带有你提交给开发平台的配置文件中匹配规则的内容,ios系统会去尝试打开你的app,如果打不开,系统就会在浏览器中转向你要访问的链接。很好的一个属性,因为通过这个属性在ios9上我们能够绕过微信的拦截从而打开app。
    以下是ios开发人员要做的百度搜索结果第一条ios中实现通用链接
    而我们要做的真的很简单,实际上我们只需要抛出链接就好了(实际上博主只是来骗经验的)。在此之前请准备好与主站不同的域名,比如主站www.xxxx.com,你们可以准备好open.xxxx.com的域名作为重定向用。好吧!实际上通用链接有一个很坑的属性,必须是异域打开,而且如果你提交的是你主站的链接,你打开你的主站你会发现网站上方会挂着一个难看的灰条转向appstore中你们的app,没错,就是ios系统干的这个事,具体的其他注意事项可以参考这篇文章IOS9通用链接(universal link)
    那么接下来我们的代码得做好更改


    然后对抛出做




    实际上就只需要更改这么点,最重要的是app端接入通用链接,注意抛出的链接不要跟主站同域即可,之后就是不断的调试,自己去踩坑吧,记得绑定域名,这个对域名具有一定的依赖性。



    微信中打开
    至此只有微信是打不开的,实际上腾讯系的产品都是打不开的,包括qq浏览器。
    对于微信中有两种方式:
    • 一种简单的方式就是弹窗告诉用户让他去浏览器中打开——在技术之外的办法
    • 还有一种方式就是应用宝

    是的如果是微信就去打开你的app对应的应用宝,应用宝会去检测你的app是否存在有则去打开,但只是去打开。实际上腾讯的应用宝对于开发者在功能上做的比想象中的要强大,你在应用宝的微下载中配置申请你的applink(目前能申请不能用)与app store的链接,之后你只要在你的链接参数中带上android_schema="myApp://"就在应用宝中打开app中的特定功能,如果忽略应用宝的页面跟自己scheme打开没有太大区别,具体的操作可以查看应用宝的说明。简而言之,腾讯的产品中都去借助应用宝这个平台去执行你需要的操作。在此就不贴代码了,只要判断浏览器如果是微信或者是qq就去跳你的应用宝链接就行。



    总结
    实际上单纯打开app非常简单,目前无论安卓还是ios都能够很好的支持scheme,当然腾讯系产品除外,实际上百度浏览器也会拦截scheme(我觉得真是奇了葩!!!微信这种尚能理解,一个浏览器居然擅自去拦截scheme)目前对百度浏览器还没有什么很好的办法,可以尝试是否能够通过百度应用市场去解决。如果是希望打开app同时又要打开下载页,那么ios9及以上就得用通用链接去解决,重点就是这个通用链接。
    展开全文
  • H5 唤醒App

    千次阅读 2019-03-15 11:18:04
    H5 唤醒App 打开APP function GetMobelType() { var browser = { versions: function() { var u = window.navigator...
  • 唤醒app

    2019-02-19 11:20:55
    安卓手机唤醒app html代码: &lt;a id="openApp" &gt;唤醒app&lt;/a&gt; jquery代码:  var android_schema ="test://",  android_download_url ="";  ...
  • App相互唤醒的几种方式

    千次阅读 2019-03-25 17:50:42
    下文皆使用Client表示操作的App,Server表示需要被唤起的远端App,Server的包名为“com.jxx.server”1. ComponentName使用C...
  • H5唤醒APP

    2019-11-21 13:29:38
    微信中H5唤醒APP 注意 安卓6.0一下不要用let声明!! <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ...
  • 通过第三方app唤醒自己的app

    千次阅读 2019-06-10 11:28:54
    提供scheme链接在第三方应用Activity中唤醒 在自己app中的AndroidManifest.xml文件里包含<action android:name="android.intent.action.MAIN" />的activity标签中添加一个新的intent-filter标签 ,注意data...
  • js点击按钮唤醒app

    千次阅读 2019-05-22 17:24:03
    点击唤醒app</a> var download_schema = 'taobao://'; //app的协议有安卓同事提供,这里是用的淘宝 var universal_link = 'ios下载地址';//ios下载地址 var getVersionUrl = 'Android下载地址';//Android...
  • h5页面唤醒APP指定页面并传参

    万次阅读 2016-08-24 10:05:24
    开发时有时会碰到这样的需求,分享到第三方的h5页面,在点击操作的时候需要跳回APP的指定页面,这时只需要在该activity下面配置一下相应的scheme host等信息就可以了 intent-filter> action android:name=...
  • Android平台下APP唤醒机制

    千次阅读 2016-11-11 16:41:08
    一、目标  在Android平台下的一个APP中,打开(唤醒)另一个APP。 二、前提 1.主动唤醒方的APP与被唤醒方的APP之间有唯一的标识... 以APPA唤醒APP B为例,以下方案的每个步骤都需要所参与的APP的开发者编码实现。
  • 凡是接触过微信分享的开发者,都遇到过一个问题:微信中为什么无法唤醒App,需要“用浏览器打开”? 类似于这种方式 因为微信对所有的分享连接做了scheme屏蔽,也就是说分享连接中所有对于scheme的调用都被...
  • 需要在app的工程中设置 1、打开工程中的myapp-Info.plist文件 2、打开文件中新增URL TYPES的一项,具体如下图所示: 3、在工程中实现如下方法 - (BOOL)application:(UIApplication *)application ...
  • 很多情况下我们需要从一个app点击启动或者唤醒另一个app,例如,天猫会启动支付,携带数据,跳到支付宝的相关页面进行支付。 其中关键的代码如下: PackageManager packageManager = MainActivity.this....
  • android html唤醒APP(原生)

    万次阅读 2015-11-24 13:43:35
    写在前面:有个需求,在微信的...但是可以通过右上角的在浏览器中打开进入网页,再唤醒APP。 首先做成HTML的页面,页面内容格式如下: a href="[scheme]://[host]/[path]?[query]">启动应用程序a> 例如,我的
  • 微信分享后点击分享唤醒app

    千次阅读 2015-08-26 18:21:48
    成功分享链接到朋友圈或 好友之后 点分享的链接会跳转到一个html页,这个网页的url是在写分享时传的值(如mWXModel.setUrl("http://hfgj.sinaapp.com/xxxx.html");) 在微信中要用浏览器打开是这样子 这个网页的...
  • 广播和Service唤醒被杀死的android app

    万次阅读 2016-10-17 16:36:43
    静态的系统广播静态的系统广播,例如:开机广播,用户开屏广播,USB插入和拔出广播等这类广播在app运行期间可以用静态注册的广播正常接收,但是在app被杀死后就无法收到了,android系统做了屏蔽,把被杀死的app的...
  • 手机浏览器唤起微信app支付说明

    万次阅读 多人点赞 2016-07-08 09:58:59
    微信支付官方文档并没有显示h5唤起微信app支付的文档,但是自微信6.0.2版本后已支持该功能,而且官方已经有了开发文档,只是没有显示出来。 微信h5支付文档地址: ...
  • 点击APP外部链接唤醒APP的研究

    万次阅读 2016-10-20 18:25:02
    思路,首先找个实现了的APP做测试。 选择手机淘宝做研究。 在淘宝中把宝贝链接分享到微信,结果如下: 直接点开,跳转到微信的内建浏览器,指示用户通过浏览器打开: 点击在浏览器中打开,效果为弹窗显示所有的...
1 2 3 4 5 ... 20
收藏数 30,135
精华内容 12,054
关键字:

唤醒app