加入消息提醒功能,每次发消息,使用通知显示人名、头像和内容
加入头像设置功能,支持拍照选取和从相册选取,裁剪
加入播放器功能,支持播放音乐和视频
首先看一下项目的总体:
项目名为Total,它是由三部分组成:Activity.java文件,9.png图形文件和xml布局文件,他简略的将之前所做过的部分实验合成在了一起;实现了部分功能:活动之间的跳转功能,发送消息功能,发送通知功能,上传图片和拍照功能以及调用多媒体功能。
实现流程:首先我们简单设置一个主功能界面用来显示几种功能: 创建 activity_main.xml文件 代码如下:
```java
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/lu">
<!-- //版权保护:NG麒麟-->
<!-- // Zc-->
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="聊天界面"/>
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送通知"/>
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="修改头像"/>
<Button
android:id="@+id/button4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="多媒体"/>
</LinearLayout>
效果图如下:
编写activity函数; 给每一个button设置监听器并且设置相对应的activity; 代码如下:(注意红线处修改)
需设置为自己的对应的按钮和类名;
package com.example.total;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.example.total.Communicate.Talk;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,Talk.class);
startActivityForResult(intent, 1);
}
});
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,Notification.class);
startActivityForResult(intent, 1);
}
});
Button button3 = (Button) findViewById(R.id.button3);
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,Change.class);
startActivityForResult(intent, 1);
}
});
Button button4 = (Button) findViewById(R.id.button4);
button4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,Media.class);
startActivityForResult(intent, 1);
}
});
}
}
之后从发送通知开始依次创建其相应的xml文件和activity文件,并且在创建的同时需要在manifest中注册activity;
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.total">
<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/Theme.Total">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Notification"/>
<activity android:name=".Change"/>
<activity android:name=".Media"/>
<activity android:name=".Communicate.Talk"/>
</application>
</manifest>
1、 发送通知: 创建activity_notification.xml:设置一个简单的发送通知按钮; 代码如下:
<LinearLayout 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:orientation="vertical"
android:background="@drawable/zc_qiao"
>
<Button android:id="@+id/send_notice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送通知"/>
</LinearLayout>
创建Notification活动类,编写相应的函数;
主要代码如下:
package com.example.total;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
@RequiresApi(api = Build.VERSION_CODES.O)
public class Notification extends AppCompatActivity implements View.OnClickListener{
NotificationManager manager ;
String id ="channel_1";
String description = "123";
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel channel = new NotificationChannel(id, "123", importance);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification);
Button sendNotice = findViewById(R.id.send_notice);
sendNotice.setOnClickListener(this);
manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onClick(View view) {
manager.createNotificationChannel(channel);
switch (view.getId()){
case R.id.send_notice:
android.app.Notification notification = new NotificationCompat.Builder(this,id)
.setContentTitle("赴火给您发来一条消息")
.setContentText("你在干嘛呢")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.cc)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.cc))
.build();
manager.notify(1,notification);
break;
default:
break;
}
}
}
注意:在Android O后 引入了一个叫NotificationChannel的类 在sdk版本为26的时候 不加入此类就设置用不了点击事件;
之后连接起来活动和布局之后就可以运行了; 效果图如下:
2、 修改头像; 同上,首先创建activity_change.xml; 代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/zc_qiao">
<Button
android:id="@+id/fromAlbum"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="从相册选取" />
<Button
android:id="@+id/takePhoto"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="拍照" />
<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp" />
</LinearLayout>
(简单设置了两个按钮用来实现调用相机功能调用相册上传照片和裁剪功能) (拍照需要连接手机,虚拟机似乎没有拍照功能,调用相册可以直接使用)
之后编写Change活动类: 代码如下:
package com.example.total;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
public class Change extends AppCompatActivity {
private Button mFromAlbum;
private Button mTakePhotos;
private ImageView mImgView;
private final int FROM_ALBUM = 0;
private final int FROM_TAKE_PHOTOS = 1;
private final int PHOTO_CUT = 2;
private final String FILE_NAME = "tempimg.jpg";
private File tempFile;
private Bitmap bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_change);
mImgView = (ImageView) findViewById(R.id.img);
mFromAlbum = (Button) findViewById(R.id.fromAlbum);
mTakePhotos = (Button) findViewById(R.id.takePhoto);
mFromAlbum.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, FROM_ALBUM);
}
});
mTakePhotos.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri
.fromFile(new File(Environment
.getExternalStorageDirectory(), FILE_NAME)));
}
startActivityForResult(intent, FROM_TAKE_PHOTOS);
}
});
}
@SuppressLint("WrongConstant")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case FROM_ALBUM:
if (data != null) {
Uri uri = data.getData();
editPic(uri);
}
break;
case FROM_TAKE_PHOTOS:
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
tempFile = new File(Environment.getExternalStorageDirectory(),
FILE_NAME);
editPic(Uri.fromFile(tempFile));
} else {
Toast.makeText(Change.this, "未找到存储卡!", 0).show();
}
break;
case PHOTO_CUT:
try {
bitmap = data.getParcelableExtra("data");
mImgView.setImageBitmap(bitmap);
tempFile.delete();
} catch (Exception e) {
e.printStackTrace();
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
private void editPic(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 250);
intent.putExtra("outputY", 250);
intent.putExtra("outputFormat", "JPEG");
intent.putExtra("noFaceDetection", true);
intent.putExtra("return-data", true);
startActivityForResult(intent, PHOTO_CUT);
}
}
代码中设置了相对应的鼠标监听器功能;调用摄像头功能,从相册中选取照片时需判断url路径和存储路径等,以及编辑照片时的editPic功能等; 效果图如下:
最终即可得到效果图;照片上传成功; 拍照功能接入手机打开开发者模式接入USB即可运行;
3、 多媒体功能: 4、 创建activity_media.xml文件;
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="3dp"
android:orientation="vertical"
android:background="@drawable/zc_qiao">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/play"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="播放" />
<Button
android:id="@+id/pause"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="暂停" />
<Button
android:id="@+id/stop"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="停止" />
</LinearLayout>
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="0"
android:progress="0"
android:secondaryProgress="0" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="当前时间" />
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="总时间" />
</RelativeLayout>
</LinearLayout>
编写Media类活动函数;
package com.example.total;
import java.io.File;
import java.io.IOException;
import android.R.integer;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class Media extends Activity implements OnClickListener,
OnSeekBarChangeListener {
private Button play, pause, stop;
private MediaPlayer player;
private SeekBar mSeekBar;
private TextView tv, tv2;
private boolean hadDestroy = false;
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0x01:
break;
default:
break;
}
};
};
Runnable runnable = new Runnable() {
@Override
public void run() {
if (!hadDestroy) {
mHandler.postDelayed(this, 1000);
int currentTime = Math
.round(player.getCurrentPosition() / 1000);
String currentStr = String.format("%s%02d:%02d", "当前时间 ",
currentTime / 60, currentTime % 60);
tv.setText(currentStr);
mSeekBar.setProgress(player.getCurrentPosition());
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_media);
play = (Button) findViewById(R.id.play);
pause = (Button) findViewById(R.id.pause);
stop = (Button) findViewById(R.id.stop);
mSeekBar = (SeekBar) findViewById(R.id.seekbar);
tv = (TextView) findViewById(R.id.tv);
tv2 = (TextView) findViewById(R.id.tv2);
mSeekBar.setOnSeekBarChangeListener(this);
play.setOnClickListener(this);
pause.setOnClickListener(this);
stop.setOnClickListener(this);
player = new MediaPlayer();
initMediaplayer();
}
private void initMediaplayer() {
try {
File file = new File(Environment.getExternalStorageDirectory()
+ "/Download/", "aiqiu.mp3");
player.setDataSource(file.getPath());
Log.e("播放器", file.toString());
player.prepare();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.play:
if (!player.isPlaying()) {
player.start();
int totalTime = Math.round(player.getDuration() / 1000);
String str = String.format("%02d:%02d", totalTime / 60,
totalTime % 60);
tv2.setText(str);
mSeekBar.setMax(player.getDuration());
mHandler.postDelayed(runnable, 1000);
}
break;
case R.id.pause:
if (player.isPlaying()) {
player.pause();
}
break;
case R.id.stop:
if (player.isPlaying()) {
player.reset();
initMediaplayer();
}
break;
default:
break;
}
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (player != null) {
player.seekTo(seekBar.getProgress());
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
protected void onDestroy() {
super.onDestroy();
if (player != null) {
player.stop();
hadDestroy = true;
player.release();
}
}
}
效果图如下:
同样需要导入手机中的音频文件才可以播放;
其中还加入了发送消息的功能正如图1所示: 布局比较简单就不放了; Talk.activity代码:
package com.example.total.Communicate;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.total.R;
import java.util.ArrayList;
import java.util.List;
public class Talk extends Activity {
private List<Msg> msgList = new ArrayList<>();
private EditText inputText;
private Button send;
private RecyclerView msgRecyclerView;
private MsgAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_talk);
initMsgs();
inputText = (EditText) findViewById(R.id.input_text);
send = (Button) findViewById(R.id.send);
msgRecyclerView = (RecyclerView) findViewById(R.id.msg_recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
msgRecyclerView.setLayoutManager(layoutManager);
adapter = new MsgAdapter(msgList);
msgRecyclerView.setAdapter(adapter);
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String content = inputText.getText().toString();
if (!("".equals(content))) {
Toast.makeText(Talk.this,"sure",Toast.LENGTH_SHORT).show();
Msg msg = new Msg(content,Msg.TYPE_SENT);
msgList.add(msg);
adapter.notifyItemInserted(msgList.size()-1);
msgRecyclerView.scrollToPosition(msgList.size()-1);
inputText.setText("");
}
}
}
);
}
private void initMsgs() {
Msg msg1 = new Msg("Hello",Msg.TYPE_RECEIVED);
msgList.add(msg1);
Msg msg2 = new Msg("I'm John",Msg.TYPE_RECEIVED);
msgList.add(msg2);
Msg msg4 = new Msg("who are you",Msg.TYPE_RECEIVED);
msgList.add(msg2);
Msg msg3 = new Msg("Hello",Msg.TYPE_SENT);
msgList.add(msg3);
}
}
谢谢关注,持续更新;
|