Android Question Create a broadcast receiver when app loads using inline java

Discussion in 'Android Questions' started by Jmu5667, Apr 16, 2015.

  1. Jmu5667

    Jmu5667 Well-Known Member Licensed User

    Hi All

    I have a app that uses a few intent filters. They are currently setup in manifest file. Example

    Code:
    ' // Power Intents
    AddReceiverText(svc_power, <intent-filter> <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/></intent-filter>)
    AddReceiverText(svc_power, <
    intent-filter> <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/></intent-filter>)
    What I want to do is register these intent filters when the app loads. I came across this http://hmkcode.com/android-sending-receiving-custom-broadcasts/ , go to point 4.

    Code:
    @Override
      protected void onResume() {
      super.onResume();
      registerReceiver(new MyReceiver(),
      new IntentFilter(
    "com.hmkcode.android.USER_ACTION"));

      
    }

    I do not want to use any existing libs. the app is quite complicated and due to customer requirements and our Bluetooth device
    communicating with the app, www.ursosbutton.com, I need the manage the intent filter registration from within the app.

    All help would be much appreciated, @Erel, @thedesolatesoul

    Kind Regards

    John.
     
  2. Erel

    Erel Administrator Staff Member Licensed User

  3. lemonisdead

    lemonisdead Well-Known Member Licensed User

    Hello @Erel
    If I well understand, John tries to remove the manifest's intent filters and create them on fly when the app starts.
     
    Johan Schoeman and Jmu5667 like this.
  4. thedesolatesoul

    thedesolatesoul Expert Licensed User

    I dont think its that easy (atleast from your link, there may be other ways).
    You missed step 2 where you need to extend BroadcastReceiver that would require a java library.
    I cant think of how to do it without a library (right now).
     
    Johan Schoeman and NJDude like this.
  5. Jmu5667

    Jmu5667 Well-Known Member Licensed User

    Hi Erel,

    Lemonisdead is spot on. That's what I want to do. I already have intents filters set up and that are getting fired before I need them, I know this may seem strange to you but this real world stuff and it the way the app as evolved.

    Most of our apps now are very different to when they were first created. We have a couple of thousand apps out there and the biggest problem users were having was the drain on the battery with the use of GPS/Bluetooth/Wifi and the phone not being able to achieve deep sleep. We have overcome most of these issues but need more control of the intent filter handling.

    Hope this makes sense to you.

    regards

    John.
     
  6. Jmu5667

    Jmu5667 Well-Known Member Licensed User

    That was just one example I found. I have seen other java code that does this, so I don't think it's impossible, particularly with the advent of inline java in b4x :)
     
  7. warwound

    warwound Expert Licensed User

    I've been working on disabling activities today, using the PackageManager class:
    http://developer.android.com/refere...tEnabledSetting(android.content.ComponentName, int, int)

    In the manifest all components - activities, services, broadcast receivers etc - are enabled by default, they can also explicitly be set to disabled.
    The PackageManager allows you to change the 'enabled state' of any component in your application, overriding the state specified in the manifest.

    So would a solution be to disable your broadcast receivers when they are not required and re-enable them when required?
    A disabled broadcast receiver will receive no broadcasts.
     
    DonManfred likes this.
  8. Erel

    Erel Administrator Staff Member Licensed User

    thedesolatesoul likes this.
  9. Jmu5667

    Jmu5667 Well-Known Member Licensed User

    @Erel My understanding of the broadcast receiver is that all intent filters set are received back into the service/module that the broadcast receiver is being used from. I was using it but dropped it in favor of using the manifest file to directly call the necessary services associated with the intent filters. This means that I do not need code running to handle the intents.

    @warwound I dont this this would help when the app is loading - eg. I use the following :

    Code:
    ' // Power Intents
    AddReceiverText(svc_power, <intent-filter> <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/></intent-filter>)
    AddReceiverText(svc_power, <
    intent-filter> <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/></intent-filter>)


    ' // BlueTooth intents
    AddReceiverText(svc_bt_state, <intent-filter> <action android:name="android.bluetooth.adapter.action.STATE_CHANGED"/></intent-filter>)
    AddReceiverText(svc_bt_disconnect, <
    intent-filter> <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED"/></intent-filter>)
    AddReceiverText(svc_bt_connected, <
    intent-filter> <action android:name="android.bluetooth.device.action.ACL_CONNECTED"/></intent-filter>)
    I have a primary service that has the #StartAtBoot: True set. Now when the device boots up and turns of the Bluetooth, the Bluetooth intents get fired and the Bluetooth services get started. On some devices the svc_power service will get started before the Bluetooth services.

    I know this may seem a bit mad to anyone who is reading this, but because of the nature of the app this intents are necessary.

    Regards

    John.
     
  10. warwound

    warwound Expert Licensed User

    So add them to the manifest disabled by default.
    A little inline java can then be used to then enable them and subsequently disable them as required.
     
    Jmu5667 likes this.
  11. Jmu5667

    Jmu5667 Well-Known Member Licensed User

    If you have time can you show me how to do this please :rolleyes:
     
  12. warwound

    warwound Expert Licensed User

    Take a look at the attached example.

    In the manifest editor i add a BroadcastReceiver for the action android.intent.action.ACTION_POWER_CONNECTED.
    The BroadcastReceiver is disabled by default in the manifest:

    Code:
    AddReceiverText(svc_power, <intent-filter><action android:name="android.intent.action.ACTION_POWER_CONNECTED"/></intent-filter>)
    SetReceiverAttribute(svc_power, android:enabled, 
    "false")
    svc_power logs the action of the starting intent and shows a toast if the starting intent action is android.intent.action.ACTION_POWER_CONNECTED:

    Code:
    Sub Process_Globals

    End Sub

    Sub Service_Create

    End Sub

    Sub Service_Start (StartingIntent As Intent)
        
    Dim Action As String=StartingIntent.Action
        
        
    Select Action
            
    Case "android.intent.action.ACTION_POWER_CONNECTED"
                
    Log("action=android.intent.action.ACTION_POWER_CONNECTED")
                
    ToastMessageShow("svc_power started, action=android.intent.action.ACTION_POWER_CONNECTED"False)
        
    End Select
        
        
    StopService("")
    End Sub

    Sub Service_Destroy

    End Sub
    The Main activity code is:

    Code:
    Sub Process_Globals
        
    '    see http://developer.android.com/reference/android/content/pm/PackageManager.html
        
        
    '    This component is in its default enabled state (as specified in its manifest). 
        Private ENABLED_STATE_DEFAULT As Int=0
        
        
    '    This component has been explicitly disabled, regardless of what it has specified in its manifest. 
        Private ENABLED_STATE_DISABLED As Int=2
        
        
    '    This component has been explicitly enabled, regardless of what it has specified in its manifest. 
        Private ENABLED_STATE_ENABLED As Int=1
        
        
    Private BROADCAST_RECEIVER_FULLY_QUALIFIED_NAME As String="b4a.example.svc_power$svc_power_BR"
    End Sub

    Sub Globals
        
    Private JavaObject1 As JavaObject
        
    Private Label1 As Label
        
    Private ToggleButton1 As ToggleButton
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        JavaObject1.InitializeContext
        
    Activity.LoadLayout("Main")
    End Sub

    Sub Activity_Resume
        UpdateUI
    End Sub

    Sub Activity_Pause (UserClosed As Boolean)

    End Sub

    Sub ToggleButton1_CheckedChange(Checked As Boolean)
        
    Dim EnabledState As Int
        
        
    If Checked Then
            EnabledState=ENABLED_STATE_ENABLED
        
    Else
            EnabledState=ENABLED_STATE_DISABLED
            
    '    as the broadcast receiver is disabled by default in the manifest, you could instead set the default value instead of disabled value:
            '    EnabledState=ENABLED_STATE_DEFAULT
        End If
        JavaObject1.RunMethod(
    "setComponentEnabledSetting"Array As Object(BROADCAST_RECEIVER_FULLY_QUALIFIED_NAME, EnabledState))
        
        UpdateUI
    End Sub

    Sub UpdateUI
        
    Dim EnabledState As Int=JavaObject1.RunMethod("getComponentEnabledSetting"Array As Object(BROADCAST_RECEIVER_FULLY_QUALIFIED_NAME))
        
        
    Select EnabledState
            
    Case ENABLED_STATE_DEFAULT
                
    '    svc_power is disabled by default (in the manifest)
                Label1.Text="ENABLED_STATE_DEFAULT"
                ToggleButton1.Checked=
    False
            
    Case ENABLED_STATE_DISABLED
                Label1.Text=
    "ENABLED_STATE_DISABLED"
                ToggleButton1.Checked=
    False
            
    Case ENABLED_STATE_ENABLED
                Label1.Text=
    "ENABLED_STATE_ENABLED"
                ToggleButton1.Checked=
    True
            
    Case Else
                Label1.Text=
    "EnabledState="&EnabledState&CRLF&"This state not anticipated..."
                ToggleButton1.Enabled=
    False
        
    End Select
    End Sub

    #If JAVA

    import android.content.ComponentName;
    import android.content.pm.PackageManager;

    public int getComponentEnabledSetting(String fullyQualifiedClassName){
        ComponentName componentName = new ComponentName(this, fullyQualifiedClassName);
        return this.getPackageManager().getComponentEnabledSetting(componentName);
    }

    public void setComponentEnabledSetting(String fullyQualifiedClassName, int enabledState){
        ComponentName componentName = new ComponentName(this, fullyQualifiedClassName);
        this.getPackageManager().setComponentEnabledSetting(componentName, enabledState, PackageManager.DONT_KILL_APP);
    }

    #End if
    Compile and install the example.
    You'll see a Label display the text "ENABLED_STATE_DEFAULT", a ToggleButton will be unchecked.
    The BroadcastReceiver is in it's default state - it is not enabled.
    You can use the ToggleButton to change the BroadcastReceiver's state from 'default' to either 'enabled' or 'disabled'.

    Connect your device to power and you'll see a Toast message if the BroadcastReceiver is enabled, otherwise you'll see nothing.

    Martin.
     

    Attached Files:

    DavideV, walterf25, Jmu5667 and 3 others like this.
  13. Jmu5667

    Jmu5667 Well-Known Member Licensed User

    Awesome, I will try this tomorrow, thanks mate ;)
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice