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

来源:互联网 发布:linux进入grub界面 编辑:程序博客网 时间:2024/05/16 15:13

摘要:本次实现了用户登录注册,将用户保存到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,Stringusername1){

            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 =newIntent(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_pageinstance;

 

然后在

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

instance = this;

在写一个instance的get方法:

public staticHome_pagegetInstance(){
   
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了!

原创粉丝点击