- 生成類庫的jar文件
通常情況下,我們需要把一個類庫打包成一個**Jar**文件溉痢,而不是**aar**文件塘揣,因此我們需要對app.gradle進行修改包雀,如下所示:
task makeJar(type: Copy){
delete 'build/libs/CrashCatcher.jar'
from('build/intermediates/bundles/release/')
into('build/libs')
include('classes.jar')
rename('classes.jar', 'CrashCatcher.jar')
}
makeJar.dependsOn(build)
配置好后,即可通過gradle生成我們想要的jar文件亲铡。
- 如何處理Linux不能啟用AVD的問題才写?
First, install some packages and libs:
$ sudo apt-get install lib64stdc++6:i386
$ sudo apt-get install mesa-utils
Second, tweak some links:
$ cd YOURPATH/Android/Sdk/tools/lib64
$ mv libstdc++/ libstdc++.bak
$ ln -s /usr/lib64/libstdc++.so.6 libstdc++
Third, relaunch your AVD device and test it.
3.遇到異常【A problem occurred starting process 'command 'E:\Tools\sdk\ndk-bundle\toolchains\mips64el-linux-android-4.9\prebuilt\windows-x86_64\bin\mips64el-linux-android-strip''】處理辦法 奖蔓, windows下異常
處理辦法:修改項目根目錄的local.properties文件中ndk.dir的值赞草,
如下,原值是:
ndk.dir=E\:\\Tools\\sdk\\ndk-bundle
修改為:
ndk.dir=E\:\\Tools\\sdk\\ndk-bundle.cmd
再次編輯即可正常吆鹤,但是可能下次進入項目時還會報一樣的錯誤厨疙,同樣處理即可!
- 網(wǎng)絡安全配置, 有時候我們可能會網(wǎng)絡不可訪問的時候疑务,可以進行一下配置
在Manifest.xml中的Application節(jié)點中配置network_security_config:
android:networkSecurityConfig="@xml/network_security_config"
配置文件(network_security_config.xml)內容如下:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
- Android 9.0的WebView打開URL頁面沾凄,報錯:ERR_CLEARTEXT_NOT_PERMITTED
需要在Manifest.xml中的Application節(jié)點中配置屬性:
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:usesCleartextTraffic="true"
...>
...
</application>
</manifest>
- 32位SO庫與64位SO庫不匹配時梗醇,又不能找到64位SO庫,只能去掉64位SO庫的引用撒蟀,以免運行時報錯叙谨,所以做一下處理
android {
........
packagingOptions {
exclude 'lib/arm64-v8a/*'
}
........
}
- 處理Linux系統(tǒng)上出現(xiàn)的/dev/kvm權限問題
當我們想要運行模擬器的時候,出現(xiàn)以上問題牙肝,該怎么處理呢唉俗?首先我們先查看一下/dev/kvm所在權限組:
ls -l /dev/kvm
我們可能會得到類似于這樣的結果:
crw-rw---- 1 root kvm 10, 232 2月 15 09:22 /dev/kvm
就結果而看,我們的/dev/kvm屬于root用戶的kvm組
怎么把當前用戶加入kvm組呢配椭?首先安裝一個軟件:
sudo apt install qemu-kvm
執(zhí)行安裝完成后虫溜,我們添加用戶到組
sudo adduser UserName kvm
添加完成后即可,然后重啟電腦股缸!
AndroidStudio就開始打開項目了,這個過程會比較緩慢,有時,AS會出現(xiàn)如下信息:
提示信息
1). 在/etc/sysctl.conf 文件末尾中添加如下代碼:
fs.inotify.max_user_watches = 524288
2). 然后在終端執(zhí)行以下命令:
sudo sysctl -p --system
最后重啟AS
- 如何獲取手機的存儲設備目錄
Android N 提供了StorageManager類衡楞,并開放了StorageVolume類的部分方法,因此可以使用一下方法可以靠譜的獲得相關路徑和信息敦姻。
10.如何保存文件到手機并同步資源
看示例代碼:
/**
* 保存到本地
* @param fileName 文件名
*/
@SuppressLint("Recycle")
private fun saveToLocal(fileName: String, bitmap: Bitmap): Boolean {
try {
var newFileName = fileName
var isOriginalExists = true
val cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null,
"${MediaStore.Images.Media.DISPLAY_NAME} like ?", arrayOf(fileName), null)
if (cursor != null && cursor.count > 0) {
if (cursor.moveToNext()) {
isOriginalExists = contentResolver.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
"${MediaStore.Images.Media._ID}=?",
arrayOf(cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media._ID)).toString())) <= 0
}
}
cursor?.close()
if (isOriginalExists) newFileName = "${System.currentTimeMillis()}_$fileName"
val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, ContentValues().apply {
@Suppress("DEPRECATION")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
put(MediaStore.Images.Media.RELATIVE_PATH, "DCIM/Pictures")
else {
val dir = when (Environment.MEDIA_MOUNTED) {
Environment.getExternalStorageState() ->
Environment.getExternalStorageDirectory().absolutePath
else -> cacheDir.absolutePath
}
put(MediaStore.Images.Media.DATA,
File("${dir}/DCIM/Pictures", newFileName).absolutePath)
}
put(MediaStore.Images.Media.DISPLAY_NAME, newFileName)
put(MediaStore.Images.Media.DESCRIPTION, newFileName)
put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
})
if (uri != null) {
val oos = contentResolver.openOutputStream(uri)
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, oos)
oos?.flush()
oos?.close()
return true
}
} catch (e: Exception) {
e.printStackTrace()
}
return false
}
11.如何解決錯誤: android studio 3 字節(jié)的 UTF-8 序列的字節(jié) 3 無效瘾境。(3 ???? UTF-8 ???е???? 3 ??Ч??)?
- 配置IDE file-coding 都為 UTF-8;
- 配置IDE vmOptions 為 -Dfile.encoding=UTF-8;
- 配置 app.gradle:
compileOptions { encoding 'UTF-8' //設置為UTF-8 .... //其他配置 }
12.如何播放本地視頻镰惦,且不黑屏迷守。 推薦使用TextureView+MediaPlayer+Surface
private var mTexture: TextureView? = null
private var mPlayer: MediaPlayer? = null
private var mSurface: Surface? = null
private var mVideoUri: Uri? = null
private var mListener: OnmPlayerStateChangedListener? = null
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
constructor(
context: Context,
attrs: AttributeSet?,
defStyleAttr: Int,
defStyleRes: Int
) : super(context, attrs, defStyleAttr, defStyleRes)
fun setOnPlayerStateChangedListener(listener: OnmPlayerStateChangedListener) {
this.mListener = listener
}
var videoUri: Uri?
get() = mVideoUri
set(value) {
mVideoUri = value
}
fun initializer(context: Context) {
mTexture = TextureView(context).apply {
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
surfaceTextureListener = this@CustomVideoView
}
addView(mTexture)
}
override fun onSurfaceTextureAvailable(surface: SurfaceTexture, width: Int, height: Int) {
if (mVideoUri == null)
throw Exception("請首先設置播放源")
mSurface = Surface(surface)
PlayerThread(mVideoUri!!).start()
mListener?.onStarted()
}
override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) {}
override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
onReleasemPlayer()
mTexture = null
mSurface = null
return true
}
override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {}
fun onReleasemPlayer() {
try {
if (mPlayer != null) {
if (mPlayer?.isPlaying == true)
mPlayer?.pause()
mPlayer?.stop()
mPlayer?.release()
}
mPlayer = null
} catch (e: Exception) {
Log.e("CustomVideoView", e.message)
} finally {
mListener?.onReleased()
}
}
/**
* 使視頻適配屏幕
* @param textureWidth Texture寬度
* @param textureHeight Texture高度
*/
private fun stretchingVideoSize(textureWidth: Float, textureHeight: Float) {
val matrix = Matrix()
val videoWidth = mPlayer?.videoWidth ?: return
val videoHeight = mPlayer?.videoHeight ?: return
val scaleX = textureWidth / videoWidth
val scaleY = textureHeight / videoHeight
val originScaleX = videoWidth / textureWidth
val originScaleY = videoHeight / textureHeight
matrix.preScale(originScaleX, originScaleY)
val maxScale = maxOf(scaleX, scaleY)
matrix.preScale(maxScale, maxScale)
mTexture?.setTransform(matrix)
mTexture?.postInvalidate()
}
private inner class PlayerThread(private val uriSource: Uri) : Thread() {
override fun run() {
try {
mPlayer = MediaPlayer().apply {
setDataSource(context, uriSource)
setSurface(mSurface)
setAudioAttributes(
AudioAttributes.Builder()
.setLegacyStreamType(AudioManager.STREAM_MUSIC)
.build()
)
setOnPreparedListener {
it?.start()
if (context is Activity) (context as Activity).runOnUiThread {
val textureWidth =
mTexture?.measuredWidth?.toFloat() ?: return@runOnUiThread
val textureHeight =
mTexture?.measuredHeight?.toFloat() ?: return@runOnUiThread
stretchingVideoSize(textureWidth, textureHeight)
}
}
setOnCompletionListener { mListener?.onCompleted() }
}
mPlayer?.prepare()
} catch (e: Exception) {
Log.e("CustomVideoView", "播放視頻失敗$e")
}
}
}
- android界面置灰效果實現(xiàn)
val paint = Paint()
val cm = ColorMatrix()
cm.setSaturation(0f)
paint.colorFilter = ColorMatrixColorFilter(cm)
window.decorView.setLayerType(View.LAYER_TYPE_HARDWARE, paint)
- WebView與Native交互,通過js方法獲取的Html內容攜帶unicode字段旺入,如何處理兑凿?
Gson().fromJson("html-unicode", String::class.java) //這樣能去掉亂碼
如果是Flutter又該如何處理?可以考慮在js中把數(shù)據(jù)URIComponentEncode(), 取出來用時茵瘾,使用Flutter的Uri.componentDecode().trim(start|end, "")去掉頭尾的雙引號礼华。
Enjoy yourself !
如果能幫到您,請點贊拗秘,謝謝圣絮!