init
@@ -0,0 +1,24 @@
|
||||
package com.yutou.doormanager
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.yutou.doormanager", appContext.packageName)
|
||||
}
|
||||
}
|
||||
103
app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.yutou.doormanager">
|
||||
|
||||
<uses-feature android:name="android.hardware.camera.any" />
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_SMS" />
|
||||
<uses-permission android:name="android.permission.SEND_SMS" />
|
||||
<uses-permission android:name="android.permission.WRITE_SMS" />
|
||||
<uses-permission android:name="android.permission.READ_SMS" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="28" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Design.NoActionBar"
|
||||
android:usesCleartextTraffic="true">
|
||||
<meta-data
|
||||
android:name="com.google.android.actions"
|
||||
android:resource="@xml/provider_paths" />
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:screenOrientation="fullSensor">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
|
||||
<activity android:name=".SMSActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND"/>
|
||||
<action android:name="android.intent.action.SENDTO"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
<data android:scheme="sms"/>
|
||||
<data android:scheme="smsto"/>
|
||||
<data android:scheme="mms"/>
|
||||
<data android:scheme="mmsto"/>
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/provider_paths" />
|
||||
</provider>
|
||||
|
||||
<!-- BroadcastReceiver that listens for incoming SMS messages -->
|
||||
<receiver
|
||||
android:name=".SmsReceiver"
|
||||
android:permission="android.permission.BROADCAST_SMS">
|
||||
<intent-filter android:priority="2147483647">
|
||||
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
||||
<action android:name="android.provider.Telephony.SMS_DELIVER" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- BroadcastReceiver that listens for incoming MMS messages -->
|
||||
<receiver
|
||||
android:name=".MmsReceiver"
|
||||
android:permission="android.permission.BROADCAST_WAP_PUSH">
|
||||
<intent-filter>
|
||||
<action android:name="android.provider.Telephony.WAP_PUSH_DELIVER"/>
|
||||
<data android:mimeType="application/vnd.wap.mms-message"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<!-- Service that delivers messages from the phone "quick response" -->
|
||||
<service
|
||||
android:name=".SmsSendService"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:scheme="sms" />
|
||||
<data android:scheme="smsto" />
|
||||
<data android:scheme="mms" />
|
||||
<data android:scheme="mmsto" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.yutou.doormanager;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class HeadlessSmsSendService extends Service {
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
263
app/src/main/java/com/yutou/doormanager/MainActivity.kt
Normal file
@@ -0,0 +1,263 @@
|
||||
package com.yutou.doormanager
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.graphics.Rect
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.provider.Telephony
|
||||
import android.widget.Button
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.FileProvider
|
||||
import com.yutou.doormanager.utils.*
|
||||
import jp.co.cyberagent.android.gpuimage.GPUImageAddBlendFilter
|
||||
import me.lake.librestreaming.core.listener.RESConnectionListener
|
||||
import me.lake.librestreaming.filter.hardvideofilter.BaseHardVideoFilter
|
||||
import me.lake.librestreaming.filter.hardvideofilter.HardVideoGroupFilter
|
||||
import me.lake.librestreaming.ws.StreamAVOption
|
||||
import me.lake.librestreaming.ws.StreamLiveCameraView
|
||||
import me.lake.librestreaming.ws.filter.hardfilter.WatermarkFilter
|
||||
import me.lake.librestreaming.ws.filter.hardfilter.extra.GPUImageCompatibleFilter
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
private lateinit var button_up: Button
|
||||
private lateinit var button_down: Button
|
||||
private lateinit var button_screen: Button
|
||||
private lateinit var button_open: Button
|
||||
private lateinit var button_af: Button
|
||||
private lateinit var mLiveCameraView: StreamLiveCameraView
|
||||
private var zoom = 0.0f
|
||||
private var isUpdate = true
|
||||
public lateinit var myDataListener: MyDataListener
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
ActivityCompat.requestPermissions(
|
||||
this, arrayOf(
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
Manifest.permission.CAMERA,
|
||||
Manifest.permission.RECORD_AUDIO,
|
||||
Manifest.permission.SEND_SMS
|
||||
), 0
|
||||
)
|
||||
initView()
|
||||
startRTMP()
|
||||
myDataListener = MyDataListener()
|
||||
DataUtils.addListener(myDataListener)
|
||||
val intent = Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT)
|
||||
intent.putExtra(
|
||||
Telephony.Sms.Intents.EXTRA_PACKAGE_NAME,
|
||||
packageName
|
||||
)
|
||||
startActivity(intent)
|
||||
val batteryLevelRcvr=SmsReceiver()
|
||||
val batteryLevelFilter= IntentFilter(Intent.ACTION_BATTERY_CHANGED)
|
||||
registerReceiver(batteryLevelRcvr, batteryLevelFilter)
|
||||
Toast.makeText(this,"version = ${ packageManager.getPackageInfo(packageName, 0).versionName}",Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
button_up = findViewById(R.id.up)
|
||||
button_down = findViewById(R.id.down)
|
||||
button_screen = findViewById(R.id.screen)
|
||||
button_open = findViewById(R.id.openPC)
|
||||
button_af = findViewById(R.id.af)
|
||||
button_up.setOnClickListener {
|
||||
zoom += 0.1f
|
||||
if (zoom > 1.0f) {
|
||||
zoom = 1.0f
|
||||
}
|
||||
mLiveCameraView.setZoomByPercent(zoom)
|
||||
uploadZoom(zoom)
|
||||
}
|
||||
button_down.setOnClickListener {
|
||||
zoom -= 0.1f
|
||||
if (zoom < 0f) {
|
||||
zoom = 0.0f
|
||||
}
|
||||
mLiveCameraView.setZoomByPercent(zoom)
|
||||
uploadZoom(zoom)
|
||||
}
|
||||
button_screen.setOnClickListener {
|
||||
mLiveCameraView.takeScreenShot {
|
||||
Utils.upload(it, this)
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
Toast.makeText(this@MainActivity, "已拍照", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
button_open.setOnClickListener {
|
||||
val json = JSONObject()
|
||||
json.put("type", "nas")
|
||||
HttpUtils.post(
|
||||
"http://192.168.31.88:8000/tools/openpc.do",
|
||||
json,
|
||||
null,
|
||||
object : HttpListener {
|
||||
override fun data(code: Int, data: String) {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
Toast.makeText(this@MainActivity, "开机成功:${data}", Toast.LENGTH_LONG)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
button_af.setOnClickListener {
|
||||
mLiveCameraView.setCreamAr()
|
||||
}
|
||||
}
|
||||
|
||||
private fun uploadZoom(zoom: Float) {
|
||||
val json = JSONObject()
|
||||
json.put("zoom", zoom)
|
||||
HttpUtils.post("http://192.168.31.88:8000/door/zoom.do", json, null, object : HttpListener {
|
||||
override fun data(code: Int, data: String) {
|
||||
if (data == "1") {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
Toast.makeText(this@MainActivity, "设置成功:${zoom}", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
lateinit var watermark: WatermarkFilter
|
||||
private fun startRTMP() {
|
||||
mLiveCameraView = findViewById(R.id.stream_previewView)
|
||||
mLiveCameraView.setActivity(this)
|
||||
val option = StreamAVOption().apply {
|
||||
streamUrl = "rtmp://192.168.31.88/live"
|
||||
}
|
||||
mLiveCameraView.let {
|
||||
it.init(this, option)
|
||||
it.addStreamStateListener(object : RESConnectionListener {
|
||||
override fun onOpenConnectionResult(result: Int) {
|
||||
mLiveCameraView.setCreamAr()
|
||||
}
|
||||
|
||||
override fun onWriteError(errno: Int) {
|
||||
}
|
||||
|
||||
override fun onCloseConnectionResult(result: Int) {
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
val files: LinkedList<BaseHardVideoFilter> = LinkedList()
|
||||
watermark =
|
||||
WatermarkFilter(
|
||||
WatermarkFilter.fromText(32f, Utils.getTime()),
|
||||
Rect(50, 50, 800, 150)
|
||||
)
|
||||
// it.setMirror(true, true, true)
|
||||
files.add(GPUImageCompatibleFilter(GPUImageAddBlendFilter()))
|
||||
files.add(watermark)
|
||||
it.setHardVideoFilter(HardVideoGroupFilter(files))
|
||||
it.startStreaming(option.streamUrl)
|
||||
Timer().schedule(object : TimerTask() {
|
||||
override fun run() {
|
||||
watermark.updateText(32f, Utils.getTime()+" 推流:${mLiveCameraView.avSpeed}")
|
||||
if (!mLiveCameraView.isStreaming||mLiveCameraView.avSpeed==0) {
|
||||
mLiveCameraView.stopStreaming()
|
||||
mLiveCameraView.startStreaming("rtmp://192.168.31.88/live")
|
||||
}
|
||||
}
|
||||
}, 0, 1000)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mLiveCameraView.destroy()
|
||||
DataUtils.removeListener(myDataListener)
|
||||
}
|
||||
|
||||
inner class MyDataListener : DataListener {
|
||||
override fun out(json: JSONObject) {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
zoom = json.getDouble("zoom").toFloat()
|
||||
mLiveCameraView.setZoomByPercent(zoom)
|
||||
if (json.getString("restart").equals("1")) {
|
||||
val intent = packageManager.getLaunchIntentForPackage(packageName);
|
||||
intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
startActivity(intent)
|
||||
android.os.Process.killProcess(android.os.Process.myPid());
|
||||
}
|
||||
|
||||
if (!json.getString("audio").equals("null"))
|
||||
AudioUtils().play(json.getString("audio"))
|
||||
|
||||
if (!json.isNull("update")) {
|
||||
val versionName = packageManager.getPackageInfo(packageName, 0).versionName
|
||||
if (json.getJSONObject("update").getString("versionName") != versionName) {
|
||||
val url = json.getJSONObject("update").getString("url")
|
||||
if (isUpdate) {
|
||||
isUpdate = false
|
||||
update(url, json.getJSONObject("update").getString("versionName"))
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!json.isNull("af")){
|
||||
mLiveCameraView.setCreamAr()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun update(url: String, version: String) {
|
||||
val dialog = AlertDialog.Builder(this).apply {
|
||||
val appVersionName = packageManager.getPackageInfo(packageName, 0).versionName
|
||||
setTitle("检测到版本更新")
|
||||
setMessage("当前版本号:${appVersionName}\n更新版本号:${version}\n是否更新?")
|
||||
setPositiveButton("更新") { _, _ ->
|
||||
HttpUtils.download(
|
||||
url,
|
||||
filesDir.absolutePath + File.separator + "download.apk",
|
||||
object : HttpListener {
|
||||
override fun data(code: Int, data: String) {
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
var apkUri = Uri.fromFile(File(data))
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
apkUri = FileProvider.getUriForFile(
|
||||
this@MainActivity, "$packageName.fileprovider",
|
||||
File(data)
|
||||
)
|
||||
}
|
||||
intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
|
||||
startActivity(intent)
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
setNegativeButton(
|
||||
"取消"
|
||||
) { p0, _ -> p0?.cancel() }
|
||||
}
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
}
|
||||
12
app/src/main/java/com/yutou/doormanager/MmsReceiver.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package com.yutou.doormanager;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
public class MmsReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
}
|
||||
}
|
||||
46
app/src/main/java/com/yutou/doormanager/MyApplication.kt
Normal file
@@ -0,0 +1,46 @@
|
||||
package com.yutou.doormanager
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.os.Bundle
|
||||
import com.yutou.doormanager.utils.DataUtils
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
class MyApplication: Application() {
|
||||
companion object{
|
||||
lateinit var activitys:WeakReference<Activity>
|
||||
}
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
|
||||
override fun onActivityCreated(p0: Activity, p1: Bundle?) {
|
||||
activitys=WeakReference(p0)
|
||||
}
|
||||
|
||||
override fun onActivityStarted(p0: Activity) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onActivityResumed(p0: Activity) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onActivityPaused(p0: Activity) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onActivityStopped(p0: Activity) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onActivitySaveInstanceState(p0: Activity, p1: Bundle) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onActivityDestroyed(p0: Activity) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
12
app/src/main/java/com/yutou/doormanager/MyViewModel.kt
Normal file
@@ -0,0 +1,12 @@
|
||||
package com.yutou.doormanager
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class MyViewModel:ViewModel() {
|
||||
var index:Int = 0
|
||||
val data:String by lazy {
|
||||
"data = "+index
|
||||
}
|
||||
}
|
||||
14
app/src/main/java/com/yutou/doormanager/SMSActivity.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package com.yutou.doormanager;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.telephony.SmsManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class SMSActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
||||
44
app/src/main/java/com/yutou/doormanager/SmsReceiver.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package com.yutou.doormanager;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.BatteryManager;
|
||||
|
||||
import com.yutou.doormanager.utils.SmsUtils;
|
||||
|
||||
public class SmsReceiver extends BroadcastReceiver {
|
||||
private static boolean isLowPower = true;
|
||||
private static boolean isPower = true;
|
||||
public static int powerData=0;
|
||||
private static int power=100;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
int status = intent.getIntExtra("status", -1);
|
||||
int rawlevel = intent.getIntExtra("level", -1);
|
||||
int scale = intent.getIntExtra("scale", -1);
|
||||
int level = -1;
|
||||
if(rawlevel >= 0 && scale > 0){
|
||||
level = (rawlevel*100)/scale;
|
||||
}
|
||||
powerData=status;
|
||||
if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) {
|
||||
isPower = true;
|
||||
if (isLowPower) {
|
||||
SmsUtils.Companion.sendSms("监控电源已断开", context);
|
||||
isLowPower = false;
|
||||
}
|
||||
if(level!=power&&level%10==0){
|
||||
SmsUtils.Companion.sendSms("监控剩余电量:"+level,context);
|
||||
power=level;
|
||||
}
|
||||
} else {
|
||||
isLowPower = true;
|
||||
if (isPower) {
|
||||
SmsUtils.Companion.sendSms("监控电源已连接", context);
|
||||
isPower = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
app/src/main/java/com/yutou/doormanager/SmsSendService.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package com.yutou.doormanager;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class SmsSendService extends Service {
|
||||
class MyBinder extends Binder {
|
||||
public SmsSendService getService(){
|
||||
return SmsSendService.this;
|
||||
}
|
||||
}
|
||||
private MyBinder binder=new MyBinder();
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return binder;
|
||||
}
|
||||
}
|
||||
8
app/src/main/java/com/yutou/doormanager/TestData.kt
Normal file
@@ -0,0 +1,8 @@
|
||||
package com.yutou.doormanager
|
||||
|
||||
class TestData {
|
||||
val str by lazy {
|
||||
println("Init lazy")
|
||||
"Hello World"
|
||||
}
|
||||
}
|
||||
21
app/src/main/java/com/yutou/doormanager/utils/AudioUtils.kt
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.yutou.doormanager.utils
|
||||
|
||||
import android.media.MediaPlayer
|
||||
|
||||
class AudioUtils() {
|
||||
fun play(url: String) {
|
||||
println("url = ${url}")
|
||||
val player = MediaPlayer()
|
||||
player.isLooping = false
|
||||
player.setOnCompletionListener {
|
||||
println(" --> play over")
|
||||
it.release()
|
||||
}
|
||||
//setAudioStreamType(AudioManager.STREAM_MUSIC)
|
||||
player.setDataSource(url)
|
||||
|
||||
|
||||
player.prepare() // might take long! (for buffering, etc)
|
||||
player.start()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.yutou.doormanager.utils
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
interface DataListener {
|
||||
fun out(json:JSONObject)
|
||||
}
|
||||
50
app/src/main/java/com/yutou/doormanager/utils/DataUtils.kt
Normal file
@@ -0,0 +1,50 @@
|
||||
package com.yutou.doormanager.utils
|
||||
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class DataUtils {
|
||||
|
||||
var listener= ArrayList<DataListener>()
|
||||
|
||||
companion object{
|
||||
private var instance:DataUtils?=null
|
||||
get() {
|
||||
if(field==null){
|
||||
field= DataUtils()
|
||||
}
|
||||
return field
|
||||
}
|
||||
@Synchronized
|
||||
fun get():DataUtils{
|
||||
return instance!!
|
||||
}
|
||||
fun addListener(_listener: DataListener){
|
||||
instance!!.listener.add(_listener)
|
||||
}
|
||||
fun removeListener(_listener: DataListener){
|
||||
instance!!.listener.remove(_listener)
|
||||
}
|
||||
}
|
||||
init {
|
||||
run()
|
||||
}
|
||||
private fun run(){
|
||||
Timer().schedule(object : TimerTask() {
|
||||
override fun run() {
|
||||
val json=JSONObject()
|
||||
json.put("def","")
|
||||
HttpUtils.post("http://192.168.31.88:8000/door/data.do",json,null,object :HttpListener{
|
||||
override fun data(code: Int, data: String) {
|
||||
if(code==200){
|
||||
listener.forEach { it.out(JSONObject(data)) }
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
},0,1000)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.yutou.doormanager.utils
|
||||
|
||||
interface HttpListener{
|
||||
fun data(code:Int,data:String)
|
||||
}
|
||||
88
app/src/main/java/com/yutou/doormanager/utils/HttpUtils.kt
Normal file
@@ -0,0 +1,88 @@
|
||||
package com.yutou.doormanager.utils
|
||||
|
||||
import okhttp3.*
|
||||
import okhttp3.RequestBody.Companion.asRequestBody
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
|
||||
class HttpUtils {
|
||||
companion object {
|
||||
fun uploadImage(body: JSONObject) {
|
||||
post(
|
||||
"http://192.168.31.88:802/qq/file.do",
|
||||
body,
|
||||
File(body.getString("filePath")),
|
||||
object : HttpListener {
|
||||
override fun data(code: Int, data: String) {
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun post(url: String, json: JSONObject, file: File?, listener: HttpListener) {
|
||||
val client = OkHttpClient()
|
||||
val builder = Request.Builder()
|
||||
builder.url(url)
|
||||
.post(
|
||||
MultipartBody.Builder().run {
|
||||
if (file != null) {
|
||||
addFormDataPart(
|
||||
"image",
|
||||
json.getString("fileName"),
|
||||
file.asRequestBody()
|
||||
)
|
||||
}
|
||||
json.keys().forEach {
|
||||
addFormDataPart(it, json.getString(it))
|
||||
}
|
||||
build()
|
||||
}
|
||||
)
|
||||
|
||||
client.newCall(builder.build()).enqueue(object : Callback {
|
||||
override fun onFailure(call: Call, e: IOException) {
|
||||
print("failure = ")
|
||||
println(e)
|
||||
}
|
||||
|
||||
override fun onResponse(call: Call, response: Response) {
|
||||
listener.data(response.code, response.body!!.string())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun download(url: String, filePath: String, listener: HttpListener) {
|
||||
val client = OkHttpClient()
|
||||
val builder = Request.Builder().url(url).build()
|
||||
client.newCall(builder).enqueue(object :Callback{
|
||||
override fun onFailure(call: Call, e: IOException) {
|
||||
println(e)
|
||||
}
|
||||
|
||||
override fun onResponse(call: Call, response: Response) {
|
||||
if(response.isSuccessful){
|
||||
if(File(filePath).exists()){
|
||||
File(filePath).delete()
|
||||
}
|
||||
println("文件大小:"+response.body?.contentLength())
|
||||
val inputStream=response.body?.byteStream()
|
||||
val outputStream=FileOutputStream(filePath)
|
||||
val bytes= ByteArray(1024)
|
||||
var len=0
|
||||
while ((inputStream?.read(bytes)).also { len=it!! }!=-1){
|
||||
outputStream.write(bytes,0,len)
|
||||
outputStream.flush()
|
||||
}
|
||||
outputStream.close()
|
||||
inputStream?.close()
|
||||
println("实际文件大小:"+File(filePath).length())
|
||||
listener.data(0,filePath)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
29
app/src/main/java/com/yutou/doormanager/utils/SmsUtils.kt
Normal file
@@ -0,0 +1,29 @@
|
||||
package com.yutou.doormanager.utils
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.telephony.SmsManager
|
||||
|
||||
|
||||
class SmsUtils {
|
||||
companion object{
|
||||
fun sendSms(message:String, context:Context){
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
|
||||
var smsManager= context.getSystemService(SmsManager::class.java)
|
||||
val sentIntent = Intent("SENT_SMS_ACTION")
|
||||
val sentPI = PendingIntent.getBroadcast(context, 0, sentIntent, 0)
|
||||
val deliverIntent = Intent("DELIVERED_SMS_ACTION")
|
||||
val deliverPI = PendingIntent.getBroadcast(context, 0, deliverIntent, 0)
|
||||
if(smsManager==null)
|
||||
smsManager=SmsManager.getDefault()
|
||||
println("smsManager = ${smsManager}")
|
||||
smsManager.sendTextMessage("+8613687358829", null, message, sentPI, deliverPI)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
app/src/main/java/com/yutou/doormanager/utils/Utils.kt
Normal file
@@ -0,0 +1,32 @@
|
||||
package com.yutou.doormanager.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class Utils {
|
||||
companion object {
|
||||
fun upload(bitmap: Bitmap, context: Context) {
|
||||
val file = File(context.cacheDir.absolutePath + File.separator + "tmp.png")
|
||||
val out = FileOutputStream(file)
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)
|
||||
out.apply {
|
||||
flush()
|
||||
close()
|
||||
}
|
||||
val json=JSONObject()
|
||||
json.put("fileName",file.name)
|
||||
json.put("filePath",file.absolutePath)
|
||||
HttpUtils.uploadImage(json)
|
||||
// file.deleteOnExit()
|
||||
}
|
||||
fun getTime():String{
|
||||
return SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss", Locale.CHINA).format(Date())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
30
app/src/main/res/drawable-v24/ic_launcher_foreground.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
170
app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
||||
BIN
app/src/main/res/drawable/tmp.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
60
app/src/main/res/layout-land/activity_main.xml
Normal file
@@ -0,0 +1,60 @@
|
||||
<?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=".MainActivity">
|
||||
|
||||
<!-- <androidx.camera.view.PreviewView
|
||||
android:id="@+id/viewFinder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />-->
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/stream_previewView"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<Button
|
||||
android:id="@+id/up"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="@string/button_up" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/down"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/button_down" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/screen"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/button_screen" />
|
||||
<Button
|
||||
android:id="@+id/af"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/button_af" />
|
||||
</LinearLayout>
|
||||
|
||||
<me.lake.librestreaming.ws.StreamLiveCameraView
|
||||
android:id="@+id/stream_previewView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/linearLayout"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
64
app/src/main/res/layout/activity_main.xml
Normal file
@@ -0,0 +1,64 @@
|
||||
<?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=".MainActivity">
|
||||
|
||||
<!-- <androidx.camera.view.PreviewView
|
||||
android:id="@+id/viewFinder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />-->
|
||||
|
||||
<me.lake.librestreaming.ws.StreamLiveCameraView
|
||||
android:id="@+id/stream_previewView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginBottom="64dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<Button
|
||||
android:id="@+id/up"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/button_up"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/down"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/button_down" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/screen"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/button_screen" />
|
||||
<Button
|
||||
android:id="@+id/openPC"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/button_open" />
|
||||
<Button
|
||||
android:id="@+id/af"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/button_af" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 982 B |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
16
app/src/main/res/values-night/themes.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.DoorManager" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_200</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/black</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_200</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
||||
10
app/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="purple_200">#FFBB86FC</color>
|
||||
<color name="purple_500">#FF6200EE</color>
|
||||
<color name="purple_700">#FF3700B3</color>
|
||||
<color name="teal_200">#FF03DAC5</color>
|
||||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
</resources>
|
||||
8
app/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<resources>
|
||||
<string name="app_name">DoorManager</string>
|
||||
<string name="button_up">+</string>
|
||||
<string name="button_down">-</string>
|
||||
<string name="button_screen">拍照</string>
|
||||
<string name="button_open">开机</string>
|
||||
<string name="button_af">对焦</string>
|
||||
</resources>
|
||||
16
app/src/main/res/values/themes.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.DoorManager" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_500</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/white</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_700</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
||||
7
app/src/main/res/xml/provider_paths.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version ="1.0" encoding ="utf-8"?><!-- Learn More about how to use App Actions: https://developer.android.com/guide/actions/index.html -->
|
||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<root-path name="root" path=""/>
|
||||
<files-path
|
||||
name="files"
|
||||
path="." />
|
||||
</paths>
|
||||
17
app/src/test/java/com/yutou/doormanager/ExampleUnitTest.kt
Normal file
@@ -0,0 +1,17 @@
|
||||
package com.yutou.doormanager
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
||||