长沙网站推广有哪些啊,计算机网站建设与维护,华与华营销策划公司,the7 wordpressAndroid设置铃声和闹钟使用的方法是一样的#xff0c;但是要区别的去获取对应的权限。
统一权限#xff0c;不管是设置闹钟还是铃声#xff0c;他们都需要一个系统设置权限如下: //高版本需要WRITE_SETTINGS权限//此权限是敏感权限#xff0c;无法动态申请#xff0c;需要…Android设置铃声和闹钟使用的方法是一样的但是要区别的去获取对应的权限。
统一权限不管是设置闹钟还是铃声他们都需要一个系统设置权限如下: //高版本需要WRITE_SETTINGS权限//此权限是敏感权限无法动态申请需要跳转到系统界面开启if (Build.VERSION.SDK_INT Build.VERSION_CODES.M) {//判断是否已经开启权限if (!Settings.System.canWrite(mContext)) {//没有开启这里需要一个弹窗来提醒用户要去设置下这个权限//自己的demo可以忽略此步骤应用商店权限申请前需要说明mBindView.tvTitle.post {//这是我自己的权限说明弹窗,自己的定义即可OpenWriteDialog.show(this.supportFragmentManager){if (it){//这一步是跳转到系统设置界面跳转之后有个回调判断是否已经开启开启了继续处理下一步val intent Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS)intent.data Uri.parse(package:$packageName)startActivityForResult(intent, PERMISSION_LOCAL_CODE)}}}} else {//开启了运行下一步todo()}} else {//低版本直接运行下一步todo()}RequiresApi(Build.VERSION_CODES.M)override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)//回调判断code是否一致if (requestCode PERMISSION_LOCAL_CODE){//判断是否已经开启if (Settings.System.canWrite(this)) {//开启了进行下一步todo()}}}设置铃声或者闹钟前都要先进行上一步的权限判断才可以继续进行
设置闹钟
首先动态判断权限
Manifest.permission.SET_ALARM
Manifest.permission.READ_EXTERNAL_STORAGE
Manifest.permission.WRITE_EXTERNAL_STORAGE然后调用代码即可
RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_ALARM, uri)注意这里的uri是手机本地的铃声路径大多数的需求是下载网络.mp3 铃声到本地然后更新闹钟这里注意下下载之后需要更新到媒体库才可以正常设置否则设置出来可能是未知或者直接设置不成功----------如何下载更新到媒体库后面统一讲
设置铃声
同闹钟一样首先需要动态获取权限
Manifest.permission.READ_EXTERNAL_STORAGE
Manifest.permission.WRITE_EXTERNAL_STORAGE其次设置铃声即可
RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE, uri)这里的uri同闹钟一样需要更新到媒体库才可以设置
下载网页铃声到本地 DownloadUtil.download(网页链接,存储路径, 文件名称.mp3,object : DownloadUtil.OnDownloadListener{override fun onDownloadSuccess(file: File?) {//下载成功以及下载后的文件}override fun onDownloading(progress: Int) {//下载进度}override fun onDownloadFailed(e: Exception?) {//下载失败}})存储路径地址这里给出建议写法 private fun getUrlPath(): String {val externalFilesDir: File? this.getExternalFilesDir()val customFile File(externalFilesDir!!.absolutePath, Sandbox)if (!customFile.exists()) {customFile.mkdirs()}return customFile.absolutePath File.separator}文件名称后缀 .mp3即可
DownloadUtil源码
object DownloadUtil {private var okHttpClient: OkHttpClient? null/*** param url 下载连接* param destFileDir 下载的文件储存目录* param destFileName 下载文件名称* param listener 下载监听*/fun download(url: String, destFileDir: String, destFileName: String, listener: OnDownloadListener) {if (url null || url ){return}if (okHttpClient null){okHttpClient OkHttpClient()}val request: Request Request.Builder().url(url).build()okHttpClient!!.newCall(request).enqueue(object : Callback {override fun onFailure(call: Call, e: IOException) {// 下载失败监听回调listener.onDownloadFailed(e)}Throws(IOException::class)override fun onResponse(call: Call, response: Response) {if (response.body ! null) {var inputStream: InputStream? nullval buf ByteArray(2048)var len 0var fos: FileOutputStream? null// 储存下载文件的目录val dir File(destFileDir)if (!dir.exists()) {dir.mkdirs()}val file File(dir, destFileName)try {inputStream response.body!!.byteStream()val total: Long response.body!!.contentLength()fos FileOutputStream(file)var sum: Long 0while (inputStream.read(buf).also { len it } ! -1) {fos.write(buf, 0, len)sum len.toLong()val progress (sum * 1.0f / total * 100).toInt()// 下载中更新进度条listener.onDownloading(progress)}fos.flush()// 下载完成listener.onDownloadSuccess(file)} catch (e: Exception) {listener.onDownloadFailed(e)} finally {try {inputStream?.close()} catch (e: IOException) {listener.onDownloadFailed(e)}try {fos?.close()} catch (e: IOException) {listener.onDownloadFailed(e)}}}else{listener.onDownloadFailed(IOException(接口失败))}}})}interface OnDownloadListener {/*** param file 下载成功后的文件*/fun onDownloadSuccess(file: File?)/*** param progress 下载进度*/fun onDownloading(progress: Int)/*** param e 下载异常信息*/fun onDownloadFailed(e: Exception?)}}此时就将网络音频下载到本地了这时候拿到file是无法更新到闹钟或者铃声的甚至本地音乐里面都找不它需要更新到媒体库才可以进行设置
更新到媒体库
更新媒体库使用的是 ContentValues 以前文章写过下载视频到本地都是一样的只不过参数不同 可以看下参数对比下
更新到媒体库的时候要注意 高版本和低版本区分更新
如果你此时使用的是网上大多数的 MediaScannerConnection.scanFile() 方法大概率是不会成功的
使用
DangUtils.setMYRingtone(mContext,mDownFile!!.absolutePath,mDownType,mDownName);其中 mDownFile 就是我下载到本地的文件 DangUtils 代码
object DangUtils {/*** 将资源更新到媒体库* context - 上下文* filePath - 本地路径* type - 类型-设置闹钟还是铃声* name - 名称提示用户的 可有可无*/fun setMYRingtone(context: Context, filePath: String?,type: String,name: String): Boolean {if (filePath null || filePath ){return false}return if (Build.VERSION.SDK_INT Build.VERSION_CODES.Q) {saveVideoToAlbumBeforeQ(context, filePath,type,name)} else {saveVideoToAlbumAfterQ(context, filePath,type,name)}}private fun saveVideoToAlbumAfterQ(context: Context, filePath: String,mDownType: String,name: String): Boolean {return try {val contentResolver context.contentResolverval tempFile File(filePath)val contentValues getVideoContentValues(context, tempFile, System.currentTimeMillis())val uri contentResolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, contentValues)copyFileAfterQ(context, contentResolver, tempFile, uri)contentValues.clear()contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0)context.contentResolver.update(uri!!, contentValues, null, null)context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri))if (mDownType Setting_LS) {// 设置系统来电铃声RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE, uri)Toast.makeText(context, 已将${name}设置为来电铃声, Toast.LENGTH_SHORT).show()}else{RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_ALARM, uri)Toast.makeText(context, 已将${name}设置为闹铃, Toast.LENGTH_SHORT).show()}true} catch (e: java.lang.Exception) {e.printStackTrace()if (mDownType Setting_LS) {Toast.makeText(context, 铃声设置失败, Toast.LENGTH_SHORT).show()}else{Toast.makeText(context, 闹铃设置失败, Toast.LENGTH_SHORT).show()}false}}private fun saveVideoToAlbumBeforeQ(context: Context, videoFile: String,mDownType: String,name: String): Boolean {val picDir Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)val tempFile File(videoFile)val destFile File(picDir, context.packageName File.separator tempFile.name)var ins: FileInputStream? nullvar ous: BufferedOutputStream? nullreturn try {ins FileInputStream(tempFile)ous BufferedOutputStream(FileOutputStream(destFile))var nread 0Lval buf ByteArray(1024)var n: Intwhile (ins.read(buf).also { n it } 0) {ous.write(buf, 0, n)nread n.toLong()}MediaScannerConnection.scanFile(context, arrayOf(destFile.absolutePath),null) { path: String?, uri: Uri? -if (mDownType Setting_LS) {// 设置系统来电铃声RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE, uri)Toast.makeText(context, 已将${name}设置为来电铃声, Toast.LENGTH_SHORT).show()}else{RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_ALARM, uri)Toast.makeText(context, 已将${name}设置为闹铃, Toast.LENGTH_SHORT).show()}}true} catch (e: java.lang.Exception) {e.printStackTrace()if (mDownType Setting_LS) {Toast.makeText(context, 铃声设置失败, Toast.LENGTH_SHORT).show()}else{Toast.makeText(context, 闹铃设置失败, Toast.LENGTH_SHORT).show()}false} finally {try {ins?.close()ous?.close()} catch (e: IOException) {e.printStackTrace()}}}Throws(IOException::class)private fun copyFileAfterQ(context: Context,localContentResolver: ContentResolver,tempFile: File,localUri: Uri?) {if (Build.VERSION.SDK_INT Build.VERSION_CODES.Q context.applicationInfo.targetSdkVersion Build.VERSION_CODES.Q) {//拷贝文件到相册的uri,android10及以上得这么干否则不会显示。可以参考ScreenMediaRecorder的save方法val os localContentResolver.openOutputStream(localUri!!)Files.copy(tempFile.toPath(), os)os!!.close()tempFile.delete()}}/*** 获取视频的contentValue*/private fun getVideoContentValues(context: Context, paramFile: File, timestamp: Long): ContentValues {val localContentValues ContentValues()if (Build.VERSION.SDK_INT Build.VERSION_CODES.Q) {localContentValues.put(MediaStore.Audio.Media.RELATIVE_PATH, Environment.DIRECTORY_MUSIC File.separator context.packageName)}localContentValues.put(MediaStore.Audio.Media.TITLE, paramFile.name)localContentValues.put(MediaStore.Audio.Media.DISPLAY_NAME, paramFile.name)localContentValues.put(MediaStore.Audio.Media.MIME_TYPE, music/mp3)localContentValues.put(MediaStore.Audio.Media.DATE_TAKEN, timestamp)localContentValues.put(MediaStore.Audio.Media.DATE_MODIFIED, timestamp)localContentValues.put(MediaStore.Audio.Media.DATE_ADDED, timestamp)localContentValues.put(MediaStore.Audio.Media.SIZE, paramFile.length())return localContentValues}}