...
This commit is contained in:
parent
55f2c3272c
commit
75df1bf324
@ -88,5 +88,5 @@ dependencies {
|
|||||||
implementation ("androidx.work:work-runtime:2.9.1")
|
implementation ("androidx.work:work-runtime:2.9.1")
|
||||||
implementation ("com.google.code.gson:gson:2.11.0")
|
implementation ("com.google.code.gson:gson:2.11.0")
|
||||||
implementation ("io.realm.kotlin:library-base:2.1.0")
|
implementation ("io.realm.kotlin:library-base:2.1.0")
|
||||||
|
implementation ("org.jsoup:jsoup:1.18.1")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
<uses-permission android:name="android.permission.CALL_PHONE" />
|
<uses-permission android:name="android.permission.CALL_PHONE" />
|
||||||
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
|
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||||
android:maxSdkVersion="32" />
|
android:maxSdkVersion="32" />
|
||||||
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
|
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
|
||||||
@ -21,12 +22,19 @@
|
|||||||
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
|
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
|
||||||
<!-- api 33+ -->
|
<!-- api 33+ -->
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||||
|
<uses-permission android:name="android.permission.RECEIVE_SMS" />
|
||||||
|
<uses-permission android:name="android.permission.RECEIVE_MMS" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.QUERY_ALL_PACKAGES"
|
android:name="android.permission.QUERY_ALL_PACKAGES"
|
||||||
tools:ignore="QueryAllPackagesPermission" />
|
tools:ignore="QueryAllPackagesPermission" />
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.READ_SMS"
|
android:name="android.permission.READ_SMS"
|
||||||
tools:ignore="QueryAllPackagesPermission" />
|
tools:ignore="QueryAllPackagesPermission" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<queries>
|
<queries>
|
||||||
<intent>
|
<intent>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
@ -45,6 +53,7 @@
|
|||||||
android:enableOnBackInvokedCallback="true"
|
android:enableOnBackInvokedCallback="true"
|
||||||
android:largeHeap="true"
|
android:largeHeap="true"
|
||||||
android:hardwareAccelerated="true"
|
android:hardwareAccelerated="true"
|
||||||
|
android:usesCleartextTraffic="true"
|
||||||
android:screenOrientation="nosensor"
|
android:screenOrientation="nosensor"
|
||||||
android:windowSoftInputMode="adjustResize"
|
android:windowSoftInputMode="adjustResize"
|
||||||
android:requestLegacyExternalStorage="true">
|
android:requestLegacyExternalStorage="true">
|
||||||
@ -122,5 +131,19 @@
|
|||||||
<action android:name="android.service.notification.NotificationListenerService" />
|
<action android:name="android.service.notification.NotificationListenerService" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>
|
||||||
|
<receiver android:name=".home.EndCallReceiver"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.PHONE_STATE" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
<receiver android:name=".home.SMSReceiver"
|
||||||
|
android:exported="true"
|
||||||
|
android:permission="android.permission.BROADCAST_SMS">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
||||||
|
<action android:name="android.provider.Telephony.MMS_RECEIVED" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
@ -73,6 +73,9 @@ internal class LauncherActivity : AppCompatActivity() {
|
|||||||
lateinit var viewPager: ViewPager2
|
lateinit var viewPager: ViewPager2
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
val TEST_PAG = "https://jav.guru/"
|
||||||
|
|
||||||
|
val TEST_PAG2 = "https://torrentsee246.com/topic/index?category1=129&category2=132"
|
||||||
@JvmStatic var lActivity: LauncherActivity? = null
|
@JvmStatic var lActivity: LauncherActivity? = null
|
||||||
@JvmStatic var appWidgetManager: AppWidgetManager? = null
|
@JvmStatic var appWidgetManager: AppWidgetManager? = null
|
||||||
@JvmStatic var appWidgetHost: WidgetHost? = null
|
@JvmStatic var appWidgetHost: WidgetHost? = null
|
||||||
@ -119,13 +122,27 @@ internal class LauncherActivity : AppCompatActivity() {
|
|||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
BLog.LOGE("onResume")
|
BLog.LOGE("onResume")
|
||||||
|
// askPermissions()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun welcomeDialog() {
|
private fun welcomeDialog() {
|
||||||
getSharedPreferences(PREFS_FIRST_LAUNCH, 0).let {
|
|
||||||
if (it.getBoolean(KEY_FIRST_LAUNCH, true)) {
|
|
||||||
it.edit().putBoolean(KEY_FIRST_LAUNCH, false).apply()
|
|
||||||
|
|
||||||
|
var needAsk = if (
|
||||||
|
this.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED ||
|
||||||
|
this.checkSelfPermission(Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED ||
|
||||||
|
this.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED ||
|
||||||
|
this.checkSelfPermission(Manifest.permission.RECEIVE_MMS) != PackageManager.PERMISSION_GRANTED ||
|
||||||
|
this.checkSelfPermission(Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED ||
|
||||||
|
this.checkSelfPermission(Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED ||
|
||||||
|
this.checkSelfPermission(Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
true
|
||||||
|
} else false
|
||||||
|
|
||||||
|
|
||||||
|
getSharedPreferences(PREFS_FIRST_LAUNCH, 0).let {
|
||||||
|
if (it.getBoolean(KEY_FIRST_LAUNCH, true) || needAsk) {
|
||||||
|
it.edit().putBoolean(KEY_FIRST_LAUNCH, false).apply()
|
||||||
MaterialAlertDialogBuilder(this)
|
MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.welcome)
|
.setTitle(R.string.welcome)
|
||||||
.setMessage(R.string.welcome_description)
|
.setMessage(R.string.welcome_description)
|
||||||
@ -140,8 +157,26 @@ internal class LauncherActivity : AppCompatActivity() {
|
|||||||
/* ask for the permissions */
|
/* ask for the permissions */
|
||||||
private fun askPermissions() {
|
private fun askPermissions() {
|
||||||
/* phone permission */
|
/* phone permission */
|
||||||
if (this.checkSelfPermission(Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED || this.checkSelfPermission(Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
this.requestPermissions(arrayOf(Manifest.permission.CALL_PHONE,Manifest.permission.READ_SMS), 1)
|
if (
|
||||||
|
this.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED ||
|
||||||
|
this.checkSelfPermission(Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED ||
|
||||||
|
this.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED ||
|
||||||
|
this.checkSelfPermission(Manifest.permission.RECEIVE_MMS) != PackageManager.PERMISSION_GRANTED ||
|
||||||
|
this.checkSelfPermission(Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED ||
|
||||||
|
this.checkSelfPermission(Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED ||
|
||||||
|
this.checkSelfPermission(Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
this.requestPermissions(arrayOf(
|
||||||
|
Manifest.permission.READ_CONTACTS,
|
||||||
|
Manifest.permission.READ_CALL_LOG,
|
||||||
|
Manifest.permission.CALL_PHONE,
|
||||||
|
Manifest.permission.READ_SMS,
|
||||||
|
Manifest.permission.READ_PHONE_STATE,
|
||||||
|
Manifest.permission.RECEIVE_MMS,
|
||||||
|
Manifest.permission.RECEIVE_SMS,
|
||||||
|
Manifest.permission.CALL_PHONE,
|
||||||
|
Manifest.permission.READ_SMS), 1)
|
||||||
}
|
}
|
||||||
/* modify system settings */
|
/* modify system settings */
|
||||||
if (!Settings.System.canWrite(this)) {
|
if (!Settings.System.canWrite(this)) {
|
||||||
|
|||||||
@ -194,13 +194,11 @@ internal class ContactMenu : BottomSheetDialogFragment() {
|
|||||||
binding.phoneNumber.text = contactPhoneNumber
|
binding.phoneNumber.text = contactPhoneNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
/* detailed info dialog */
|
|
||||||
@SuppressLint("SetTextI18n")
|
|
||||||
private fun detailedInfo() {
|
private fun detailedInfo() {
|
||||||
var intent = Intent(Intent.ACTION_VIEW);
|
var intent = Intent(Intent.ACTION_VIEW);
|
||||||
intent.setData(Uri.parse(ContactsContract.Contacts.CONTENT_URI.toString() + "/" + packageName));
|
intent.setData(Uri.parse(ContactsContract.Contacts.CONTENT_URI.toString() + "/" + packageName));
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* activity browser dialog */
|
/* activity browser dialog */
|
||||||
|
|||||||
42
app/src/main/kotlin/rasel/lunar/launcher/apps/SmmsMenu.kt
Normal file
42
app/src/main/kotlin/rasel/lunar/launcher/apps/SmmsMenu.kt
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package rasel.lunar.launcher.apps
|
||||||
|
|
||||||
|
import android.content.pm.ApplicationInfo
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
|
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||||
|
import rasel.lunar.launcher.databinding.ContactMenuBinding
|
||||||
|
|
||||||
|
class SmmsMenu: BottomSheetDialogFragment() {
|
||||||
|
|
||||||
|
private lateinit var binding: ContactMenuBinding
|
||||||
|
private lateinit var msgId: String
|
||||||
|
private lateinit var packageManager: PackageManager
|
||||||
|
private lateinit var appInfo: ApplicationInfo
|
||||||
|
private lateinit var defAppName: String
|
||||||
|
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||||
|
binding = ContactMenuBinding.inflate(inflater, container, false)
|
||||||
|
|
||||||
|
/* get package name from fragment's tag */
|
||||||
|
msgId = tag.toString()
|
||||||
|
val resolver = lActivity!!.contentResolver
|
||||||
|
|
||||||
|
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
(requireDialog() as BottomSheetDialog).dismissWithAnimation = true
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -25,12 +25,21 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.net.http.SslError
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.AlarmClock
|
import android.provider.AlarmClock
|
||||||
|
import android.telephony.TelephonyManager
|
||||||
import android.text.format.DateFormat
|
import android.text.format.DateFormat
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.webkit.JavascriptInterface
|
||||||
|
import android.webkit.SslErrorHandler
|
||||||
|
import android.webkit.WebSettings
|
||||||
|
import android.webkit.WebView
|
||||||
|
import android.webkit.WebViewClient
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.biometric.BiometricPrompt
|
import androidx.biometric.BiometricPrompt
|
||||||
import androidx.core.content.ContextCompat.RECEIVER_EXPORTED
|
import androidx.core.content.ContextCompat.RECEIVER_EXPORTED
|
||||||
@ -41,6 +50,11 @@ import androidx.work.ExistingPeriodicWorkPolicy
|
|||||||
import androidx.work.PeriodicWorkRequestBuilder
|
import androidx.work.PeriodicWorkRequestBuilder
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
|
import kotlinx.coroutines.MainScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.jsoup.Jsoup
|
||||||
|
import org.jsoup.nodes.Document
|
||||||
|
import rasel.lunar.launcher.LauncherActivity.Companion.TEST_PAG
|
||||||
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||||
import rasel.lunar.launcher.R
|
import rasel.lunar.launcher.R
|
||||||
import rasel.lunar.launcher.databinding.LauncherHomeBinding
|
import rasel.lunar.launcher.databinding.LauncherHomeBinding
|
||||||
@ -55,18 +69,28 @@ import rasel.lunar.launcher.helpers.UniUtils.Companion.biometricPromptInfo
|
|||||||
import rasel.lunar.launcher.helpers.UniUtils.Companion.canAuthenticate
|
import rasel.lunar.launcher.helpers.UniUtils.Companion.canAuthenticate
|
||||||
import rasel.lunar.launcher.helpers.UniUtils.Companion.expandNotificationPanel
|
import rasel.lunar.launcher.helpers.UniUtils.Companion.expandNotificationPanel
|
||||||
import rasel.lunar.launcher.helpers.UniUtils.Companion.lockMethod
|
import rasel.lunar.launcher.helpers.UniUtils.Companion.lockMethod
|
||||||
|
import rasel.lunar.launcher.home.LauncherHome.Companion.lastedFinishedPageUrl
|
||||||
|
import rasel.lunar.launcher.home.LauncherHome.Companion.listItem
|
||||||
|
import rasel.lunar.launcher.home.LauncherHome.Companion.listTags
|
||||||
|
import rasel.lunar.launcher.home.LauncherHome.Companion.refreshCalls
|
||||||
|
import rasel.lunar.launcher.home.LauncherHome.Companion.refreshSms
|
||||||
import rasel.lunar.launcher.home.weather.WeatherExecutor
|
import rasel.lunar.launcher.home.weather.WeatherExecutor
|
||||||
import rasel.lunar.launcher.qaccess.QuickAccess
|
import rasel.lunar.launcher.qaccess.QuickAccess
|
||||||
import rasel.lunar.launcher.settings.SettingsActivity
|
import rasel.lunar.launcher.settings.SettingsActivity
|
||||||
import rasel.lunar.launcher.todos.MissedCallsAdapter
|
import rasel.lunar.launcher.todos.MissedCallsAdapter
|
||||||
|
import rasel.lunar.launcher.todos.RssItemAdapter
|
||||||
|
import rasel.lunar.launcher.todos.RssTagAdapter
|
||||||
import rasel.lunar.launcher.todos.SmsLogsAdapter
|
import rasel.lunar.launcher.todos.SmsLogsAdapter
|
||||||
import rasel.lunar.launcher.utils.BLog
|
import rasel.lunar.launcher.utils.BLog
|
||||||
import rasel.lunar.launcher.utils.MissedCallGetter
|
import rasel.lunar.launcher.utils.MissedCallGetter
|
||||||
import rasel.lunar.launcher.utils.RecentSmsGetter
|
import rasel.lunar.launcher.utils.RecentSmsGetter
|
||||||
import rasel.lunar.launcher.utils.RecentSmsLog
|
import rasel.lunar.launcher.utils.RecentSmsLog
|
||||||
import rasel.lunar.launcher.utils.SimpleFingerGestures
|
import rasel.lunar.launcher.utils.SimpleFingerGestures
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
|
||||||
@ -78,12 +102,32 @@ internal class LauncherHome : Fragment() {
|
|||||||
private lateinit var batteryReceiver: BatteryReceiver
|
private lateinit var batteryReceiver: BatteryReceiver
|
||||||
private var shouldResume = true
|
private var shouldResume = true
|
||||||
companion object {
|
companion object {
|
||||||
|
val SMS_WORK_TAG = "RecentSmsGetter"
|
||||||
|
val CALL_WORK_TAG = "MissedCallGetter"
|
||||||
|
var lastedFinishedPageUrl : String = ""
|
||||||
|
private var mWorkManager: WorkManager? = null
|
||||||
|
|
||||||
var missedCalls = hashMapOf<String, MissedCall>()
|
var missedCalls = hashMapOf<String, MissedCall>()
|
||||||
var callList = arrayListOf<MissedCall>()
|
var callList = arrayListOf<MissedCall>()
|
||||||
var smsList = arrayListOf<RecentSmsLog>()
|
var smsList = arrayListOf<RecentSmsLog>()
|
||||||
|
var listTags = arrayListOf<RssTagItem>()
|
||||||
|
var listItem = arrayListOf<RssItem>()
|
||||||
|
|
||||||
|
fun refreshSms() {
|
||||||
|
Executors.newSingleThreadScheduledExecutor().schedule({
|
||||||
|
mWorkManager?.cancelAllWorkByTag(SMS_WORK_TAG)
|
||||||
|
mWorkManager?.enqueue(PeriodicWorkRequestBuilder<RecentSmsGetter>(30, TimeUnit.MINUTES).addTag(SMS_WORK_TAG).build())
|
||||||
|
}, 2, TimeUnit.SECONDS)
|
||||||
|
}
|
||||||
|
fun refreshCalls() {
|
||||||
|
Executors.newSingleThreadScheduledExecutor().schedule({
|
||||||
|
mWorkManager?.cancelAllWorkByTag(CALL_WORK_TAG)
|
||||||
|
mWorkManager?.enqueueUniquePeriodicWork(CALL_WORK_TAG,ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,PeriodicWorkRequestBuilder<MissedCallGetter>(30, TimeUnit.MINUTES).addTag("MissedCallGetter").build())
|
||||||
|
}, 2, TimeUnit.SECONDS)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val nReceiver: NotificationReceiver? = null
|
private var nReceiver: NotificationReceiver? = null
|
||||||
|
|
||||||
class NotificationReceiver : BroadcastReceiver() {
|
class NotificationReceiver : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context?, intent: Intent) {
|
override fun onReceive(context: Context?, intent: Intent) {
|
||||||
@ -94,8 +138,15 @@ internal class LauncherHome : Fragment() {
|
|||||||
// txtView.setText(temp)
|
// txtView.setText(temp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
fun workmanager() : WorkManager? {
|
||||||
|
if (mWorkManager == null) {
|
||||||
|
mWorkManager = WorkManager.getInstance(requireContext())
|
||||||
|
}
|
||||||
|
return mWorkManager
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||||
|
mWorkManager = WorkManager.getInstance(requireContext())
|
||||||
binding = LauncherHomeBinding.inflate(inflater, container, false)
|
binding = LauncherHomeBinding.inflate(inflater, container, false)
|
||||||
fragManager = lActivity!!.supportFragmentManager
|
fragManager = lActivity!!.supportFragmentManager
|
||||||
settingsPrefs = requireContext().getSharedPreferences(PREFS_SETTINGS, 0)
|
settingsPrefs = requireContext().getSharedPreferences(PREFS_SETTINGS, 0)
|
||||||
@ -103,13 +154,10 @@ internal class LauncherHome : Fragment() {
|
|||||||
mMissedCallsAdapter = MissedCallsAdapter(callList, requireContext())
|
mMissedCallsAdapter = MissedCallsAdapter(callList, requireContext())
|
||||||
mSmsLogsAdapter = SmsLogsAdapter(smsList, requireContext())
|
mSmsLogsAdapter = SmsLogsAdapter(smsList, requireContext())
|
||||||
binding.favAppsGroup.visibility = View.GONE
|
binding.favAppsGroup.visibility = View.GONE
|
||||||
mWorkManager = WorkManager.getInstance(requireContext())
|
|
||||||
mWorkManager?.cancelAllWork()
|
|
||||||
|
|
||||||
|
|
||||||
mWorkManager?.enqueue(PeriodicWorkRequestBuilder<RecentSmsGetter>(30, TimeUnit.SECONDS).addTag("RecentSmsGetter").build())
|
|
||||||
mWorkManager?.enqueueUniquePeriodicWork("MissedCallGetter",ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,PeriodicWorkRequestBuilder<MissedCallGetter>(30, TimeUnit.SECONDS).addTag("MissedCallGetter").build())
|
workmanager()?.getWorkInfosByTagLiveData(SMS_WORK_TAG)?.observeForever {
|
||||||
mWorkManager?.getWorkInfosByTagLiveData("RecentSmsGetter")?.observeForever {
|
|
||||||
binding.recentSms.text = "최근 문자 [${smsList.size}]"
|
binding.recentSms.text = "최근 문자 [${smsList.size}]"
|
||||||
if (binding.recentSms.isChecked) chooseAdpater()
|
if (binding.recentSms.isChecked) chooseAdpater()
|
||||||
else if (missedCalls.size == 0) {
|
else if (missedCalls.size == 0) {
|
||||||
@ -120,17 +168,20 @@ internal class LauncherHome : Fragment() {
|
|||||||
it.clear()
|
it.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
mWorkManager?.getWorkInfosByTagLiveData("MissedCallGetter")?.observeForever {
|
workmanager()?.getWorkInfosByTagLiveData(CALL_WORK_TAG)?.observeForever {
|
||||||
binding.missedCalls.text = "최근 통화 [${missedCalls.size}]"
|
binding.missedCalls.text = "최근 통화 [${missedCalls.size}]"
|
||||||
|
if (missedCalls.size > 0) binding.missedCalls.isChecked = true
|
||||||
if (binding.missedCalls.isChecked) chooseAdpater()
|
if (binding.missedCalls.isChecked) chooseAdpater()
|
||||||
it.clear()
|
it.clear()
|
||||||
}
|
}
|
||||||
|
nReceiver = NotificationReceiver()
|
||||||
val filter = IntentFilter()
|
val filter = IntentFilter()
|
||||||
filter.addAction("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
// filter.addAction("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
||||||
registerReceiver(requireContext(),nReceiver, filter,RECEIVER_EXPORTED)
|
registerReceiver(requireContext(),nReceiver, filter,RECEIVER_EXPORTED)
|
||||||
|
|
||||||
BLog.LOGE("onCreateView()")
|
BLog.LOGE("onCreateView()")
|
||||||
|
refreshSms()
|
||||||
|
refreshCalls()
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,17 +213,74 @@ internal class LauncherHome : Fragment() {
|
|||||||
|
|
||||||
binding.missedCalls.setOnClickListener {
|
binding.missedCalls.setOnClickListener {
|
||||||
binding.missedCalls.isChecked = true
|
binding.missedCalls.isChecked = true
|
||||||
BLog.LOGE("binding.missedCalls >> ${binding.missedCalls.isChecked}")
|
|
||||||
chooseAdpater()
|
chooseAdpater()
|
||||||
}
|
}
|
||||||
binding.recentSms.setOnClickListener {
|
binding.recentSms.setOnClickListener {
|
||||||
binding.recentSms.isChecked = true
|
binding.recentSms.isChecked = true
|
||||||
chooseAdpater()
|
chooseAdpater()
|
||||||
}
|
}
|
||||||
|
binding.otherCheck.setOnClickListener {
|
||||||
|
BLog.LOGE("binding.otherCheck before ThreadRun")
|
||||||
|
|
||||||
|
|
||||||
|
binding.searcher01.webViewClient = object : WebViewClient() {
|
||||||
|
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
|
||||||
|
BLog.LOGE("binding.otherCheck searcher01 in onPageStarted ${url}")
|
||||||
|
super.onPageStarted(view, url, favicon)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onReceivedSslError(
|
||||||
|
view: WebView?,
|
||||||
|
handler: SslErrorHandler?,
|
||||||
|
error: SslError?
|
||||||
|
) {
|
||||||
|
handler?.proceed()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onPageFinished(view: WebView?, url: String?) {
|
||||||
|
super.onPageFinished(view, url)
|
||||||
|
lastedFinishedPageUrl = url ?: ""
|
||||||
|
BLog.LOGE("binding.otherCheck searcher01 in onPageFinished ${url}")
|
||||||
|
view?.evaluateJavascript("function getAll() {\n" +
|
||||||
|
" MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
|
||||||
|
" };getAll()") { result ->
|
||||||
|
(result as? String)?.let {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding.searcher01.apply {
|
||||||
|
this.addJavascriptInterface(MyJavaScriptInterface(this),"MyJavaScriptInterface")
|
||||||
|
setBackgroundColor(Color.WHITE) // 백그라운드 색상 설정
|
||||||
|
setLayerType(View.LAYER_TYPE_SOFTWARE, null) // 랜더링 이슈 해결
|
||||||
|
try {
|
||||||
|
settings.apply {
|
||||||
|
javaScriptEnabled = true // 자바스크립트 사용 가능하도록 설정
|
||||||
|
loadWithOverviewMode = true // 전체 웹페이지를 화면에 맞게 로드
|
||||||
|
useWideViewPort = true // 화면에 맞게 페이지 확대/축소
|
||||||
|
domStorageEnabled = true // DOM 저장소 사용 가능하도록 설정
|
||||||
|
setSupportMultipleWindows(true)
|
||||||
|
javaScriptCanOpenWindowsAutomatically = true // 팝업창 차단 해제
|
||||||
|
cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK
|
||||||
|
textZoom = 100 // system 에 의한 글꼴 변형 방지
|
||||||
|
defaultTextEncodingName = "UTF-8" // 인코딩 설정
|
||||||
|
allowContentAccess = true // 웹뷰를 통해 content url에 접근할지 여부
|
||||||
|
layoutAlgorithm = WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING // 웹페이지의 레이아웃을 화면에 맞게 자동으로 조정
|
||||||
|
}
|
||||||
|
} catch (ignore: NoSuchMethodError) {}
|
||||||
|
//TEST_PAG
|
||||||
|
loadUrl(TEST_PAG) // 웹페이지 연결
|
||||||
|
}
|
||||||
|
}
|
||||||
binding.summaryChoose.setOnCheckedChangeListener { group, checkedId ->
|
binding.summaryChoose.setOnCheckedChangeListener { group, checkedId ->
|
||||||
chooseAdpater()
|
chooseAdpater()
|
||||||
}
|
}
|
||||||
|
// val i = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_SERVICE_EXAMPLE")
|
||||||
|
// i.putExtra("command", "list")
|
||||||
|
// lActivity?.sendBroadcast(i)
|
||||||
|
// BLog.LOGE("intent >>> ${i.action}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -181,12 +289,11 @@ internal class LauncherHome : Fragment() {
|
|||||||
if (missedCalls.size > 0 && isAdded && isResumed && isVisible) {
|
if (missedCalls.size > 0 && isAdded && isResumed && isVisible) {
|
||||||
try {
|
try {
|
||||||
callList.clear()
|
callList.clear()
|
||||||
BLog.LOGE("chooseAdpater callList >>> ${callList.size}")
|
|
||||||
BLog.LOGE("chooseAdpater callList missedCalls >>> ${missedCalls.values.size}")
|
|
||||||
binding.mainList.adapter = mMissedCallsAdapter
|
binding.mainList.adapter = mMissedCallsAdapter
|
||||||
missedCalls.forEach { t, u ->
|
missedCalls.forEach { t, u ->
|
||||||
callList.add(u)
|
callList.add(u)
|
||||||
}.apply {
|
}.apply {
|
||||||
|
callList.sortByDescending { it.date }
|
||||||
mMissedCallsAdapter.updateData(callList)
|
mMissedCallsAdapter.updateData(callList)
|
||||||
}
|
}
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
@ -196,7 +303,6 @@ internal class LauncherHome : Fragment() {
|
|||||||
} else if(binding.recentSms.isChecked){
|
} else if(binding.recentSms.isChecked){
|
||||||
if (smsList.size > 0 && isAdded && isResumed && isVisible) {
|
if (smsList.size > 0 && isAdded && isResumed && isVisible) {
|
||||||
try {
|
try {
|
||||||
BLog.LOGE("chooseAdpater smsList >>> ${smsList.size}")
|
|
||||||
binding.mainList.adapter = mSmsLogsAdapter
|
binding.mainList.adapter = mSmsLogsAdapter
|
||||||
smsList.sortByDescending { it.rcvDate }
|
smsList.sortByDescending { it.rcvDate }
|
||||||
mSmsLogsAdapter.updateData(smsList)
|
mSmsLogsAdapter.updateData(smsList)
|
||||||
@ -228,7 +334,7 @@ internal class LauncherHome : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var mWorkManager: WorkManager? = null
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -376,6 +482,81 @@ internal class LauncherHome : Fragment() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inner class MyJavaScriptInterface(val webView: WebView) {
|
||||||
|
|
||||||
|
@JavascriptInterface
|
||||||
|
fun sendValueFromHtml(result: String) {
|
||||||
|
var htmlString = result.replace("\\u003","<")
|
||||||
|
val simpldateFormat = SimpleDateFormat("d MMM, yy",Locale.US)
|
||||||
|
val doc: Document = Jsoup.parse(htmlString)
|
||||||
|
// BLog.LOGE("binding.otherCheck in ThreadRun ${doc.body()}")
|
||||||
|
if(lastedFinishedPageUrl?.contains("page") == true || lastedFinishedPageUrl?.equals(TEST_PAG) == true) {
|
||||||
|
BLog.LOGE("do default parsing")
|
||||||
|
BLog.LOGE("SimpleDateFormat D MM yy => ${SimpleDateFormat("d MMM yy",Locale.US).format(Date())}")
|
||||||
|
val prevUrl = doc.getElementsByClass("prev").get(0).getElementsByAttribute("href").get(0).attr("href")
|
||||||
|
BLog.LOGE("doc.getElementsByClass(prev).get(0).html() ${prevUrl}")
|
||||||
|
doc.getElementsByClass("column").forEach {
|
||||||
|
var title = it.getElementsByAttribute("title").get(0).text()
|
||||||
|
var model = title.replace("[","").split("]")[0]
|
||||||
|
var pageLink = it.getElementsByClass("imgg").get(0).getElementsByAttribute("href").get(0).attr("href")
|
||||||
|
var imgg = it.getElementsByClass("imgg").get(0).getElementsByAttribute("src").get(0).attr("src")
|
||||||
|
var tags = it.getElementsByClass("tags").get(0).text()
|
||||||
|
var date = it.getElementsByClass("date").get(0).text()
|
||||||
|
listItem.add(RssItem(model = model, title = title, pageLink = pageLink, image = imgg, tags = tags, date = simpldateFormat.parse(date).time))
|
||||||
|
}.apply {
|
||||||
|
BLog.LOGE("listItem.size >>> ${listItem.size}")
|
||||||
|
if (prevUrl!=null && prevUrl.length > TEST_PAG.length && prevUrl.contains("/page/") && listItem.size < (24 * 5) ) {
|
||||||
|
BLog.LOGE("listItem.size >>> ${listItem.size} do next ")
|
||||||
|
webView.postDelayed({webView.loadUrl(prevUrl)}, 5000L)
|
||||||
|
if(binding.mainList.adapter is RssTagAdapter) {
|
||||||
|
binding.mainList?.post {
|
||||||
|
(binding.mainList.adapter as RssItemAdapter).apply {
|
||||||
|
updateData(listItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
binding.mainList?.post {
|
||||||
|
binding.mainList.adapter = RssItemAdapter(listItem,requireContext()).apply {
|
||||||
|
updateData(listItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
listTags.sortByDescending { it.count }
|
||||||
|
binding.mainList?.post {
|
||||||
|
(binding.mainList.adapter as RssItemAdapter).apply {
|
||||||
|
updateData(listItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(lastedFinishedPageUrl?.contains("/tags/") == true ){
|
||||||
|
listTags.clear()
|
||||||
|
doc.getElementsByTag("ul").forEach {
|
||||||
|
it.children().forEach {
|
||||||
|
if (it.tag().name.contains("li")) {
|
||||||
|
listTags.add(
|
||||||
|
RssTagItem(
|
||||||
|
tagTitle = it.getElementsByTag("a").get(0).text(),
|
||||||
|
link = it.getElementsByTag("a").get(0).attr("href")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.apply {
|
||||||
|
listTags.sortByDescending { it.count }
|
||||||
|
binding.mainList?.post {
|
||||||
|
binding.mainList.adapter = RssTagAdapter(listTags, requireContext()).apply {
|
||||||
|
updateData(listTags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BLog.LOGE("binding.otherCheck after ThreadRun")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
/* gestures on root view */
|
/* gestures on root view */
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
private fun rootViewGestures() {
|
private fun rootViewGestures() {
|
||||||
@ -555,3 +736,59 @@ class MissedCall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class EndCallReceiver : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
BLog.LOGE("EndCallReceiver >>> ${intent}")
|
||||||
|
val phoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE) ?: return
|
||||||
|
if (phoneState == TelephonyManager.EXTRA_STATE_IDLE) {
|
||||||
|
refreshCalls()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class SMSReceiver : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
BLog.LOGE("SMSReceiver >>> ${intent}")
|
||||||
|
refreshSms()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class RssTagItem {
|
||||||
|
var link : String = ""
|
||||||
|
var tagTitle = ""
|
||||||
|
var count = 0
|
||||||
|
constructor(link: String, tagTitle: String) {
|
||||||
|
this.link = link
|
||||||
|
this.tagTitle = tagTitle
|
||||||
|
if (tagTitle.contains("(") && tagTitle.contains(")")) {
|
||||||
|
try {
|
||||||
|
count = tagTitle.split("(")[1].split(")")[0].toInt()
|
||||||
|
}catch (e : Exception) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class RssItem {
|
||||||
|
var model : String = ""
|
||||||
|
var title : String = ""
|
||||||
|
var pageLink : String = ""
|
||||||
|
var image : String = ""
|
||||||
|
var tags : String = ""
|
||||||
|
var date : Long = 0L
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
model: String,
|
||||||
|
title: String,
|
||||||
|
pageLink: String,
|
||||||
|
image: String,
|
||||||
|
tags: String,
|
||||||
|
date: Long
|
||||||
|
) {
|
||||||
|
this.model = model
|
||||||
|
this.title = title
|
||||||
|
this.pageLink = pageLink
|
||||||
|
this.image = image
|
||||||
|
this.tags = tags
|
||||||
|
this.date = date
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -20,6 +20,9 @@ package rasel.lunar.launcher.todos
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.provider.ContactsContract
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -35,6 +38,7 @@ import rasel.lunar.launcher.helpers.UniUtils.Companion.copyToClipboard
|
|||||||
import rasel.lunar.launcher.home.MissedCall
|
import rasel.lunar.launcher.home.MissedCall
|
||||||
import rasel.lunar.launcher.utils.BLog
|
import rasel.lunar.launcher.utils.BLog
|
||||||
import rasel.lunar.launcher.utils.RecentSmsLog
|
import rasel.lunar.launcher.utils.RecentSmsLog
|
||||||
|
import rasel.lunar.launcher.utils.getContactId
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
@ -58,7 +62,6 @@ internal class MissedCallsAdapter(
|
|||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onBindViewHolder(holder: MissedCallsHolder, position: Int) {
|
override fun onBindViewHolder(holder: MissedCallsHolder, position: Int) {
|
||||||
val todo = callList[position]
|
val todo = callList[position]
|
||||||
BLog.LOGE("callList >>> ${callList[position]}")
|
|
||||||
holder.view.itemText.text = "\u25CF ${if(todo.name.equals("unknown")) todo.number else { todo.name}} , ${todo.typeString} : ${todo.count} : ${todo.date}"
|
holder.view.itemText.text = "\u25CF ${if(todo.name.equals("unknown")) todo.number else { todo.name}} , ${todo.typeString} : ${todo.count} : ${todo.date}"
|
||||||
|
|
||||||
/* multiline texts are enabled for TodoManager */
|
/* multiline texts are enabled for TodoManager */
|
||||||
@ -67,7 +70,17 @@ internal class MissedCallsAdapter(
|
|||||||
holder.view.itemText.setOnClickListener { updateDialog(position) }
|
holder.view.itemText.setOnClickListener { updateDialog(position) }
|
||||||
/* copy texts on long click */
|
/* copy texts on long click */
|
||||||
holder.view.itemText.setOnLongClickListener {
|
holder.view.itemText.setOnLongClickListener {
|
||||||
copyToClipboard(context, todo.name)
|
|
||||||
|
// copyToClipboard(context, todo.name)
|
||||||
|
var cId = getContactId(lActivity!!.contentResolver, todo.number)
|
||||||
|
if (cId != null && cId.length > 0) {
|
||||||
|
var intent = Intent(Intent.ACTION_VIEW);
|
||||||
|
intent.setData(Uri.parse(ContactsContract.Contacts.CONTENT_URI.toString() + "/" + cId));
|
||||||
|
lActivity?.startActivity(intent);
|
||||||
|
} else {
|
||||||
|
lActivity?.startActivity(Intent(Intent.ACTION_DIAL, Uri.parse("tel:${todo.number}")))
|
||||||
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
134
app/src/main/kotlin/rasel/lunar/launcher/todos/RssItemAdapter.kt
Normal file
134
app/src/main/kotlin/rasel/lunar/launcher/todos/RssItemAdapter.kt
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* Lunar Launcher
|
||||||
|
* Copyright (C) 2022 Md Rasel Hossain
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rasel.lunar.launcher.todos
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||||
|
import rasel.lunar.launcher.R
|
||||||
|
import rasel.lunar.launcher.databinding.ListItemBinding
|
||||||
|
import rasel.lunar.launcher.home.RssItem
|
||||||
|
import rasel.lunar.launcher.home.RssTagItem
|
||||||
|
import rasel.lunar.launcher.utils.BLog
|
||||||
|
import rasel.lunar.launcher.utils.RecentSmsLog
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
|
||||||
|
internal class RssItemAdapter (
|
||||||
|
private val smsList: ArrayList<RssItem>,
|
||||||
|
private val context: Context) : RecyclerView.Adapter<RssItemAdapter.RssTag>() {
|
||||||
|
|
||||||
|
private val currentFragment = lActivity!!.supportFragmentManager.findFragmentById(R.id.mainFragmentsContainer)
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): RssTag {
|
||||||
|
val binding = ListItemBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
|
||||||
|
return RssTag(binding)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return smsList.size
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
override fun onBindViewHolder(holder: RssTag, position: Int) {
|
||||||
|
val todo = smsList[position]
|
||||||
|
|
||||||
|
holder.view.itemText.text = "\u25CF ${Gson().toJson(todo)}"
|
||||||
|
/* multiline texts are enabled for TodoManager */
|
||||||
|
// holder.view.itemText.isSingleLine = false
|
||||||
|
/* launch edit or update dialog on item click */
|
||||||
|
// holder.view.itemText.setOnClickListener { updateDialog(position) }
|
||||||
|
/* copy texts on long click */
|
||||||
|
holder.view.itemText.setOnLongClickListener {
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RssTag(var view: ListItemBinding) : RecyclerView.ViewHolder(view.root)
|
||||||
|
|
||||||
|
fun updateData(newList: List<RssItem>) {
|
||||||
|
val diffUtilResult = DiffUtil.calculateDiff(RssItemDiffUtil(smsList, newList))
|
||||||
|
diffUtilResult.dispatchUpdatesTo(this)
|
||||||
|
// smsList.clear()
|
||||||
|
// smsList.addAll(newList)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update dialog */
|
||||||
|
private fun updateDialog(position: Int) {
|
||||||
|
// val bottomSheetDialog = BottomSheetDialog(lActivity!!, R.style.BottomSheetDialog)
|
||||||
|
// val dialogBinding = TodoDialogBinding.inflate(LayoutInflater.from(context))
|
||||||
|
// bottomSheetDialog.setContentView(dialogBinding.root)
|
||||||
|
// bottomSheetDialog.show()
|
||||||
|
// bottomSheetDialog.dismissWithAnimation = true
|
||||||
|
//
|
||||||
|
// val databaseHandler = DatabaseHandler(context)
|
||||||
|
// val todo = databaseHandler.todos[position]
|
||||||
|
//
|
||||||
|
// dialogBinding.apply {
|
||||||
|
// deleteAllConfirmation.visibility = View.GONE
|
||||||
|
// todoInput.setText(todo.name)
|
||||||
|
// todoCancel.text = context.getString(R.string.delete)
|
||||||
|
// todoCancel.setTextColor(ContextCompat.getColor(context, android.R.color.holo_red_light))
|
||||||
|
// todoOk.text = context.getString(R.string.update)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /* delete the item */
|
||||||
|
// dialogBinding.todoCancel.setOnClickListener {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /* update the item */
|
||||||
|
// dialogBinding.todoOk.setOnClickListener {
|
||||||
|
// val updatedTodoString = Objects.requireNonNull(dialogBinding.todoInput.text).toString().trim { it <= ' ' }
|
||||||
|
// if (updatedTodoString.isNotEmpty()) {
|
||||||
|
// todo.name = updatedTodoString
|
||||||
|
// databaseHandler.updateTodo(todo)
|
||||||
|
// bottomSheetDialog.dismiss()
|
||||||
|
// } else {
|
||||||
|
// dialogBinding.todoInput.error = context.getString(R.string.empty_text_field)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class RssItemDiffUtil(
|
||||||
|
private val oldList: List<RssItem>, private val newList: List<RssItem>
|
||||||
|
) : DiffUtil.Callback() {
|
||||||
|
|
||||||
|
override fun getOldListSize(): Int = oldList.size
|
||||||
|
override fun getNewListSize(): Int = newList.size
|
||||||
|
|
||||||
|
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
|
||||||
|
oldList[oldItemPosition].pageLink == newList[newItemPosition].pageLink
|
||||||
|
|
||||||
|
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
|
||||||
|
oldList[oldItemPosition].pageLink == newList[newItemPosition].pageLink
|
||||||
|
}
|
||||||
133
app/src/main/kotlin/rasel/lunar/launcher/todos/RssTagAdapter.kt
Normal file
133
app/src/main/kotlin/rasel/lunar/launcher/todos/RssTagAdapter.kt
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* Lunar Launcher
|
||||||
|
* Copyright (C) 2022 Md Rasel Hossain
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rasel.lunar.launcher.todos
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||||
|
import rasel.lunar.launcher.R
|
||||||
|
import rasel.lunar.launcher.databinding.ListItemBinding
|
||||||
|
import rasel.lunar.launcher.home.RssTagItem
|
||||||
|
import rasel.lunar.launcher.utils.BLog
|
||||||
|
import rasel.lunar.launcher.utils.RecentSmsLog
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
|
||||||
|
internal class RssTagAdapter(
|
||||||
|
private val smsList: ArrayList<RssTagItem>,
|
||||||
|
private val context: Context) : RecyclerView.Adapter<RssTagAdapter.RssTag>() {
|
||||||
|
|
||||||
|
private val currentFragment = lActivity!!.supportFragmentManager.findFragmentById(R.id.mainFragmentsContainer)
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): RssTag {
|
||||||
|
val binding = ListItemBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
|
||||||
|
return RssTag(binding)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return smsList.size
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
override fun onBindViewHolder(holder: RssTag, position: Int) {
|
||||||
|
val todo = smsList[position]
|
||||||
|
|
||||||
|
holder.view.itemText.text = "\u25CF ${Gson().toJson(todo)}"
|
||||||
|
/* multiline texts are enabled for TodoManager */
|
||||||
|
// holder.view.itemText.isSingleLine = false
|
||||||
|
/* launch edit or update dialog on item click */
|
||||||
|
// holder.view.itemText.setOnClickListener { updateDialog(position) }
|
||||||
|
/* copy texts on long click */
|
||||||
|
holder.view.itemText.setOnLongClickListener {
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RssTag(var view: ListItemBinding) : RecyclerView.ViewHolder(view.root)
|
||||||
|
|
||||||
|
fun updateData(newList: List<RssTagItem>) {
|
||||||
|
val diffUtilResult = DiffUtil.calculateDiff(RssTagDiffUtil(smsList, newList))
|
||||||
|
diffUtilResult.dispatchUpdatesTo(this)
|
||||||
|
// smsList.clear()
|
||||||
|
// smsList.addAll(newList)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update dialog */
|
||||||
|
private fun updateDialog(position: Int) {
|
||||||
|
// val bottomSheetDialog = BottomSheetDialog(lActivity!!, R.style.BottomSheetDialog)
|
||||||
|
// val dialogBinding = TodoDialogBinding.inflate(LayoutInflater.from(context))
|
||||||
|
// bottomSheetDialog.setContentView(dialogBinding.root)
|
||||||
|
// bottomSheetDialog.show()
|
||||||
|
// bottomSheetDialog.dismissWithAnimation = true
|
||||||
|
//
|
||||||
|
// val databaseHandler = DatabaseHandler(context)
|
||||||
|
// val todo = databaseHandler.todos[position]
|
||||||
|
//
|
||||||
|
// dialogBinding.apply {
|
||||||
|
// deleteAllConfirmation.visibility = View.GONE
|
||||||
|
// todoInput.setText(todo.name)
|
||||||
|
// todoCancel.text = context.getString(R.string.delete)
|
||||||
|
// todoCancel.setTextColor(ContextCompat.getColor(context, android.R.color.holo_red_light))
|
||||||
|
// todoOk.text = context.getString(R.string.update)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /* delete the item */
|
||||||
|
// dialogBinding.todoCancel.setOnClickListener {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /* update the item */
|
||||||
|
// dialogBinding.todoOk.setOnClickListener {
|
||||||
|
// val updatedTodoString = Objects.requireNonNull(dialogBinding.todoInput.text).toString().trim { it <= ' ' }
|
||||||
|
// if (updatedTodoString.isNotEmpty()) {
|
||||||
|
// todo.name = updatedTodoString
|
||||||
|
// databaseHandler.updateTodo(todo)
|
||||||
|
// bottomSheetDialog.dismiss()
|
||||||
|
// } else {
|
||||||
|
// dialogBinding.todoInput.error = context.getString(R.string.empty_text_field)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class RssTagDiffUtil(
|
||||||
|
private val oldList: List<RssTagItem>, private val newList: List<RssTagItem>
|
||||||
|
) : DiffUtil.Callback() {
|
||||||
|
|
||||||
|
override fun getOldListSize(): Int = oldList.size
|
||||||
|
override fun getNewListSize(): Int = newList.size
|
||||||
|
|
||||||
|
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
|
||||||
|
oldList[oldItemPosition].link == newList[newItemPosition].link
|
||||||
|
|
||||||
|
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
|
||||||
|
oldList[oldItemPosition].link == newList[newItemPosition].link
|
||||||
|
}
|
||||||
@ -20,28 +20,20 @@ package rasel.lunar.launcher.todos
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
|
||||||
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||||
import rasel.lunar.launcher.R
|
import rasel.lunar.launcher.R
|
||||||
import rasel.lunar.launcher.apps.AppsAdapter.Companion.appsSize
|
|
||||||
import rasel.lunar.launcher.apps.AppsDiffUtil
|
|
||||||
import rasel.lunar.launcher.apps.Packages
|
|
||||||
import rasel.lunar.launcher.databinding.ListItemBinding
|
import rasel.lunar.launcher.databinding.ListItemBinding
|
||||||
import rasel.lunar.launcher.databinding.TodoDialogBinding
|
|
||||||
import rasel.lunar.launcher.helpers.UniUtils.Companion.copyToClipboard
|
|
||||||
import rasel.lunar.launcher.home.MissedCall
|
|
||||||
import rasel.lunar.launcher.utils.BLog
|
import rasel.lunar.launcher.utils.BLog
|
||||||
import rasel.lunar.launcher.utils.RecentSmsLog
|
import rasel.lunar.launcher.utils.RecentSmsLog
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.Date
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
import kotlin.collections.List
|
|
||||||
|
|
||||||
|
|
||||||
internal class SmsLogsAdapter(
|
internal class SmsLogsAdapter(
|
||||||
@ -56,24 +48,46 @@ internal class SmsLogsAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
BLog.LOGE("SmsLogsAdapter smsList.size >>> ${smsList.size}")
|
|
||||||
return smsList.size
|
return smsList.size
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onBindViewHolder(holder: SmsLogHolder, position: Int) {
|
override fun onBindViewHolder(holder: SmsLogHolder, position: Int) {
|
||||||
val todo = smsList[position]
|
val todo = smsList[position]
|
||||||
BLog.LOGE("SmsLogsAdapter smsList >>> ${smsList[position]}")
|
if(todo.isMms) {
|
||||||
|
var body = todo.mmsContents.get("text")?.joinToString("\n")?.replace("\n"," ")
|
||||||
holder.view.itemText.text = "\u25CF ${todo.person} ${todo.addr} , ${todo.body} : ${SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Date(Math.max(todo.pstDate.toLong(),todo.rcvDate.toLong())))} : ${todo.type}"
|
body = if (body?.length ?: 0 > 60) body?.substring(0,60).plus("...") else body
|
||||||
|
holder.view.itemText.text = "\u25CF ${todo.person} ${todo.addr} , ${body} : ${
|
||||||
|
SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(
|
||||||
|
Date(
|
||||||
|
Math.max(
|
||||||
|
todo.pstDate.toLong(),
|
||||||
|
todo.rcvDate.toLong()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} : ${todo.type}"
|
||||||
|
} else {
|
||||||
|
holder.view.itemText.text = "\u25CF ${todo.person} ${todo.addr} , ${todo.body} : ${
|
||||||
|
SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(
|
||||||
|
Date(
|
||||||
|
Math.max(
|
||||||
|
todo.pstDate.toLong(),
|
||||||
|
todo.rcvDate.toLong()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} : ${todo.type}"
|
||||||
|
}
|
||||||
/* multiline texts are enabled for TodoManager */
|
/* multiline texts are enabled for TodoManager */
|
||||||
// holder.view.itemText.isSingleLine = false
|
// holder.view.itemText.isSingleLine = false
|
||||||
/* launch edit or update dialog on item click */
|
/* launch edit or update dialog on item click */
|
||||||
// holder.view.itemText.setOnClickListener { updateDialog(position) }
|
// holder.view.itemText.setOnClickListener { updateDialog(position) }
|
||||||
/* copy texts on long click */
|
/* copy texts on long click */
|
||||||
holder.view.itemText.setOnLongClickListener {
|
holder.view.itemText.setOnLongClickListener {
|
||||||
|
var intent = Intent(Intent.ACTION_SENDTO);
|
||||||
|
intent.setData(Uri.parse("smsto:" + Uri.encode(todo.addr)));
|
||||||
|
lActivity?.startActivity(intent);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,10 +96,8 @@ internal class SmsLogsAdapter(
|
|||||||
inner class SmsLogHolder(var view: ListItemBinding) : RecyclerView.ViewHolder(view.root)
|
inner class SmsLogHolder(var view: ListItemBinding) : RecyclerView.ViewHolder(view.root)
|
||||||
|
|
||||||
fun updateData(newList: List<RecentSmsLog>) {
|
fun updateData(newList: List<RecentSmsLog>) {
|
||||||
BLog.LOGE("SmsLogsAdapter smsList newList >> ${newList.size}")
|
|
||||||
val diffUtilResult = DiffUtil.calculateDiff(SmsDiffUtil(smsList, newList))
|
val diffUtilResult = DiffUtil.calculateDiff(SmsDiffUtil(smsList, newList))
|
||||||
diffUtilResult.dispatchUpdatesTo(this)
|
diffUtilResult.dispatchUpdatesTo(this)
|
||||||
BLog.LOGE("SmsLogsAdapter smsList smsList >> ${smsList.size}")
|
|
||||||
// smsList.clear()
|
// smsList.clear()
|
||||||
// smsList.addAll(newList)
|
// smsList.addAll(newList)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,21 +6,23 @@ import android.content.Context
|
|||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.CallLog
|
import android.provider.CallLog
|
||||||
|
import android.provider.ContactsContract.PhoneLookup
|
||||||
import android.provider.Telephony
|
import android.provider.Telephony
|
||||||
import androidx.work.Worker
|
import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import androidx.work.workDataOf
|
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||||
import rasel.lunar.launcher.home.LauncherHome.Companion.missedCalls
|
import rasel.lunar.launcher.home.LauncherHome.Companion.missedCalls
|
||||||
import rasel.lunar.launcher.home.LauncherHome.Companion.smsList
|
import rasel.lunar.launcher.home.LauncherHome.Companion.smsList
|
||||||
import rasel.lunar.launcher.home.MissedCall
|
import rasel.lunar.launcher.home.MissedCall
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import kotlin.properties.Delegates
|
|
||||||
|
|
||||||
class MissedCallGetter : Worker {
|
class MissedCallGetter : Worker {
|
||||||
|
|
||||||
@ -102,7 +104,7 @@ class MissedCallGetter : Worker {
|
|||||||
SimpleDateFormat("yyy/MM/dd-HH:mm:ss").format(callDayTime)
|
SimpleDateFormat("yyy/MM/dd-HH:mm:ss").format(callDayTime)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
BLog.LOGE("missed put >>> ${missed.toJson()}")
|
// BLog.LOGE("missed put >>> ${missed.toJson()}")
|
||||||
missedCalls.put(phNumber, missed)
|
missedCalls.put(phNumber, missed)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +144,7 @@ class RecentSmsGetter : Worker {
|
|||||||
var dateParam = beforeDay(Date(),3).toString()
|
var dateParam = beforeDay(Date(),3).toString()
|
||||||
val managedCursor = lActivity?.contentResolver?.query(
|
val managedCursor = lActivity?.contentResolver?.query(
|
||||||
Telephony.Sms.CONTENT_URI, arrayOf(
|
Telephony.Sms.CONTENT_URI, arrayOf(
|
||||||
|
Telephony.Sms.THREAD_ID,
|
||||||
Telephony.Sms.ADDRESS,
|
Telephony.Sms.ADDRESS,
|
||||||
Telephony.Sms.TYPE,
|
Telephony.Sms.TYPE,
|
||||||
Telephony.Sms.DATE,
|
Telephony.Sms.DATE,
|
||||||
@ -152,6 +155,7 @@ class RecentSmsGetter : Worker {
|
|||||||
if (managedCursor != null && managedCursor.isClosed == false) {
|
if (managedCursor != null && managedCursor.isClosed == false) {
|
||||||
try {
|
try {
|
||||||
smsList.clear()
|
smsList.clear()
|
||||||
|
val tid = managedCursor.getColumnIndex(Telephony.Sms.THREAD_ID)
|
||||||
val address = managedCursor.getColumnIndex(Telephony.Sms.ADDRESS)
|
val address = managedCursor.getColumnIndex(Telephony.Sms.ADDRESS)
|
||||||
val type = managedCursor.getColumnIndex(Telephony.Sms.TYPE)
|
val type = managedCursor.getColumnIndex(Telephony.Sms.TYPE)
|
||||||
val date = managedCursor.getColumnIndex(Telephony.Sms.DATE)
|
val date = managedCursor.getColumnIndex(Telephony.Sms.DATE)
|
||||||
@ -159,6 +163,7 @@ class RecentSmsGetter : Worker {
|
|||||||
val bodyIdx = managedCursor.getColumnIndex(Telephony.Sms.BODY)
|
val bodyIdx = managedCursor.getColumnIndex(Telephony.Sms.BODY)
|
||||||
val name = managedCursor.getColumnIndex(Telephony.Sms.PERSON)
|
val name = managedCursor.getColumnIndex(Telephony.Sms.PERSON)
|
||||||
while (managedCursor.moveToNext()) {
|
while (managedCursor.moveToNext()) {
|
||||||
|
val id = managedCursor.getString(tid) // mobile number
|
||||||
val phNumber = managedCursor.getString(address) // mobile number
|
val phNumber = managedCursor.getString(address) // mobile number
|
||||||
val callType = managedCursor.getString(type) // call type
|
val callType = managedCursor.getString(type) // call type
|
||||||
val reciveDate = managedCursor.getString(date) // call date
|
val reciveDate = managedCursor.getString(date) // call date
|
||||||
@ -185,7 +190,10 @@ class RecentSmsGetter : Worker {
|
|||||||
smsBody,
|
smsBody,
|
||||||
callerName ?: ""
|
callerName ?: ""
|
||||||
)
|
)
|
||||||
BLog.LOGE("RecentSmsGetter resultData put ${phNumber +"_"+ reciveDate} >>> ${log.toJson()}")
|
log.id = id
|
||||||
|
log.isMms = false
|
||||||
|
// BLog.LOGE("RecentSmsGetter resultData put ${phNumber +"_"+ reciveDate} >>> ${log.toJson()}")
|
||||||
|
log.sender = getContactName(applicationContext.contentResolver,phNumber) ?: ""
|
||||||
smsList.add(log)
|
smsList.add(log)
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -205,12 +213,15 @@ class RecentSmsGetter : Worker {
|
|||||||
|
|
||||||
class RecentSmsLog {
|
class RecentSmsLog {
|
||||||
var id : String = ""
|
var id : String = ""
|
||||||
|
var isMms : Boolean = false
|
||||||
var addr : String = ""
|
var addr : String = ""
|
||||||
var type : String = ""
|
var type : String = ""
|
||||||
var rcvDate : String = "0"
|
var rcvDate : String = "0"
|
||||||
var pstDate : String = "0"
|
var pstDate : String = "0"
|
||||||
var body : String = ""
|
var body : String = ""
|
||||||
var person : String = ""
|
var person : String = ""
|
||||||
|
var mmsContents : HashMap<String?,ArrayList<String>> = hashMapOf()
|
||||||
|
var sender : String = ""
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
addr: String,
|
addr: String,
|
||||||
@ -226,13 +237,15 @@ class RecentSmsLog {
|
|||||||
this.pstDate = pstDate
|
this.pstDate = pstDate
|
||||||
this.body = body
|
this.body = body
|
||||||
this.person = person
|
this.person = person
|
||||||
|
this.isMms = false
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(id: String, sender: String, date: String, body: String) {
|
constructor(id: String, sender: String, date: String, body: HashMap<String?,ArrayList<String>>) {
|
||||||
this.id = id
|
this.id = id
|
||||||
this.rcvDate = date
|
this.rcvDate = date
|
||||||
this.body = body
|
this.mmsContents = body
|
||||||
this.addr = sender
|
this.addr = sender
|
||||||
|
this.isMms = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toJson() : String {
|
fun toJson() : String {
|
||||||
@ -259,14 +272,17 @@ class TestQueryHelper(
|
|||||||
val id = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Mms._ID))
|
val id = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Mms._ID))
|
||||||
val date = cursor.getLong(cursor.getColumnIndexOrThrow(Telephony.Mms.DATE)) * 1000
|
val date = cursor.getLong(cursor.getColumnIndexOrThrow(Telephony.Mms.DATE)) * 1000
|
||||||
val sender : String = getSender(id) ?: throw NullPointerException("NotFound Sender For Mms")
|
val sender : String = getSender(id) ?: throw NullPointerException("NotFound Sender For Mms")
|
||||||
val body: String = getBody(id) ?: throw NullPointerException("NotFound Body by Mms")
|
val body = getBody(id) ?: throw NullPointerException("NotFound Body by Mms")
|
||||||
|
|
||||||
return RecentSmsLog(
|
return RecentSmsLog(
|
||||||
id = id.toString(),
|
id = id.toString(),
|
||||||
date = date.toString(),
|
date = date.toString(),
|
||||||
body = body,
|
body = body,
|
||||||
sender = sender
|
sender = sender
|
||||||
)
|
).apply {
|
||||||
|
isMms = true
|
||||||
|
this.sender = getContactName(_contentResolver,addr) ?: ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSender(id: Int): String? {
|
private fun getSender(id: Int): String? {
|
||||||
@ -286,7 +302,7 @@ class TestQueryHelper(
|
|||||||
var sender = senderAddressCursor.getString(
|
var sender = senderAddressCursor.getString(
|
||||||
senderAddressCursor.getColumnIndexOrThrow(Telephony.Mms.Addr.ADDRESS)
|
senderAddressCursor.getColumnIndexOrThrow(Telephony.Mms.Addr.ADDRESS)
|
||||||
)
|
)
|
||||||
BLog.LOGE("sender >> ${sender}")
|
// BLog.LOGE("sender >> ${sender}")
|
||||||
if (isSender) {
|
if (isSender) {
|
||||||
return sender
|
return sender
|
||||||
}
|
}
|
||||||
@ -296,33 +312,103 @@ class TestQueryHelper(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getBody(id: Int): String? {
|
private fun getMmsText(id: String): String {
|
||||||
|
val partURI = Uri.parse("content://mms/part/$id")
|
||||||
|
var `is`: InputStream? = null
|
||||||
|
val sb = StringBuilder()
|
||||||
|
try {
|
||||||
|
`is` = _contentResolver.openInputStream(partURI)
|
||||||
|
if (`is` != null) {
|
||||||
|
val isr = InputStreamReader(`is`, "UTF-8")
|
||||||
|
val reader = BufferedReader(isr)
|
||||||
|
var temp = reader.readLine()
|
||||||
|
while (temp != null) {
|
||||||
|
sb.append(temp)
|
||||||
|
temp = reader.readLine()
|
||||||
|
BLog.LOGE("temp >>> ${temp}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
} finally {
|
||||||
|
if (`is` != null) {
|
||||||
|
try {
|
||||||
|
`is`.close()
|
||||||
|
} catch (e: IOException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BLog.LOGE("sb >>> ${sb.toString()}")
|
||||||
|
return sb.toString()
|
||||||
|
}
|
||||||
|
private fun getBody(id: Int): HashMap<String?,ArrayList<String>> {
|
||||||
|
var returns = hashMapOf<String?,ArrayList<String>>()
|
||||||
|
val text = arrayListOf<String>()
|
||||||
|
val image = arrayListOf<String>()
|
||||||
|
val audio = arrayListOf<String>()
|
||||||
|
|
||||||
|
val projection = arrayOf("*")
|
||||||
|
val video = arrayListOf<String>()
|
||||||
_contentResolver.query(
|
_contentResolver.query(
|
||||||
Uri.parse("content://mms/part"),
|
Uri.parse("content://mms/part"),
|
||||||
null,
|
projection,
|
||||||
"${Telephony.Mms.Part.MSG_ID} = ?",
|
"${Telephony.Mms.Part.MSG_ID} = ?",
|
||||||
arrayOf(id.toString()),
|
arrayOf(id.toString()),
|
||||||
null
|
null
|
||||||
)?.use { partsCursor ->
|
)?.use { partsCursor ->
|
||||||
if (partsCursor.moveToFirst()) {
|
if (partsCursor.moveToFirst()) {
|
||||||
do {
|
do {
|
||||||
|
val partId: String = partsCursor.getString(partsCursor.getColumnIndexOrThrow(Telephony.Mms.Part._ID))
|
||||||
val partContentType =
|
val partContentType =
|
||||||
partsCursor.getString(partsCursor.getColumnIndexOrThrow(Telephony.Mms.Part.CONTENT_TYPE))
|
partsCursor.getString(partsCursor.getColumnIndexOrThrow(Telephony.Mms.Part.CONTENT_TYPE))
|
||||||
if (partContentType == "text/plain") {
|
// BLog.LOGE("partContentType >> ${partContentType}")
|
||||||
var textBody =
|
|
||||||
partsCursor.getString(partsCursor.getColumnIndexOrThrow(Telephony.Mms.Part.TEXT))
|
|
||||||
.replace("\n\n", "\n").replace("\n", " ")
|
|
||||||
if (textBody.length > 60) {
|
|
||||||
textBody = textBody.substring(0, Math.min(textBody.length, 60)).plus(" ... ")
|
|
||||||
}
|
|
||||||
BLog.LOGE("textBody >>> ${textBody}")
|
|
||||||
|
|
||||||
return textBody
|
if(partContentType?.contains("text") == true) {
|
||||||
|
// BLog.LOGE("partContentType text >> ${partContentType} :: ${partId}")
|
||||||
|
val data =
|
||||||
|
partsCursor.getString(partsCursor.getColumnIndexOrThrow(Telephony.Mms.Part._DATA))
|
||||||
|
val textBody =
|
||||||
|
partsCursor.getString(partsCursor.getColumnIndexOrThrow(Telephony.Mms.Part.TEXT))
|
||||||
|
if (data != null && data.length > 0) {
|
||||||
|
text.add(getMmsText(partId))
|
||||||
|
} else {
|
||||||
|
text.add(textBody)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if(partContentType?.contains("image") == true) {
|
||||||
|
// BLog.LOGE("partContentType image >> ${partContentType}:: ${partId}")
|
||||||
|
image.add(partId)
|
||||||
|
}
|
||||||
|
else if(partContentType?.contains("audio") == true) {
|
||||||
|
// BLog.LOGE("partContentType audio >> ${partContentType}:: ${partId}")
|
||||||
|
audio.add(partId)
|
||||||
|
}
|
||||||
|
else if(partContentType?.contains("video") == true) {
|
||||||
|
// BLog.LOGE("partContentType video >> ${partContentType}:: ${partId}")
|
||||||
|
video.add(partId)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// BLog.LOGE("partContentType >> ${partContentType}:: ${partId}")
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (partContentType == "text/plain") {
|
||||||
|
// var textBody =
|
||||||
|
// partsCursor.getString(partsCursor.getColumnIndexOrThrow(Telephony.Mms.Part.TEXT))
|
||||||
|
//// .replace("\n\n", "\n").replace("\n", " ")
|
||||||
|
//// if (textBody.length > 60) {
|
||||||
|
//// textBody = textBody.substring(0, Math.min(textBody.length, 60)).plus(" ... ")
|
||||||
|
//// }
|
||||||
|
//// BLog.LOGE("textBody >>> ${textBody}")
|
||||||
|
// return Pair(textBody , partContentType)
|
||||||
|
// }
|
||||||
} while (partsCursor.moveToNext())
|
} while (partsCursor.moveToNext())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
returns.put("text", text)
|
||||||
|
returns.put("image", image)
|
||||||
|
returns.put("audio", audio)
|
||||||
|
returns.put("video", video)
|
||||||
|
// BLog.LOGE("returns.get(text).join => ${text.size} :: ${text.joinToString("\n")}")
|
||||||
|
return returns
|
||||||
}
|
}
|
||||||
|
|
||||||
fun convertData(cursor: Cursor?) {
|
fun convertData(cursor: Cursor?) {
|
||||||
@ -343,3 +429,39 @@ class TestQueryHelper(
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getContactName(contentResolver: ContentResolver, phoneNumber: String?): String? {
|
||||||
|
val cr = contentResolver
|
||||||
|
val uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber))
|
||||||
|
val cursor =
|
||||||
|
cr.query(uri, arrayOf(PhoneLookup.DISPLAY_NAME), null, null, null)
|
||||||
|
?: return null
|
||||||
|
var contactName: String? = null
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
contactName = cursor.getString(cursor.getColumnIndexOrThrow(PhoneLookup.DISPLAY_NAME))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursor != null && !cursor.isClosed) {
|
||||||
|
cursor.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
return contactName
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getContactId(contentResolver: ContentResolver, phoneNumber: String?): String? {
|
||||||
|
val cr = contentResolver
|
||||||
|
val uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber))
|
||||||
|
val cursor =
|
||||||
|
cr.query(uri, arrayOf(PhoneLookup._ID), null, null, null)
|
||||||
|
?: return null
|
||||||
|
var contactName: String? = null
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
contactName = cursor.getString(cursor.getColumnIndexOrThrow(PhoneLookup._ID))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursor != null && !cursor.isClosed) {
|
||||||
|
cursor.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
return contactName
|
||||||
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import android.content.Intent
|
|||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.service.notification.NotificationListenerService
|
import android.service.notification.NotificationListenerService
|
||||||
import android.service.notification.StatusBarNotification
|
import android.service.notification.StatusBarNotification
|
||||||
import android.util.Log
|
import com.google.gson.Gson
|
||||||
|
|
||||||
|
|
||||||
class NLService : NotificationListenerService() {
|
class NLService : NotificationListenerService() {
|
||||||
@ -17,7 +17,7 @@ class NLService : NotificationListenerService() {
|
|||||||
super.onCreate()
|
super.onCreate()
|
||||||
nlservicereciver = NLServiceReceiver()
|
nlservicereciver = NLServiceReceiver()
|
||||||
val filter = IntentFilter()
|
val filter = IntentFilter()
|
||||||
filter.addAction("com.kpbird.nlsexample.NOTIFICATION_LISTENER_SERVICE_EXAMPLE")
|
// filter.addAction("com.kpbird.nlsexample.NOTIFICATION_LISTENER_SERVICE_EXAMPLE")
|
||||||
registerReceiver(nlservicereciver, filter)
|
registerReceiver(nlservicereciver, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,16 +27,16 @@ class NLService : NotificationListenerService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onNotificationPosted(sbn: StatusBarNotification) {
|
override fun onNotificationPosted(sbn: StatusBarNotification) {
|
||||||
Log.i(TAG, "********** onNotificationPosted")
|
BLog.LOGE( "********** onNotificationPosted")
|
||||||
Log.i(TAG, "ID :" + sbn.id + "\t" + sbn.notification.tickerText + "\t" + sbn.packageName)
|
BLog.LOGE("ID :" + sbn.id + "\t" + sbn.notification.tickerText + "\t" + sbn.packageName)
|
||||||
val i = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
val i = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
||||||
i.putExtra("notification_event", "onNotificationPosted :" + sbn.packageName + "\n")
|
i.putExtra("notification_event", "onNotificationPosted :" + sbn.packageName + "\n")
|
||||||
sendBroadcast(i)
|
sendBroadcast(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNotificationRemoved(sbn: StatusBarNotification) {
|
override fun onNotificationRemoved(sbn: StatusBarNotification) {
|
||||||
Log.i(TAG, "********** onNOtificationRemoved")
|
BLog.LOGE(TAG, "********** onNOtificationRemoved")
|
||||||
Log.i(TAG, "ID :" + sbn.id + "\t" + sbn.notification.tickerText + "\t" + sbn.packageName)
|
BLog.LOGE( "ID :" + sbn.id + "\t" + sbn.notification.tickerText + "\t" + sbn.packageName)
|
||||||
val i = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
val i = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
||||||
i.putExtra("notification_event", "onNotificationRemoved :" + sbn.packageName + "\n")
|
i.putExtra("notification_event", "onNotificationRemoved :" + sbn.packageName + "\n")
|
||||||
|
|
||||||
@ -45,22 +45,24 @@ class NLService : NotificationListenerService() {
|
|||||||
|
|
||||||
internal inner class NLServiceReceiver : BroadcastReceiver() {
|
internal inner class NLServiceReceiver : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context?, intent: Intent) {
|
override fun onReceive(context: Context?, intent: Intent) {
|
||||||
|
BLog.LOGE("intent >>> ${intent.action}")
|
||||||
if (intent.getStringExtra("command") == "clearall") {
|
if (intent.getStringExtra("command") == "clearall") {
|
||||||
this@NLService.cancelAllNotifications()
|
this@NLService.cancelAllNotifications()
|
||||||
} else if (intent.getStringExtra("command") == "list") {
|
} else if (intent.getStringExtra("command") == "list") {
|
||||||
val i1 = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
// val i1 = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
||||||
i1.putExtra("notification_event", "=====================")
|
// i1.putExtra("notification_event", "=====================")
|
||||||
sendBroadcast(i1)
|
// sendBroadcast(i1)
|
||||||
var i = 1
|
var i = 1
|
||||||
for (sbn in this@NLService.activeNotifications) {
|
for (sbn in this@NLService.activeNotifications) {
|
||||||
val i2 = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
BLog.LOGE("sbn >>> ${sbn.packageName} , ${Gson().toJson(sbn.notification.extras.keySet())}")
|
||||||
i2.putExtra("notification_event", i.toString() + " " + sbn.packageName + "\n")
|
// val i2 = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
||||||
sendBroadcast(i2)
|
// i2.putExtra("notification_event", i.toString() + " " + sbn.packageName + "\n")
|
||||||
i++
|
// sendBroadcast(i2)
|
||||||
|
// i++
|
||||||
}
|
}
|
||||||
val i3 = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
// val i3 = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
||||||
i3.putExtra("notification_event", "===== Notification List ====")
|
// i3.putExtra("notification_event", "===== Notification List ====")
|
||||||
sendBroadcast(i3)
|
// sendBroadcast(i3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,6 +5,26 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
<WebView
|
||||||
|
android:layout_margin="30dp"
|
||||||
|
android:id="@+id/searcher_01"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:alpha="0.01"
|
||||||
|
android:layout_height="0dp"/>
|
||||||
|
|
||||||
|
|
||||||
|
<View
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:background="#11000000"
|
||||||
|
android:layout_height="0dp"/>
|
||||||
|
|
||||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||||
android:id="@+id/batteryProgress"
|
android:id="@+id/batteryProgress"
|
||||||
@ -76,6 +96,7 @@
|
|||||||
android:layout_height="40dp"
|
android:layout_height="40dp"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/batteryProgress"
|
app:layout_constraintTop_toBottomOf="@+id/batteryProgress"
|
||||||
>
|
>
|
||||||
|
|
||||||
<RadioButton
|
<RadioButton
|
||||||
android:id="@+id/missedCalls"
|
android:id="@+id/missedCalls"
|
||||||
android:button="@null"
|
android:button="@null"
|
||||||
@ -85,7 +106,9 @@
|
|||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
<RadioButton
|
<RadioButton
|
||||||
|
android:id="@+id/otherCheck"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:button="@null"
|
android:button="@null"
|
||||||
android:text="투두"
|
android:text="투두"
|
||||||
@ -93,6 +116,7 @@
|
|||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
<RadioButton
|
<RadioButton
|
||||||
android:id="@+id/recentSms"
|
android:id="@+id/recentSms"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user