前段时间写了一篇关于友盟推送的文章,从阅读量来看,大家在这方面踩了很多坑,所以我觉得有必要来个全面的总结,给大家更好的过坑意见;

先从分享开始说吧

第一步集成SDK:官方文档说的很详细了,集成大家就看文档吧,我就总结一下要注意的地方:

友盟分享SDK集成

微信,qq,短信等友盟的api都有了,不过为了方便自己调用,可以自定义一个接口:

/**
 * Created by Administrator on 2018/1/5 0005.
 * 分享回调
 */

public interface ShareHandler {

    void shareSuccess();

    void shareFailed(String msg);

    void shareCancel();

}

然后自定义一个分享的工具类

public class ShareUtils {

    private Activity mContext;

    public ShareUtils(Activity context) {
        mContext = context;
    }

    private ShareHandler mShareHandler;

    /**为方便参数的传递,把需要的参数封装为一个shareBean
     * @param shareBean 分享参数类
     */
    public void beginShare(ShareBean shareBean, ShareHandler shareHandler) {
        mShareHandler = shareHandler;
        UMWeb shareUrl = new UMWeb(shareBean.getUrl());
        shareUrl.setTitle(shareBean.getTitle());
        shareUrl.setDescription(shareBean.getDesc());
        shareUrl.setThumb(new UMImage(mContext, R.mipmap.ic_launcher));
        new ShareAction(mContext)
                .withText(shareBean.getTitle())
                .withMedia(shareUrl)
                .setPlatform(shareBean.getType())
                .setCallback(shareListener)
                .share();

    }

    public UMShareListener shareListener = new UMShareListener() {
        /**
         * @descrption 分享开始的回调
         * @param platform 平台类型
         */
        @Override
        public void onStart(SHARE_MEDIA platform) {
//            ToastUtils.showShortToast("share start");
        }

        /**
         * @descrption 分享成功的回调
         * @param platform 平台类型
         */
        @Override
        public void onResult(SHARE_MEDIA platform) {
//            ToastUtils.showShortToast("share success");
            if (mShareHandler != null)
                mShareHandler.shareSuccess();
        }

        /**
         * @descrption 分享失败的回调
         * @param platform 平台类型
         * @param t 错误原因
         */
        @Override
        public void onError(SHARE_MEDIA platform, Throwable t) {
//            ToastUtils.showShortToast("share failed" + t.getMessage());
            if (mShareHandler != null)
                mShareHandler.shareFailed(t.getMessage());
        }

        /**
         * @descrption 分享取消的回调
         * @param platform 平台类型
         */
        @Override
        public void onCancel(SHARE_MEDIA platform) {
//            ToastUtils.showShortToast("share calcel");
            if (mShareHandler != null)
                mShareHandler.shareCancel();
        }
    };
}



shareBean也就几个参数

//分享 kotlin格式  不会kotlin的吧参数copy到自己的实体类即可
data class ShareBean(
        val type: SHARE_MEDIA, //QQ
        val url: String, //分享的Url
        val title: String, //标题
        val thumb: String, //图片地址
        val desc: String //描述文字
)

工具类写好了然后就是调用

private void share(SHARE_MEDIA platform) {
        ShareUtils shareUtils = new ShareUtils(InvitingFriendActivity.this);
        //这里的参数除了都可以从服务器获取,然后赋值就行
        ShareBean shareBean = new ShareBean(platform, shareUrl, shareTitle, shareIcon, "");
        shareUtils.beginShare(shareBean, new ShareHandler() {
            @Override
            public void shareSuccess() {
//                ToastUtils.showShortToast("分享成功");
            }

            @Override
            public void shareFailed(String msg) {
//                ToastUtils.showShortToast("分享失败:" + msg);
            }

            @Override
            public void shareCancel() {
//                ToastUtils.showShortToast("分享取消");
            }
        });
    }

    /**因为qq和qq空间6.0以后有权限管理校验,这一步是校验,可以直接调用这个方法发起分享
     * @param paltform pingtai
     */
    public void checkPermissionToshare(final SHARE_MEDIA paltform) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //判断该应用是否有写SD卡权限,如果没有再去申请
            if (ContextCompat.checkSelfPermission(InvitingFriendActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                RxPermissions rxPermissions = new RxPermissions(this);
                rxPermissions
                        .request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        .subscribe(new Consumer<Boolean>() {
                            @Override
                            public void accept(Boolean aBoolean) throws Exception {
                                if (aBoolean) {
                                    share(paltform);
                                } else {
                                    ToastUtils.showShortToast("分享取消");
                                }
                            }
                        });
            } else {
                share(paltform);
            }
        }
    }



调用示例

checkPermissionToshare(SHARE_MEDIA.QQ);

下面是通过gradle配置,不打包release版本apk测试微信和微信朋友圈分享的推荐方法

当我们在做微信微博sdk分享的时候调试非常麻烦,因为要使用对应的签名版本才能调用sdk成功。

当我们使用AndroidStudio的Gradle之后会很简单的解决这个问题。

1.我们把签名文件放到工程根目录下(这样做是为了保持路径的统一)

2.在Gradle中引入如下代码:

    //配置keystore签名
    signingConfigs {
        release {
            storeFile file('F:/keystone/vc_secret_key/Keystore.jks')//把正式版签名文件保存到本地磁盘,这里写入全路径
            storePassword "xxxxxxxx"
            keyAlias "timehut team"
            keyPassword "xxxxxxxx"
        }
    }


    buildTypes {
        debug {
            signingConfig signingConfigs.release
        }
        release {
            signingConfig signingConfigs.release
        }
    }

只需要在debug的配置下使用release的配置就可以运行达到打包release版本的效果



为了出现问题解决不了,可以在application中启用友盟的日志提示,这样有什么问题会给你一个解决方案的链接

Config.DEBUG = true;//打印友盟分享日志

然后是第三方登录授权获取用户信息

private class InnerUMAuthListener implements UMAuthListener {
        /**
         * 授权开始的回调
         *
         * @param platform 平台名称
         */
        @Override
        public void onStart(SHARE_MEDIA platform) {

        }

        /**
         * 授权成功的回调
         *
         * @param platform 平台名称
         * @param action   行为序号,开发者用不上
         * @param data     用户资料返回
         */
        @Override
        public void onComplete(SHARE_MEDIA platform, int action, Map<String, String> data) {
            if (data != null) {
                String city = data.get("city");
                String country = data.get("country");
                String iconurl = data.get("iconurl");
                String language = data.get("language");
                String name = data.get("name");
                String openid = data.get("openid");
                String province = data.get("province");
                String gender = data.get("gender");
                String unionid = data.get("unionid");
                //拿到信息去请求登录接口。。。
                mPresenter.bindWeixin(city, country, iconurl, language, name, openid, province, gender.equals("男") ? 1 : 2, unionid);
            }
        }

        /**
         * 授权失败的回调
         *
         * @param platform 平台名称
         * @param action   行为序号,开发者用不上
         * @param t        错误原因
         */
        @Override
        public void onError(SHARE_MEDIA platform, int action, Throwable t) {
            showToast("微信登陆失败!" + t.getMessage());
        }

        /**
         * 授权取消的回调
         *
         * @param platform 平台名称
         * @param action   行为序号,开发者用不上
         */
        @Override
        public void onCancel(SHARE_MEDIA platform, int action) {

        }
    }

授权调用

mShareAPI.getPlatformInfo(this, SHARE_MEDIA.WEIXIN, new InnerUMAuthListener());

删除授权调用

mShareAPI.deleteOauth(this, SHARE_MEDIA.WEIXIN, new InnerUMAuthListener());







《***************************

分享就是这么多,相对分享推送的需要讲的东西比较多

*****************************》

之前有写一篇关于推送的图文讲解

里面提供了推送的一个工具类,现在给它完善一下,然后再讲讲推送要注意的地方

/**
 * 完善后的友盟推送类
 */
public class UmengHelper {

    private static final String TAG = "UmengHelper";
    public static final String UPDATE_STATUS_ACTION = "com.umeng.message.example.action.UPDATE_STATUS";
    private static UmengHelper mUmengHelper;
    private NotificationManager mNotificationManager;
    private static String USER_ALIAS_KEY = "WEIC_ALIAS";
    private static String USER_ALIAS_VALUE = "userId_";
    public static String LOGING_TAG = "log_on";
    public static String BID_TAG = "bid";

    public static UmengHelper getInstance() {
        if (mUmengHelper == null) {
            mUmengHelper = new UmengHelper();
        }
        return mUmengHelper;
    }

    public void init() {
        mNotificationManager = (NotificationManager) ContextUtils.getContext().getSystemService(Context.NOTIFICATION_SERVICE);
        PushAgent mPushAgent = PushAgent.getInstance(ContextUtils.getContext());
        //注册推送服务,每次调用register方法都会回调该接口
        UMConfigure.setLogEnabled(true);
        mPushAgent.setNotificationPlaySound(MsgConstant.NOTIFICATION_PLAY_SDK_ENABLE);
        mPushAgent.register(new IUmengRegisterCallback() {
            @Override
            public void onSuccess(String deviceToken) {
                //注册成功会返回device token
                Log.d(TAG, "onSuccess: deviceToken----" + deviceToken);
                ContextUtils.getContext().sendBroadcast(new Intent(UPDATE_STATUS_ACTION));
            }

            @Override
            public void onFailure(String s, String s1) {
                Log.d(TAG, "onFailure: ---" + s + "     s1--" + s1);
                ContextUtils.getContext().sendBroadcast(new Intent(UPDATE_STATUS_ACTION));
            }
        });
        UMConfigure.init(ContextUtils.getContext(), "", "", UMConfigure.DEVICE_TYPE_PHONE, "");

        setMessageHandler();
        setNotificationClickHandler();
    }

    public static void startPushAgent() {
        PushAgent.getInstance(ContextUtils.getContext()).onAppStart();
    }

    /**
     * 设置用户别名
     */
    public static void setUserAlias(long user_id) {
        //设置用户id和device_token的一对多的映射关系:
        PushAgent.getInstance(ContextUtils.getContext()).addAlias(USER_ALIAS_VALUE + user_id, USER_ALIAS_KEY, new UTrack.ICallBack() {
            @Override
            public void onMessage(boolean isSuccess, String message) {
                Log.d(TAG, "设置别名" + isSuccess + "     别名--" + message);
            }
        });
    }

    public static void delUserAlias() {
        long userid = BaseApplication.getInstance().getUser() == null ? 0 : BaseApplication.getInstance().getUser().getUser_id();
        PushAgent.getInstance(ContextUtils.getContext()).deleteAlias(USER_ALIAS_VALUE + userid, USER_ALIAS_KEY, new UTrack.ICallBack() {
            @Override
            public void onMessage(boolean b, String s) {
                LogUtils.e("删除别名..." + b + "删除结果..." + s);
            }
        });
    }

    /**
     * 设置用户标签  通常是用户登录了或者有其他操作才调用此方法设置标签
     */
    public static void setUserTag(String... var2) {
        PushAgent.getInstance(ContextUtils.getContext()).getTagManager().addTags(new TagManager.TCallBack() {

            @Override
            public void onMessage(final boolean isSuccess, final ITagManager.Result result) {
                //isSuccess表示操作是否成功
                Log.e(TAG, "添加标签" + isSuccess);
            }
        }, var2);
    }

    public static void delUserTag() {
        PushAgent.getInstance(ContextUtils.getContext()).getTagManager().deleteTags(new TagManager.TCallBack() {
            @Override
            public void onMessage(boolean b, ITagManager.Result result) {
                Log.e(TAG, "删除标签" + b);
            }
        }, LOGING_TAG, BID_TAG);
    }

    public void setMessageHandler() {
        UmengMessageHandler messageHandler = new UmengMessageHandler() {
            @Override
            public void dealWithCustomMessage(final Context context, final UMessage msg) {
                Log.e(TAG, "dealWithCustomAction msg=" + msg.toString() + ", msg.custom=" + msg.text);
                new Handler(context.getMainLooper()).post(new Runnable() {

                    @Override
                    public void run() {
                        // 对自定义消息的处理方式,点击或者忽略
                        boolean isClickOrDismissed = true;
                        if (isClickOrDismissed) {
                            //自定义消息的点击统计
                            UTrack.getInstance(ContextUtils.getContext()).trackMsgClick(msg);
                        } else {
                            //自定义消息的忽略统计
                            UTrack.getInstance(ContextUtils.getContext()).trackMsgDismissed(msg);
                        }
                    }
                });
            }

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


            @Override
            public Notification getNotification(Context context, UMessage msg) {
                Log.e(TAG, "dealWithCustomAction msg=" + msg.toString() + ", msg.custom=" + msg.text);
                if (msg.extra != null) {
                    String url = msg.extra.get("weic");
                    // TODO: 2018/1/29 根据自定义参数跳转activity
                }
                sendTenNotifications(msg, context);//有时候官方demo的通知不好用,自己写一个,switch里面给它返回一个就行
                switch (msg.builder_id) {
                    case 1:
                        Notification.Builder builder = new Notification.Builder(context);
                        return builder.build();
                    default:
                        //默认为0,若填写的builder_id并不存在,也使用默认。
                        return super.getNotification(context, msg);
                }
            }
        };
        PushAgent.getInstance(ContextUtils.getContext()).setMessageHandler(messageHandler);
    }

    /**
     * 发送通知  默认的通知栏样式
     */
    private void sendTenNotifications(UMessage msg, Context context) {
        Intent intent = new Intent();
        intent.setClassName(context, "需要打开的activity全路径");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(ContextUtils.getContext())
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle(msg.title)
                .setContentText(msg.text)
                .setContentIntent(PendingIntent.getActivity(context, 0, intent, 0));
        mNotificationManager.notify(1, builder.build());
    }

    /**
     * 自定义行为的回调处理,参考文档:高级功能-通知的展示及提醒-自定义通知打开动作
     * UmengNotificationClickHandler是在BroadcastReceiver中被调用,故
     * 如果需启动Activity,需添加Intent.FLAG_ACTIVITY_NEW_TASK
     */
    public void setNotificationClickHandler() {
        /**
         * 该Handler是在BroadcastReceiver中被调用,故
         * 如果需启动Activity,需添加Intent.FLAG_ACTIVITY_NEW_TASK
         * */
        UmengNotificationClickHandler notificationClickHandler = new UmengNotificationClickHandler() {
            @Override
            public void dealWithCustomAction(Context context, UMessage msg) {
                Log.e(TAG, "dealWithCustomAction msg=" + msg.toString() + ", msg.custom=" + msg.custom);
                startActivity(context);
            }

            @Override
            public void launchApp(Context context, UMessage msg) {
                Log.e(TAG, "launchApp msg=" + msg.toString() + ", msg.custom=" + msg.custom);
                if (msg.extra != null) {
                    String url = msg.extra.get("weic");
                    // TODO: 2018/1/29 根据自定义参数跳转activity
                }
                super.launchApp(context, msg);
            }

            @Override
            public void openUrl(Context context, UMessage msg) {
                Log.e(TAG, "openUrl msg=" + msg.toString() + ", msg.custom=" + msg.custom);
                super.openUrl(context, msg);
            }

            @Override
            public void openActivity(Context context, UMessage msg) {
                Log.e(TAG, "openActivity msg=" + msg.toString() + ", msg.custom=" + msg.custom);
            }
        };
        PushAgent.getInstance(ContextUtils.getContext()).setNotificationClickHandler(notificationClickHandler);
    }

    private void startActivity(Context context) {
        Intent i = new Intent();
        i.setAction(Intent.ACTION_MAIN);
        i.addCategory(Intent.CATEGORY_LAUNCHER);
        i.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_NEW_TASK);//如友盟官方的注释所说,如果点击消息要做页面跳转需要添加这个标志
        i.setComponent(new ComponentName("项目包名", "需要打开的activity的全路径"));
        context.startActivity(i);
    }

    private void getAppInfo() {
        String pkgName = ContextUtils.getContext().getPackageName();
        String info = String.format("DeviceToken:%s\n" + "SdkVersion:%s\nAppVersionCode:%s\nAppVersionName:%s",
                PushAgent.getInstance(ContextUtils.getContext()).getRegistrationId(), MsgConstant.SDK_VERSION,
                UmengMessageDeviceConfig.getAppVersionCode(ContextUtils.getContext()), UmengMessageDeviceConfig.getAppVersionName(ContextUtils.getContext()));
        Log.d(TAG, "应用包名:" + pkgName + "\n" + info);
    }
}



然后还有个小米,华为,魅族的离线通道

/**
 * Created by Administrator on 2017/11/23 0023.
 * 小米弹窗功能
 * 小米对后台进程做了诸多限制。若使用一键清理,应用的channel进程被清除,将接收不到推送。
 * 为了增加推送的送达率,可选择接入小米托管弹窗功能。通知将由小米系统托管弹出,
 * 点击通知栏将跳转到指定的Activity。该Activity需继承自UmengNotifyClickActivity,
 * 同时实现父类的onMessage方法,对该方法的intent参数进一步解析即可,该方法异步调用,不阻塞主线程
 */

public class MipushDialogActivity extends UmengNotifyClickActivity {

    private static String TAG = MipushDialogActivity.class.getName();
    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.notification_view);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.e(TAG, "onNewIntent: " + intent);
    }


    @Override
    public void onMessage(Intent intent) {
        super.onMessage(intent);  //此方法必须调用,否则无法统计打开数
        String body = intent.getStringExtra(AgooConstants.MESSAGE_BODY);
        Log.e(TAG, "onMessage: " + body);
        Message message = Message.obtain();
        message.obj = body;
        handler.sendMessage(message);
    }
}

下面这个实体类是在onMessage中获取到的body

/**
 * Created by Administrator on 2018/1/29.
 * 离线通知实体类
 */

data class PushInfo(
		val display_type: String, //notification  推送消息类型
		val extra: Extra,
		val msg_id: String, //uuapugn151720757171510  推送消息的id
		val body: Body,
		val random_min: Int //0
)
//自定义参数  可根据此参数做页面跳转
data class Extra(
		val url: String //"mainActivity"  key为url-->value为mainActivity
)

data class Body(
		val after_open: String, //go_app  点击推送消息打开应用后的行为描述 go_qpp(启动应用) go_custom(自定义行为) go_activity(打开指定页面) go_url(打开指定链接)
		val play_lights: String, //false 是否亮灯(手机消息呼吸灯)
		val ticker: String, //惺惺惜惺惺
		val play_vibrate: String, //false
		val custom: String, //自定义行为的value
		val activity: String,//activity的全路径
		val url: String, //链接地址
		val text: String, //阿德法阿萨德  内容
		val title: String, //惺惺惜惺惺   标题
		val play_sound: Boolean //true   是否播放声音
)

manifest配置

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xxx">

    <permission
        android:name="${applicationId}.permission.MIPUSH_RECEIVE"
        android:protectionLevel="signatureOrSystem" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.BROADCAST_PACKAGE_ADDED" />
    <uses-permission android:name="android.permission.BROADCAST_PACKAGE_CHANGED" />
    <uses-permission android:name="android.permission.BROADCAST_PACKAGE_INSTALL" />
    <uses-permission android:name="android.permission.BROADCAST_PACKAGE_REPLACED" />
    <uses-permission android:name="android.permission.RESTART_PACKAGES" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="${applicationId}.permission.MIPUSH_RECEIVE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
    <!-- 兼容flyme5.0以下版本,魅族内部集成pushSDK必填,不然无法收到消息 -->
    <uses-permission android:name="com.meizu.flyme.push.permission.RECEIVE" />
    <permission
        android:name="${applicationId}.push.permission.MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="${applicationId}.push.permission.MESSAGE" />

    <!-- 兼容flyme3.0配置权限 -->
    <uses-permission android:name="com.meizu.c2dm.permission.RECEIVE" />
    <permission
        android:name="${applicationId}.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
    <!--LinkedME SDK 需要开启的权限-->  <!--LinkedME SDK 需要开启的权限-->
    <uses-permission android:name="android.permission.BLUETOOTH" />

    <application>

        <service
            android:name="com.taobao.accs.ChannelService"
            android:exported="true"
            android:process=":channel">
            <intent-filter>
                <action android:name="com.taobao.accs.intent.action.SERVICE" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.taobao.accs.intent.action.ELECTION" />
            </intent-filter>
        </service>

        <service
            android:name="com.taobao.accs.data.MsgDistributeService"
            android:exported="true">
            <intent-filter>
                <action android:name="com.taobao.accs.intent.action.RECEIVE" />
            </intent-filter>
        </service>

        <receiver
            android:name="com.taobao.accs.EventReceiver"
            android:process=":channel">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_REMOVED" />
                <data android:scheme="package" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.USER_PRESENT" />
            </intent-filter>
        </receiver>

        <receiver
            android:name="com.taobao.accs.ServiceReceiver"
            android:process=":channel">
            <intent-filter>
                <action android:name="com.taobao.accs.intent.action.COMMAND" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.taobao.accs.intent.action.START_FROM_AGOO" />
            </intent-filter>
        </receiver>

        <service
            android:name="com.taobao.accs.internal.AccsJobService"
            android:permission="android.permission.BIND_JOB_SERVICE"
            android:process=":channel" />

        <service
            android:name="com.taobao.accs.ChannelService$KernelService"
            android:process=":channel" />

        <service
            android:name="org.android.agoo.accs.AgooService"
            android:exported="true">
            <intent-filter>
                <action android:name="com.taobao.accs.intent.action.RECEIVE" />
            </intent-filter>
        </service>

        <service
            android:name="com.umeng.message.UmengIntentService"
            android:exported="true"
            android:process=":channel">
            <intent-filter>
                <action android:name="org.agoo.android.intent.action.RECEIVE" />
            </intent-filter>
        </service>

        <service
            android:name="com.umeng.message.XiaomiIntentService"
            android:exported="true"
            android:process=":channel">
            <intent-filter>
                <action android:name="org.agoo.android.intent.action.RECEIVE" />
            </intent-filter>
        </service>

        <receiver
            android:name="com.taobao.agoo.AgooCommondReceiver"
            android:exported="true"
            android:process=":channel">
            <intent-filter>
                <action android:name="${applicationId}.intent.action.COMMAND" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_REMOVED" />
                <data android:scheme="package" />
            </intent-filter>
        </receiver>

        <service
            android:name="com.umeng.message.UmengMessageIntentReceiverService"
            android:exported="true"
            android:process=":channel">
            <intent-filter>
                <action android:name="org.android.agoo.client.MessageReceiverService" />
            </intent-filter>
        </service>

        <receiver
            android:name="com.umeng.message.NotificationProxyBroadcastReceiver"
            android:exported="false" />

        <service
            android:name="com.umeng.message.UmengMessageCallbackHandlerService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.umeng.messge.registercallback.action" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.umeng.message.enablecallback.action" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.umeng.message.disablecallback.action" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.umeng.message.message.handler.action" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.umeng.message.message.sendmessage.action" />
            </intent-filter>
        </service>

        <service
            android:name="com.umeng.message.UmengDownloadResourceService"
            android:exported="false" />

        <provider
            android:name="com.umeng.message.provider.MessageProvider"
            android:authorities="${applicationId}.umeng.message"
            android:exported="false">
            <grant-uri-permission android:pathPattern=".*" />
        </provider>

        <!-- mipush -->
        <service
            android:name="com.xiaomi.mipush.sdk.PushMessageHandler"
            android:enabled="true"
            android:exported="true" />

        <service
            android:name="com.xiaomi.mipush.sdk.MessageHandleService"
            android:enabled="true" />

        <receiver
            android:name="org.android.agoo.xiaomi.MiPushBroadcastReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.xiaomi.mipush.ERROR" />
            </intent-filter>
        </receiver>

        <!-- huawei push -->
        <receiver android:name="org.android.agoo.huawei.HuaWeiReceiver">
            <intent-filter>
                <action android:name="com.huawei.android.push.intent.REGISTRATION" />
                <action android:name="com.huawei.android.push.intent.RECEIVE" />
                <action android:name="com.huawei.intent.action.PUSH" />
                <action android:name="com.huawei.intent.action.PUSH_STATE" />
            </intent-filter>
        </receiver>

        <meta-data
            android:name="UMENG_CHANNEL"
            android:value="${UMENG_CHANNEL_VALUE}" />

        <meta-data
            android:name="UMENG_APPKEY"
            android:value="${UMENG_APPKEY}" />

        <meta-data
            android:name="UMENG_MESSAGE_SECRET"
            android:value="${UMENG_MESSAGE_SECRET}" />

        <!-- 小米华为推送配置 -->
        <activity
            android:name="com.jinzaofintech.investlib.MipushDialogActivity"
            android:exported="true"
            android:launchMode="singleTask">
            <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="myscheme" />
            </intent-filter>
        </activity>

        <receiver
            android:name="com.meizu.cloud.pushsdk.SystemReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="com.meizu.cloud.pushservice.action.PUSH_SERVICE_START" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

        <!-- meizu push -->
        <service
            android:name="com.meizu.cloud.pushsdk.NotificationService"
            android:exported="true" />
    </application>
</manifest>

推送的项目结构图如下

android 友盟推送处理 友盟 个推_android 友盟推送处理

推送代码相关的总共就这些东西了。jar包so文件从sdk中copy就行了

下面讲坑


友盟社会化分享集成问题大全


友盟推送集成问题大全


小白集成友盟自动更新


基本百分之九十以上的问题这几个链接都能解决了,还有一些解决不了,我恰好知道的下面给说一下


主要是几个方面吧


  1. 奔溃有可能引起的因素,少了某个资源文件,有可能是图片,string文件里面的文字,比如第三方登录授权要获取用户信息的时候需要这两个资源
<string name="umeng_socialize_female">女</string>
    <string name="umeng_socialize_male">男</string>
有时候是布局写错了,比如log能看到推送消息,但是消息通知栏不显示notification,如果用了自定义notification的话建议检查一下布局,然后需要设置大小图片 myNotificationView.setImageViewBitmap(R.id.notification_large_icon, getLargeIcon(context, msg));                      myNotificationView.setImageViewResource(R.id.notification_small_icon, getSmallIconId(context, msg));要记得给上匹配名字的图片
包名是否和友盟后台的一致,ID这些
没办法的办法就是去找友盟客服了,基本通过这些方法都能解决掉你的问题了,还不行你就在下方留言,大家一起商讨