⑴ 判斷android用戶拒絕了某項許可權這個問題您解決了嗎
源碼中被用來檢查和請求許可權的方法分別是Activity的checkSelfPermission和requestPermissions。這些方法api23引入,如下代碼:
java">privatestaticfinalStringTAG="Contacts";
privatevoidinsertDummyContact(){
//.
ArrayList<ContentProviderOperation>operations=newArrayList<ContentProviderOperation>(2);
//First,setupanewrawcontact.
ContentProviderOperation.Builderop=
ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE,null)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME,null);
operations.add(op.build());
//Next,setthenameforthecontact.
op=ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID,0)
.withValue(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
"__");
operations.add(op.build());
//Applytheoperations.
ContentResolverresolver=getContentResolver();
try{
resolver.applyBatch(ContactsContract.AUTHORITY,operations);
}catch(RemoteExceptione){
Log.d(TAG,"Couldnotaddanewcontact:"+e.getMessage());
}catch(){
Log.d(TAG,"Couldnotaddanewcontact:"+e.getMessage());
}
}
⑵ android 許可權清單中有許可權,但是使用時取消了該許可權,請問,如何判斷是否取消了該許可權
音頻錄音的許可權<uses-permissionandroid:name="android.permission.RECORD_AUDIO"/> 。在代碼中,如果你要判斷,可以這么寫:
PackageManager pm = getPackageManager();
boolean flag = (PackageManager.PERMISSION_GRANTED ==
pm.checkPermission("android.permission.RECORD_AUDIO", "packageName"));
if (flag) {
//有這個許可權,做相應處理
}else {
//沒有許可權
}
⑶ app錄音許可權關閉了,安卓手機系統還是能錄取聲音怎麼回事
可能是你禁止錄音功能的時候沒有點完成。
在點擊錄音彈出許可權彈窗前,先判斷是否開啟錄音許可權,如果沒有開啟錄音許可權,就開啟一段虛擬假錄音,這時就會彈出許可權提示了,而真的錄音又沒有被觸發,只有有許可權後真的錄音才會被觸發,這樣就完美的解決了以上問題。
要開始錄音時,這里就會彈出提示框了,如果不給許可權,我們有異常處理,而且下次想錄音時還是會有此提示。
⑷ 判斷軟體是否具有錄音許可權
最簡單的辦法就是,你用這個有錄音功能的軟體錄音下試試,能正常使用那就是有許可權,不能使用就沒有許可權,還提醒你許可權問題。
實踐是檢驗真理的唯一標准
⑸ 如何判斷android用戶拒絕了某項許可權
Android框架包含了對各種Camera以及其上可用的Camera功能的支持,它允許你在應用程序中抓拍照片和視頻。
注意事項
在開啟應用程序使用Android設備上的Camera功能之前,要考慮一些打算如何使用這些硬體功能的問題:
1. Camera需求:要考慮應用程序是否必須要運行在有Camera的設備上,如果必須,就要在應用程序的清單中聲明Camera需求;
2. 快照或定製Camera:應用程序准備如何使用Camera?是只對抓拍或視頻剪輯感興趣?還是要應用程序提供使用Camera的新方法?對於抓拍或剪輯,要考慮使用既存的Camera應用程序。對於開發定製化的Camera功能,請看下文的「構建Camera應用程序」
基礎
Android框架通過Camera API或Camera Intent來支持拍照和錄像,以下是相關的類:
Camera
這個類是控制設備Camera的主API。在構建一個Camera應用程序時,它被用於拍照或錄像。
SurfaceView
這個類用於向用戶實時的展現Camera的預覽。
MediaRecorder
這個類用於記錄來自Camera的視頻
Intent
MediaStore.ACTION_IMAGE_CAPTURE或MediaStore.ACTION_VIDEO_CAPTURE類型的Intent動作被用於不直接使用Camera對象來拍照或錄像。
清單聲明
在開始使用Camera API開發應用程序之前,要確保清單文件已經有了適當的聲明,以允許使用Camera硬體和其他相關的功能。
1. Camera許可權:應用程序必須申請使用設備Camera的許可權。
<uses-permissionandroid:name="android.permission.CAMERA"/>
注意:如果通過Intent來使用Camera,應用程序就不需要申請這個許可權。
2. Camera功能:應用程序還必須要聲明打算使用的Camera功能,例如:
<uses-featureandroid:name="android.hardware.camera"/>
把Camera功能添加到應用程序的清單中,會讓Google Play防止把程序安裝到不包含Camera或不支持你所需要的Camera功能的設備上。關於如何使用基於功能過濾的Google Play,請看Google Play和基於功能的過濾
如果應用程序能夠使用Camera或正確的操作Camera功能,但卻不需要它,那麼就應該在清單中指定android:required屬性,並把屬性值設置為false:
<uses-feature android:name="android.hardware.camera" android:required="false" />
3. 存儲許可權:如果應用程序要把圖片或視頻保存到設備的外部存儲器上(如SD卡),就必須在清單中指定這個許可權:
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
4. 音頻錄音許可權:對於視頻採集的音頻錄音,應用程序必須要申請音頻採集許可權:
<uses-permissionandroid:name="android.permission.RECORD_AUDIO"/>
5. 位置定位許可權:如果應用程序要給圖片標記GPS位置信息,就必須申請位置定位許可權:
<uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/>
關於獲得用戶位置的更多信息,請看「定位策略」
使用既存的Camera應用
在應用程序中不需要太多的額外代碼就可以快速的開啟拍照或錄像的方法是:使用Intent來調用一個既存的Android Camera應用程序。一個Camera Intent能夠通過既存的Camera應用程序和它返回給應用程序的播放控制來申請採集一張照片或一段視頻。本節會向你展示如何使用這項技術來採集一張圖片或一段視頻。
調用Camera Intent的過程會遵循以下這些大概的步驟:
1. 編寫一個Camera Intent:創建一個申請圖片或視頻的Intent對象,使用以下Intent類型之一:
MediaStore.ACTION_IMAGE_CAPTURE:從一個既存的Camera應用中申請圖片功能的Intent動作類型;
MediaStore.ACTION_VIDEO_CAPTURE:從一個既存的Camera應用中申請視頻功能的Intent動作類型。
2. 啟動Camera的Intent:使用startActivityForResult()方法來執行Camera的Intent。Intent啟動後,該Camera應用程序的用戶界面會顯示在屏幕上,並且用戶能夠拍照或錄像;
3. 接收Intent的結果:在你的應用程序中建立一個onActivityResult()方法來接收來自Camera Intent的回調和數據。當用戶完成成拍照或錄像(或者是取消操作),系統會調用這個方法。
圖像採集Intent
使用Camera Intent來採集圖像是你的應用程序用最少的代碼來拍照的快捷方式。一個圖片採集Intent能夠包含以下額外的信息:
MediaStore.EXTRA_OUTPUT:這個設置需要一個指定了保存圖片路徑和文件名的Uri對象。這個設置是可選,但強烈推薦使用。如果不指定這個值,Camera應用程序會用默認的名稱把採集到的圖片保存到默認的位置,這些默認值在Intent.getData()方法的返回欄位中指定。
以下示例演示了如何構建一個圖片採集Intent,並執行它。示例中GetOutputMediaFileUri()方法引用了下面「保存媒體文件」一節中的示例代碼:
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private Uri fileUri;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
startActivityResult()方法執行完成後,用戶就會看到Camera應用程序的界面。用戶完成拍照(或取消操作)之後,用戶界面就會返回到你的應用程序中,並且你必須監聽onActivityResult()方法來接收Intent的結果,並繼續你的應用程序的執行。
視頻採集Intent
使用Camera Intent採集視頻是讓你的應用程序能夠用最少的代碼來錄像的一中快捷方式。視頻採集Intent能夠包含以下額外信息:
MediaStore.EXTRA_OUTPUT:這個設置要求用一個URI來指定保存視頻的路徑和文件名。雖然它是可選的,但強烈推薦使用這個設置。如果沒有指定這個設置,那麼Camera應用程序會把採集到的視頻用默認的名稱保存到默認的位置,默認的設置是在Intent的Intent.getData()方法域中返回的。
MediaStore.EXTRA_VIDEO_QUALITY:這個值的范圍是0~1,0的時候質量最差且文件最小,1的時候質量最高且文件最大。
MediaStore.EXTRA_DURATION_LIMIT:這個值以秒為單位,顯示視頻採集的時長。
MediaStore.EXTRA_SIZE_LIMIT:這個值以位元組為單位,限制視頻採集的文件大小。
下面的示例演示了如何構造一個視頻採集的Intent,並執行它。這個例子中的getOutputMediaFileUri()方法引用了下文的「保存媒體文件」中的示例代碼:
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
private Uri fileUri;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//create new Intent
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO); // create a file to save the video
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high
// start the Video Capture Intent
startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
}
當startActivityForResult()方法被執行時,用戶就會看到一個可編輯的Camera應用程序界面。在用戶完成錄像(或取消操作)之後,該用戶界面就會返回到你的應用程序中,並且你必須監聽onActivityResult()方法來接收Intent的結果,並繼續執行你的應用程序。
接收Camera Intent結果
一旦你構建並執行了一個圖片或視頻的Camera Intent,那麼就必須要配置你應用程序來接收Intent的結果。本節向你展示了如何監聽來自Camera Intent的回調,以便應用程序能夠對採集到的圖片或視頻做進一步的處理。
為了接收Intent的結果,必須在啟動Intent的那個Activity中重寫onActivityResult()方法。下面的示例演示了如何重寫onActivityResult()方法來採集圖片Camera Intent或視頻Camera Intent的返回結果:
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Image captured and saved to fileUri specified in the Intent
Toast.makeText(this, "Image saved to:\n" +
data.getData(), Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Video captured and saved to fileUri specified in the Intent
Toast.makeText(this, "Video saved to:\n" +
data.getData(), Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the video capture
} else {
// Video capture failed, advise user
}
}
}
一旦Activity接收到一個成功的結果,那麼你的應用程序就可以訪問指定位置中的被採集的圖片或視頻。
⑹ android開發中如果有些app的相機,gps,錄音許可權被系統禁用之後,我們在代碼中怎麼判斷是否被禁用
代碼中判斷不了,例如你禁用了相機,你再去調用相機的話,可能屏幕是黑的,
也有可能會拋出異常
因為這是屬於第三方rom的問題
android 原生系統是沒有這種限制的
一但被禁用了,只能手動去系統設置的應用管理受權那裡開啟
⑺ 判斷Android手機是否有錄音許可權
IMEI是一個串號,每個手機出廠都有的。 IMSI確實可以用來識別每一個移動用戶,但是IMSI很長,很難記憶,另外,傳統電話號碼都用0-9的數字來表示,有個用戶習慣問題。所以就規定了ISDN號碼,即我們現在用的手機號碼,通過設定和IMSI號碼綁定來識別用戶。 ISDN號碼完全是規定,因為香港的移動號碼和固話是相同的。原來cdma制式的大靈通也採用的是固定電話的編號方式。 其實那都是軟體開發者的統計需要,裝個看書軟體也啥都要查看聯系人,查看簡訊,後台發簡訊,後台打電話,查看地里位置,有不要嘛?當然沒有,但是他可以調查我們的愛好,然後後台給我們推軟體,當然會跑流量也存在偷窺我們隱私功能,你可以用聯想的樂安全和LBE安全大師這倆安全軟體可以禁止一切後台啟動和限制查看我們的隱私。預防流量丟失和後台開啟我們的錄音,電話,簡訊,攝像頭功能等。希望對你有用
⑻ 安卓許可權控制指南
早期的 Android 系統沒有現在這么多許可權控制設定,管理功能也較不完善(其實是因為當時軟體申請的許可權也沒有現在這么過分)。
在 Android 4.0 中,谷歌對許可權系統進行了改進,於是再經過各大手機廠商的優化,每個國內定製系統就有了如今的許可權管理功能。
許可權管理,各大品牌其實差不多。
就我用過的幾個品牌來講,華為的許可權管理最好,小米其次,OPPO 最差。
當然,這里的「差」是相對的,相對於原生 Android 系統來說,這些廠商的許可權管理做的都很好。
(其實是因為 Google Play 的審核比較嚴格,上架的軟體幾乎都很克制)
所以,如果你要買新手機,在預算充足的情況下,選華為吧。不只是因為技術很牛,可定製性上也很好。
目前,安卓系統的許可權主要分為以下幾類:
這里,重點解釋一下某些許可權的用途。
獲取 IMEI 碼:很多應用都會申請這一許可權, 讀取手機的唯一識別碼 (估計是用於用戶的身份驗證和判斷多開)
存儲:這里指的是 內置存儲的讀寫許可權 ,不包含系統 Android/data 文件夾下的應用私有文件夾,如果這些應用需要在根目錄下存儲數據,則必須擁有該許可權。
讀取位置信息: 只有在已經開啟位置信息開關時,應用才能讀取該信息 。這項許可權不包含加速度計等感測器。
讀取已安裝應用列表: 允許應用讀取已經安裝的軟體 ,一些應用中讓用戶選擇其它應用的功能就是這樣實現的。
身體感測器:允許應用使用諸如 計步器 等感測器。這可以實現計步功能。
運動數據:也可以實現計步功能,但這項許可權是 依賴系統自帶的計步演算法 實現的,這也是有些計步軟體的數據和其它軟體數據不同的原因。
創建快捷方式:你在手機主屏上看到的 APP 圖標就屬於快捷方式,但這是系統在應用安裝完成後自動創建的。這項許可權允許應用 主動創建快捷方式 (比如微信小程序的圖標和的「寫文章」按鈕)。
懸浮窗:微信視頻聊天時切換到其它應用或主屏,這就是懸浮窗。但輸入法不屬於懸浮窗。
忽略電池優化:在 Android 6.0 以上系統中,有一種成為 Doze 模式的省電策略。在這種模式下,應用的聯網將被禁止,直到下一個窗口或接收到 Google 高優先順序推送(需要開發者和網路環境支持)。該許可權允許應用在這種模式下連接網路。
是否授予軟體相應的許可權,取決於該軟體的功能和你的需要。
例如,在導航軟體中,獲取位置信息是一項核心許可權,但在效率軟體中並不是。
對於所有軟體,都建議啟用「獲取 IMEI 碼」許可權 ,否則會給開發者帶來不便,也會影響用戶體驗(國內的一些軟體甚至會在啟動時進行檢查,如該許可權未開啟則不能使用軟體)。
建議對所有軟體關閉「撥打電話」和除「存儲」以外的所有操作類許可權(考慮到可能會有惡意軟體利用這些許可權進行扣費)。
建議關閉除「獲取位置信息」和「讀取已安裝應用列表」以外的所有讀取類許可權( 注意:關閉「讀取簡訊」許可權會導致部分應用無法自動填充簡訊驗證碼,但考慮到國內 ROM 對此都有一定優化,故不建議開啟該許可權 )
對於位置信息許可權,我建議以下軟體保持開啟:
其它軟體要求位置信息許可權的,一律拒絕(有些軟體失去此許可權可能不能正常運行,視情況而定)
至於「讀取已安裝應用列表」許可權,凡是不需要獲取其它軟體名稱的,都可以拒絕此許可權。
攝像頭和錄音許可權比較好判斷,凡是軟體需要這些功能的,都應該允許,否則拒絕即可。
身體感測器和運動數據許可權除計步軟體外均選擇拒絕。
創建快捷方式許可權,目前我打開的軟體只有一個:com.tencent.mm 包名,slogan 是「生活方式」,啟動界面是月亮的那個國民級應用。
懸浮窗許可權,一部分輔助類軟體需要打開,比如手機管家和綠色守護,以及前面提到的那個國民級應用的視頻懸浮窗。
至於開機自啟動等關於後台省電的許可權,請看下期......
⑼ Android實現錄音功能
1 Android錄音需要聲明錄音許可權
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
2.錄音文件要寫到文件夾中,創建文件夾,在Application的onCreate方法中創建文件夾
@Override
public void onCreate() {
super.onCreate();
CrashHandler mCrashHandler = CrashHandler.getInstance();
mCrashHandler.init(getApplicationContext(), getClass());
initFile();
}
private void initFile() {
//錄音文件
File audioFile = new File(Constant.UrlAudio);
if (!audioFile.exists()) {
audioFile.mkdirs();
} else if (!audioFile.isDirectory()) {
audioFile.delete();
audioFile.mkdirs();
}
//拍攝圖片文件
File imageFile = new File(Constant.UrlImage);
if (!imageFile.exists()) {
imageFile.mkdirs();
} else if (!imageFile.isDirectory()) {
imageFile.delete();
imageFile.mkdirs();
}
}
Constant.UrlImage是個靜態的文件路徑
//錄音文件
public static String UrlAudio = FileUtil.getSdcardPathOnSys()+"/EhmFile/media/audio/";
3.在activity中開始錄音
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.media.MediaRecorder;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Locale;
public class Record2Activity extends AppCompatActivity {
// 錄音界面相關
Button btnStart;
Button btnStop;
TextView textTime;
// 錄音功能相關
MediaRecorder mMediaRecorder; // MediaRecorder 實例
boolean isRecording; // 錄音狀態
String fileName; // 錄音文件的名稱
String filePath; // 錄音文件存儲路徑
Thread timeThread; // 記錄錄音時長的線程
int timeCount; // 錄音時長 計數
final int TIME_COUNT = 0x101;
// 錄音文件存放目錄
final String audioSaveDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/audiodemo/";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_record2);
btnStart = (Button) findViewById(R.id.btn_start);
btnStop = (Button) findViewById(R.id.btn_stop);
textTime = (TextView) findViewById(R.id.text_time);
btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 開始錄音
btnStart.setEnabled(false);
btnStop.setEnabled(true);
startRecord();
isRecording = true;
// 初始化錄音時長記錄
timeThread = new Thread(new Runnable() {
@Override
public void run() {
countTime();
}
});
timeThread.start();
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 停止錄音
btnStart.setEnabled(true);
btnStop.setEnabled(false);
stopRecord();
isRecording = false;
}
});
}
// 記錄錄音時長
private void countTime() {
while (isRecording) {
Log.d("mediaRe","正在錄音");
timeCount++;
Message msg = Message.obtain();
msg.what = TIME_COUNT;
msg.obj = timeCount;
myHandler.sendMessage(msg);
try {
timeThread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.d("mediaRec", "結束錄音");
timeCount = 0;
Message msg = Message.obtain();
msg.what = TIME_COUNT;
msg.obj = timeCount;
myHandler.sendMessage(msg);
}
/**
* 開始錄音 使用amr格式
* 錄音文件
*
* @return
*/
public void startRecord() {
// 開始錄音
/* ①Initial:實例化MediaRecorder對象 */
if (mMediaRecorder == null)
mMediaRecorder = new MediaRecorder();
try {
/* ②setAudioSource/setVedioSource */
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 設置麥克風
/*
* ②設置輸出文件的格式:THREE_GPP/MPEG-4/RAW_AMR/Default THREE_GPP(3gp格式
* ,H263視頻/ARM音頻編碼)、MPEG-4、RAW_AMR(只支持音頻且音頻編碼要求為AMR_NB)
*/
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
/* ②設置音頻文件的編碼:AAC/AMR_NB/AMR_MB/Default 聲音的(波形)的采樣 */
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
fileName = DateFormat.format("yyyyMMdd_HHmmss", Calendar.getInstance(Locale.CHINA)) + ".m4a";
//注意文件夾要創建之後才能使用
filePath = Constant.UrlAudio + fileName;
/* ③准備 */
mMediaRecorder.setOutputFile(filePath);
mMediaRecorder.prepare();
/* ④開始 */
mMediaRecorder.start();
} catch (IllegalStateException e) {
Log.i("mediaEr", "call startAmr(File mRecAudioFile) failed!" + e.getMessage());
} catch (IOException e) {
e.printStackTrace();
Log.i("mediaEr", "call startAmr(File mRecAudioFile) failed!" + e.getMessage());
}
}
/**
* 停止錄音
*/
public void stopRecord() {
//有一些網友反應在5.0以上在調用stop的時候會報錯,翻閱了一下谷歌文檔發現上面確實寫的有可能會報錯的情況,捕獲異常清理一下就行了,感謝大家反饋!
try {
mMediaRecorder.stop();
mMediaRecorder.release();
mMediaRecorder = null;
filePath = "";
} catch (RuntimeException e) {
Log.e("mediaR", e.toString());
mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;
File file = new File(filePath);
if (file.exists())
file.delete();
filePath = "";
}
}
// 格式化 錄音時長為 秒
public static String FormatMiss(int miss) {
return "" + miss;
}
Handler myHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case TIME_COUNT:
int count = (int) msg.obj;
Log.d("meidaRe","count == " + count);
textTime.setText(FormatMiss(count));
break;
}
}
};
@Override
protected void onDestroy() {
super.onDestroy();
myHandler.removeCallbacksAndMessages(null);
}
}
布局文件很簡單
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
tools:context=".Record2Activity">
<Button
android:id="@+id/btn_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="結束"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btn_start"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="開始"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btn_stop"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:layout_marginTop="47dp"
android:text="時間"
app:layout_constraintStart_toStartOf="@+id/btn_start"
app:layout_constraintTop_toBottomOf="@+id/btn_start" />
</androidx.constraintlayout.widget.ConstraintLayout>
這樣就可以使用錄音功能了