Not able to run when injecting dependencies with Hilt into Android Classes - kotlin

I'm in the process of making an application using Hilt. But my question is, am I only able to run my app through AndroidManifest.xml? I'd like to run it through another class, but it keeps giving me a blank page.
My Classes:
Application class using #HiltAndroidApp
#HiltAndroidApp
class ExampleApplication : Application()
Activity class using #AndroidEntryPoint
#AndroidEntryPoint
class ExampleActivity : ComponentActivity() {
#RequiresApi(Build.VERSION_CODES.N)
override fun onCreate(instance: Bundle?) {
super.onCreate(instance)
setContent {
AppTheme {
Surface() {
......
Manifest.xml
(This is the only way I can run the class, ExampleActivity).
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".ui.ExampleApplication"
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:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.App"
tools:targetApi="31">
<activity
android:name=".ExampleActivity"
android:exported="true"
android:label="#string/app_name"
android:theme="#style/Theme.App">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
</application>
</manifest>
So, I've tried calling my application from another class, but I can't call ExampleActivity.kt alone, so I tried calling two classes, but it keeps giving me a blank page.
Here's what I've tried:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AppTheme {
ExampleApplication()
ExampleActivity()
}
}
}
}
It gives a blank screen.
I will create another class and make it my start class, where I will then call ExampleApplication and ExampleActivity.
How am I supposed to call two classes using Hilt dependencies from another class?
Of course, I have updated the manifest.xml so that it says .MainActivity.

First of all, why do you need Hilt? What are you trying to Inject and where?
ExampleApplication() is just a place where you configure app-wide settings, you are never supposed to call it from somewhere else, so you don't need that line.
Furthermore, Which activity are you trying to start? MainActivity or ExampleActivity()? Calling ExampleActivity within MainActivity won't have any effect.
SetContent { ... } is the place where you create the UI.
If you want to open another activity from MainActivity then you need to implement navigation or use Intents.

Related

How to add an service accessibility Android that registre Alert Dialog

I would Like to listen to Alert Dialog, and i have adding an exemple but it dont work, and i cant follow the starting and capturing the event like Key Up ..etc by using Log.d.
I confirm that the Accessibility Service has Enabled, but i would like to to assure that is executing
here is my code
public class MyService extends AccessibilityService {
public static String TAG = "USD";
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.i(TAG, "onAccessibilityEvent: gettting");
String text = event.getText().toString();
if (event.getClassName().equals("android.app.AlertDialog")) {
Log.i(TAG, " Getting USSD"+text);
Toast.makeText(this, text, Toast.LENGTH_LONG).show();
}
}
and the Manifest code
<service android:name=".MyService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:label=""
android:exported="false">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/accessibility_service_config" />
</service>
and the config XML
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:packageNames="com.android.phone"
android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged"
android:accessibilityFlags="flagDefault"
android:accessibilityFeedbackType="feedbackGeneric"
android:notificationTimeout="0"
android:canRetrieveWindowContent="true"
android:canRequestFilterKeyEvents="true"
android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity"
/>

Kotlin - Navigation Components - Navigation action/destination cannot be found from the current destination

ISSUE
java.lang.IllegalArgumentException: Navigation action/destination xxxx/action_scanFragment_to_addVehicleFragment cannot be found from the current destination xxxx/addVehicleFragment
The error occurs when I do
findNavController().navigate(R.id.action_scanFragment_to_addVehicleFragment)
in scanFragment. Which means that current destination is addVehicleFragment, but it should be scanFragment.
I am clueless on how to approach this. See my earlier question for some troubleshooting and what really goes on in scanFragment:
Kotlin - fragment lifecycle navigation issues; why does child fragment become current destination?
I suspect my navigation setup is wrong, but I can't find the solution anywhere.
I'm posting my entire navigation implementation/code below.
My nav_graph design:
My nav_graph XML:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/nav_graph"
app:startDestination="#id/mainFragment">
<fragment
android:id="#+id/scanFragment"
android:name="xxxx.ui.scan.ScanFragment"
android:label="#string/tab_bar_first_item_title"
tools:layout="#layout/fragment_scan" >
<action
android:id="#+id/action_scanFragment_to_addVehicleFragment"
app:destination="#id/addVehicleFragment"
app:enterAnim="#anim/from_left"
app:exitAnim="#anim/to_left" />
</fragment>
<fragment
android:id="#+id/addVehicleFragment"
android:name="xxxx.ui.scan.AddVehicleFragment"
android:label="#string/add_vehicle_fragment_title_string"
tools:layout="#layout/fragment_add_vehicle">
<action
android:id="#+id/action_addVehicleFragment_to_scanFragment"
app:destination="#id/scanFragment" />
</fragment>
<fragment
android:id="#+id/mainFragment"
android:name="xxxx.ui.main.MainFragment"
android:label="#string/tab_bar_second_item_title"
tools:layout="#layout/fragment_main" />
<fragment
android:id="#+id/profileFragment"
android:name="xxxx.ui.profile.ProfileFragment"
android:label="#string/tab_bar_third_item_title"
tools:layout="#layout/fragment_profile">
<action
android:id="#+id/actionMyVehicles"
app:destination="#id/myVehiclesFragment"
app:enterAnim="#anim/from_right"
app:exitAnim="#anim/to_left" />
<action
android:id="#+id/actionMyRooms"
app:destination="#+id/myRoomsFragment"
app:enterAnim="#anim/from_right"
app:exitAnim="#anim/to_left" />
</fragment>
<fragment
android:id="#+id/myVehiclesFragment"
android:name="xxxx.ui.profile.MyVehiclesFragment"
android:label="fragment_my_vehicles"
tools:layout="#layout/fragment_my_vehicles" >
<action
android:id="#+id/action_myVehiclesFragment_to_profileFragment"
app:destination="#id/profileFragment"
app:enterAnim="#anim/from_left"
app:exitAnim="#anim/to_right" />
</fragment>
<fragment
android:id="#+id/myRoomsFragment"
android:name="xxxx.ui.profile.MyRoomsFragment"
android:label="fragment_my_rooms"
tools:layout="#layout/fragment_my_rooms" >
<action
android:id="#+id/action_myRoomsFragment_to_profileFragment"
app:destination="#id/profileFragment"
app:enterAnim="#anim/from_left"
app:exitAnim="#anim/to_right" />
</fragment>
</navigation>
My Main Activity XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_activity_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/light_gray"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/navHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#+id/tabBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/nav_graph">
</androidx.fragment.app.FragmentContainerView>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/tabBar"
android:layout_width="match_parent"
android:layout_height="58dp"
android:layout_alignParentBottom="true"
app:elevation="2dp"
app:itemBackground="#color/light_gray"
app:itemIconSize="30dp"
app:itemIconTint="#color/tab_bar_icon_tint_color"
app:labelVisibilityMode="unlabeled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="#menu/tab_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity:
class MainActivity : AppCompatActivity() {
private lateinit var viewBinding: ActivityMainBinding
private lateinit var tabBar: BottomNavigationView
private lateinit var navHostFragment: NavHostFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
println("MainActivity || onCreate ||")
// Initialize viewBinding object
viewBinding = ActivityMainBinding.inflate(layoutInflater)
// Hide the default navigation bar; we implement our own
supportActionBar!!.hide()
viewBinding.loadingPageLayout.visibility = View.GONE
setContentView(viewBinding.root)
setupBottomBarNavigation()
}
private fun setupBottomBarNavigation() {
tabBar = viewBinding.tabBar
navHostFragment = supportFragmentManager.findFragmentById(R.id.navHostFragment) as NavHostFragment
val navigationController = navHostFragment.navController
val appBarConfiguration = AppBarConfiguration(setOf(R.id.scanFragment, R.id.mainFragment, R.id.profileFragment))
setupActionBarWithNavController(navigationController, appBarConfiguration)
tabBar.setupWithNavController(navigationController)
val navHost = supportFragmentManager.currentNavigationFragment
println("Current navigation fragment: $navHost")
}
override fun onSupportNavigateUp() =
Navigation.findNavController(this, R.id.navHostFragment).navigateUp()
Please help a desperate fellow out!
If someone had the same issues due to multiple clicks on the screen. It can be resolved by checking the current destination first before navigating
For example
Fragments A, B, and C
navigating from A to B while clicking on a button in fragment A that navigates to C might lead to crashes in some cases
for that you should check the current destination first as follows:
if(findNavController().currentDestination?.id==R.id.AFragment)
findNavController().navigate(
AFragmentDirections.actionAFragmentToCFragment()
)
The problem was not in Navigation Components but instead - I think - in my ImageAnalyzer. Turns out I accidentally allowed multiple calls to findNavController.navigate(). Now that I fixed that, my navigation issue is gone.

How Can I Use BroadcastReceiver on API 26 and Higher?

I'm developing an Android App. Users can chat each other. I fetch the messages on PushReceiver class. App opened or closed I mean foreground or background; the code block working from API 19 to API 26 but not working higher than API 26. I try to debug onReceive function but it's not call on Android O.
I want to say again. My code block working API 25 and lower versions.
I'm using pushy.me service.
My BroadcastReceiver Class:
public class PushReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String notificationTitle = "Title";
String notificationText = "Text";
Bundle bundle = intent.getExtras();
JSONObject jsonObject = new JSONObject();
for (String key : bundle.keySet()) {
try {
jsonObject.put(key, wrap(bundle.get(key)));
} catch (Exception e) {
e.printStackTrace();
}
}
try {
notificationText = jsonObject.get("body").toString();
notificationTitle = jsonObject.get("title").toString();
} catch (Exception e) {}
// Prepare a notification with vibration, sound and lights
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setAutoCancel(true)
.setSmallIcon(android.R.drawable.ic_dialog_info)
.setContentTitle(notificationTitle)
.setContentText(notificationText)
.setLights(Color.RED, 1000, 1000)
.setVibrate(new long[]{0, 400, 250, 400})
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setContentIntent(PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT));
// Automatically configure a Notification Channel for devices running Android O+
Pushy.setNotificationChannel(builder, context);
// Get an instance of the NotificationManager service
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
// Build the notification and display it
notificationManager.notify(1, builder.build());
}
}
My Manifest:
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
...
<receiver
android:name=".Notification.PushReceiver"
android:exported="false">
<intent-filter>
<!-- Do not modify this -->
<action android:name="pushy.me" />
</intent-filter>
</receiver> <!-- Pushy Update Receiver -->
<!-- Do not modify - internal BroadcastReceiver that restarts the listener service -->
<receiver
android:name="me.pushy.sdk.receivers.PushyUpdateReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver> <!-- Pushy Boot Receiver -->
<!-- Do not modify - internal BroadcastReceiver that restarts the listener service -->
<receiver
android:name="me.pushy.sdk.receivers.PushyBootReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver> <!-- Pushy Socket Service -->
<!-- Do not modify - internal service -->
<service android:name="me.pushy.sdk.services.PushySocketService" /> <!-- Pushy Job Service (added in Pushy SDK 1.0.35) -->
<!-- Do not modify - internal service -->
<service
android:name="me.pushy.sdk.services.PushyJobService"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" />
Edit: pushy.me Android Demo here
The latest Pushy Android SDK has added support for Android O power saving optimizations (App Standby / deprecation of Service), please update by following the instructions on this page:
https://pushy.me/docs/android/get-sdk
Also, make sure to add the following new JobService declaration to your AndroidManifest.xml, under the <application> tag:
<!-- Pushy Job Service (added in Pushy SDK 1.0.35) -->
<!-- Do not modify - internal service -->
<service android:name="me.pushy.sdk.services.PushyJobService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true" />

Recieving Sms using a broadcast receiver-xamarin

My last question was not a great question.
so here my new one.
I want to write an app that has and activity which get some info(like a phone number) from the user and then It is destroyed and the app icon is also hidden from the user.but i want to continuously receive sms from that phone number and do some stuff.
until now i have learned that if i register my broadcast receiver in the manifest it can still receive even though my app is not running or hidden.
so here is my app which i'm using xamarin (mono android):
my simple activity (it is not complete yet):
my main XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:p1="http://schemas.android.com/apk/res/android"
p1:orientation="vertical"
p1:minWidth="25px"
p1:minHeight="25px"
p1:layout_width="match_parent"
p1:layout_height="match_parent"
p1:id="#+id/linearLayout1">
<EditText
p1:layout_width="match_parent"
p1:layout_height="wrap_content"
p1:id="#+id/txt_phone" />
<Button
p1:text="OK"
p1:layout_width="match_parent"
p1:layout_height="wrap_content"
p1:id="#+id/btn_ok" />
</LinearLayout>
and the activity class:
namespace SmsBroadcastReceiver
{
[Activity (Label = "SmsBroadcastReceiver", MainLauncher = true)]
public class MainActivity : Activity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
EditText txt_number = FindViewById<EditText> (Resource.Id.txt_phone);
Button btn_ok = FindViewById<Button> (Resource.Id.btn_ok);
btn_ok.Click += delegate {
//save the number in the sharedpreference and then...
Toast.MakeText (Context, "Your App Will be Closed now", ToastLength.Short).Show ();
};
}
}
}
now my broadcast receiver:
namespace SmsBroadcastReceiver
{
[BroadcastReceiver]
public class SmsReceiver : BroadcastReceiver
{
public override void OnReceive (Context context, Intent intent)
{
Toast.MakeText (context, "sms rec", ToastLength.Long).Show ();
//get the sharedpreference and then do stuff
}
}
}
and my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="SmsBroadcastReceiver.SmsBroadcastReceiver">
<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="18" />
<application android:label="SmsBroadcastReceiver">
</application>
<receiver android:name=".SmsReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
</manifest>
I know that the using a toast in a BR is not ideal but i just want to see that it is working which is not,everytime i send and sms to my phone it doesn't show anything.
where is my problem?
I think, you created BroadcastReceiver in the wrong way.
You should create it entirely with xamarin attributes.
Mono for Android translates each IntentFilterAttribute into an <intent-filter/> element.
[BroadcastReceiver]
[IntentFilter(new string[] { "android.provider.Telephony.SMS_RECEIVED" })]
public class SmsReceiver : BroadcastReceiver
{
...
}
therefore there is no need to write receiver tags manually in your AndroidManifest file.
You can also use attribute's named parameters for Priority, Categories, etc.
[IntentFilter(new string[] { "android.provider.Telephony.SMS_RECEIVED" }, Priority = Int32.MaxValue)]

android.intent.action.CAMERA_BUTTON not broadcasting on Desire Z (Froyo)?

I have hard time intercepting HW camera button on Desire Z (Froyo). I wrote a sample that runs fine on G1 (1.6) but not on aforementioned phone.
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.company" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="4" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".CameraReceiverTestActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:enabled="true" android:exported="true"
android:name=".CameraButtonReceiver">
<intent-filter android:priority="999">
<action android:name="android.intent.action.CAMERA_BUTTON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
</manifest>
And CameraButtonReceiver.java
package net.company;
public class CameraButtonReceiver extends BroadcastReceiver {
static {
Log.w("CBR", "onReceive clazz init");
}
#Override
public void onReceive(Context context, Intent intent) {
Log.w("CBR", "onReceive camera");
abortBroadcast();
}
}
On G1 (1.6) I see both messages as soon as press the camera button and default camera app is suppressed. However, on Desire Z (Froyo) no such thing happens. After playing with priority, code/xml declarations I dare to say this phone sends this broadcast with some other name.
There is no requirement for a device manufacturer to send any broadcast when the CAMERA button is clicked, from my reading of the Compatibility Definition Document. It might only be used by the foreground activity on the Desire Z. I don't have a Z and so cannot confirm your tests.
Since the vast majority of Android devices do not have a CAMERA button at all, you will need to ensure that your app works well without such a button, and that you advise users that the CAMERA button may or may not work with your app depending upon device.