I not sure if this can be done.
I want to develop a website and keep it in the device always, without the possibility of exit. I mean disabling the hardware/software buttons and only being able to power off/on. When you reboot automatically will be launch the app. I think this can be done rooting the phone or something similar, but I don't know how can I start. Any idea?
Maybe this cannot be done with a HTML page, but embedding that website inside an application and keeping that application always active...
Some point where I can start?
Sounds like you want to implement something like a Kioskmode. The Kioskmode is only available on Samsung devices.
On other devices you have to implement a Kiosk by yourself. But it is possible! There are some nice tutorials in the web. However you need to implement an application to get the user interactions.
First of all you need to activate the Kiosk after booting the device. You can use a Broadcast Reciever to get the Boot Event:
<receiver android:name=".BootReceiver">
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
You have to declare the permission in your manifest file:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
You can start your implementation in a class witch extends the BroadcastReciever. Start the activity from the actual android context.
public class BootReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Intent kioskIntent = new Intent(context, KioskMode.class);
kioskIntent .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(kioskIntent);
}
}
In the activity you can disable every button of the device, like back pressed, etc.
You can find a good tutorial for developing a kiosk under the following link, it shows how to disable power button, home button, back pressed,etc.:
http://www.andreas-schrade.de/2015/02/16/android-tutorial-how-to-create-a-kiosk-mode-in-android/
To disable the statusbar you just need to hide it with a theme:
android:theme="#android:style/Theme.Holo.NoActionBar.Fullscreen"
To display a HTML Page you can use a WebView. However in a webview is javascript and all errors disabled. So if you just want to show some information on the page your good with a WebView.
http://developer.android.com/reference/android/webkit/WebView.html
It is possible to use android for this type of scenario but only in Android 6.+
See Single use devices here for some information
I hope this is the information you are looking for.
Related
I'm trying to add Android Auto capability to my existing app. It's a messaging app, but some messages have an audio attachment. So far, I was successfully able to create a CarAppService to display the messages themselves, but I can't seem to be able to get the audio playback to connect to the Android Auto (so that it's tied to a a media session and showing playback controls in the Android Auto dashboard).
I followed the instructions here, and I also tried using the new Media3 library (using sample code here), but neither one seems to activate the MediaBrowserService (or MediaLibraryService in case of Media3).
I have the foreground service permission and the browser service declared in the manifest
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
android:resource="#drawable/ic_auto_icon" />
<service
android:name=".auto.MediaService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
and I have the MediaLibraryService all set with creating a media session, using my existing ExoPlayer instance, and being initialized with the proper MediaLibrarySession.Callback. But the `onCreate()' method of the MediaLibraryService (or MediaBrowserService) never gets called.
What am I missing? Is there something that I need to do in the car app itself to make it bind to the media browser service?
I figured out what was happening, and the problem is basically due to almost complete lack of documentation for Android Auto. As I said in my OP, I have two different services set up: CarAppService and MediaBrowserService. Because of that, my app gets shown twice in AA (2 icons that launch 2 completely different versions of the app). So, each service gets treated like a completely separate app. And once I realized that, I created different icons and labels for each service in the Manifest, so at least now I'm able to differentiate them.
When launching the MediaBrowserService, it acts as expected - it automatically binds to the service, and allows the user to browse through the media files (as if it were just a simple media player app).
But even launching the other one (which is the one I was originally posting about), I had to manually create a media browser client, and have it bind to the media browser service using MediaBrowserCompat.
I also figured out a way to have the MediaBrowserService icon hidden, but still retain the functionality to use it for before payback in the background. That can be done by removing the <intent-filter> component of that service from the Manifest. The only problem with doing it that way is that we also lose Android Auto's payback controls, so the media plays without a problem, but it would have to be controlled from the CarAppService, which eliminates the option of controlling it in the background.
I am new to Android development, but I have experience with Java.
My goal is to create an application that will try to connect to open Wifi AP when device gets unlocked (after screen on and pin/password is entered correctly).
This would ensure that application is run only before a user is going to use the phone so to save power while not in use. Also other ways of detecting when phone is actively in use while my application is not running in foreground.
My application is relatively linear:
1. Detect device unlocks (user is actively using the phone) state ore some other kind of trigger.
2. If wifi is on and the device isn't already connected to any AP, scan wifi.
3. If open AP's is in range select one with the strongest signal and try to connect.
Right now I am researching options how to detect device unlock state, but different API level limitations make it confusing. I am not planing to publish this application to play store so Google Play's target API level requirement doesn't bother me.I would like if my application could work on android 4.3 and up or android 5 and up if 4.3 is not possible.
These are the options I have come across right now.
1. Broadcast Receiver -> ACTION_USER_PRESENT
2. Job Scheduler for android 5 and up only (also fine by me).
3. Background service. Newer android versions would restrict these.
I am open to any suggestion and information, including problems that might come up in other steps.
Thanks.
Sorry!
I already had project created and I was testing multiple code snippets on AVD, but nothing seemed to work. Then I tried to run my application on my phone and turns out everything works as expected.
Class that will handle broadcast.
public class ConBroRec extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())) {
//when device is unlocked
}
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
...
<application ...>
...
<receiver android:name=".ConBroRec"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
...
</application>
...
</manifest>
targetSdkVersion<=25
Android API level 24 introduces a new Service called the CallScreeningService. The documentation says that the service can by implemented by the default dialer to screen incoming calls. I would like to implement this service in my own app, preferably without creating an entire dialer app, but a simple naive implementation seems to be ignored by the OS when an incoming call happens.
AndroidManifest.xml snippet:
<service android:name="com.example.callbouncer.CallService" android:permission="android.permission.BIND_SCREENING_SERVICE">
<intent-filter>
<action android:name="android.telecom.CallScreeningService"/>
</intent-filter>
</service>
CallService.java:
// imports...
public class CallService extends CallScreeningService {
#Override
public void onScreenCall(Call.Details callDetails) {
CallResponse.Builder response = new CallResponse.Builder();
Log.e("CallBouncer", "Call screening service triggered");
respondToCall(callDetails, response.build() );
}
}
There are no errors while building or installing this program, but the screening doesn't seem to be taking place. Have I done something wrong (like the manifest or missing implementations/overrides in the service) or is it just not possible? If it's not possible in a small app like this, will it be possible if I implement an entire dialing app and set it as the default dialer? Finally, if that's the case, is there anything preventing me from just forking the dialer out of the AOSP and adding my features to it?
As of Android 10 (API 29+), you can have a CallScreeningService without the requirement of also implementing an entire dialer app. Until Android 10, only the default dialer app's call CallScreeningService would be invoked.
https://developer.android.com/about/versions/10/features#call-screening
Don't get too excited though, because it's very buggy and does not work as the documentation says it does:
CallScreeningService#onScreenCall is called for known contacts
CallScreeningService#setSkipCallLog doesn't show blocked calls in the call log
My workaround for getting called for known contacts was to ask the user for contact access and check if the incoming caller was in the user's contacts. There is no workaround for the other issues at the moment.
I made a very basic screening app that declines all calls from numbers not in the user's contacts you can use an an example if you like: https://github.com/joshfriend/gofccyourself
Looking at the docs you linked to:
This service can be implemented by the default dialer (see
getDefaultDialerPackage()) to allow or disallow incoming calls before
they are shown to a user.
Don't think you can do this in a separate app (at least with the current interface: I'd expect in the not too distant feature it will be exposed).
The application that I am working on connects successfully with a device over the USB connection.
Additionally, it now remembers the device from different launches as also pointed out in the following thread storing usb default connections.
However, this leaves the undesired effect of always launching the Activity when the USB device is attached. I have not been able to remember the defaults without launching the application. Launching the application on a connect is not a desired effect. Small code samples below are what the manifest currently looks like in order to get the default USB connections stored in memory for future connections at a quick glance. Can this storage of defaults be done without causing an application launch?
<activity
android:name="com.MainScreen"
android:theme="#style/Theme.Default"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="#xml/device_filter" />
</activity>
I had been thinking that perhaps there was a type of category that I could add to the intent filter that would specify it as a non-launchable intent. Something that was listened for during the activity, but handled by the activity. So far, I haven't found this however.
Update:
Declaring the intent for usb device connection within a service or a receiver in the manifest has also been an attempt at storing connection information. However, only the intent within an activity remembers connection state so that it doesn't need to ask the user a subsequent time when it is re-connected at a later given point in time. It looks as though it is designed only to save state combined with launching an application when it is connected. A bit odd, but no workaround for getting a no-launch combined with remembering the default connection for usb attached device.
You don't have to launch an activity always. You can let a background service handle the intent quietly.
<service android:name=".MyService">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
</service>
Update:
You might have to request some permissions explicitly. Here's what you should do:
When user installs the app and open it first time, ask for USB related permissions.
Set a service to handle USB attach event as mentioned above. When attached, display a persistent notification in status bar as long as a recognized device is attached.
The status bar notification is also useful to notify user that more permissions are required and main UI activity can be accessed.
You should make a small re-design.
Create a Service and run the logic like 'When USB device attached' etc. (probably you have them in that Activity now) within this service.
By the way, you can always make good use of your MainActivity from or apart from this service.
I can confirm by my own experiments that the USB device will not be remembered from within a service. It seems that requestPermission() must come out of an Activity.
To avoid the launch of the activity, I implemented onPostCreate() like this:
#Override // from Activity
public void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
Intent triggerIntent = getIntent();
if (triggerIntent != null) {
if ( ! triggerIntent.hasCategory(Intent.CATEGORY_LAUNCHER) ) {
Log.e(LOGTAG, "not started by launcher! exit now.");
finish();
}
}
}
I used onPostCreate() instead of pasting the code into onCreate() because when calling finish() from onCreate() it will cause onDestroy() to be called immediately and typically not all members of the Activity class are setup properly yet. It seems to be more safe to me using the onPostCreate() approach.
In my Application I am not having any UI part, so I need to start a Service as soon as the Applicaton gets installed on the Device. I saw many links from which the answer was that its not possible but I guess it is surely possible. Just have a look at PlanB Application on the Android Market that does fulfil my requirement. Below is my Manifest file how I tried, but the Service was not called at all. So, let me know what is the best possible way to start a Service when the Application gets Installed.
UPDATE
I also tried using android.intent.action.PACKAGE_ADDED it works fine for detecting the Package for the other Applications but not for itself.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.auto.start"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:icon="#drawable/ic_launcher" >
<service android:name=".MyService">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</service>
<receiver android:name=".BootUpReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.PACKAGE_INSTALL" />
<action android:name="android.intent.action.PACKAGE_ADDED" />
<data android:scheme="package"/>
</intent-filter>
</receiver>
</application>
</manifest>
Fortunately, Plan B does not work on Android 3.1+, as tested on a XOOM and a Galaxy Nexus.
What Plan B does is exploit a security hole that could be used by drive-by malware, which is specifically why Android prevents it from happening anymore.
UPDATE
To clarify: As inazaruk posted and I put into comments on other answers, all applications, upon installation, are placed in a "stopped" state. This is the same state that the application winds up in after the user force-stops the app from the Settings application. While in this "stopped" state, the application will not run for any reason, except by a manual launch of an activity. Notably, no BroadcastReceviers will be invoked, regardless of the event for which they have registered, until the user runs the app manually.
This block covers the Plan B scenario of remote-install-and-run, which they were taking advantage of previously. After all, with that, anyone with a hacked Google account would be at risk of having their device infected, hands-free as it were.
So, when the OP says:
I need to start a Service as soon as the Applicaton gets installed on the Device
the OP will be unsuccessful and will need to redesign the application to avoid this purported "need".
Applications installed on the /system partition are not subject to being placed into the "stopped" state after installation. If you have root, you can do,
$ adb root
$ adb remount
$ adb push your.apk /system/app
And it can immediately receive broadcast intents. This certainly doesn't provide a general purpose solution, but i wanted to mention it for completeness.
EDIT: Keep in mind that different versions of Android locate system APKs in different places. For example, Android 8 puts them under /system/app//.apk. Shell into your device and poke around and follow the same scheme used for other system APKs.
I agree with CommonsWare's answer to question: How to start android service on installation. In other words, you can't automatically start your service after you've just been installed.
One more thing about newer Android platforms: if you don't have UI at all, you'll have trouble starting your service even when using BOOT_COMPLETE intent on Android 3.1+.
That's because all installed applications are in stopped state. In this state applications will not receive ANY broadcast notifications.
In order to activate your application some other application (or user) needs to start your service or activity, or content provider. The usual workflow is when user clicks on your application's icon.
I've written a detailed explanations about this in my blog post.
Plan B does this launch by listening to the events which happen in the system. It uses a receiver which literally listenes to hundreds of events hoping that some of them will eventually fire up. So this is how you can do it. Otherwise, there are no built-in means to launch the application as soon as it gets installed.
I'm not sure what your constraints/purpose is, but if you can install another application that has an activity you can have it send an intent with the flag FLAG_INCLUDE_STOPPED_PACKAGES.
This will use your application for the intent resolution, even though it's in a stopped state. If the action of the intent matches one of your filters, it will also bring the package out of the stopped state.
I don't think so You can start service immediately after installed your application on device,
The application must first be invoked by the user through some sort of Activity.The only things you have to register some Broadcast Receiver with appropriate intents in manifest which invoke you service when something is happening on device but this remaing to Android 3.1 version.
EDIT:
After Android 3.1+ onwards you can not use any Broadcast for starting your application, because all application remains in inactive state after completion of device boot and to launch the application the user have to invoke it.(By touching the app icon).
As stated by CommonsWare in the answer to this question (which I suppose you have all ready seen, but chose to ignore) starting a Service on install is not possible - it is simply not a thing that is implemented into the platform.
Starting it automaticly at the next boot is however possible.
As stated in the Technical Details for PlanB:
Plan B will attempt to launch as soon as it downloads, but in some cases you will need to send an SMS to get it started.
My guess is that on a rooted phone you might be able to start the Service on install - but there's no guarantee that the phone is rooted, which is why PlanB will require recieving a text in some cases because that can be registered by the IntentFilter of the app and then used to start the Service.
there is an app on google play Android Lost which invoke the registration service for google push messages via an incoming sms without launching the app even once for version 3.0+.
Perhaps the best way to accomplish this (and now I'm speaking to the specific intent of the OP, a program that gets installed in order to retrieve a stolen phone, not the general question) is social engineering, not software engineering.
So, an icon with text like "Password List" or "My Bank Accounts" which suddenly appeared on the home screen would undoubtedly be clicked on. Look at the success of all sorts of other phishing, and here you would be targeting a thief, who's already motivated to continue nefarious activity. Let the thief start it for you. :)
HEY I think using a BroadcastRecivier to automatically start the app on restart of device hence it will automatically start on device start.Hope this will help