android蓝牙聊天开发(2)图文混排+Notification消息通知

使用listView,继承BaseAdapter,实现聊天界面:,运行图:

layout_list_item.xml单个item条目的布局,即图片,聊天内容,时间的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/tvTime"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:layout_alignParentTop="true"
        android:text="TextView" />

    <ImageView
        android:id="@+id/ivIcon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxWidth="48dp"
        android:maxHeight="48dp"
        android:adjustViewBounds="true"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/tvTime"
        android:background="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/tvMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/ivIcon"
        android:textSize="22dp"
        android:layout_below="@id/tvTime"
        android:text="TextView" />

</RelativeLayout>

 main_activity.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/textView1"
        android:scrollingCache="false"
        >
    </ListView>

</RelativeLayout>

MyAdapter:通过循环向控件中添加数据,在封装进Adapter适配器里面,重写四个方法

public class MyAdapter extends BaseAdapter {
	private List<HashMap<String, Object>> mDataSet;
	private Context mContext;
	// 转换器,XML文件转化成控件对象
	private LayoutInflater mInflater;

	public MyAdapter(Context c) {
		mContext = c;
		mDataSet = new ArrayList<HashMap<String, Object>>();
		HashMap<String, Object> map;
		for (int i = 0; i < 30; i++) {
			map = new HashMap<String, Object>();
			map.put("image", R.drawable.ic_launcher);
			map.put("time", "19:32");
			map.put("message", "聊天内容" + i);
			mDataSet.add(map);
		}

		// 获得系统转化器
		mInflater = (LayoutInflater) mContext
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}

	public List<HashMap<String, Object>> getDataSet(){
		return mDataSet;
	}

	/**
	 * 用于返回数据集合数量
	 */
	@Override
	public int getCount() {
		return mDataSet.size();
	}
//position:它要组装数据集合中第几个数据记录
	//getItem : 根据一个索引(位置)获得该位置的对象
	@Override
	public Object getItem(int position) {
		return null;
	}
//getItemId : 获取条目的id
	@Override
	public long getItemId(int position) {
		return 0;
	}

	/**
	 * 用于将循环器中将要显示的项进行数据组装 ListView会将移出显示区域的View项放到循环器中,等待getView来组装新项
	 * position:它要组装数据集合中第几个数据记录 convertView:循环器中的待用对象(可能为null)
	 * parent:ListVIew的父控件对象
	 */
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {

		// 判断convertView是否为空,如果为空,说明ListView刚刚初始化显示
		// 如果不为空,说明是循环器中可用的项
		if (convertView == null) {
			// 将Layout文件中的控件转化成可用的控件对象
			convertView = mInflater.inflate(R.layout.layout_list_item, null);

			ImageView image = (ImageView) convertView.findViewById(R.id.ivIcon);
			TextView time = (TextView) convertView.findViewById(R.id.tvTime);
			TextView message = (TextView) convertView
					.findViewById(R.id.tvMessage);
			convertView.setTag(new Holder(image, time, message));
		}
		// long start = System.currentTimeMillis();
		// System.out.println("Delay:" + (System.currentTimeMillis() - start));

		// 重复使用已经存在的项
		// 将position位置处的数据组装到该项中,返回
		Holder h = (Holder) convertView.getTag();
		h.image.setImageResource((Integer) mDataSet.get(position).get("image"));
		h.time.setText((String) mDataSet.get(position).get("time"));
		h.message.setText((String) mDataSet.get(position).get("message"));

		return convertView;
	}

	private class Holder {
		ImageView image;
		TextView time;
		TextView message;

		public Holder(ImageView img, TextView tm, TextView msg) {
			image = img;
			time = tm;
			message = msg;
		}
	}
}
MainActivity里面给每个listView里面的item(每一条)设置一个监听事件
public class MainActivity extends Activity {
	private ListView mListView;
	private List<String> mDataSet;

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

		mListView = (ListView) findViewById(R.id.listView1);

      /*  // 生成ListView数据
        mDataSet = new ArrayList<String>();
        for(int i = 0; i < 30; i++){
        	mDataSet.add("显示数据" + i);
        }


        // 适配器中封装有要显示的数据

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
        		android.R.layout.simple_list_item_1,
        		mDataSet
        		);

        mListView.setAdapter(adapter);*/

		final MyAdapter adapter = new MyAdapter(this);
		mListView.setAdapter(adapter);

		mListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
									long arg3) {
				Toast.makeText(MainActivity.this, "您点击了:" + adapter.getDataSet().get(arg2).get("message"),  Toast.LENGTH_SHORT).show();
			}
		});

		mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

			@Override
			public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
										   int arg2, long arg3) {
				Toast.makeText(MainActivity.this, "您长击了:" + adapter.getDataSet().get(arg2).get("message"),  Toast.LENGTH_SHORT).show();
				return true;
			}
		});

	}

}

接下来:如何创建通知:Notification通知图解

Android Notification

 

Notification,是一种具有全局效果的通知,可以在系统的通知栏中显示。当 APP 向系统发出通知时,它将先以图标的形式显示在通知栏中。用户可以下拉通知栏查看通知的详细信息。 

 

发送通知的函数:

Notification在android 8.0以上设置时,需要设置渠道信息才能够正常显示通知,新增如下代码

 NotificationChannel mChannel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_LOW);

//Notification在android 8.0以上设置时,需要设置渠道信息才能够正常显示通知
private void notifyMessage(){
    String id = "my_channel_01";
    String name="我是渠道名字";
    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    Notification notification = null;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel mChannel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_LOW);
        Toast.makeText(this, mChannel.toString(), Toast.LENGTH_SHORT).show();
        Log.i(TAG, mChannel.toString());
        notificationManager.createNotificationChannel(mChannel);
        notification = new Notification.Builder(this)
                .setChannelId(id)
                .setContentTitle("5 new messages")
                .setContentText("hahaha")
                .setSmallIcon(R.mipmap.ic_launcher).build();
    } else {
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setContentTitle("5 new messages")
                .setContentText("hahaha")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setOngoing(true);

        notification = notificationBuilder.build();
    }
    notificationManager.notify(111123, notification);

}

全部代码:

mainActivity:

package com.lmj.bluetoothchat;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.view.View;

public class MainActivity extends Activity {
    /**
     * 表示xx通知ID
     */
    public static final int NOTIFY_ID = 100;

   private Notification builder;
    private PendingIntent contentIntent = null;
    private NotificationManager nm;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }


    @RequiresApi(api = Build.VERSION_CODES.O)
    private void notifyMessage(){
        String id = "my_channel_01";
        String name="我是渠道名字";
        // 发送通知需要用到NotificationManager对象
        nm = (NotificationManager)this.getSystemService(NOTIFICATION_SERVICE);
        // 消息对象
        Intent notificationIntent = new Intent(this, NotifyActivity.class);
        // PendingIntent.getActivity(Context context, int requestCode, Intent intent, int flags)
        // 用来获得一个挂起的PendingIntent,让该Intent去启动新的Activity来处理通知
        //通过PendingIntent,来实现点击通知栏,跳转到Activity页面的功能,它类似于intent跳转页面。
        contentIntent = PendingIntent.getActivity(MainActivity.this, 0, notificationIntent, 0);

        // 定制我们要在状态栏显示的通知样式
       //anv= new Notification.Builder(this)

        builder = new Notification.Builder(this)
                .setChannelId(id)
                .setContentIntent(contentIntent)
                .setSmallIcon(R.drawable.ic_launcher)//设置状态栏里面的图标(小图标)                     .setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.i5))//下拉下拉列表里面的图标(大图标)        .setTicker("this is bitch!") //设置状态栏的显示的信息
                .setWhen(System.currentTimeMillis())//设置时间发生时间
                .setAutoCancel(true)//设置可以清除
                .setContentTitle("我是标题")//设置下拉列表里的标题
                .setContentText("我是内容").build();//设置上下文内容
        Notification在android 8.0以上设置时,需要设置渠道信息才能够正常显示通知,即需要加上NotificationChannel对象信息

      //点击通知要跳转到 目标activity
      /*  Intent intent = new Intent(this, SecondeActivity.class);
        PendingIntent pendingIntent =
                PendingIntent.getActivity(this,1,intent,PendingIntent.FLAG_CANCEL_CURRENT);
//设置通知默认效果
        builder.contentIntent = pendingIntent;
        builder.flags = Notification.FLAG_SHOW_LIGHTS;*/
       // startForegroundService(1, builder);

        NotificationChannel mChannel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_LOW);
        nm.createNotificationChannel(mChannel);
        // 获得刚才创建的通知对象
      //  Notification notification = builder.getNotification();//获取一个Notification
       // notification.defaults = Notification.DEFAULT_SOUND;//设置为默认的声音

        // 通过NotificationManger来发送通知消息
        // 参数1通知的ID,参数2发送哪个通知
      //  nm.notify(NOTIFY_ID, notification);
        nm.notify(NOTIFY_ID,builder);
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    public void sendNotifyBtn(View v){
        notifyMessage();
    }

    public void cancelNotifyBtn(View v){
        NotificationManager manger = (NotificationManager)this.getSystemService(NOTIFICATION_SERVICE);
        manger.cancel(NOTIFY_ID);
    }
    public void turn1(View view){
        Intent intent=new Intent(this,NotifyActivity.class);
        startActivity(intent);
    }
}
NotifyActivity代码:点击通知栏,弹出(原生android)对话框

package com.lmj.bluetoothchat;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.NotificationManager;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;

public class NotifyActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		showDialog();
	}


	private void showDialog() {
		// 创建并显示一个对话框
		AlertDialog.Builder dlg = new AlertDialog.Builder(this);
		// 自定义Dialog需要自己创建或转换一个View,将其通过下面的方法显示。
		//dlg.setView(view);

		// 设置对话框显示样式
		dlg.setTitle("我是对话框标题");
		dlg.setMessage("我是对话框内容");
		dlg.setIcon(R.drawable.ic_launcher);
		dlg.setPositiveButton("是", new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				System.out.println("PositiveButton被点击");
				NotificationManager manger = (NotificationManager)NotifyActivity.this.getSystemService(NOTIFICATION_SERVICE);
				manger.cancel(MainActivity.NOTIFY_ID);
			}
		});
		dlg.setNegativeButton("否", new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				System.out.println("NegativeButton被点击");
			}
		});
		dlg.setNeutralButton("取消", new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				System.out.println("NeutralButton被点击");
			}
		});
		// 不允许用户取消对话框
		dlg.setCancelable(false);
		dlg.create();

		// 对话框显示必须要调用 show();
		dlg.show();
	}

}

secondeActivity:用于点击跳转第二个页面的测试类:

public class SecondeActivity extends AppCompatActivity {

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

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="44dp"
        android:onClick="cancelNotifyBtn"
        android:text="取消Notification" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button2"
        android:layout_alignParentTop="true"
        android:layout_marginTop="134dp"
        android:onClick="sendNotifyBtn"
        android:text="发送Notification" />

</RelativeLayout>

secondeActivity.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
  >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是第二个页面" />

</android.support.constraint.ConstraintLayout>

运行如下:

最后记得在mainfest里添加相应配置:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.lmj.bluetoothchat">
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
        tools:ignore="ProtectedPermissions" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".NotifyActivity"/>
        <activity android:name=".SecondeActivity"/>
    </application>

</manifest>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值