commit 8f9ae202db5ca87c292ea3b282193e22178e2447 Author: Yutousama <583819556@qq.com> Date: Fri Mar 11 08:43:32 2022 +0800 init diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..76832e2 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,106 @@ +import java.text.SimpleDateFormat + +plugins { + id 'com.android.application' + id 'kotlin-android' +} + +android { + signingConfigs { + release { + storeFile file('D:\\AndroidKeys\\yutou.jks') + storePassword '34864394' + keyPassword '34864394' + keyAlias 'yutou' + } + } + compileSdk 31 + + defaultConfig { + + applicationId "com.yutou.doormanager" + minSdk 21 + targetSdk 30 + versionCode 1 + versionName "1.3.1-" + new SimpleDateFormat("MMddhhmmss").format(new Date()) + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + ndk { + abiFilters "armeabi-v7a" + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } + buildFeatures { + viewBinding true + } +} + +dependencies { + + implementation 'androidx.core:core-ktx:1.3.2' + implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'com.google.android.material:material:1.4.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.1' + + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' + implementation project(path: ':libWSLive') + + testImplementation 'junit:junit:4.+' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + + def camerax_version = "1.1.0-beta01" + implementation "androidx.camera:camera-core:${camerax_version}" + implementation "androidx.camera:camera-camera2:${camerax_version}" + implementation "androidx.camera:camera-lifecycle:${camerax_version}" + implementation "androidx.camera:camera-video:${camerax_version}" + + implementation "androidx.camera:camera-view:${camerax_version}" + implementation "androidx.camera:camera-extensions:${camerax_version}" + + implementation("com.squareup.okhttp3:okhttp:4.9.3") + + implementation 'jp.co.cyberagent.android.gpuimage:gpuimage-library:1.4.1' +} + +task buildApk(dependsOn: "assembleRelease") { + doFirst { + println '开始打包' + } + //dependsOn("assembleRelease") + + doLast { + def files = new File("X:\\servier\\tools\\web\\apk\\door\\").listFiles() + for (File file : files) { + println file.name + file.delete() + } + + def keystore = file("D:\\AndroidKeys\\yutou.jks") + def unsignedApk = file("build\\intermediates\\apk\\release\\app-release-unsigned.apk") + + def signedApk = file("X:\\servier\\tools\\web\\apk\\door\\app-release-" + android.defaultConfig.versionName + ".apk") + def cmd = "jarsigner -verbose -keystore " + keystore + " -signedjar " + signedApk + " " + unsignedApk + " yutou -storepass 34864394" + println cmd + def pr = Runtime.getRuntime().exec("cmd /c ${cmd}") + def input = new BufferedReader(new InputStreamReader(pr.getInputStream(), "GBK")) + String line; + while ((line = input.readLine()) != null) { + println line + } + assert pr.waitFor() == 0 + } +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/yutou/doormanager/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/yutou/doormanager/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..e5be24f --- /dev/null +++ b/app/src/androidTest/java/com/yutou/doormanager/ExampleInstrumentedTest.kt @@ -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) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..f1cef91 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/yutou/doormanager/HeadlessSmsSendService.java b/app/src/main/java/com/yutou/doormanager/HeadlessSmsSendService.java new file mode 100644 index 0000000..7a38c05 --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/HeadlessSmsSendService.java @@ -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; + } +} diff --git a/app/src/main/java/com/yutou/doormanager/MainActivity.kt b/app/src/main/java/com/yutou/doormanager/MainActivity.kt new file mode 100644 index 0000000..9340f7d --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/MainActivity.kt @@ -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 = 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() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/yutou/doormanager/MmsReceiver.java b/app/src/main/java/com/yutou/doormanager/MmsReceiver.java new file mode 100644 index 0000000..a7a85ef --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/MmsReceiver.java @@ -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) { + + } +} diff --git a/app/src/main/java/com/yutou/doormanager/MyApplication.kt b/app/src/main/java/com/yutou/doormanager/MyApplication.kt new file mode 100644 index 0000000..55d5d5e --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/MyApplication.kt @@ -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 + } + 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") + } + + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yutou/doormanager/MyViewModel.kt b/app/src/main/java/com/yutou/doormanager/MyViewModel.kt new file mode 100644 index 0000000..01eeca7 --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/MyViewModel.kt @@ -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 + } +} diff --git a/app/src/main/java/com/yutou/doormanager/SMSActivity.java b/app/src/main/java/com/yutou/doormanager/SMSActivity.java new file mode 100644 index 0000000..cbfd1b9 --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/SMSActivity.java @@ -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); + } +} diff --git a/app/src/main/java/com/yutou/doormanager/SmsReceiver.java b/app/src/main/java/com/yutou/doormanager/SmsReceiver.java new file mode 100644 index 0000000..3eb9ed5 --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/SmsReceiver.java @@ -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; + } + } + } +} diff --git a/app/src/main/java/com/yutou/doormanager/SmsSendService.java b/app/src/main/java/com/yutou/doormanager/SmsSendService.java new file mode 100644 index 0000000..ae41d59 --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/SmsSendService.java @@ -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; + } +} diff --git a/app/src/main/java/com/yutou/doormanager/TestData.kt b/app/src/main/java/com/yutou/doormanager/TestData.kt new file mode 100644 index 0000000..acf69de --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/TestData.kt @@ -0,0 +1,8 @@ +package com.yutou.doormanager + +class TestData { + val str by lazy { + println("Init lazy") + "Hello World" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yutou/doormanager/utils/AudioUtils.kt b/app/src/main/java/com/yutou/doormanager/utils/AudioUtils.kt new file mode 100644 index 0000000..7c049e4 --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/utils/AudioUtils.kt @@ -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() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yutou/doormanager/utils/DataListener.kt b/app/src/main/java/com/yutou/doormanager/utils/DataListener.kt new file mode 100644 index 0000000..afe67b7 --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/utils/DataListener.kt @@ -0,0 +1,7 @@ +package com.yutou.doormanager.utils + +import org.json.JSONObject + +interface DataListener { + fun out(json:JSONObject) +} \ No newline at end of file diff --git a/app/src/main/java/com/yutou/doormanager/utils/DataUtils.kt b/app/src/main/java/com/yutou/doormanager/utils/DataUtils.kt new file mode 100644 index 0000000..baa8386 --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/utils/DataUtils.kt @@ -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() + + 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yutou/doormanager/utils/HttpListener.kt b/app/src/main/java/com/yutou/doormanager/utils/HttpListener.kt new file mode 100644 index 0000000..95ece4d --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/utils/HttpListener.kt @@ -0,0 +1,5 @@ +package com.yutou.doormanager.utils + +interface HttpListener{ + fun data(code:Int,data:String) +} \ No newline at end of file diff --git a/app/src/main/java/com/yutou/doormanager/utils/HttpUtils.kt b/app/src/main/java/com/yutou/doormanager/utils/HttpUtils.kt new file mode 100644 index 0000000..c485a59 --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/utils/HttpUtils.kt @@ -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) + } + } + + }) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yutou/doormanager/utils/SmsUtils.kt b/app/src/main/java/com/yutou/doormanager/utils/SmsUtils.kt new file mode 100644 index 0000000..42f9cc1 --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/utils/SmsUtils.kt @@ -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 + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yutou/doormanager/utils/Utils.kt b/app/src/main/java/com/yutou/doormanager/utils/Utils.kt new file mode 100644 index 0000000..69e74f7 --- /dev/null +++ b/app/src/main/java/com/yutou/doormanager/utils/Utils.kt @@ -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()) + } + } +} + diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/tmp.png b/app/src/main/res/drawable/tmp.png new file mode 100644 index 0000000..5f25bf8 Binary files /dev/null and b/app/src/main/res/drawable/tmp.png differ diff --git a/app/src/main/res/layout-land/activity_main.xml b/app/src/main/res/layout-land/activity_main.xml new file mode 100644 index 0000000..60957c9 --- /dev/null +++ b/app/src/main/res/layout-land/activity_main.xml @@ -0,0 +1,60 @@ + + + + + + +