Android studio:修订间差异

来自OSSmedia
 
(未显示同一用户的12个中间版本)
第84行: 第84行:
    
    
==发送Notification消息(kotlin)==  
==发送Notification消息(kotlin)==  
fun sendNotification(channel_id:String ,channle_name:String,nTitle:String,nContentText:String,id:Int){  
fun sendNotification(channel_id:String ,channle_name:String,nTitle:String,nContentText:String,id:Int){
var notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager  
 
var notification: Notification? = null  
var notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
//val intent = Intent(Intent.ACTION_VIEW, Uri.parse('http://www.baidu.com/'))  
 
//val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)  
var notification: Notification? = null
//如需链接到网站使用注释代码  
 
val intent = Intent()  
//val intent = Intent(Intent.ACTION_VIEW, Uri.parse('http://www.baidu.com/'))
intent.setClass(this@MainActivity, MainActivity::class.  
 
val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)  
//val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {  
 
val mChannel = NotificationChannel(channel_id, channle_name, NotificationManager.IMPORTANCE_LOW)  
//如需链接到网站使用注释代码
notificationManager.createNotificationChannel(mChannel)  
 
notification = Notification.Builder(this)  
val intent = Intent()
.setChannelId(channel_id)  
 
.setContentTitle(nTitle)  
intent.setClass(this@MainActivity, MainActivity::class.
.setContentText(nContentText)  
 
val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)
 
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
 
val mChannel = NotificationChannel(channel_id, channle_name, NotificationManager.IMPORTANCE_LOW)     notificationManager.createNotificationChannel(mChannel)
 
notification = Notification.Builder(this) .setChannelId(channel_id)  
.setContentTitle(nTitle)     .setContentText(nContentText)
 
.setContentIntent(pendingIntent)  
.setContentIntent(pendingIntent)  
.setSmallIcon(R.drawable.house).build()  
.setSmallIcon(R.drawable.house).build()
} else {  
 
val notificationBuilder = NotificationCompat.Builder(this)  
}
.setContentTitle(nTitle)  
 
.setContentText(nContentText)  
else {
.setSmallIcon(R.drawable.house)  
 
.setOngoing(true)  
val notificationBuilder = NotificationCompat.Builder(this)
 
.setContentTitle(nTitle)
 
.setContentText(nContentText)
 
.setSmallIcon(R.drawable.house)
 
.setOngoing(true)
 
//.setChannel(id)//无效  
//.setChannel(id)//无效  
notification = notificationBuilder.build()  
 
}
notification = notificationBuilder.build()
 
notificationManager.notify(id, notification)  
notificationManager.notify(id, notification)  
}  
}  
第116行: 第135行:
==禁止使用http链接解决方法==  
==禁止使用http链接解决方法==  
访问网络时报异常   
访问网络时报异常   
Cleartext HTTP traffic to not permitted  
Cleartext HTTP traffic to not permitted  
在<application标签里增加android:usesCleartextTraffic="true"即可  
在<application标签里增加android:usesCleartextTraffic="true"即可  
    
    
==bitmap缩小显示==  
==bitmap缩小显示==  
var matrix = Matrix()  
var matrix = Matrix()
matrix.postScale(0.3f,0.3f)//长和宽放大缩小的比例  
 
matrix.postScale(0.3f,0.3f)//长和宽放大缩小的比例
 
val resizeBmp = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true)  
val resizeBmp = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true)  
    
    
==textview 连续左移==  
==textview 连续左移==  
设置一下参数,自动连续左移动  
设置一下参数,自动连续左移动
android:ellipsize="marquee"  
 
android:focusable="auto"  
android:ellipsize="marquee"
android:focusableInTouchMode="true"  
 
android:marqueeRepeatLimit="marquee_forever"  
android:focusable="auto"
android:scrollHorizontally="true"  
 
android:focusableInTouchMode="true"
 
android:marqueeRepeatLimit="marquee_forever"
 
android:scrollHorizontally="true"
 
android:singleLine="true"  
android:singleLine="true"  
    
    
==useAndroidx Error==  
==useAndroidx Error==  
编译报错 This project uses AndroidX dependencies, but the 'android.useAndroidX' property is not enabled.  
编译报错  
 
This project uses AndroidX dependencies, but the 'android.useAndroidX' property is not enabled.  
    
    
在gradle.propeties文件里增加如下语句,允许AnsiroidX  
在gradle.propeties文件里增加如下语句,允许AnsiroidX
 
android.useAndroidX=true  
android.useAndroidX=true  
==post获取数据(kotlin)==  
==post获取数据(kotlin)==  
Thread(Runnable {  
Thread(Runnable {
val toMain1 = mAppMesHandler.obtainMessage()  
 
val toMain1 = mAppMesHandler.obtainMessage()
 
toMain1.arg1 = 1  
toMain1.arg1 = 1  
    
    
var conn: HttpURLConnection? = null  
var conn: HttpURLConnection? = null
var urlString = "http://server/new.php"  
 
try {  
var urlString = "http://server/new.php"
conn = URL(urlString).openConnection() as HttpURLConnection  
 
conn.requestMethod = "POST" // 指定POST请求  
try {
 
conn = URL(urlString).openConnection() as HttpURLConnection
 
conn.requestMethod = "POST" // 指定POST请求
 
conn.doOutput = true // 设置请求过程可以传递参数给服务器  
conn.doOutput = true // 设置请求过程可以传递参数给服务器  
    
    
// post请求参数  
// post请求参数
val param = String.format("name=%s&age=%s&action=%s", "fengxueyan", "23", "query")  
 
DataOutputStream(conn.outputStream).use { os ->  
val param = String.format("name=%s&age=%s&action=%s", "fengxueyan", "23", "query")                     DataOutputStream(conn.outputStream).use { os ->
os.writeBytes(param)  
 
}  
os.writeBytes(param)
 
}
 
conn.connect()  
conn.connect()  
conn.inputStream.use { input ->  
 
conn.inputStream.use { input ->
 
val data = input.bufferedReader().readText()  
val data = input.bufferedReader().readText()  
toMain1.obj = data.toString()  
toMain1.obj = data.toString()
 
}
 
}
 
catch (e: Exception) { 
 
toMain1.obj = e.toString() 
 
}  
}  
} catch (e: Exception) {
 
toMain1.obj = e.toString()
finally {
} finally {  
 
conn?.disconnect()  
conn?.disconnect()
 
}  
}  
    
    
第170行: 第224行:
    
    
    
    
//访问网络必须使用线程,而且线程不允许更新UI  
 
val mAppMesHandler = object : Handler() {  
//访问网络必须使用线程,而且线程不允许更新UI
override fun handleMessage(msg: Message) {  
 
if(msg.arg1 == 1){  
val mAppMesHandler = object : Handler() {
 
override fun handleMessage(msg: Message) {
 
if(msg.arg1 == 1){
 
var hList0 = msg.obj as String  
var hList0 = msg.obj as String  
textView.setText(hList0)  
textView.setText(hList0)
// Toast.makeText(applicationContext,hList0,Toast.LENGTH_LONG).show()  
 
// Toast.makeText(applicationContext,hList0,Toast.LENGTH_LONG).show()
 
}  
}  
    
    
}
    
    
}
}  
}  
==时间日期选择==  
==时间日期选择==  
<TimePicker  
<TimePicker  
android:id="@+id/ptime"  
android:id="@+id/ptime"
android:layout_width="310dp"  
 
android:layout_height="347dp"  
android:layout_width="310dp"
app:layout_constraintEnd_toEndOf="parent"  
 
app:layout_constraintStart_toStartOf="parent"  
android:layout_height="347dp"
 
app:layout_constraintEnd_toEndOf="parent"
 
app:layout_constraintStart_toStartOf="parent"
 
app:layout_constraintTop_toBottomOf="@+id/button2" />  
app:layout_constraintTop_toBottomOf="@+id/button2" />  
    
    
textView.setText(ptime.hour.toString()+":"+ptime.minute.toString())  
textView.setText(ptime.hour.toString()+":"+ptime.minute.toString())  
    
    
<DatePicker  
<DatePicker
android:id="@+id/pdate"  
 
android:layout_width="358dp"  
android:id="@+id/pdate"
android:layout_height="428dp"  
 
android:layout_marginTop="20dp"  
android:layout_width="358dp"
app:layout_constraintEnd_toEndOf="parent"  
 
app:layout_constraintHorizontal_bias="0.566"  
android:layout_height="428dp"
app:layout_constraintStart_toStartOf="parent"  
 
android:layout_marginTop="20dp"
 
app:layout_constraintEnd_toEndOf="parent"
 
app:layout_constraintHorizontal_bias="0.566"
 
app:layout_constraintStart_toStartOf="parent"
 
app:layout_constraintTop_toBottomOf="@+id/button2" />  
app:layout_constraintTop_toBottomOf="@+id/button2" />  
    
    
第232行: 第306行:
}  
}  
    
    
Activity向Fragment传递数据直接定义函数  
Activity向Fragment传递数据直接定义函数
Fragment向Activity传递数据发送消息  
 
val toMain1 = aHandle!!.obtainMessage()  
Fragment向Activity传递数据发送消息
toMain1.obj = “message or data”  
 
val toMain1 = aHandle!!.obtainMessage()
 
toMain1.obj = “message or data”
 
toMain1.arg1 = 1  
toMain1.arg1 = 1  
    
    
aHandle!!.sendMessage(toMain1)  
aHandle!!.sendMessage(toMain1)  
==实现扫码二维码(kotlin)==  
==实现扫码二维码(kotlin)==  
dependencies增加引用  
dependencies增加引用
 
implementation 'com.hongyelinggu:scancode:1.0.0'  
implementation 'com.hongyelinggu:scancode:1.0.0'  
    
    
申请相机权限  
申请相机权限
<uses-permission android:name="android.permission.CAMERA"/>  
 
val REQUEST_EXTERNAL_STORAGE = 1234  
<uses-permission android:name="android.permission.CAMERA"/>
if (ActivityCompat.checkSelfPermission(this,  
 
"android.permission.CAMERA") != PackageManager.PERMISSION_GRANTED ) {  
val REQUEST_EXTERNAL_STORAGE = 1234
 
if (ActivityCompat.checkSelfPermission(this, "android.permission.CAMERA") != PackageManager.PERMISSION_GRANTED ) {
 
ActivityCompat.requestPermissions(this,  
ActivityCompat.requestPermissions(this,  
arrayOf(Manifest.permission.CAMERA), REQUEST_EXTERNAL_STORAGE)  
arrayOf(Manifest.permission.CAMERA), REQUEST_EXTERNAL_STORAGE)
 
}  
}  
 
else{  
else{  
    
    
第258行: 第342行:
startActivityForResult(Intent(this@MainActivity, CommonScanActivity::class.java), 1)  
startActivityForResult(Intent(this@MainActivity, CommonScanActivity::class.java), 1)  
    
    
返回结果字符串  
返回结果字符串
override fun onActivityResult(requestCode:Int, resultCode:Int, data:Intent?){  
 
super.onActivityResult(requestCode, resultCode, data)  
override fun onActivityResult(requestCode:Int, resultCode:Int, data:Intent?){
val rCode = data!!.extras!!.getString(Constant.REQUEST_SCAN_MODE) //得到新Activity关闭后返回的数据  
 
super.onActivityResult(requestCode, resultCode, data)
 
val rCode = data!!.extras!!.getString(Constant.REQUEST_SCAN_MODE) //得到新Activity关闭后返回的数据
 
Toast.makeText(applicationContext, rCode, Toast.LENGTH_LONG).show()  
Toast.makeText(applicationContext, rCode, Toast.LENGTH_LONG).show()  
}  
}  
第267行: 第355行:
写入文件  
写入文件  
    
    
val fn = filesDir.toString() + "文件名.txt"  
val fn = filesDir.toString() + "文件名.txt"
var fff = "文本内容"  
 
try {  
var fff = "文本内容"
val tfw = FileWriter(fn)  
 
tfw.write(fff)  
try {
 
val tfw = FileWriter(fn)
 
tfw.write(fff)
 
tfw.close()  
tfw.close()  
    
    
Toast.makeText(applicationContext, "保存成功", Toast.LENGTH_LONG).show()  
Toast.makeText(applicationContext, "保存成功", Toast.LENGTH_LONG).show()
} catch (e: Exception) {  
 
Toast.makeText(applicationContext, e.toString(), Toast.LENGTH_LONG).show()  
}
 
catch (e: Exception) {
 
Toast.makeText(applicationContext, e.toString(), Toast.LENGTH_LONG).show()
 
}  
}  
    
    
读取文件  
读取文件
val fn = filesDir.toString() + "文件名.txt"  
 
try {  
val fn = filesDir.toString() + "文件名.txt"
val fb = FileReader(fn)  
 
val tv2:TextView = findViewById(R.id.textView2)  
try {
tv2.setText(fb.readText())    //显示到TextView  
 
fb.close()  
val fb = FileReader(fn)
}  
 
catch(e:Exception){  
val tv2:TextView = findViewById(R.id.textView2)
Toast.makeText(applicationContext, e.toString(), Toast.LENGTH_LONG).show()  
 
tv2.setText(fb.readText())    //显示到TextView
 
fb.close()
 
}
 
catch(e:Exception){
 
Toast.makeText(applicationContext, e.toString(), Toast.LENGTH_LONG).show()
 
}  
}  
    
    
如果路径访问需要权限  
如果路径访问需要权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>  
 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
 
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>  
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>  
    
    
//获取sd卡读写权限  
//获取sd卡读写权限
//val REQUEST_EXTERNAL_STORAGE = 1234  
 
if (ActivityCompat.checkSelfPermission(this,  
//val REQUEST_EXTERNAL_STORAGE = 1234
"android.permission.WRITE_EXTERNAL_STORAGE") != PackageManager.PERMISSION_GRANTED ) {  
 
ActivityCompat.requestPermissions(this,  
if (ActivityCompat.checkSelfPermission(this, "android.permission.WRITE_EXTERNAL_STORAGE") != PackageManager.PERMISSION_GRANTED ) {
arrayOf(WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE), REQUEST_EXTERNAL_STORAGE)  
 
ActivityCompat.requestPermissions(this, arrayOf(WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE), REQUEST_EXTERNAL_STORAGE)
 
}  
}  
 
else{  
else{  
    
    
}  
}  
==多项选择对话框 kotlin==  
==多项选择对话框 kotlin==  
val builder = AlertDialog.Builder(this)  
val builder = AlertDialog.Builder(this)
builder.setTitle("请选择")  
 
builder.setIcon(R.drawable.ic_launcher_foreground)  
builder.setTitle("请选择")
 
builder.setIcon(R.drawable.ic_launcher_foreground)
 
builder.setCancelable(true)  
builder.setCancelable(true)  
    
    
val items = arrayOf("第一项", "第二项", "第三项")  
val items = arrayOf("第一项", "第二项", "第三项")
 
var selected = booleanArrayOf(true, false, true)  
var selected = booleanArrayOf(true, false, true)  
    
    
    
    
builder.setMultiChoiceItems(items, selected) { dialog, which, isChecked -> // dialog.dismiss();  
builder.setMultiChoiceItems(items, selected) { dialog, which, isChecked ->
 
// dialog.dismiss();
 
// Toast.makeText(this@MainActivity, items[which] + isChecked, Toast.LENGTH_SHORT).show()  
// Toast.makeText(this@MainActivity, items[which] + isChecked, Toast.LENGTH_SHORT).show()  
    
    
}  
}  
    
    
//此代码实现输入文本对话框  
//此代码实现输入文本对话框
//val filename :EditText = EditText(this)  
 
//val filename :EditText = EditText(this)
 
//builder.setView(filename)  
//builder.setView(filename)  
    
    
builder.setPositiveButton(" 确定发送 ") { dialogInterface, i ->  
builder.setPositiveButton(" 确定发送 ") { dialogInterface, i ->
 
val tw: TextView = findViewById(R.id.textView1)  
val tw: TextView = findViewById(R.id.textView1)  
var sd = ""  
var sd = ""
for (i in 0 until items.count()) {  
 
if (selected[i])  
for (i in 0 until items.count()) {
sd += items[i]  
 
}  
if (selected[i])
tw.setText(sd)  
 
sd += items[i]
 
}
 
tw.setText(sd)
 
Toast.makeText(this@MainActivity, sd, Toast.LENGTH_SHORT).show()  
Toast.makeText(this@MainActivity, sd, Toast.LENGTH_SHORT).show()  
    
    
//tw.setText(filename.text.toString())  
//tw.setText(filename.text.toString())
}  
 
builder.setNegativeButton("取消发送") { dialogInterface, i ->  
}
 
builder.setNegativeButton("取消发送") { dialogInterface, i ->
 
// finish()  
// finish()  
    
    
    
    
}
builder.show()  
builder.show()  
==OptionsMenu kotlin==  
==OptionsMenu kotlin==  
app 右键 new=》android resouce file  
app 右键 new=》android resouce file resouce type 选择Menu
resouce type 选择Menu  
 
创建菜单项目,编辑ID和title  
创建菜单项目,编辑ID和title
//显示菜单  
 
//显示菜单
 
override fun onCreateOptionsMenu(menu: Menu?): Boolean {  
override fun onCreateOptionsMenu(menu: Menu?): Boolean {  
menuInflater.inflate(R.menu.mainmanu,menu)  
menuInflater.inflate(R.menu.mainmanu,menu)  
return true  
return true  
// return super.onCreateOptionsMenu(menu)  
// return super.onCreateOptionsMenu(menu)  
}  
}  
//处理菜单点击响应  
//处理菜单点击响应  
override fun onOptionsItemSelected(item: MenuItem): Boolean {  
override fun onOptionsItemSelected(item: MenuItem): Boolean {  
    
    
if(item?.itemId == R.id.menu_exit){  
if(item?.itemId == R.id.menu_exit){
finish()  
 
}  
finish()
if(item?.itemId == R.id.menu_upate){  
 
Toast.makeText(this,"system update",Toast.LENGTH_LONG).show()  
}
 
if(item?.itemId == R.id.menu_upate){
 
Toast.makeText(this,"system update",Toast.LENGTH_LONG).show()
 
}  
}  
    
    

2024年3月14日 (四) 13:35的最新版本


项目中引用MPChartLib

1、 将MPChartLib文件夹拷贝到项目根目录

2、在根目录里的settings.gradle里增加include ':app', ':MPChartLib'

3、将文件MPChartLib.aar拷贝到libs文件夹里

4、在build.grade(app)中增加

dependencies { implementation project(':MPChartLib') }

设置app自动启动

增加权限

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

注册消息接收

<receiver android:name=".BootBroadcastReceiver">

<intent-filter>

<action android:name="android.intent.action.BOOT_COMPLETED" />

</intent-filter>

</receiver>

消息接收函数

class BootBroadcastReceiver: BroadcastReceiver() {

override public fun onReceive(context: Context, intent: Intent) {

val mBootIntent = Intent(context, MainActivity::class.java)

mBootIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

context.startActivity(mBootIntent)

}

}

获取位置信息(kotlin)

val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager

val location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)

If (location != null) {

val sb = StringBuffer()

sb.append('实时的位置信息:经度:')

sb.append(location.longitude) sb.append('纬度:')

sb.append(location.latitude) sb.append('高度:')

sb.append(location.altitude) sb.append('速度:')

sb.append(location.speed) sb.append('方向:')

sb.append(location.bearing) sb.append('精度:')

sb.append(location.accuracy)

Toast.makeText(applicationContext, sb.toString(), Toast.LENGTH_LONG).show() }

添加权限

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

发送Notification消息(kotlin)

fun sendNotification(channel_id:String ,channle_name:String,nTitle:String,nContentText:String,id:Int){

var notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

var notification: Notification? = null

//val intent = Intent(Intent.ACTION_VIEW, Uri.parse('http://www.baidu.com/'))

//val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)

//如需链接到网站使用注释代码

val intent = Intent()

intent.setClass(this@MainActivity, MainActivity::class.

val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

val mChannel = NotificationChannel(channel_id, channle_name, NotificationManager.IMPORTANCE_LOW) notificationManager.createNotificationChannel(mChannel)

notification = Notification.Builder(this) .setChannelId(channel_id) .setContentTitle(nTitle) .setContentText(nContentText)

.setContentIntent(pendingIntent) .setSmallIcon(R.drawable.house).build()

}

else {

val notificationBuilder = NotificationCompat.Builder(this)

.setContentTitle(nTitle)

.setContentText(nContentText)

.setSmallIcon(R.drawable.house)

.setOngoing(true)

//.setChannel(id)//无效

notification = notificationBuilder.build() }

notificationManager.notify(id, notification) }

禁止使用http链接解决方法

访问网络时报异常

Cleartext HTTP traffic to not permitted

在<application标签里增加android:usesCleartextTraffic="true"即可

bitmap缩小显示

var matrix = Matrix()

matrix.postScale(0.3f,0.3f)//长和宽放大缩小的比例

val resizeBmp = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true)

textview 连续左移

设置一下参数,自动连续左移动

android:ellipsize="marquee"

android:focusable="auto"

android:focusableInTouchMode="true"

android:marqueeRepeatLimit="marquee_forever"

android:scrollHorizontally="true"

android:singleLine="true"

useAndroidx Error

编译报错

This project uses AndroidX dependencies, but the 'android.useAndroidX' property is not enabled.

在gradle.propeties文件里增加如下语句,允许AnsiroidX

android.useAndroidX=true

post获取数据(kotlin)

Thread(Runnable {

val toMain1 = mAppMesHandler.obtainMessage()

toMain1.arg1 = 1

var conn: HttpURLConnection? = null

var urlString = "http://server/new.php"

try {

conn = URL(urlString).openConnection() as HttpURLConnection

conn.requestMethod = "POST" // 指定POST请求

conn.doOutput = true // 设置请求过程可以传递参数给服务器

// post请求参数

val param = String.format("name=%s&age=%s&action=%s", "fengxueyan", "23", "query") DataOutputStream(conn.outputStream).use { os ->

os.writeBytes(param)

}

conn.connect()

conn.inputStream.use { input ->

val data = input.bufferedReader().readText() toMain1.obj = data.toString()

}

}

catch (e: Exception) {

toMain1.obj = e.toString()

}

finally {

conn?.disconnect()

}

mAppMesHandler.sendMessage(toMain1) }).start()


//访问网络必须使用线程,而且线程不允许更新UI

val mAppMesHandler = object : Handler() {

override fun handleMessage(msg: Message) {

if(msg.arg1 == 1){

var hList0 = msg.obj as String textView.setText(hList0)

// Toast.makeText(applicationContext,hList0,Toast.LENGTH_LONG).show()

}

}

}

时间日期选择

<TimePicker android:id="@+id/ptime"

android:layout_width="310dp"

android:layout_height="347dp"

app:layout_constraintEnd_toEndOf="parent"

app:layout_constraintStart_toStartOf="parent"

app:layout_constraintTop_toBottomOf="@+id/button2" />

textView.setText(ptime.hour.toString()+":"+ptime.minute.toString())

<DatePicker

android:id="@+id/pdate"

android:layout_width="358dp"

android:layout_height="428dp"

android:layout_marginTop="20dp"

app:layout_constraintEnd_toEndOf="parent"

app:layout_constraintHorizontal_bias="0.566"

app:layout_constraintStart_toStartOf="parent"

app:layout_constraintTop_toBottomOf="@+id/button2" />

textView.setText(pdate.year.toString()+"-"+(pdate.month+1).toString()+"-"+pdate.dayOfMonth.toString())

多个Fragment和Activity的简易数据交换方法(kotlin)

动态创建多个Fragment后,和Activity数据交换有很多种方式,消息方式简单快捷,代码量少

在Activity中定义消息处理 val mMainHandler = object : Handler() {

   override fun handleMessage(msg: Message) { 
       if (msg.arg1 == 1) { 
           val sVerRes = msg.obj as String 
           Toast.makeText(applicationContext, sVerRes, Toast.LENGTH_LONG).show() 
       } 
 

}


在Fragment里定义消息handle private var aHandle:Handler? = null


建立初始化函数,将Activity的消息handle传入 fun setHandler(AHandler: Handler?) {

   try {    
       aHandle = AHandler 
   } catch (e: Exception) { 
  throw ClassCastException(context.toString()  
   } 
 

}

Activity向Fragment传递数据直接定义函数

Fragment向Activity传递数据发送消息

val toMain1 = aHandle!!.obtainMessage()

toMain1.obj = “message or data”

toMain1.arg1 = 1

aHandle!!.sendMessage(toMain1)

实现扫码二维码(kotlin)

dependencies增加引用

implementation 'com.hongyelinggu:scancode:1.0.0'

申请相机权限

<uses-permission android:name="android.permission.CAMERA"/>

val REQUEST_EXTERNAL_STORAGE = 1234

if (ActivityCompat.checkSelfPermission(this, "android.permission.CAMERA") != PackageManager.PERMISSION_GRANTED ) {

ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), REQUEST_EXTERNAL_STORAGE)

}

else{

}

执行扫描 startActivityForResult(Intent(this@MainActivity, CommonScanActivity::class.java), 1)

返回结果字符串

override fun onActivityResult(requestCode:Int, resultCode:Int, data:Intent?){

super.onActivityResult(requestCode, resultCode, data)

val rCode = data!!.extras!!.getString(Constant.REQUEST_SCAN_MODE) //得到新Activity关闭后返回的数据

Toast.makeText(applicationContext, rCode, Toast.LENGTH_LONG).show() }

读取写入文本文件(kotlin)

写入文件

val fn = filesDir.toString() + "文件名.txt"

var fff = "文本内容"

try {

val tfw = FileWriter(fn)

tfw.write(fff)

tfw.close()

Toast.makeText(applicationContext, "保存成功", Toast.LENGTH_LONG).show()

}

catch (e: Exception) {

Toast.makeText(applicationContext, e.toString(), Toast.LENGTH_LONG).show()

}

读取文件

val fn = filesDir.toString() + "文件名.txt"

try {

val fb = FileReader(fn)

val tv2:TextView = findViewById(R.id.textView2)

tv2.setText(fb.readText()) //显示到TextView

fb.close()

}

catch(e:Exception){

Toast.makeText(applicationContext, e.toString(), Toast.LENGTH_LONG).show()

}

如果路径访问需要权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>

//获取sd卡读写权限

//val REQUEST_EXTERNAL_STORAGE = 1234

if (ActivityCompat.checkSelfPermission(this, "android.permission.WRITE_EXTERNAL_STORAGE") != PackageManager.PERMISSION_GRANTED ) {

ActivityCompat.requestPermissions(this, arrayOf(WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE), REQUEST_EXTERNAL_STORAGE)

}

else{

}

多项选择对话框 kotlin

val builder = AlertDialog.Builder(this)

builder.setTitle("请选择")

builder.setIcon(R.drawable.ic_launcher_foreground)

builder.setCancelable(true)

val items = arrayOf("第一项", "第二项", "第三项")

var selected = booleanArrayOf(true, false, true)


builder.setMultiChoiceItems(items, selected) { dialog, which, isChecked ->

// dialog.dismiss();

// Toast.makeText(this@MainActivity, items[which] + isChecked, Toast.LENGTH_SHORT).show()

}

//此代码实现输入文本对话框

//val filename :EditText = EditText(this)

//builder.setView(filename)

builder.setPositiveButton(" 确定发送 ") { dialogInterface, i ->

val tw: TextView = findViewById(R.id.textView1) var sd = ""

for (i in 0 until items.count()) {

if (selected[i])

sd += items[i]

}

tw.setText(sd)

Toast.makeText(this@MainActivity, sd, Toast.LENGTH_SHORT).show()

//tw.setText(filename.text.toString())

}

builder.setNegativeButton("取消发送") { dialogInterface, i ->

// finish()

}

builder.show()

OptionsMenu kotlin

app 右键 new=》android resouce file resouce type 选择Menu

创建菜单项目,编辑ID和title

//显示菜单

override fun onCreateOptionsMenu(menu: Menu?): Boolean {

menuInflater.inflate(R.menu.mainmanu,menu)

return true

// return super.onCreateOptionsMenu(menu)

}

//处理菜单点击响应

override fun onOptionsItemSelected(item: MenuItem): Boolean {

if(item?.itemId == R.id.menu_exit){

finish()

}

if(item?.itemId == R.id.menu_upate){

Toast.makeText(this,"system update",Toast.LENGTH_LONG).show()

}

return super.onOptionsItemSelected(item)

}

ContextMenu kotlin

app 右键 new=》android resouce file resouce type 选择Menu 创建菜单项目,编辑ID和title

override fun onCreateContextMenu(menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo?) { 
super.onCreateContextMenu(menu, v, menuInfo) 
menuInflater.inflate(R.menu.menupop,menu) 
menu!!.setHeaderTitle("请选择")  
} 

重载函数

override fun onContextItemSelected(item: MenuItem): Boolean { 
   if(item.itemId == R.id.media_route_menu_item1){ 
   Toast.makeText(this,"11111111",Toast.LENGTH_LONG).show() 
 } 
 return super.onContextItemSelected(item) 
} 
 

onCreate

val bt_menu: Button = findViewById(R.id.button_menu) 
registerForContextMenu(bt_menu) 
bt_menu.setOnClickListener { 
openContextMenu(it) 
}

如果在list view item弹出菜单,直接

val tv_houseList = findViewById(R.id.listview_house_list) as ListView
registerForContextMenu(tv_houseList) 

这样长按item自动会弹出菜单

androidstudio使用WebView显示网页(kotlin)

val wset = wview1.settings
  wset.javaScriptEnabled = true
     wview1.setWebViewClient(object : WebViewClient() {
           override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
               view.loadUrl(url)
               return true
           }
       })
wview1.loadUrl(“http://www.baidu.com”)

在AndroidManifest.xml增加

android:usesCleartextTraffic="true"

需要添加网络权限

如果需要支持网页弹出alert:

wview1.setWebChromeClient (object : WebChromeClient() 
   override fun onJsAlert(view: WebView,url: String,message: String,result: JsResult):Boolean{
         return super.onJsAlert(view, url, message, result)
    }
 })

androidstudio使用viewPager显示多张图片并关联tabLayout(kotlin)

val mImgId = intArrayOf(R.drawable.h1, R.drawable.h2, R.drawable.h3)

    val mList = ArrayList()
   var tabName : Array = Array(3,{""})
      tabName[0] = "TAB1"
      tabName[1] = "TAB2"
      tabName[2] = "TAB3"
       vpage.setAdapter(object : PagerAdapter() {
          override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
            container.removeView(mList.get(position))
          }
          override fun instantiateItem(container: ViewGroup, position: Int): Any {
             val imageView = ImageView(this@MainActivity)
            imageView.setImageResource(mImgId[position])
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP)
            container.addView(imageView)
             mList.add(imageView)
             return imageView
          }
          override fun getCount(): Int {
             return mImgId.size
          }
          override fun isViewFromObject(view: View, `object`: Any): Boolean {
             return view === `object`
          }
          override fun getPageTitle(position:Int):CharSequence{
              return tabName[position]
          }
      })
      tabcus.setupWithViewPager(vpage)

使用ViewPager2和TabLayout实现多frgment切换

private fun initTab(){
       val viewpage = findViewById(R.id.viewpage2) as ViewPager2
       viewpage.adapter = object : FragmentStateAdapter(this){
           override fun getItemCount(): Int {
               return  3
           }
           override fun createFragment(position: Int): Fragment {
               return when(position){
                   0 -> myFragment()
                   1 -> hlistFragment()
                   else -> hlistFragment()
               }
           }
       }
       val tabmain = findViewById(R.id.tabLayout) as TabLayout
       TabLayoutMediator(
           tabmain,
           viewpage,
           object : TabLayoutMediator.TabConfigurationStrategy{
               override fun onConfigureTab(tab: TabLayout.Tab, position: Int) {
                   when(position){
                       0 -> tab.text = "资源汇总"
                       1 -> tab.text = "我的房源"
                       else -> tab.text = "房源资源库"
                   }
               }
           }).attach()

xml文件

<com.google.android.material.tabs.TabLayout
<androidx.viewpager2.widget.ViewPager2

建立Fragement list 用于访问每个动态创建的Fragment

var list_frm:ArrayList<Fragment> = ArrayList()
            override fun createFragment(position: Int): Fragment {
                when(position){
                   0 -> {
                       val fg =  myFragment()
                       list_frm.add(fg )
                       return fg
                   }
                   1 -> {
                       val fg =  hlistFragment()
                       list_frm.add(fg)
                       return fg
                   }
                   else -> {
                       val fg =  hlistFragment()
                       list_frm.add(fg)
                       return fg
                   }
               }
           }

使用BaseAdapter为listview装入数据

 class myAdapter (context: Activity,listValue:String): BaseAdapter(){
     private var ct:Activity
     private var lv:String
     init {
         ct = context
         lv = listValue
     }
     override fun getCount():Int{
         val hma_list = lv.split("^")
         return hma_list.count()
     }
     override fun getItem(position: Int):String{
         val hma_list = lv.split("^")
         return hma_list[position].toString()
     }
     override fun getItemId(position: Int):Long{
         return position.toLong()
     }
     override fun getView(position: Int, view: View?, parent: ViewGroup): View {
         val rowView = ct.layoutInflater.inflate(R.layout.layout_house_info_item, null, true)
         val hm_name = rowView.findViewById(R.id.tv_item_name) as TextView
         val hm_price = rowView.findViewById(R.id.tv_item_price) as TextView
         val hm_size = rowView.findViewById(R.id.tv_item_size) as TextView
         val hm_room = rowView.findViewById(R.id.tv_item_room) as TextView
         val hm_time = rowView.findViewById(R.id.tv_item_time) as TextView
         val hm_status = rowView.findViewById(R.id.tv_item_status) as TextView
         val hma_list = lv.split("^")
         var hma_value = hma_list[position].split("~")
         hm_name.text = hma_value[0]
         if(hma_value[12] == "2" )
             hm_price.text = hma_value[4]+"/月"
         else
             hm_price.text = hma_value[2]+"万"
         hm_size.text = hma_value[9] +"  "+ hma_value[1]+"平米"
         hm_room.text = hma_value[6]+"室"+hma_value[7]+"厅"+hma_value[8]+"卫    "+hma_value[5]+"层"
         hm_time.text = "最后跟进"+hma_value[11]
         return rowView
     }
 }

listview 操作

  val adapter = myAdapter(this,listStr)
  tv_houseList.setAdapter(adapter)

让EditText不能编辑,只读

 et_tel.keyListener = null

让WebView支持手机定位

静态申请权限

   <uses-permission android:name="android.permission.INTERNET"/>
   <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
   <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
   <uses-permission android:name="android.permission.ACCESS_GPS" />
   <uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
   <uses-permission android:name="android.permission.ACCESS_LOCATION" />

动态申请权限

   if (ActivityCompat.checkSelfPermission(this,
           "android.permission.WRITE_EXTERNAL_STORAGE") != PackageManager.PERMISSION_GRANTED ) {
           ActivityCompat.requestPermissions(this,
               arrayOf(ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION), 1234)
       }

设置WebView参数

       val wview1 = findViewById(R.id.vview1) as WebView
       val wset = wview1.settings
       wset.javaScriptEnabled = true
       wset.setGeolocationEnabled(true)  //允许定位
       wview1.setWebViewClient(object : WebViewClient() {
           override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
               view.loadUrl(url)
               return true
           }
       })
       wview1.setWebChromeClient (object : WebChromeClient() {
           override fun onJsAlert(view: WebView, url: String, message: String, result: JsResult):Boolean{
               return super.onJsAlert(view, url, message, result)
           }
           override fun onGeolocationPermissionsShowPrompt(
               origin: String?,
               callback: GeolocationPermissions.Callback?
           ) {
               val remember = true
               val builder: AlertDialog.Builder = AlertDialog.Builder(this@MainActivity)
               builder.setTitle("位置信息")
               builder.setMessage(origin + "允许获取您的地理位置信息吗?").setCancelable(true)
                           .setPositiveButton("允许",
                               DialogInterface.OnClickListener { dialog, id ->
                                   callback?.invoke(
                                       origin,
                                       true,
                                       remember
                                   )
                               })
                           .setNegativeButton("不允许",
                               DialogInterface.OnClickListener { dialog, id ->
                                   callback?.invoke(
                                       origin,
                                       false,
                                       remember
                                   )
                               })
                       val alert: AlertDialog = builder.create()
                       alert.show()
               }
           })