Android detect usb storage for kitkat (4.4) - android

I've created a webview app which hosts a website within the app in the assets-directory.
I want to update the website via an USBstick inserted in my tablets usbslot.
I tried it first with the .MEDIA_MOUNTED broadcast which doesn't work for my android 4.4. Tablet.
I've searched for an alternative and found the "MediaScannerConnection".
There are several examples here, which didn't help me much, to solve my issue.
I'm looking for an easy and clean solution and a little explanation would be nice too, to detect if an USB-Storage is connected and the chance to execute some code afterwards.
And how make this USB-check run all the time is a question in addition. I assume i have to put it in the OnResume method, but i'm not quite shure.

Please post code for your BroadcastReceiver and AndroidManifest.xml.
Manifest should look something like
<application>
<!--- ... --->
<receiver android:name=".UsbBroadcastReceiver"
android:exported="true"
android:enabled="true" >
<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>
</application>
Note the data tag, it's often overlooked.
In your onReceive implementation the URI to root of mount can be obtained from Intent#getData().
Also note that this will not work on Android 6.0 (M) and above. For 6.0 and above your code must request access to USB via one of two ways:
1) UsbManager#requestPermission
2) Intent#ACTION_OPEN_DOCUMENT_TREE as part of Storage Access Framework

Related

Android App Intent Filter sometimes not working

For a project I have encountered a very strange issue:
Deeplinks have been working very well for the last year, but recently (since the beginning of January-2019) we have been getting complaints from our users that deeplinks have stopped working (some say 9 out of 10 time).
We have not changed any of this code and have great difficulty reproducing this issue.
Even stranger, in the sparse times that we do encounter the issue ourselves, the android OS does not even show our app as an option through the 'open with'-dialog. This suggest to us that the OS sometimes forgets that the app has intent-filters registered in its Manifest.
Restarting the app appears to fix this and deeplinks start working again.
The app also seems to work every time we do a new build from Android Studio, which makes it very hard to reproduce.
Our manifest has a specific activity that handles deeplinks:
<activity
android:name="com.company.DeepLinkActivity"
android:noHistory="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="ideal-payment"
android:scheme="com.company.ideal" />
<data
android:host="ideal-payment"
android:scheme="com-company-ideal" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="${appLinkIdealHost}"
android:pathPrefix="/ideal-betaling/landingpage"
android:scheme="https" />
</intent-filter>
<intent-filter android:autoVerify="true">
...
</intent-filter>
<intent-filter android:autoVerify="true">
...
</intent-filter>
</activity>
We thought it might have something to do with the autoVerify not being accessible, but then the OS should show the 'open with'-dialog, which does not happen when the issue surfaces.
Is there someone that has encountered a similar issue? Any help or suggestions would be greatly appreciated.
When app is stopped for example with an exception or when user have force stopped it from settings or in some devices when user removes app from history (or from tasks) the app will be force stopped automatically (which is not a good choice from manufacturer) when app is in stopped state its manifest intentFilter will not be used (when app is first installed and never opened also it is in this phase)
While in stopped state, the application will not run for any reason,
except by a manual launch of an activity, or an explicit intent that
addresses an activity ,service or broadcast.
https://riptutorial.com/android/example/30592/android-stopped-state
Most of Android versions you mentioned was 8 or grater thus below quotation also may be useful but this is for services and broadcast receivers.
Whenever an app runs in the background, it consumes some of the
device's limited resources, like RAM. This can result in an impaired
user experience, especially if the user is using a resource-intensive
app, such as playing a game or watching video. To improve the user
experience, Android 8.0 (API level 26) imposes limitations on what
apps can do while running in the background.
https://developer.android.com/about/versions/oreo/background
Can you specify the version of android OS ? because android:autoVerify="true" works only on Android 6.0 and higher to cause the system to attempt to verify all hosts associated with the URLs in any of your app's intent filters.
these two entries also look strange to me, not sure what you are trying to accomplish there:
<data android:host="ideal-payment" android:scheme="com.company.ideal" />
<data android:host="ideal-payment" android:scheme="com-company-ideal" />
this is far from being ideal, because those hosts and schemes are both invalid, see data-element.
I would assume, based upon all the code which obviously had been withheld... that other intent-filter might also feature duplicate data elements, which would need to be moved into separate intent-filter, of which an activity element permits several. set android:autoVerify="true" on all these intent-filter and then closely review the logcat after the package installation.
Great news, we were able to find a solution.
The issue originated from an older version of the Chrome browser.
https://bugs.chromium.org/p/chromium/issues/detail?id=935864
After the release of version 73.0.3683.90 a few days ago, the issue has gone away.
Thanks Google :D

Replacing in call app

Background
I'm trying to develop a really simple in call app to replace the stock version. Basically, I just want to answer incoming calls and present the user with a really simple customized UI. There is no need for outgoing calls or any fancy stuff.
Searching the web I've found package android.telecom.incallservice (available in API 23). This service is implemented by any app that wishes to provide the user-interface for managing phone calls.
It seems promising but I'm having trouble getting it to work. I've created simple service extending InCallService and declared it in my manifest as described by the docs. However, I would expect to be able to change the default phone app in the settings to my own, but I can only find the stock phone app.
Code
This is the manifest declaration from the docs. I've replaced BIND_IN_CALL_SERVICE with BIND_INCALL_SERVICE since I guess this is a typo.
<service android:name="your.package.YourInCallServiceImplementation" android:permission="android.permission.BIND_INCALL_SERVICE">
<meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="true" />
<intent-filter>
<action android:name="android.telecom.InCallService"/>
</intent-filter>
</service>
Questions
Is it even possible for third-party app to replace the default in call app?
Are there any sample implementations using this API out there I may use as a reference? I've found the google implementation, but this is a system app which makes use of some permissions that are not available for other apps (ex: android.permission.MODIFY_PHONE_STATE).
Am I correct in the assumption that after providing a correct InCallService manifest registration and a stub implementation I could expect to find my app under Default Apps -> Phone? Do I need to declare something else?
Thanks.
Is it even possible for third-party app to replace the default in call app?
Yes, starting with API 23 it is possible.
Are there any sample implementations using this API out there I may use as a reference? I've found the google implementation, but this is a system app which makes use of some permissions that are not available for other apps (ex: android.permission.MODIFY_PHONE_STATE).
The only one I'm aware of, is the sample I created https://github.com/arekolek/simple-phone that was already mentioned in the other answer as well.
Am I correct in the assumption that after providing a correct InCallService manifest registration and a stub implementation I could expect to find my app under Default Apps -> Phone? Do I need to declare something else?
Actually, no.
Like mentioned in another answer on the topic, you don't need InCallService at all to appear on that list.
What you need though, is to register an activity with two intent filters, one with a tel Uri scheme, and one with an empty scheme (having just one of them is not enough):
<intent-filter>
<action android:name="android.intent.action.DIAL" />
<data android:scheme="tel" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.DIAL" />
</intent-filter>
It is vaguely mentioned in the docs, and stated explicitly in AOSP code.
That is enough to appear on that list. Only then, to provide the UI for the call, will you actually need the InCallService.
According to the docs and as you comment yourself, you need to add this in your manifest:
<service android:name="your.package.YourInCallServiceImplementation"
android:permission="android.permission.BIND_INCALL_SERVICE">
<meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="true" />
<intent-filter>
<action android:name="android.telecom.InCallService"/>
</intent-filter>
</service>
android:name must be replaced by the class that implements this service.
<activity android:name="your.package.YourDialerActivity">
<intent-filter>
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
android:name must be replaced by the class that implements the main activity for your own dialer implementation.
Here you can find more information about this:
https://developer.android.com/guide/topics/connectivity/telecom/selfManaged
And here's a sample project that you can use as a guide:
https://github.com/arekolek/simple-phone
And this: https://stackoverflow.com/a/49835987/1916449

Interact with Android Setup Wizard

I am trying to develop a setup wizard for Android, as I would like to add some functionality to the one existing from Google. Is it possible to somehow interact with the Android wizard? Because when I have searched for information I've seen that not using Google's Wizard might cause some trouble, regarding gmail account activation and so on.
If not, could an activity be called immediately before or after Google's wizard? Would it be enough to just listen to the BOOT_COMPLETED event?
Thank you very much in advance!
I don't know how you will use this unless you are making a rom and can add your app to system but basically you make your setupwizard add-on a Home activity with action MAIN, and categories HOME,DEFAULT. You should also set the priority higher than 1. If any of this is unclear you can look at the Launcher source/manifest that is publicly available.
When your activity is done it should deactivate itself with the PackageManager (setComponentEnabledSetting) and that should be it.
You can add additional activities that start the first time the phone is boot up. You just have to mimic the same behavior as Google's SetupWizardActivity.
Here's the relevant portion in the AndroidManifest.xml for reference:
<activity android:theme="#style/InvisibleNoTitle" android:label="#string/setup_wizard_title" android:name="SetupWizardActivity" android:excludeFromRecents="true" android:launchMode="singleTop" android:immersive="true">
<intent-filter android:priority="5">
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.DEVICE_INITIALIZATION_WIZARD" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
This will allow you to run your application before/after SetupWizardActivity, depending on your priority. I believe higher numbers for android:prioirity run first, but don't quote me on that.
You can find out the AndroidManifest xml for various Android-related apks using apktool. You can even inspect some of apks you picked up from the Play Store or whatever other sources.

Applications Installed Listener and Suspending internet/3G connections

I am presently working on an android application but am stuck in getting a workable solution. So please I would like to know three things:
1. Is there any code to Listen for Installed Applications and also when an Application is being installed?
2. Is there anyway to suspend internet permissions granted to installed applications?
3. Is there anyway to suspend 3G connection in the device without totally disabling it?
Please if there is anyone that has an answer to these questions and if possible a code kindly give drop it here. Additionally if one has a better solution that covers these three questions, am also open to it.
Thanks Devs.
Given below is the answer to question 1, Put this in your manifest and you have to then write "YourReceiver" which will receive the intent. With this I'm getting a call to onRecieve, but struggling to find the name/info about the app which got just installed.
<receiver android:name=".YourReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_INSTALL" />
<action android:name="android.intent.action.PACKAGE_ADDED" />
<data android:scheme="package"/>
</intent-filter>
</receiver>
Possible duplicate of
Receiving package install and uninstall events
Where's the man?

Push notifications on emulator working, but not on real device

I got a working example of a third party server to send push notifications to the device which is perfectly working in the Android emulators I use. As soon as I try to use it on my real device (Samsung Galaxy S) I don't receive my notifications anymore, even tough I reregister the device at the google server (as I use the same gmail account). I basically have no clue where to start looking as Logcat is not giving me any interesting information about it. The code is working in the emulator device, so my guess would be to start looking at the permission rules. Any ideas?
I don't know if this matters, but I am using Ubuntu 10.10 to develop/debug.
Is your ROLE Account gmail ID same as the gmail ID configured on the phone ? I did have problems with this. If so, can you try using some other gmail ID on the phone ? For more see this.
could that be a permission issue? did you set right permission in the manifest?
maybe the emulator is not so strict on lack of permissions (I've experienced that sometimes, some devices worked and other didn't, and all I was missing was a manifest permission)
you have to set both
<permission
android:name="your.packagename.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
and
<uses-permission android:name="your.packagename.matchtracker.permission.C2D_MESSAGE" />
in the main section of your manifest and declare a brodcast receiver with
<receiver
android:name=".push.RegistrationReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="your.packagename" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="your.packagename" />
</intent-filter>
</receiver>

Categories

Resources