Android: How to Detect "Turn on USB storage" Broadcast? - java

I am trying to detect the Turn on USB storage using BroadcastReceiver though i am able to detect the USB connected using android.intent.action.UMS_CONNECTED action
and
disconnected using android.intent.action.UMS_DISCONNECTED action.
How can i detect the USB storage ?

Below is how I check if storage card is mounted/unmounted. You can change it to check removed/insterted. I do this by register a BroadcastReceiver to get the "mount events" then check what state the storage card is in. If it is not mounted and is not while it is checking (the state during it mounts the card again) it is unmounted or the card has been removed.
public class MemCardReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
onMemcardMounted();
}
else if (!Environment.getExternalStorageState().equals(Environment.MEDIA_CHECKING)){
onMemorycardUnMounted();
}
}
private void onMemorycardUnMounted() {}
private void onMemcardMounted() {}
}
And in ManifestFile
<receiver android:enabled="true" android:exported="true" android:name="the.name">
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<action android:name="android.intent.action.MEDIA_UNMOUNTED" />
<data android:scheme="file" />
</intent-filter>
</receiver>
There are several different states checkout this if there are any other stated like. removed

I think android.Intent.action.ACTION_MEDIA_EJECT is broadcast when user takes the USB storage in use and ACTION_MEDIA_MOUNTED when it's turned off.

Related

How to detect Incoming call number and Out going call number when app is killed OR not in background Android 8.0,9.0

I am working on a application and my requirement is to store all incoming and outgoing call details like number,duration,time
I am using broadcast receiver for this along with run time permissions READ_PHONE_STATE,READ_CALL_LOG
With the current code app is working fine when app is in foreground as well as background BUT when I kills the app,it is not working,it is not detecting incoming/outgoing calls.
Below is my code of manifest file
<receiver
android:name=".utils.CallReceiver"
android:enabled="true"
android:exported="true">
<intent-filter >
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
Broadcast receiver
override fun onReceive(context: Context?, intent: Intent) {
//We listen to two intents. The new outgoing call only tells us of an outgoing call. We use it to get the number.
if (intent.action == "android.intent.action.NEW_OUTGOING_CALL") {
savedNumber = intent.extras!!.getString("android.intent.extra.PHONE_NUMBER")
} else {
val stateStr =
intent.extras!!.getString(TelephonyManager.EXTRA_STATE)
val number =
intent.extras!!.getString(TelephonyManager.EXTRA_INCOMING_NUMBER)
var state = 0
if (stateStr == TelephonyManager.EXTRA_STATE_IDLE) {
state = TelephonyManager.CALL_STATE_IDLE
} else if (stateStr == TelephonyManager.EXTRA_STATE_OFFHOOK) {
state = TelephonyManager.CALL_STATE_OFFHOOK
} else if (stateStr == TelephonyManager.EXTRA_STATE_RINGING) {
state = TelephonyManager.CALL_STATE_RINGING
}
if (number != null && !number.isEmpty() && !number.equals("null")) {
onCallStateChanged(context, state, number);
Log.d("TEST :","NUMBER =>"+number);
return;
}
}
I need solution which can detect incoming call when app is killed like true caller app and want to start receiver on Android 7,8,9 when call happens
when an app is killed via "FORCE CLOSE" by the user, all the app's broadcast receiver are immediately put on pause, and the system prevents them from receiving future broadcasts until the user manually reopens that app.
This is to prevent apps working around a force-close by the user that obviously wants that app shutdown, while an incoming broadcast receiver can wake that app up again.
see here
This rule has one exception - if the app had been set to be the default Phone/SMS app, it will still be able to wake up upon getting a call / sms.
I assume TrueCaller was set as a default handler to be able to workaround this limitation.
To become the default Phone handler on Android P and below - see the documentation here: https://developer.android.com/reference/android/telecom/TelecomManager#ACTION_CHANGE_DEFAULT_DIALER
On Android Q, call this method: https://developer.android.com/reference/android/app/role/RoleManager#createRequestRoleIntent(java.lang.String) with ROLE_DIALER

Android detecting incoming and outgoing calls is not working with Redmi and Oppo mobiles

Here is my code:
public class CallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
showToast(context,"Call started...");
}
else if(intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_IDLE)){
showToast(context,"Call ended...");
}
else if(intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)){
showToast(context,"Incoming call...");
}
}
void showToast(Context context,String message){
Toast toast=Toast.makeText(context,message,Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER,0,0);
toast.show();
}
}
//here i have registered my receiver in manifest
<receiver android:name=".CallReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
I am detecting incoming and outgoing calls in my Android application. This code is not working with the device Redmi and Oppo, and I want the code to be working for all the devices. How can I determine what the issue is?
As part of the Android 8.0 (API level 26) Background Execution Limits, apps that target the API level 26 or higher can no longer register broadcast receivers for implicit broadcasts in their manifest. you can register your receiver dynamically in Activity by calling registerReceiver(new CallReceiver(), new IntentFilter().addAction("android.intent.action.PHONE_STATE"));
also, a bad thing about this approach is your receiver will only work when your app is in the foreground. If you close your app then you don't trigger any broadcasts in background. also, refer this if you are looking for call log data.

Is there method to get referral code from google play store in android?

if userA share his link referral with userB .when userB download app and do some function then app send referral id for userA to backend to increase points for userA
Is it possible to see that referrer (if any) in the code of my app?
i have tried used Play Install Referrer Library
but returned referrer string is
utm_source=(not%20set)&utm_medium=(not%20set)
for referral link https://play.google.com/store/apps/details?id=com.sfn.android&referrer=9BE46550
then try using BroadcastReceiver
for example:
public class InstallReferrerReceiver extends BroadcastReceiver {
public static String TAG = "InstallReferrerReceiver";
#Override
public void onReceive(Context context, Intent intent) {
String referrer = intent.getStringExtra("referrer");
//Use the referrer
Log.d(TAG, "onReceive:InstallReferrerReceiver " + referrer);
}
}
in androidManifest.xml:
<application>
<receiver
android:name="com.gosnash.android.utils.InstallReferrerReceiver"
android:exported="true"
android:permission="android.permission.INSTALL_PACKAGES">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
</application>
but not work also

Debug app that runs at boot

I am using Android Studio.
I added a BroadcastReceiver for my app that receives android.intent.action.BOOT_COMPLETED, the receiver just shows up a Toast for testing. The problem is I get "App has stopped" message just after Android starts up.
My first question is: is there anyway to debug that at startup and see where is the problem by myself? Because I can't see any log referring to that problem in Android Studio.
My second question is related to the problem itself. Here is the code:
XML:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="myapp">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
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="MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".AutoStartReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
Java: BroadcastReceiver
public class AutoStartReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "loaded", Toast.LENGTH_LONG).show();
throw new UnsupportedOperationException("Not yet implemented");
}
}
The third question is: Is it OK to do some heavy work (read some files and set the AlarmManager) in the receiver rather than creating a service? because as of API 26 Android is putting a lot of restriction to services.
Thank you
For the debugging part I used this (in the Terminal, when the emulator is on) :
adb shell am set-debug-app -w --persistent <your.app.package>
to start debugging, then click Attach debugger to android process when the app prompts for it on the emulator.
To disable this:
adb shell am clear-debug-app <your.app.package>
Found answer here : https://medium.com/#elye.project/debug-app-deeplink-at-launch-time-bdb2cf04a9e6
Apps that launch on boot can be debugged the second your device gets a debugging connection, which usually happens just before the app itself would boot. Just open logcat and watch for the device and app to pop up after reboot. Note that this assumes the app is debuggable. Apps that aren't will simply not show any logs.
You get the MyApp has unfortunately stopped message for the obvious reason of this code:
public class AutoStartReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "loaded", Toast.LENGTH_LONG).show();
throw new UnsupportedOperationException("Not yet implemented");
}
}
You throw an exception, meaning it'll stop.
As for what you do in the service, as long as it uses within a reasonable amount of RAM and processor (extremely heavy services are more likely to be killed to save battery and memory) you're good to go

Broadcast Receiver not receiving BOOT and MEDIA_MOUNTED intent

I'm trying to create a simple BroadcastReceiver that can receive the android.intent.action.BOOT_COMPLETED intent as well as the android.intent.action.MEDIA_MOUNTED intent. The idea is to start a service on receiving either of these intents. Thus the service should be started after Android boot is complete or when an USB storage device is connected to the Android target(if the service is not already started by then).
Permissions used by the application are defined in this section
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
The following section defines the BroadcastReceiver responsible for handling the intents and starting the corresponding service.
<receiver
android:name="com.example.systemupgradeapplication.IntentReceiver"
android:label="USB Detection Receiver"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_REMOVED" />
<action android:name="android.intent.action.MEDIA_EJECT" />
<action android:name="android.intent.action.MEDIA_BAD_REMOVAL" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<data android:scheme="file" />
</intent-filter>
<intent-filter android:priority="999" >
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
The corresponding service that should be started from the Broadcast Receiver is defined in the following section
<service android:name=".SysUpgradeService" />
Note: The receiver and service components are defined within the <application> section of the Android Manifest.
The following snippet is the Class responsible for handling the intents broadcasted
public class IntentReceiver extends BroadcastReceiver {
private final static String TAG = "IntentReceiver";
private static boolean m_UsbInserted = false;
private static boolean m_UsbRemoved = true;
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "LaunchReceiver::ACTION_MEDIA_MOUNTED :: intent received with path= ");
// TODO Auto-generated method stub
//if(intent.)
String action = intent.getAction();
if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
String path = intent.getDataString();
if(path.contains("usb")) {
m_UsbInserted = true;
Log.d(TAG, "LaunchReceiver::ACTION_MEDIA_MOUNTED :: intent received with path= "+path);
Intent myIntent = new Intent(context, SysUpgradeService.class);
myIntent.putExtra("path", path);
context.startService(myIntent);
}
}else if(action.equals(Intent.ACTION_BOOT_COMPLETED)) {
Log.d(TAG, "BOOT Completed intent received");
context.startService(new Intent(context, SysUpgradeService.class));
}
The problem I am facing is that none of the intents are arriving at my broadcast receiver(None of the Logs in the IntentReceiver class are being printed in logcat) even though I can see in the Android Debug logs that the BOOT_COMPLETE and MEDIA_MOUNTED intents are being broadcast. Also This application is not starting after android system is booting up.
I appreciate your help in this regard, what may be wrong with my approach and some possible solutions.
Okay, so I pushed the apk to /system/priv-app which is where System Applications which are part of custom ROM are placed. Now I do not need any activity in my application since it is part of the custom ROM and is recognized as a system application. It seems that if your application is a 3rd party application it must have an activity to be able to receive broadcasted intents.
However in this case I have control over the custom ROM source code as well as root access on the device. So both the approaches work
Make your application part of the custom ROM source, build and flash on device.
Get root access on device, push your apk to /system/priv-app (4.4 onwards), reboot and voila!
Make Sure you have atleat one activity present in your Application.From Android 3.1, BroadcastReceiver will not work until the user has manually launched an activity, This is for provide security . once the user runs the app for the first time then your BroadcastReceiver will run always except it does not Force Stop it. Once activity launch at first time your broadcast receiver will run even after reboot your deice.

Categories