极光消息推送及角标实现,附带完整demo

摘要:本次实现了用户登录注册,将用户保存到Application 里面实现用户持久化,用户有已读消息查看,未读消息查看,发送消息功能,未读消息读取后,添加到已读消息里面,发送消息具有推送功能 可以全部发送,和选择人员发送,发送消息过后,如果当前用户在线会收到一条任务栏通知,点击通知可以查看到该消息,登录App时,APP应用会生成,未读信息角标,(实现了vivo和小米。

 

流程图:

 

项目结构

 

 

项目使用jar:

 

项目使用权限:

 

广播接收器:

 

<!-- Required SDK 核心功能 -->
<!-- 可配置android:process参数将PushService放在其他进程中 -->
<service
    android:name="cn.jpush.android.service.PushService"
    android:enabled="true"
    android:exported="false">
    <intent-filter>
        <action android:name="cn.jpush.android.intent.REGISTER" />
        <action android:name="cn.jpush.android.intent.REPORT" />
        <action android:name="cn.jpush.android.intent.PushService" />
        <action android:name="cn.jpush.android.intent.PUSH_TIME" />
    </intent-filter>
</service>

<!-- since 1.8.0 option 可选项。用于同一设备中不同应用的JPush服务相互拉起的功能。 -->
<!-- 若不启用该功能可删除该组件,将不拉起其他应用也不能被其他应用拉起 -->
<service
    android:name="cn.jpush.android.service.DaemonService"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="cn.jpush.android.intent.DaemonService" />

        <category android:name="com.example.pk.tuisong" />
    </intent-filter>
</service>

<!-- Required SDK核心功能 -->
<receiver
    android:name="cn.jpush.android.service.PushReceiver"
    android:enabled="true">
    <intent-filter android:priority="1000">
        <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" />

        <category android:name="com.example.pk.tuisong" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.USER_PRESENT" />
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
    <!-- Optional -->
    <intent-filter>
        <action android:name="android.intent.action.PACKAGE_ADDED" />
        <action android:name="android.intent.action.PACKAGE_REMOVED" />

        <data android:scheme="package" />
    </intent-filter>
</receiver>

<!-- Required SDK核心功能 -->
<activity
    android:name="cn.jpush.android.ui.PushActivity"
    android:configChanges="orientation|keyboardHidden"
    android:exported="false"
    android:theme="@android:style/Theme.NoTitleBar">
    <intent-filter>
        <action android:name="cn.jpush.android.ui.PushActivity" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="com.example.pk.tuisong" />
    </intent-filter>
</activity>
<!-- SDK核心功能 -->
<activity
    android:name="cn.jpush.android.ui.PopWinActivity"
    android:configChanges="orientation|keyboardHidden"
    android:exported="false"
    android:theme="@style/MyDialogStyle">
    <intent-filter>
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="com.example.pk.tuisong" />
    </intent-filter>
</activity>

<!-- Required SDK核心功能 -->
<service
    android:name="cn.jpush.android.service.DownloadService"
    android:enabled="true"
    android:exported="false" />

<!-- Required SDK核心功能 -->
<receiver android:name="cn.jpush.android.service.AlarmReceiver" />

 

数据表结构:

 

User表:

字段

类型

作用

备注

ID

Int

主键,自增长

确定每条数据的唯一性

Username

String

用户名,唯一

极光推送的别名

Password

String

密码

 

 

 

Xiaoxi表:

字段

类型

作用

备注

ID

Int

主键

确定每条数据的唯一性

Username

String

用户名

确定是哪个用户的消息

Xiaoxi

String

消息,内容

该条消息的内容

Biaoti

String

消息的标题

本条消息的标题

 

第一步:

实现登录注册,把账号信息发送给服务器,绑定用户,以便后面消息传送操作!

(此功能上次已做!)

 

第二步:

消息的传送:

 

进入该activity时 通过服务器查询出该用户的 已读消息 和未读消息,

点击已读消息时 会跳转到一个listview 里面显示了该用户的已读消息,

点击未读消息的时候 会跳转到一个listview 里面显示了该用户的未读消息,改listview 拥有一个点击事件,当点击某条消息时,会跳转到一个显示页面,显示该条信息,并把该消息的状态改为已读。

 

Listview的点击事件:


ListView  list = (ListView) findViewById(R.id.listwd);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                            long arg3) {
        text=(TextView)arg1.findViewById(R.id.friend_username);

        String name1 = text.getText().toString();
        int aid =text.getId();

        Toast.makeText(Unread.this,"ID" + arg2 + "个项目",Toast.LENGTH_SHORT).show();
        xiaoxics.setUsername(name);
        xiaoxics.setBiaoti(name1);
        xiaoxics.setXiaoxizt(arg2+"");

        String xiaoxijson = JSON.toJSONString(xiaoxics);

        Intent intent = new Intent(Unread.this,XianshiXinXi.class);
        intent.putExtra("shuju",xiaoxijson);
        startActivity(intent);
    }
});

 

 

此处实现了listview里面 拥有一个简单的Textview的点击事件,请勿假如Button,加入Button 此点击事件将无效!

 

点击发送消息时,会跳到一个全新的activity

 

在这里 输入消息的标题和内容 点击发送所有人时 会把次消息发送给服务器 服务器保存该消息,并像用户推送

 

      public staticString push(List<String> username,Stringbiaoti,String username1){

            User user = new User();

            user.setUsername(username1);

            user.setPassword(biaoti);   

            String userjson = JSON.toJSONString(user);

           

            String fhz = "loser";

            String masterSecret ="cb79148f2b69efa00dbc16b0";

            String appKey = "76a005b037fa2b8194fe412a";

            JPushClient jpushClient =new JPushClient(masterSecret,appKey);   

           

            PushPayload payload =PushPayload.newBuilder()

                        .setMessage(Message.content(userjson))

                        .setPlatform(Platform.android_ios())

                        .setAudience(Audience.alias(username))

                        .setNotification(Notification.newBuilder()

                               .addPlatformNotification(AndroidNotification.newBuilder()

                                        .addExtra("type","传回去的数据)

                                        .setAlert("你有一条新消息")

                                        .build())

                               .addPlatformNotification(IosNotification.newBuilder()

                                        .addExtra("type","传回去的数据")

                                        .setAlert("你有一条新消息")

                                        .build())

                                .build())

                        .setOptions(Options.newBuilder()

                                .setApnsProduction(false)

                                .setTimeToLive(90)/

                                .build())

                        .build();         

 

点击发送对象时 会把该页面的主题 和内容传到一个新的页面,该页面有一个listview ,该listview 显示了所有的用户名,具有一个多选事件,当选择完用户后,会把主题和内容和用户集合发送给服务器,服务器会根据用户名推送消息。

public class SendOut extends BaseActivity {
    ListView list;
    List<User> userList,usernamelist = null;
    Fsong fsong = null;
    MyHandiler2 myHandiler2;
    ArrayList<HashMap<String, Object>> listData;
    //适配器
    CheckboxAdapter listItemAdapter;
    String name1=null;
    TextView buttonfsdxfhsy;

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


        buttonfsdxfhsy = (TextView) findViewById(R.id.buttonfsdxfhsy);



        myHandiler2 = new MyHandiler2();

        Intent intent = getIntent();
        String fsongjson = intent.getStringExtra("fsong");
        fsong = JSON.parseObject(fsongjson, Fsong.class);

//反回主页
        buttonfsdxfhsy.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent23 = new Intent(SendOut.this,Home_page.class);
                intent23.putExtra("dxfsfh",fsong.getUsername());
                startActivity(intent23);
            }
        });


        Button getValue = (Button) findViewById(R.id.get_value);
        getValue.setOnClickListener(listener);
//listview
        list = (ListView) findViewById(R.id.list);
//存储数据的数组列表
        listData = new ArrayList<HashMap<String, Object>>();

        //显示所有已读消息
        final okHttp ok = new okHttp();
        try {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Message msg = new Message();
                    try {
                        userList = ok.duxianzs();
                        msg.what = 1;
                        String listjson = JSON.toJSONString(userList);
                        Bundle bundle = new Bundle();
                        bundle.putSerializable("list", listjson);
                        msg.setData(bundle);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    myHandiler2.sendMessage(msg);
                }
            }).start();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    //事件响应
    View.OnClickListener listener = new View.OnClickListener() {

        @Override
        public void onClick(View v) {
// TODO Auto-generated method stub
            HashMap<Integer, Boolean> state = listItemAdapter.state;
            List<User> stringlist =new  ArrayList<User>();
            String options = "选择的项是:";
            for (int j = 0; j < listItemAdapter.getCount(); j++) {
                System.out.println("state.get(" + j + ")==" + state.get(j));
                if (state.get(j) != null) {
                    User user = new User();
                    @SuppressWarnings("unchecked")
                    HashMap<String, Object> map = (HashMap<String, Object>) listItemAdapter.getItem(j);
                    String username = map.get("friend_username").toString();
                    user.setUsername(username);
                    Log.i("info", "__________________________9527___________________" +username);
                    options+="\n"+"."+username;
                    Log.i("info", "__________________________9527___________________" +options);
                    stringlist.add(user);
                }
            }
            fsong.setUserList(stringlist);
            Log.i("info", "__________________________9527___________________" +fsong.getXiaoxi());


            final okHttp ok = new okHttp();
            try {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Message msg = new Message();
                        try {
                            String xiaoxi = ok.dxtssj(fsong);
                            msg.what = 2;
                            Bundle bundle = new Bundle();
                            bundle.putSerializable("xiaoxixi", xiaoxi);
                            Log.i("info", "____________9527______________9527___________________" +xiaoxi);
                            msg.setData(bundle);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        myHandiler2.sendMessage(msg);
                    }
                }).start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    //数据的传递
    public class MyHandiler2 extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                    String list12 = (String) msg.getData().getSerializable("list");
                   List<User> userlistqw =JSON.parseArray(list12, User.class);

                    Log.i("info","____________________________________________________________"+userList.size());
                    for(int i=0;i<userList.size();i++){
                        HashMap<String, Object> map=new HashMap<String, Object>();
                        map.put("friend_username",userList.get(i).getUsername());
                        map.put("selected", false);
                        //添加数据
                        listData.add(map);
                    }
                    //适配器
                    listItemAdapter = new CheckboxAdapter(SendOut.this, listData);
                    list.setAdapter(listItemAdapter);
                    break;
                case 2:
                    String xiaoxixi = (String) msg.getData().getSerializable("xiaoxixi");
                    Log.i("info","_______________________888____888____888_____________________________"+xiaoxixi);
                    String name =xiaoxixi.substring(0,1);
                    if (name.equals("1")) {
                        Toast.makeText(getApplicationContext(), "发送成功!", Toast.LENGTH_LONG).show();
                    } else {
                        //显示选择内容
                        Toast.makeText(getApplicationContext(), "发送失败!", Toast.LENGTH_LONG).show();
                    }
                    break;
            }
        }
    }

 

 

第三步:

对接收推送回来的数据进行操作:

 

推送回来的消息会被BroadcastReceiver广播接收,在此广播中队接到的数据进行操作!

public class MyReceiver extends BroadcastReceiver{
    String username = null;
    @Override
    public void onReceive(Context context, Intent intent) {

//判断是否接收到了数据,并任务栏显示:
        if (intent.getAction().equals(JPushInterface.ACTION_MESSAGE_RECEIVED)) {
            Bundle bundle = intent.getExtras();
            String title = bundle.getString(JPushInterface.EXTRA_TITLE);
            String  message = bundle.getString(JPushInterface.EXTRA_MESSAGE);
            username = message;
            String shuju =bundle.getString("type");
            Toast.makeText(context, message, Toast.LENGTH_LONG).show();
            Log.i("info","___message_____123_______________________"+bundle.toString());

        }
//判断任务栏的推送是否被点击 点击了后的操作!
        if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
            
            Bundle bundle = intent.getExtras();
            int name1=bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);
            String title = bundle.getString(JPushInterface.EXTRA_TITLE);
            String name =bundle.getString(JPushInterface.EXTRA_EXTRA);
            String  message = bundle.getString(JPushInterface.EXTRA_MESSAGE);
            Log.i("info", "用户点击打开了通知--------120----->"+name.toString());

            Mapp map =JSON.parseObject(name,Mapp.class);
            Log.i("info", "用户点击打开了通知--------120----->"+map.toString());
            String usernam = map.getType();
         
            Log.i("info", "用户点击打开了通知--------120----->"+usernam);

//点击过后 把推送回来的数据 转发到消息显示页面,让该页面显示此消息!
            Intent intent1 = new Intent();
            intent1.putExtra("cgb",usernam);
            intent1.setClass(context,Tuisongxianshi.class);
            intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent1);
        }
    }

 

最后角标的实现:

 

下面就是手机角标的实现,只需要得到未读消息的条数,然后传入这两个方法就行

 


//获取手机品牌
String phoneName = android.os.Build.MODEL;

 

//vivo 角标设置

if(phoneName.equals("vivo Y51")){
    Intent intent2 = new Intent("launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM");
    intent2.putExtra("packageName",packageName);
    String launchClassName =lancherActivityClassName;
    intent2.putExtra("className", launchClassName);
    //显示的角标数!
    intent2.putExtra("notificationNum",a);
    sendBroadcast(intent2);
}
//小米角标判断
else{
    try {
        Field field = notification.getClass().getDeclaredField("extraNotification");
        Object extraNotification = field.get(notification);
        Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class);
        method.invoke(extraNotification, a);
    } catch (Exception e) {
        e.printStackTrace();
    }
    mNotificationManager.notify(0, notification);
}

 

 

此次学习的难点集合:

角标的实现:

 

每种手机品牌的角标实现方法并不一致,有的手机根本不支持角标,所以针对各种手机角标的问题,需要写入大量的代码,有的手机角标Dome 十分难找,所以写起来十分困难!

华为角标:

华为的角标只对大型的某些应用开发,所以在这里无法实现! 

从保护用户体验的角度出发,华为角标暂时只对较大型的纯即时通讯类应用(例:聊天工具、邮箱)和大型企业的内部办公应用开放,还请各位开发者谅解!

 

Listview 的点击事件:

 

网上有很多 listview的点击Dome 但是并不都适用,这要看你listview里面的布局是什么样子的,如果只是简单的Textview 就可以直接 listview的对象点setOnItemClickListener(newAdapterView.OnItemClickListener()来实现点击事件,如果要加入Button等有需要另外的方法!

 

BroadcastReceiver 的取值问题:

 

当点击任务栏 进入if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {

 

后,并取不到message 里面的值,最好吧 bundle。toString打印出来看一下,看里面传过来的究竟是什么,应为上面个IF取到了值,所以很容易忽略下面的if里面有可能是取不到值的,如果 不小心这里会怎么都找不出错来!

 

 

Intent 跳转新页面时,加入

intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK| Intent.FLAG_ACTIVITY_NEW_TASK);

这句!每次清除前面的activity ,让后面点击返回按钮时 会打开新的activity 这样让数据刷新!

列如:

Intent intent1 =new Intent(Tuisongxianshi.this,Home_page.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK| Intent.FLAG_ACTIVITY_NEW_TASK);
intent1.putExtra("tuisfh",name1);
startActivity(intent1);

 

实现BroadcastReceiver 接收到通知就更新 未读消息条数:

先在Home_page中 定义一个instance的成员变量!

staticHome_page instance;

 

然后在

protected voidonCreate(Bundle savedInstanceState) {
   
super.onCreate(savedInstanceState);
   
setContentView(R.layout.activity_home_page);

instance = this;

在写一个instance的get方法:

public staticHome_page getInstance(){
   
return instance;
}

 

在BroadcastReceiver 中 得到消息的地方:

public voidonReceive(Context context,Intent intent) {

   
if (intent.getAction().equals(JPushInterface.ACTION_MESSAGE_RECEIVED)) {
       
Home_page.getInstance().runOnUiThread(newRunnable() {
           
@Override
           
public void run() {
               
// TODOAuto-generated method stub
               
//Toast.makeText(MessSendActivity.getInstance(),
                // "frommessSend", 1).show();
               
TextView pb = (TextView) Home_page
                        .getInstance().findViewById(R.id.
textViewjiaobiao);
               
String jiaobiaoshu = (String) pb.getText();
                int
a=Integer.parseInt(jiaobiaoshu);
               
pb.setText((a+1)+"");
           
}
        })
;

   
}

 

就可以更新UI了!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值