Using this manual http://www.techotopia.com/index.php/Kotlin_Android_Broadcast_Intents_and_Broadcast_Receivers#.EF.BB.BFSummary I have implemented BroadcastReceiver in Kotlin so I expect that after rebooting application will start but it does not.
Please, help. Thank you!
BroadcastReceiver
class BroadcastReceiverOnBootComplete : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action.equals(Intent.ACTION_BOOT_COMPLETED, ignoreCase = true)) {
val message = "Broadcast intent detected " + intent.action
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
}
}
}
Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.simplemobiletools.applauncher"
android:installLocation="internalOnly">
<uses-permission
android:name="android.permission.USE_FINGERPRINT"
tools:node="remove"/>
<permission
android:name="com.simplemobiletools.applauncher.permission.INSTALL_SHORTCUT"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="dangerous"
android:label="#string/permlab_install_shortcut"
android:description="#string/permdesc_install_shortcut" />
<permission
android:name="com.simplemobiletools.applauncher.permission.READ_SETTINGS"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="normal"
android:label="#string/permlab_read_settings"
android:description="#string/permdesc_read_settings"/>
<permission
android:name="com.simplemobiletools.applauncher.permission.WRITE_SETTINGS"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="signatureOrSystem"
android:label="#string/permlab_write_settings"
android:description="#string/permdesc_write_settings"/>
<permission
android:name="com.simplemobiletools.applauncher.permission.RECEIVE_LAUNCH_BROADCASTS"
android:protectionLevel="signature"
/>
<permission
android:name="com.simplemobiletools.applauncher.permission.RECEIVE_FIRST_LOAD_BROADCAST"
android:protectionLevel="signatureOrSystem" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.BIND_APPWIDGET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BROADCAST_STICKY"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS" />
<uses-permission android:name="com.android.launcher3.permission.READ_SETTINGS" />
<uses-permission android:name="com.android.launcher3.permission.WRITE_SETTINGS" />
<uses-permission android:name="com.android.launcher3.permission.RECEIVE_LAUNCH_BROADCASTS" />
<uses-permission android:name="com.android.launcher3.permission.RECEIVE_FIRST_LOAD_BROADCAST" />
<application
android:name=".App"
android:hardwareAccelerated="true"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_launcher_name"
android:roundIcon="#mipmap/ic_launcher"
android:theme="#style/AppTheme"
android:supportsRtl="true"
android:restoreAnyVersion="true">
<receiver android:name=".activities.BroadcastReceiverOnBootComplete">
<intent-filter>
<action android:name="com.simplemobiletools.applauncher.sendbroadcast" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>
</receiver>
<activity
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="nosensor"
android:resumeWhilePausing="true"
android:taskAffinity=""
android:enabled="true"
android:name=".activities.SplashActivity"
android:theme="#style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
</intent-filter>
</activity>
<activity android:name=".activities.MainActivity"/>
<activity
android:name=".activities.SettingsActivity"
android:label="#string/settings"
android:parentActivityName=".activities.MainActivity"/>
<activity
android:name="com.simplemobiletools.commons.activities.AboutActivity"
android:label="#string/about"
android:parentActivityName=".activities.MainActivity"/>
<activity
android:name="com.simplemobiletools.commons.activities.LicenseActivity"
android:label="#string/third_party_licences"
android:parentActivityName="com.simplemobiletools.commons.activities.AboutActivity"/>
<activity
android:name="com.simplemobiletools.commons.activities.CustomizationActivity"
android:label="#string/customize_colors"
android:parentActivityName=".activities.SettingsActivity"/>
</application>
</manifest>
MainActivity with BroadcastReceiver
class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
private var launchers = ArrayList<AppLauncher>()
private var mStoredPrimaryColor = 0
private var mStoredTextColor = 0
private var mStoredUseEnglish = false
private var receiver: BroadcastReceiver? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
appLaunched()
setupLaunchers()
checkWhatsNewDialog()
storeStateVariables()
configureReceiver()
fab.setOnClickListener {
AddAppLauncherDialog(this, launchers) {
setupLaunchers()
}
}
}
override fun onDestroy() {
// super.onDestroy()
unregisterReceiver(receiver)
}
override fun onResume() {
super.onResume()
if (mStoredUseEnglish != config.useEnglish) {
restartActivity()
return
}
if (mStoredTextColor != config.textColor) {
getGridAdapter()?.updateTextColor(config.textColor)
}
if (mStoredPrimaryColor != config.primaryColor) {
getGridAdapter()?.updatePrimaryColor(config.primaryColor)
}
updateTextColors(coordinator_layout)
}
override fun onPause() {
super.onPause()
storeStateVariables()
}
private fun configureReceiver() {
val filter = IntentFilter()
filter.addAction("com.simplemobiletools.applauncher.sendbroadcast")
filter.addAction("android.intent.action.ACTION_POWER_DISCONNECTED")
filter.addAction("android.intent.action.BOOT_COMPLETED")
receiver = BroadcastReceiverOnBootComplete()
registerReceiver(receiver, filter)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.settings -> launchSettings()
R.id.about -> launchAbout()
else -> return super.onOptionsItemSelected(item)
}
return true
}
private fun launchSettings() {
startActivity(Intent(applicationContext, SettingsActivity::class.java))
}
private fun launchAbout() {
startAboutActivity(R.string.app_name, LICENSE_KOTLIN or LICENSE_MULTISELECT or LICENSE_STETHO, BuildConfig.VERSION_NAME)
}
private fun getGridAdapter() = launchers_grid.adapter as? LaunchersAdapter
private fun setupLaunchers() {
launchers = dbHelper.getLaunchers()
checkInvalidApps()
val adapter = LaunchersAdapter(this, launchers, this, launchers_grid) {
val launchIntent = packageManager.getLaunchIntentForPackage((it as AppLauncher).packageName)
if (launchIntent != null) {
startActivity(launchIntent)
finish()
} else {
val url = "https://play.google.com/store/apps/details?id=${it.packageName}"
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
startActivity(intent)
}
}
adapter.setupDragListener(true)
launchers_grid.adapter = adapter
}
private fun checkInvalidApps() {
val invalidIds = ArrayList<String>()
for ((id, name, packageName) in launchers) {
val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
if (launchIntent == null && !packageName.isAPredefinedApp()) {
invalidIds.add(id.toString())
}
}
dbHelper.deleteLaunchers(invalidIds)
launchers = launchers.filter { !invalidIds.contains(it.id.toString()) } as ArrayList<AppLauncher>
}
private fun storeStateVariables() {
config.apply {
mStoredPrimaryColor = primaryColor
mStoredTextColor = textColor
mStoredUseEnglish = useEnglish
}
}
override fun refreshItems() {
setupLaunchers()
}
private fun checkWhatsNewDialog() {
arrayListOf<Release>().apply {
add(Release(7, R.string.release_7))
checkWhatsNew(this, BuildConfig.VERSION_CODE)
}
}
}
As I could discoverd the prob;em was missing settings here
android:enabled="true"
android:stopWithTask="false"
So it should be like
<receiver android:name=".activities.BroadcastReceiverOnBootComplete" android:enabled="true"
android:stopWithTask="false" >
<intent-filter>
<action android:name="com.simplemobiletools.applauncher.sendbroadcast" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>
</receiver>
Related
I am using broadcast receiver to scan for available devices. it was working at first, but then something happened and it started to find too many devices(there are only 3 bt device in room but it finds more than 10 sometimes) and only find their mac addresses(bluetoothDevice.name comes as null). I can't figure out why it's behaving like this
This is my MainActivity:
class MainActivity : AppCompatActivity() {
private var bluetoothAdapter: BluetoothAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val receiver = MyBroadcast()
val bluetoothManager: BluetoothManager = getSystemService(BluetoothManager::class.java)
bluetoothAdapter = bluetoothManager.adapter
// request permission
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.BLUETOOTH_CONNECT
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_ADMIN
), 1
)
}
val button = findViewById<Button>(R.id.button_b)
button.setOnClickListener {
Log.i("TAG,", "clicked")
bluetoothAdapter?.startDiscovery()
IntentFilter(BluetoothDevice.ACTION_FOUND).also {
registerReceiver(receiver, it)
}
}
}
}
This is the broadcast receiver:
class MyBroadcast:BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when(intent?.action) {
BluetoothDevice.ACTION_FOUND -> {
// Discovery has found a device. Get the BluetoothDevice
// object and its info from the Intent.
val device: BluetoothDevice =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)!!
Log.i("here", device.toString())
}
}
}
}
And this is the manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/Theme.Broadcast"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
It turns out there a lot of unnamed Bluetooth devices around which are nameless and you can't connect them either. So I had to check with if(device.name!= null && device.address != null) to get the names devices
I'm working on an android application and i need alarm manager to fire events at certain times , the code works fine and the notification fires in time but only in one scenario is not working when the screen is off , the device is not waking up and wait for notification to fire up , actually this works in emulators ( i guess because there is no such power saving mode like in some physical devices ) , I've looked up most topics and could not find any solution , any help would be appreciated Thank you .
Firing Alarm Manager
fun fireAlarmManager(context: Context , time : MutableList<Long>){
val intent = Intent(context, AlarmReceiver::class.java)
for (i in 0 until time.size){
if(time[i] > deviceTimeInMillis()){
list.add(time[i])
val pendingIntent = PendingIntent.getBroadcast(context,time[i].toInt(),intent,PendingIntent.FLAG_IMMUTABLE)
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,time[i],pendingIntent)
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP,time[i],pendingIntent)
}
}
}
setDataFromSharedPreferences(list)
}
Broadcast receiver
class AlarmReceiver : BroadcastReceiver() {
override fun onReceive(context : Context?, intent : Intent?) {
wakeUp(context)
val serviceIntent = Intent(context,OnClearFromRecentServices::class.java)
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
context!!.startForegroundService(serviceIntent)
} else {
context!!.startService(serviceIntent)
}
}
private fun wakeUp(context: Context?) {
val pm = context!!.getSystemService(Context.POWER_SERVICE) as PowerManager
val wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK or PowerManager.FULL_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP, "app::tag")
wakeLock.acquire(60000)
val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val keyguardLock = keyguardManager.newKeyguardLock("TAG")
keyguardLock.disableKeyguard()
}
}
Alarm Service
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
fireNotification(this)
return START_STICKY
}
Manifest File
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.kotlin.quranapp">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:name=".koin.BaseApplication"
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:largeHeap="true"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.QuranApp"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="false"
android:launchMode="singleInstance"
android:screenOrientation="portrait" />
<activity
android:name=".views.SplashActivity"
android:exported="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".alarm.AlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
<receiver
android:name=".alarm.PlayerReceiver"
android:exported="false" />
<service android:name=".alarm.services.OnClearFromRecentServices" />
</application>
</manifest>
I am trying to start my service when the user wants the service to start on boot. So I have a checkbox preference on my settings fragment to control it. When the box is checked and the user starts the service, the StartOnBootBroadcast BroadcastReceiver will be registered and it will start the service after boot is completed. By default the BroadcastReceiver will not be registered unless the user wants it. But the problem is If I install the app and restarts my device, the broadcast receiver starts the service (BUT I NEVER REGISTERED IT). I've checked the condition with debugger and the conditions never met for starting the receiver.
Broadcast receiver:
class StartOnBootBroadcast : BroadcastReceiver() {
companion object {
private var instance: StartOnBootBroadcast? = null
fun getinstance(): StartOnBootBroadcast {
if (instance == null) {
instance = StartOnBootBroadcast()
}
return instance as StartOnBootBroadcast
}
}
override fun onReceive(context: Context?, intent: Intent?) {
Log.d("BOOTCAST", "onReceive: FIRED")
val serviceIntent = Intent(context, MyService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context!!.startForegroundService(serviceIntent)
} else {
context!!.startService(serviceIntent)
}
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sourav.bettere">
<application
android:name=".App"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".activities.MainActivity"
android:configChanges="orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".service.ChargeLoggerService" />
<receiver android:name=".broadcasts.BatteryBroadcast">
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED" />
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
<receiver android:name=".broadcasts.ChargingBroadcast">
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED" />
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
<receiver android:name=".broadcasts.StartOnBootBroadcast">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<meta-data
android:name="preloaded_fonts"
android:resource="#array/preloaded_fonts" />
</application>
</manifest>
Methods for registering / unregistering the BroadcastReciever:
prefViewmodel.getBootStatus.observe(viewLifecycleOwner, Observer { value ->
onBoot = value
if (Utilities.getInstance(mContext).isMyServiceRunning(ChargeLoggerService::class.java)){
startOnBoot(onBoot)
}
})
////unrelated codes
switch.setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
startService()
Utilities.getInstance(mContext)
.writeToPref(
Constants.PREF_TYPE_BOOL,
Constants.PREF_LOGGER_ACTIVE,
valueBool = true
)
} else {
stopService()
Utilities.getInstance(mContext)
.writeToPref(
Constants.PREF_TYPE_BOOL,
Constants.PREF_LOGGER_ACTIVE,
valueBool = false
)
}
startOnBoot(onBoot)
}
private fun startOnBoot(value: Boolean){
when(value){
true -> Utilities.getInstance(mContext).loadBroadcastReceiver(startOnBoot, IntentFilter(Intent.ACTION_BOOT_COMPLETED))
false -> {
try {
requireContext().unregisterReceiver(startOnBoot)
}catch (e:Exception){
e.printStackTrace()
}}
}
Log.d(TAG, "startOnBoot: $value")
}
I have an app that, when is first installed a splash screen appears and then a intro with 3 fragments appears and explains how the app works. However once the user walked through that "intro" only the splash screen appears. How should I do that? I belive this has to do my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.pfinal">
<!-- Permissoes para o acesso a camera -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- Permissoes para o acesso ao GPS -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_fire_round"
android:label="AppFogos"
android:roundIcon="#mipmap/ic_fire_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".Intro">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- The below is for the splash screen and we need no action bar and the default theme -->
<activity
android:name=".SplashScreen"
android:theme="#style/AppTheme.NoActionBar">
<!-- <intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>-->
</activity>
<activity android:name=".AppFogos" />
<activity android:name=".HomePage">
<!-- <intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>-->
</activity>
</application>
Intro is the activity with the walktrough and SplashScreen is the activity with the splash screen.
Right now, only the Intro appears.
Here is the code for the "Intro":
val fragment1 = SliderFragment()
val fragment2 = SliderFragment()
val fragment3 = SliderFragment()
lateinit var adapter : myPagerAdapter
lateinit var activity: Activity
lateinit var preference : SharedPreferences
val pref_show_intro = "Intro"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_intro)
activity = this
preference = getSharedPreferences("~PFinal", Context.MODE_PRIVATE)
if(!preference.getBoolean(pref_show_intro,true)){
startActivity(Intent(activity,SplashScreen::class.java))
finish()
}
fragment1.setTitle("welcome")
fragment2.setTitle("fogos")
fragment3.setTitle("o que utilizamos")
adapter = myPagerAdapter(supportFragmentManager)
adapter.list.add(fragment1)
adapter.list.add(fragment2)
adapter.list.add(fragment3)
view_pager.adapter = adapter
next.setOnClickListener {
view_pager.currentItem++
}
skip.setOnClickListener { goToHomePage() }
view_pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener{
override fun onPageScrollStateChanged(state: Int) {
}
override fun onPageScrolled(
position: Int,
positionOffset: Float,
positionOffsetPixels: Int
) {
}
override fun onPageSelected(position: Int) {
if(position == adapter.list.size-1)
{
//lastpage
next.text="DONE"
next.setOnClickListener {
goToHomePage()
}
}else{
next.text="NEXT"
next.setOnClickListener {
view_pager.currentItem++
}
}
when(view_pager.currentItem)
{
0->{
indicator1.setTextColor(Color.BLACK)
indicator2.setTextColor(Color.GRAY)
indicator3.setTextColor(Color.GRAY)
}
1->{
indicator1.setTextColor(Color.GRAY)
indicator2.setTextColor(Color.BLACK)
indicator3.setTextColor(Color.GRAY)
}
2->{
indicator1.setTextColor(Color.GRAY)
indicator2.setTextColor(Color.GRAY)
indicator3.setTextColor(Color.BLACK)
}
}
}
})
}
fun goToHomePage(){
startActivity(Intent(activity,HomePage::class.java))
finish()
val editor = preference.edit()
editor.putBoolean(pref_show_intro,false)
editor.apply()
}
class myPagerAdapter(manager : FragmentManager): FragmentPagerAdapter(manager){
val list : MutableList<Fragment> = ArrayList()
override fun getItem(position: Int): Fragment {
return list[position]
}
override fun getCount(): Int {
return list.size
}
}
I have a Jobservice that runs periodically every time.My activity only is to job start for running on the app.i can stop or destroy the app manually using UI and the JobService not running ,the jobservice why stop i don't know.i attached the my manifistfile and Jobdispatcher what i do something else?
dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(getActivity()));
Bundle myExtrasBundle = new Bundle();
myExtrasBundle.putString("some_key", "some_value");
if (myJob == null) {
myJob = dispatcher.newJobBuilder()
// the JobService that will be called
.setService(ReminderService.class)
// uniquely identifies the job
.setTag("my-unique-tag")
// one-off job
.setRecurring(true)
// don't persist past a device reboot
.setLifetime(Lifetime.FOREVER)
// start between 0 and 60 seconds from now
.setTrigger(Trigger.executionWindow(0, 60))
// don't overwrite an existing job with the same tag
.setReplaceCurrent(true)
// retry with exponential backoff
.setRetryStrategy(RetryStrategy.DEFAULT_LINEAR)
// constraints that need to be satisfied for the job to run
.setConstraints(
// only run on an unmetered network
Constraint.ON_ANY_NETWORK
)
.setExtras(myExtrasBundle)
.build();
dispatcher.mustSchedule(myJob);
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.vvsugar">
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
<permission
android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<application
android:name=".AppController"
android:hardwareAccelerated="true"
android:icon="#mipmap/ic_launcher"
android:installLocation="internalOnly"
android:label="#string/app_name"
android:largeHeap="true"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
tools:replace="android:icon,android:theme">
<meta-data
android:name="DATABASE"
android:value="vvsugae.db" />
<meta-data
android:name="VERSION"
android:value="1.45" />
<meta-data
android:name="QUERY_LOG"
android:value="true" />
<meta-data
android:name="DOMAIN_PACKAGE_NAME"
android:value="com.vvsugar.dbview" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
<activity
android:name=".activity.LoginActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.vvsugar.activity.ReminderService"
android:enabled="true"
android:exported="false"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="android.intent.action.REBOOT"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
<activity android:name=".activity.DashBoardActivity" />
<activity android:name=".base.BaseActivity" />
<activity
android:name=".activity.MainActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:windowSoftInputMode="stateAlwaysHidden|adjustResize" />
<activity android:name=".uicomponent.imagepicker.activities.AlbumSelectActivity" />
<activity android:name=".uicomponent.imagepicker.activities.HelperActivity" />
<activity android:name=".uicomponent.imagepicker.activities.ImageSelectActivity" />
<activity
android:name=".adapters.PaymentsAdapter"
android:label="#string/title_activity_payments_adapter"
android:theme="#style/AppTheme.NoActionBar" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyBwdtoapVVM-Yg4VIKNuFaH8f3GqN7pd98" />
<!--
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"/>
-->
<meta-data
android:name="io.fabric.ApiKey"
android:value="eab11ffa174990145b21fef7ed3fd2ddcf6ca4c8" />
<activity android:name=".activity.ActiveWindow"></activity>
</application>
</manifest>
On your Job service return true on onStartJob
override fun onStartJob(jobParameters: JobParameters): Boolean {
return true
}
also override onStartCommand like this
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
return Service.START_STICKY
}
and for menifest write code like this
<service
android:name=".JobServiceEx"
android:permission="android.permission.BIND_JOB_SERVICE"/>
Your service will look like this for Kolin code
class JobServiceEx : JobService() {
var startTime: Long = 0
val workHandler = Handler()
var workRunnable: Runnable? = null
// Called by the Android system when it's time to run the job
override fun onStartJob(jobParameters: JobParameters): Boolean {
Log.d(TAG, "Job started!")
workRunnable = object : Runnable {
override fun run() {
val millis = System.currentTimeMillis() - startTime
var seconds = (millis / 1000).toInt()
val minutes = seconds / 60
seconds %= 60
var curTime = "$seconds"
Toast.makeText(baseContext, "Current Sec : $curTime", Toast.LENGTH_SHORT).show()
Log.e("TAG", "Current Time : $curTime")
workHandler.postDelayed(this, 1000)
}
}
workHandler.post(workRunnable)
return true
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
return Service.START_STICKY
}
// Called if the job was cancelled before being finished
override fun onStopJob(jobParameters: JobParameters): Boolean {
workHandler.removeCallbacks(workRunnable);
return false
}
companion object {
private val TAG = JobServiceEx::class.java.simpleName
}
}
and start and stop service like this
R.id.buttonStart -> {
/**
* start job service to test
*/
var componentName = ComponentName(this, JobServiceEx::class.java)
var jobInfo: JobInfo? = null
jobInfo = JobInfo.Builder(JOB_ID, componentName)
.setRequiresCharging(true)
.setMinimumLatency(1)
.setOverrideDeadline(1)
.build()
var jobScheduler = getSystemService(JOB_SCHEDULER_SERVICE) as JobScheduler
var resultCode = jobScheduler.schedule(jobInfo);
if (resultCode == JobScheduler.RESULT_SUCCESS) {
Log.e("TAG", "Job scheduled!");
} else {
Log.e("TAG", "Job not scheduled");
}
}
R.id.buttonStop -> {
/**
* stop job service to test
*/
val jobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
jobScheduler.cancel(JOB_ID)
}