android开发集成友盟推送4.0.0版本 SDK步骤

版权声明:--------------------------------------------博文可随意转载,但请注明出处,谢谢!-------------------------------------------- https://blog.csdn.net/zxc514257857/article/details/79682139

编写不易,如有转载,请声明出处: 梦回河口:https://blog.csdn.net/zxc514257857/article/details/79682139

1,创建友盟帐号

  在友盟官网 http://www.umeng.com/ 上创建一个帐号

2,找到集成文档

  登陆后在 开发者中心—>文档中心—>UPush集成文档 http://dev.umeng.com/sdk_integate/android_sdk/android_push_doc,按照文档步骤进行操作

3,创建应用

  在 http://message.umeng.com 上使用你的应用包名创建应用(注:Android Studio请使用applicationId作为包名)

4,留意三个码

  留意应用管理—>应用信息中的Appkey,Umeng Message Secret,App Master Secret这三个码;Appkey是友盟应用的唯一标识,集成友盟其他SDK时都是可以使用同一个的;Appkey,Umeng Message Secret是集成推送时Android端需要的两个码;App Master Secret是服务器端调用API请求时需要用到的码。

5,下载示例Demo,添加依赖

  在 https://github.com/umeng/UMAndroidSdkDemo 上下载示例Demo:UMAndroidSdkDemo-master,将其中的PushSDK以module的形式导入,并在build.gradle中添加依赖;将umeng-common.jar 和 utdid4all-.* jar文件分别拷贝到工程的libs目录,并在build.gradle中添加依赖;要保证工程中的so文件夹与PushSDK下的so文件夹内容保持一致

6,SDK初始化

  使用通用接口进行初始化并设置Appkey和Secret;在项目的Manifest文件中Application节点下面配置友盟的appkey,channel以及message secret:

<meta-data
    android:name="UMENG_APPKEY"
    android:value="5ab1f624b27b0a27c20002ac"/>

<meta-data
    android:name="UMENG_CHANNEL"
    android:value="Umeng"/>

<meta-data
    android:name="UMENG_MESSAGE_SECRET"
    android:value="5f6a0b6f9da839bd9f531f0fc6dca272"/>

  在项目工程的自定义application中的onCreate方法中添加:

UMConfigure.init(this, UMENG_APPKEY, UMENG_CHANNEL, UMConfigure.DEVICE_TYPE_PHONE, UMENG_MESSAGE_SECRET);

7,添加相关权限

  在项目的Manifest文件中添加友盟推送可能用到的权限,若主工程的targetSdkVersion为23及以上,请在代码中遵循Android 6.0的运行时权限机制申请存储权限(WRITE_EXTERNAL_STORAGE),可以更好的在Android 6.0及以上版本的机型中使用推送

<!-- 必须的权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

<!-- 推荐的权限 -->
<!-- 添加如下权限,以便使用更多的第三方SDK和更精准的统计数据 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

8,进行代码混淆

  如果应用使用了混淆, 请添加

-keep class com.umeng.commonsdk.** {*;}

9,代码

// App
package com.example.zhr.together;

import android.app.Application;
import android.app.Notification;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.RemoteViews;
import com.umeng.commonsdk.UMConfigure;
import com.umeng.message.IUmengRegisterCallback;
import com.umeng.message.MsgConstant;
import com.umeng.message.PushAgent;
import com.umeng.message.UTrack;
import com.umeng.message.UmengMessageHandler;
import com.umeng.message.UmengNotificationClickHandler;
import com.umeng.message.entity.UMessage;

/**
 * 添加通知,自定义消息,插屏消息等
 * 
 * 1,设置一些通知参数,并获取到device_token,通过device_token方便指定设备进行测试(方便判断是否可发送推送),若没获取到device_token则无法推送;
 * 2,如果需要获取点击推送通知后的后续操作,在Application中还需创建UmengNotificationClickHandler,并重写dealWithCustomAction,通过Intent进行打开
 * 应用,url,指定Activity,自定义行为等操作;代码通过Intent跳转到其他Activity,并通过bundle传递url等参数过去,取出并展示。如果测试时在U-Push后台的测试模式
 * 下无法通过指定device_token推送通知消息,可在U-Push后台的消息列表位置通过指定device_token推送通知消息。推送的声音以及图片都可自定义
 * 3,接SplashActivity中的内容
 * 4,接InAppMessageActivity中的内容
 * 5,接LoadUrlActivity中的内容
 * 6,消息推送实现自动更新。采用推送应用下载链接的形式来实现。可将链接设置为官网的APK下载链接或第三方应用市场下载链接。此方法可确保开发者避开应用市场、
 * 系统厂商、运营商等多方对自动更新服务的限制,进而成功实现用消息推送实现自动更新功能。通过Application中的UmengNotificationClickHandler方法,重写
 * openUrl方法即可实现
 * 7,友盟消息推送提供了"测试模式"和"正式模式"两种推送方式。"正式模式",顾名思义,在该模式下消息会发送给线上真实用户;而"测试模式"是为便于开发者测试,
 * 允许开发者向测试库中添加测试设备,消息只会发送给测试库中的设备,如论如何都不会发送到没有在"测试模式"下填写token的线上用户的
 */
public class App extends Application {

    private static final String TAG = App.class.getSimpleName();
    private static final String UMENG_APPKEY = "5ab34a368f4a9d2fc70000bf";
    private static final String UMENG_CHANNEL = "Umeng";
    private static final String UMENG_MESSAGE_SECRET = "ab037a8ad70d21ae5f8482f68db6e297";

    @Override
    public void onCreate() {
        super.onCreate();

        // 设置LOG开关,默认为false
        UMConfigure.setLogEnabled(true);
        // 设置日志加密  默认为false
        UMConfigure.setEncryptEnabled(true);
        // 初始化组件化基础库, 统计SDK/推送SDK/分享SDK都必须调用此初始化接口
        UMConfigure.init(this, UMENG_APPKEY, UMENG_CHANNEL, UMConfigure.DEVICE_TYPE_PHONE, UMENG_MESSAGE_SECRET);
        // PushSDK初始化(如使用推送SDK,必须调用此方法)
        initUpush();
    }

    private void initUpush() {
        PushAgent mPushAgent = PushAgent.getInstance(this);
        // 设置在23点至7点之间收到通知消息静音(免打扰模式)
        mPushAgent.setNoDisturbMode(23 , 0 , 7 , 0);
        // 设置在60s内收到应用的多条信息,不重复提醒,替换通知(冷却时间)
        mPushAgent.setMuteDurationSeconds(60);
        // 设置通知栏最多显示两条通(当通知栏已经有两条通知,此时若第三条通知到达,则会把第一条通知隐藏)
        // 设置为0表示不合并通知
        mPushAgent.setDisplayNotificationNumber(2);
        // 响铃、振动、呼吸灯服务端控制
        // MsgConstant.NOTIFICATIONPLAYSERVER(服务端控制)
        // MsgConstant.NOTIFICATIONPLAYSDKENABLE(客户端允许)
        // MsgConstant.NOTIFICATIONPLAYSDKDISABLE(客户端禁止)
        mPushAgent.setNotificationPlaySound(MsgConstant.NOTIFICATION_PLAY_SERVER);
        mPushAgent.setNotificationPlayVibrate(MsgConstant.NOTIFICATION_PLAY_SERVER);
        mPushAgent.setNotificationPlayLights(MsgConstant.NOTIFICATION_PLAY_SERVER);
        // 设置应用在前台时显示通知
        mPushAgent.setNotificaitonOnForeground(true);

        // 注册推送服务,每次调用register方法都会回调该接口
        mPushAgent.register(new IUmengRegisterCallback() {
            @Override
            public void onSuccess(String deviceToken) {
                // 获取到token之后才能发送推送消息
                Log.i(TAG , "deviceToken:" + deviceToken);
            }

            @Override
            public void onFailure(String s, String s1) {
                // 获取token出错,无法发送推送消息
                Log.i(TAG , "error!!!");
            }
        });

        // 没有拦截SDK默认的处理  若拦截 直接在GetThumbService中写获取到custom text title的值 不用写下面的逻辑了
//        mPushAgent.setPushIntentServiceClass(GetThumbService.class);

        /**
         * SDK的默认处理:点击 通知 之后的处理
         */
        UmengNotificationClickHandler umengNotificationClickHandler = new UmengNotificationClickHandler() {

            /**
             * 打开指定的url链接,可以用于实现软件的下载更新等
             */
            @Override
            public void openUrl(Context context, UMessage uMessage) {
                super.openUrl(context, uMessage);
            }

            @Override
            public void dismissNotification(Context context, UMessage uMessage) {
                super.dismissNotification(context, uMessage);
            }

            @Override
            public void autoUpdate(Context context, UMessage uMessage) {
                super.autoUpdate(context, uMessage);
            }

            @Override
            public void launchApp(Context context, UMessage uMessage) {
                super.launchApp(context, uMessage);
            }

            @Override
            public void openActivity(Context context, UMessage uMessage) {
                super.openActivity(context, uMessage);
            }

            /**
             * 自定义行为处理方式
             * 如果用来加载url的话,不会调用系统浏览器去加载
             */
            @Override
            public void dealWithCustomAction(Context context, UMessage msg) {
                Log.i(TAG , "dealWithCustomAction:" + msg.custom);
                super.dealWithCustomAction(context, msg);
                Intent intent = new Intent(getApplicationContext(), LoadUrlActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                Bundle bundle = new Bundle();
                bundle.putString("openUrl" , msg.custom);
                bundle.putString("openTitle" , "加载url页面的Activity");
                PrefUtils.putString(context, "openUrl" , msg.custom);
                PrefUtils.putString(context, "openTitle" , "加载url页面的Activity");
                intent.putExtras(bundle);
                startActivity(intent);
            }
        };
        mPushAgent.setNotificationClickHandler(umengNotificationClickHandler);

        /**
         * SDK的默认处理:点击 自定义消息 之后的处理
         */
        UmengMessageHandler messageHandler = new UmengMessageHandler(){

            @Override
            public void dealWithCustomMessage(final Context context, final UMessage msg) {
                new Handler(getMainLooper()).post(new Runnable() {

                    @Override
                    public void run() {
                        // 对于自定义消息,PushSDK默认只统计送达。若开发者需要统计点击和忽略,则需手动调用统计方法。
                        boolean isClickOrDismissed = true;
                        if(isClickOrDismissed) {
                            //自定义消息的点击统计
                            UTrack.getInstance(getApplicationContext()).trackMsgClick(msg);
                        } else {
                            //自定义消息的忽略统计
                            UTrack.getInstance(getApplicationContext()).trackMsgDismissed(msg);
                        }
                        // 自定义消息的内容
                        Log.i(TAG , "custom:" + msg.custom);
                        // 通知标题
                        Log.i(TAG , "title:" + msg.title);
                        // 通知内容
                        Log.i(TAG , "content:" + msg.text);

                        // 将消息内容以广播的形式传递给MainActivity
                        Intent broadcaseIntent = new Intent();
                        if(!"".equals(msg.custom)){
                            broadcaseIntent.putExtra("custom" , msg.custom);
                        }
                        if(!"".equals(msg.title)){
                            broadcaseIntent.putExtra("title" , msg.title);
                        }
                        if(!"".equals(msg.text)){
                            broadcaseIntent.putExtra("content" , msg.text);
                        }
                        broadcaseIntent.setAction("com.example.zhr.together.app");
                        sendBroadcast(broadcaseIntent);
                    }
                });
            }

            /**
             * 自定义通知栏样式的回调方法
             */
            @Override
            public Notification getNotification(Context context, UMessage msg) {
                switch (msg.builder_id) {
                    case 1:
                        Notification.Builder builder = new Notification.Builder(context);
                        RemoteViews myNotificationView = new RemoteViews(context.getPackageName(), R.layout.notification_view);
                        myNotificationView.setTextViewText(R.id.notification_title, msg.title);
                        myNotificationView.setTextViewText(R.id.notification_text, msg.text);
                        myNotificationView.setImageViewBitmap(R.id.notification_large_icon, getLargeIcon(context, msg));
                        myNotificationView.setImageViewResource(R.id.notification_small_icon, getSmallIconId(context, msg));
                        builder.setContent(myNotificationView)
                                .setSmallIcon(getSmallIconId(context, msg))
                                .setTicker(msg.ticker)
                                .setAutoCancel(true);

                        return builder.getNotification();
                    default:
                        //默认为0,若填写的builder_id并不存在,也使用默认。
                        return super.getNotification(context, msg);
                }
            }
        };
        mPushAgent.setMessageHandler(messageHandler);
    }
}
------------------------------------------------------------------------------
// SplashActivity 
package com.example.zhr.together;

import com.umeng.message.inapp.InAppMessageManager;
import com.umeng.message.inapp.UmengSplashMessageActivity;

/**
 * 5,应用内消息,Splash页面全屏消息显示的Activity,先设置一个logo图,再设置一个倒计时广告图,倒计时广告图上半部分可以设置点击之后的操作,通过
 * Intent等进行控制。注意这里的类名和后台需要输入的页面名称都需要输入全类名即包名加类名模式。应用内消息用来区分是开发还是测试模式是通过显示Splash插屏的
 * Activity调用mInAppMessageManager.setInAppMsgDebugMode(true)方法来实现的
 */
public class SplashActivity extends UmengSplashMessageActivity {

    @Override
    public boolean onCustomPretreatment() {
        InAppMessageManager mInAppMessageManager = InAppMessageManager.getInstance(this);
        // 设置应用内消息为debug模式
        mInAppMessageManager.setInAppMsgDebugMode(true);
        // 全屏消息默认跳转至Activity的路径 这里要写完整的类名即包名加类名
        mInAppMessageManager.setMainActivityPath("com.example.zhr.together.InAppMessageActivity");
        return super.onCustomPretreatment();
    }
}
------------------------------------------------------------------------------
// InAppMessageActivity 

package com.example.zhr.together;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import com.umeng.message.PushAgent;
import com.umeng.message.inapp.IUmengInAppMsgCloseCallback;
import com.umeng.message.inapp.InAppMessageManager;

/**
 * 6,应用内消息:插屏消息显示的Activity 包括大尺寸图片插屏消息,小尺寸图片插屏消息,文字插屏消息,Splash页的全屏图片插屏消息,自定义插屏消息。
 * 通过广播接收者获取自定义消息中的内容并显示
 */
public class InAppMessageActivity extends AppCompatActivity {

    private static final String TAG = InAppMessageActivity.class.getSimpleName();
    private TextView mTvCustomMsg;
    private TextView mTvTitle;
    private TextView mTvContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_in_app_msg);

        mTvCustomMsg = (TextView) findViewById(R.id.tv_custom_msg);
        mTvTitle = (TextView) findViewById(R.id.tv_title);
        mTvContent = (TextView) findViewById(R.id.tv_content);

        // 所有的Activity 的onCreate 方法或在应用的BaseActivity的onCreate方法中添加,用于统计应用启动数据
        PushAgent.getInstance(this).onAppStart();

        // 如果显示文字信息的话 设置的文字大小  int titleTextSize, int contentTextSize, int buttonTextSize
        InAppMessageManager.getInstance(this).setPlainTextSize(18 , 16 , 16);
        // 每进入此Activity就会打开插屏消息  这里的label要和pc端配置的label一致
        // main_card_msg 插屏消息   main_word_msg 文字消息
        InAppMessageManager.getInstance(this).showCardMessage(this, "main_word_msg", new IUmengInAppMsgCloseCallback() {
            // 插屏消息关闭时,会回调该方法  分为小尺寸和大尺寸插屏
            @Override
            public void onColse() {
                Toast.makeText(getApplicationContext() , "插屏图片或文字消息关闭!" , Toast.LENGTH_LONG).show();
            }
        });

        // 在Activity中接收广播 过滤action
        registReceiver();
    }

    /**
     * 在Activity中接收广播 过滤action
     */
    private void registReceiver() {
        MyReceiver receiver = new MyReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.zhr.together.app");
        registerReceiver(receiver , intentFilter);
    }

    /**
     * 自定义广播接收者
     */
    public class MyReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            // 从Bundle中获取数据
            Bundle bundle = intent.getExtras();
            Log.i(TAG , "bundle:" + bundle.getString("custom"));
            mTvCustomMsg.setText(bundle.getString("custom"));
            mTvTitle.setText(bundle.getString("title"));
            mTvContent.setText(bundle.getString("content"));
        }
    }
}
------------------------------------------------------------------------------
// LoadUrlActivity 

package com.example.zhr.together;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.webkit.WebView;
import android.widget.TextView;

/**
 * 7,应用内消息,加载显示url页面的Activity,如果从其他页面传入url则直接显示,若没有传入则从SP中恢复,在电脑端配置的指定页面的Activity要通过包名加类名的方式
 */
public class LoadUrlActivity extends AppCompatActivity{

    private static final String TAG = LoadUrlActivity.class.getSimpleName();
    private Context mContext = LoadUrlActivity.this;
    private WebView mWebView;
    private TextView mTv;
    private String mOpenUrl;
    private String mOpenTitle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_load_uri);
        mWebView = (WebView) findViewById(R.id.webView);
        mTv = (TextView) findViewById(R.id.tv);

        Intent intent = getIntent();
        Bundle bundle = intent.getExtras();
        if(bundle != null){
            mOpenUrl = bundle.getString("openUrl");
            mOpenTitle = bundle.getString("openTitle");
        }

        if("".equals(mOpenUrl) || mOpenUrl == null){
            mOpenUrl = PrefUtils.getString(mContext, "openUrl", "没有缓存,显示默认数据");
        }
        if("".equals(mOpenTitle) || mOpenTitle == null){
            mOpenTitle = PrefUtils.getString(mContext, "openTitle", "");
        }
        Log.i(TAG , "openUrl:" + mOpenUrl);
        Log.i(TAG , "openTitle:" + mOpenTitle);
        mTv.setText(mOpenTitle);
        mWebView.loadUrl(mOpenUrl);
    }
}
------------------------------------------------------------------------------
// PrefUtils 

import android.content.Context;
import android.content.SharedPreferences;

/**
 * 专门存放和获取SharePreference数据的工具类, 保存和配置一些设置信息
 */
public class PrefUtils {

    private static final String SHARE_PREFS_NAME = "config";

    /**
     *  描述:存放布尔类型的数据到sp中
     */
    public static void putBoolean(Context ctx, String key, boolean value) {
        SharedPreferences pref = ctx.getSharedPreferences(SHARE_PREFS_NAME,
                Context.MODE_PRIVATE);

        pref.edit().putBoolean(key, value).commit();
    }

    /**
     *  描述:取出sp中布尔类型的数据
     */
    public static boolean getBoolean(Context ctx, String key,
            boolean defaultValue) {
        SharedPreferences pref = ctx.getSharedPreferences(SHARE_PREFS_NAME,
                Context.MODE_PRIVATE);

        return pref.getBoolean(key, defaultValue);
    }

    /**
     *  描述:存放string类型的数据到sp中
     */
    public static void putString(Context ctx, String key, String value) {
        SharedPreferences pref = ctx.getSharedPreferences(SHARE_PREFS_NAME,
                Context.MODE_PRIVATE);

        pref.edit().putString(key, value).commit();
    }

    /**
     *  描述:取出sp中string类型的数据
     */
    public static String getString(Context ctx, String key, String defaultValue) {
        SharedPreferences pref = ctx.getSharedPreferences(SHARE_PREFS_NAME,
                Context.MODE_PRIVATE);

        return pref.getString(key, defaultValue);
    }

    /**
     *  描述:存放int类型的数据到sp中
     */
    public static void putInt(Context ctx, String key, int value) {
        SharedPreferences pref = ctx.getSharedPreferences(SHARE_PREFS_NAME,
                Context.MODE_PRIVATE);

        pref.edit().putInt(key, value).commit();
    }

    /**
     *  描述:取出sp中int类型的数据
     */
    public static int getInt(Context ctx, String key, int defaultValue) {
        SharedPreferences pref = ctx.getSharedPreferences(SHARE_PREFS_NAME,
                Context.MODE_PRIVATE);

        return pref.getInt(key, defaultValue);
    }
}
------------------------------------------------------------------------------
// AndroidManifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.zhr.together">

    <!-- 必须的权限 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />

    <!-- 推荐的权限 -->
    <!-- 添加如下权限,以便使用更多的第三方SDK和更精准的统计数据 -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:name=".App"
        android:theme="@style/AppTheme">

        <meta-data
            android:name="UMENG_APPKEY"
            android:value="5ab34a368f4a9d2fc70000bf"/>

        <meta-data
            android:name="UMENG_CHANNEL"
            android:value="Umeng"/>

        <meta-data
            android:name="UMENG_MESSAGE_SECRET"
            android:value="ab037a8ad70d21ae5f8482f68db6e297"/>

        <activity android:name="com.example.zhr.together.SplashActivity"
                  android:screenOrientation="portrait"
                  android:theme="@style/Theme_Umeng_Push_Splash">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name="com.example.zhr.together.InAppMessageActivity"/>

        <activity android:name="com.example.zhr.together.LoadUrlActivity"/>

    </application>
</manifest>

10,注意

  布局文件代码就不贴上了,如需参考可在后面的Demo中下载获取

  如果要自定义Splash页面和通知栏logo图标,需在drawable目录下放置:umeng_push_default_splash_bg.png , umeng_push_notification_default_large_icon.png , umeng_push_notification_default_small_icon.png 这三个文件;如需自定义通知声音,需在raw目录下放置:umeng_push_notification_default_sound.mp3文件

  如需使用后面的Demo只需将包名(AndroidManifest文件下的applicationId)和两个码替换为自己的即可

Demo下载请移步:https://download.csdn.net/download/zxc514257857/10306869


因本人才疏学浅,如博客或Demo中有错误的地方请大家随意指出,与大家一起讨论,共同进步,谢谢!

猜你喜欢

转载自blog.csdn.net/zxc514257857/article/details/79682139