參考書籍:《第一行代碼》 第二版 郭霖
如有錯漏吊档,請批評指出!
通知(Notification)的使用
我們在使用手機過程中夫啊,經常會收到應用程序發(fā)出的通知顿肺。當某個應用程序希望向用戶發(fā)送一些提示信息或推送時,就可以借助通知來實現性昭。發(fā)出一條通知后拦止,狀態(tài)欄會顯示一個應用圖標,下拉狀態(tài)欄后可以看到通知的詳細內容糜颠。
- 通知的基本用法
- 首先要獲取一個NotificationManager來對通知進行管理汹族。
調用Context的 getSystemService() 方法獲取,這個方法接收一個String參數用于確定獲取系統(tǒng)的哪個服務其兴,我們傳入Context.NOTIFICATION_SERVICE 即可顶瞒。NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- 接下來需要使用一個Builder構造器來創(chuàng)建 Notification 對象,這里我們使用 support-v4 庫中的 NotificationConpat 類的構造器來創(chuàng)建(因為Android系統(tǒng)每次更新版本基本都會對Notification功能進行修改忌警,所以使用app包下的構造器可能存在不穩(wěn)定性)搁拙。
NotificationCompat.Builder() 接收兩個參數秒梳,第一個參數是Context,第二個參數是一個String箕速,用于對Notification進行分類酪碘。我們可以通過一系列的set方法來豐富我們創(chuàng)建的Notification對象。這里我們使用了幾個最基本的方法盐茎,setContentTitle() 用于設置通知的標題兴垦,setContentText()用于設置通知顯示的內容,setWhen()用于設置通知創(chuàng)建的時間字柠,setSmallIcon()用于設置狀態(tài)欄顯示的小圖標探越,setLargeIcon()用于設置下拉狀態(tài)欄中顯示的大圖標。最后還要調用build()方法來創(chuàng)建Notification對象窑业。Notification notification = new NotificationCompat.Builder(this, "default") .setContentText("通知") .setContentTitle("第一行代碼") .setWhen(System.currentTimeMillis()) .setSmallIcon(R.drawable.ic_huaji) .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_android)) .build();
- 然后我們調用 NotificationManager 對象的notify()方法來發(fā)送通知钦幔。這個方法接收兩個參數,第一個參數是id常柄,是通知的唯一標識鲤氢,第二個參數就是要發(fā)送的 Notification 對象。
manager.notify(1, notification);
- 最后西潘,雖然我們的 Notification 創(chuàng)建并且發(fā)送出去了卷玉,但是我們并沒有給這個通知指定事件,當我們點擊這個通知時喷市,是沒有任何反應的相种,下面我們來設置點擊通知時跳轉到某個Activity,并且通知消失品姓。
這里我們調用了setContentIntent()方法寝并,這個方法接收有一個PendingIntent 參數,這種Intent可以理解為一種延時執(zhí)行的Intent缭黔,因為我們在使用Intent時食茎,必須依賴于一個Activity跳轉到另一個Activity,否則馏谨,我們傳遞的數據會被清理掉别渔,而我們這里點擊通知跳轉到另一個Activity,明顯發(fā)送通知的Activity很多時候并不在后臺惧互,因此我們可以理解為哎媚,PendingIntent實現Activity跳轉的這個動作延時了,當我們點擊通知時喊儡,才進行跳轉拨与。這里由于我們要實現Activity跳轉,因此我們調用PendingIntent的getActivity()方法來獲取實例艾猜,這個方法接收四個參數买喧,第一個參數是Context捻悯,第三個參數是一個Intent對象,另兩個參數我們傳0即可淤毛,感興趣的話可以查看文檔今缚,了解每個參數的含義。setAutoCancel()方法用于設置通知被點擊時自動取消掉低淡。這里給出的代碼是創(chuàng)建以及發(fā)送通知的過程姓言,我們需要將這段代碼放到某一個Button的點擊事件里面,才會觸發(fā)蔗蹋。直接運行看看效果吧何荚。Intent intent = new Intent(this, CpMainActivity.class); PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0); NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); Notification notification = new NotificationCompat.Builder(this, "default") .setContentText("通知") .setContentTitle("第一行代碼") .setWhen(System.currentTimeMillis()) .setSmallIcon(R.drawable.ic_huaji) .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_android)) .setContentIntent(pi) .setAutoCancel(true) .build(); manager.notify(1, notification);
關于通知的內容遠不止這么多,我們只是實現了一個簡單的通知猪杭,Notification.Builder 中提供了很豐富的API餐塘,可以幫助我們實現很多炫酷的通知效果,我們這里就不一一介紹了胁孙,可以根據自己的需求去查詢相關文檔唠倦。
播放多媒體文件
-
播放音頻
在Android中,播放音頻一般都是使用Mediaplayer類來實現涮较,它對多種音頻提供了非常全面的控制方法,使得播放音樂的工作變得十分簡單冈止。
我們先來了解一下Mediaplayer的工作流程:首先創(chuàng)建一個MediaPlayer對象狂票,然后調用setDataSource()方法來設置音頻文件的路徑,再調用prepare()方法使MediaPlayer進入準備狀態(tài)熙暴,接下來調用start()方法就可以開始播放音頻闺属,調用pause()方法可以暫停播放,調用reset()方法可以將Mediaplayer對象重置到剛剛創(chuàng)建的狀態(tài)周霉,想要再播放音頻掂器,就需要重新給它設置音頻文件路徑;而stop()方法則會使當前Mediaplayer對象無法再播放個音頻俱箱。
接下來寫一個小Demo国瓮,首先看一下布局:很簡單,就不貼代碼了狞谱,三個Button乃摹,點擊Start,開始播放音樂跟衅;點擊pause孵睬,音樂會暫停,再點擊start伶跷,會從暫停的地方繼續(xù)播放掰读;點擊stop秘狞,音樂停止,再點擊start蹈集,從頭開始播放音樂烁试。功能很簡單,下面來看代碼雾狈。
- 首先創(chuàng)建MediaPlayer對象廓潜,并進行初始化操作:
private static final int TAG_AUDIO_PERMISSION = 100; private MediaPlayer mMediaPlayer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.mm_activity_audio_and_video); ButterKnife.bind(this); initView(); } private void initView() { mMediaPlayer = new MediaPlayer(); if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, TAG_AUDIO_PERMISSION); }else { initMediaPlayer(); } } private void initMediaPlayer() { try{ File file = new File(Environment.getExternalStorageDirectory(), "music.mp3"); mMediaPlayer.setDataSource(file.getPath()); mMediaPlayer.prepare(); } catch (Exception e) { e.printStackTrace(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case TAG_AUDIO_PERMISSION: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){ initMediaPlayer(); }else { ToastUtil.showShortToast(this, "拒絕權限將無法使用程序"); finish(); } break; default: break; } }
可以看到,我們動態(tài)申請了 WRITE_EXTERNAL_STORAGE 這個權限善榛,因為我們要指定音頻文件的位置辩蛋,并讀取這個文件,因此我們需要讀取手機存儲的權限(關于動態(tài)權限申請的內容在前面講過)移盆,我們這里主要看關于MediaPlayer的內容悼院。Environment.getExternalStorageDirectory() 這個方法獲取的是手機外部存儲的根目錄,也就是說咒循,我們指定了在手機外部存儲的根目錄讀取 music.mp3 這個文件据途,為什么讀取這個位置呢?當然是因為我在這個目錄下準備了一個 music.mp3 音頻文件(你可以指定別的位置叙甸,只要你在相應的位置放了這個文件)颖医。接下來就是調用 prepare() 方法了,這時我們的 Mediaplayer 對象已經為播放音樂做好了準備裆蒸。
關于內部存儲 和 外部存儲 熔萧,我們可能會有疑問,其實在我們使用的智能手機中僚祷,無論是手機自帶的XXG的內存還是插入SD卡的內存佛致,都屬于外部存儲。具體可以參考 這篇博客 辙谜。- 接下來就是給我們的Button添加點擊事件了(使用了 ButterKnife)
@OnClick({R.id.but_start, R.id.but_pause, R.id.but_stop}) public void click(View view) { switch (view.getId()){ default: break; case R.id.but_start: if (!mMediaPlayer.isPlaying()){ mMediaPlayer.start(); } break; case R.id.but_pause: if (mMediaPlayer.isPlaying()){ mMediaPlayer.pause(); } break; case R.id.but_stop: mMediaPlayer.reset(); initMediaPlayer(); break; } }
邏輯很簡單俺榆,就不解釋了。
- 最后別忘了調用 MediaPlayer 對象的 stop() 和 release() 方法將 MediaPlayer相關的資源釋放掉装哆。
最后附上 MediaPlayer 相關的常用方法:@Override protected void onDestroy() { super.onDestroy(); if (mMediaPlayer.isPlaying()){ mMediaPlayer.stop(); } if (mMediaPlayer != null){ mMediaPlayer.release(); } }
-
播放視頻
播放視頻主要使用VideoView 類來實現罐脊,其實它的使用方法和Mediaplayer很像。這個類將視頻的顯示和控制集于一身烂琴,是的我們僅僅使用這個類就可以實現一個簡單的視頻播放器爹殊。下面直接看完整的代碼吧(包括前面的音頻部分)。- 布局部分:
<LinearLayout 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" android:orientation="vertical" tools:context=".multimedia.MmAudioAndVideoActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:layout_marginTop="24dp"> <Button android:id="@+id/but_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/start" android:textAllCaps="false" tools:ignore="ButtonStyle" /> <Button android:id="@+id/but_pause" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="24dp" android:text="@string/pause" android:textAllCaps="false" tools:ignore="ButtonStyle" /> <Button android:id="@+id/but_stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="24dp" android:text="@string/stop" android:textAllCaps="false" tools:ignore="ButtonStyle" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_marginTop="20dp"> <VideoView android:id="@+id/video_view" android:layout_width="match_parent" android:layout_height="wrap_content" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal"> <Button android:id="@+id/but_start_video" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/start" android:textAllCaps="false" tools:ignore="ButtonStyle" /> <Button android:id="@+id/but_pause_video" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="24dp" android:text="@string/pause" android:textAllCaps="false" tools:ignore="ButtonStyle" /> <Button android:id="@+id/but_replay_video" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="24dp" android:text="@string/replay" android:textAllCaps="false" tools:ignore="ButtonStyle" /> </LinearLayout> </LinearLayout> </LinearLayout>
- java代碼:
下面也附上 VideoView 的常用方法:public class MmAudioAndVideoActivity extends AppCompatActivity { @BindView(R.id.video_view) VideoView mVideoView; private static final int TAG_AUDIO_PERMISSION = 100; private MediaPlayer mMediaPlayer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.mm_activity_audio_and_video); ButterKnife.bind(this); initView(); } private void initView() { mMediaPlayer = new MediaPlayer(); if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, TAG_AUDIO_PERMISSION); }else { initMediaPlayer(); initVideoPath(); } } private void initMediaPlayer() { try{ File file = new File(Environment.getExternalStorageDirectory(), "music.mp3"); mMediaPlayer.setDataSource(file.getPath()); mMediaPlayer.prepare(); } catch (Exception e) { e.printStackTrace(); } } private void initVideoPath() { File file = new File(Environment.getExternalStorageDirectory(), "movie.mp4"); mVideoView.setVideoPath(file.getPath()); } @OnClick({R.id.but_start, R.id.but_pause, R.id.but_stop, R.id.but_start_video, R.id.but_pause_video, R.id.but_replay_video}) public void click(View view) { switch (view.getId()){ default: break; case R.id.but_start: if (!mMediaPlayer.isPlaying()){ mMediaPlayer.start(); } break; case R.id.but_pause: if (mMediaPlayer.isPlaying()){ mMediaPlayer.pause(); } break; case R.id.but_stop: mMediaPlayer.stop(); mMediaPlayer.reset(); initMediaPlayer(); break; case R.id.but_start_video: if (!mVideoView.isPlaying()){ mVideoView.start(); } break; case R.id.but_pause_video: if (mVideoView.isPlaying()){ mVideoView.pause(); } break; case R.id.but_replay_video: mVideoView.resume(); break; } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case TAG_AUDIO_PERMISSION: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){ initMediaPlayer(); initVideoPath(); }else { ToastUtil.showShortToast(this, "拒絕權限將無法使用程序"); finish(); } break; default: break; } } @Override protected void onDestroy() { super.onDestroy(); if (mMediaPlayer.isPlaying()){ mMediaPlayer.stop(); } if (mMediaPlayer != null){ mMediaPlayer.release(); } if (mVideoView != null){ mVideoView.suspend(); } } }
上一篇:Android基礎回顧(六)| 關于 Content provider
下一篇:Android基礎回顧(八)| 使用HTTP協(xié)議訪問網絡