- 根据uri获取文件真实路径
/**
* 根据uri获取文件真实路径
*/
private fun getPathFromUri(ctx: Context, uri: Uri): String? {
if (DocumentsContract.isDocumentUri(ctx, uri)) {
val docId = DocumentsContract.getDocumentId(uri)
when (uri.authority?.toLowerCase()) {
"com.android.externalstorage.documents" -> {
val arr = docId.split(":")
if (arr[0] == "primary") {
return "${Environment.getExternalStorageDirectory()}/${arr[1]}"
}
}
"com.android.providers.downloads.documents" -> {
val contentUri =
ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), docId.toLong())
return queryPathFromUri(ctx, contentUri, null, null)
}
"com.android.providers.media.documents" -> {
val arr = docId.split(":")
val contentUri: Uri? = when (arr[0]) {
"image" -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI
"video" -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI
"audio" -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
else -> null
}
contentUri?.let {
return queryPathFromUri(ctx, it, "_id=?", arrayOf(arr[1]))
}
}
}
} else if (uri.scheme == "content") {
return queryPathFromUri(ctx, uri, null, null)
} else if (uri.scheme == "file") {
return uri.path
}
return null
}
/**
* 根据uri查询文件真实路径
*/
private fun queryPathFromUri(context: Context, uri: Uri, selection: String?, selectionArgs: Array<String>?): String? {
val column = "_data"
val projection = arrayOf(column)
context.contentResolver.query(uri, projection, selection, selectionArgs, null)?.let {
if (it.moveToFirst()) {
return it.getString(it.getColumnIndex(column))
}
it.close()
}
return null
}
-
在fragment中模拟返回栈
在FragmentTransaction中添加addToBackStack() -
判断是否平板
fun isPad(): Boolean{
val mCtx = MyApplication.getContext()
if(mCtx != null){
return (mCtx.resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE
}
return false
}
- service
- 按back键仅切换到后台而不退出
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if(keyCode == KeyEvent.KEYCODE_BACK){
val home = Intent(Intent.ACTION_MAIN)
home.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
home.addCategory(Intent.CATEGORY_HOME)
startActivity(home)
return true
}
return super.onKeyDown(keyCode, event)
}
- 按2次back键退出
private var mExitTime = 0L
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if(keyCode == KeyEvent.KEYCODE_BACK){
if((System.currentTimeMillis() - mExitTime) > 2000){
Toast.makeText(this, "再按一次退出", Toast.LENGTH_SHORT).show()
mExitTime = System.currentTimeMillis()
}else{
finish()
}
return true
}
return super.onKeyDown(keyCode, event)
}
- activity的4种启动模式(standard|singleTop|singleTask|singleInstance)
<activity android:name=".MainActivity"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
- 在子线程中new Handler时报错--Can't create handler inside thread that has not called Looper.prepare()
Looper.prepare()
Handler().postDelayed({
// todo
}, 1000)
Looper.loop()
- Notification API的兼容性(用support-v4库的NotificationCompat类)
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
var intent = Intent(this, MainActivity::class.java)
val pi = PendingIntent.getActivity(this, 0, intent,0)
val notify = NotificationCompat.Builder(this)
.setContentTitle("title")
.setContentText("content")
.setSmallIcon(R.mipmap.ic_launcher)
.setWhen(System.currentTimeMillis())
.setContentIntent(pi)
.setDefaults(NotificationCompat.DEFAULT_ALL)
// 重要程度 -2, -1, 0, 1, 2
.setPriority(NotificationCompat.PRIORITY_MAX)
.setAutoCancel(true)
.build()
manager.notify(1, notify)