Android Application with only Service - android

I need to make an application "x" that has only service in it(no activity and no broadcast receiver) which can be called from activity of another application "y". I need to ask is it possible because on clicking a button in application "y" service of application "x" must be called but it is not happening. I don't see service running in the android phone. So is it even possible to have a single service in a project and nothing else?
application "y" code
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.button);
if(button!=null){
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startService(new Intent("com.example.sonali.serviceonly.OnlyService"));
Toast.makeText(getApplicationContext(), "text", Toast.LENGTH_SHORT).show();// Perform action on click
}
});
}
}
}
application "x" manifest file
``
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<service android:name="com.example.sonali.serviceonly.OnlyService" android:exported="true" android:enabled="true">
<intent-filter>
<action android:name="com.example.sonali.serviceonly.OnlyService"/>
</intent-filter>
</service>
</application>
``

Yes it's possible.
You have to start service like this.
Intent intentService = new Intent();
intentService.setComponent(new ComponentName("com.example.app", "com.example.app.servicename"));
startService(intentService);
You must have to set this exported as true in menifest file.
android:exported="true"
I have tested it's working fine on 4.4.4 Version.
Try Explicit Intent for version 5+
ComponentName n = new ComponentName("com.xxx.yyy", "com.xxx.yyy.OnlyService");
Intent a = new Intent();
a.setComponent(n);
a.setAction(Intent.ACTION_MAIN);
a.addCategory(Intent.CATEGORY_LAUNCHER);
a.putExtra("destinationAddress","5554");
ComponentName c = getApplication().startService(a);
if(c==null)
{
Log.e("error", "failed to start with " + a);
}

Related

Broadcast receiver is not working - why so?

I'm studying Android.
I try to implement a Custom static Broadcast Receiver but it is not working.
I search for some issue from Google but I can't find something to solve this.
I work on Android 7.0 Min Level 24 Target Level 28
In fact, MyStaticReceiver isn't launching when I start the Activity (no log)
MyDynamicReceiver work perfectly
Do you have a solution?
AndroidManifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="test.receiver">
<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="test.receiver.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".MyStaticReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="#string/StaticAction" />
</intent-filter>
</receiver>
</application>
</manifest>
MainActivity.java :
public class MainActivity extends Activity {
public final static boolean Debug = true;
public final static String TAG = "TagDebug";
private MyDynamicReceiver dynamicReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ComponentName receiver = new ComponentName(this, MyStaticReceiver.class);
PackageManager pm = this.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
#Override
protected void onResume() {
super.onResume();
if (Debug) Log.i(TAG, "MainActivity:onResume");
configureDynamicReceiver();
}
#Override
protected void onDestroy(){
super.onDestroy();
if (Debug) Log.i(TAG, "MainActivity:onDestroy");
unregisterReceiver(dynamicReceiver);
}
public void onClickButton(View v) {
if (Debug) Log.i(TAG, "MainActivity:onClickButton");
Intent staticIntent = new Intent();
staticIntent.setAction(getString(R.string.StaticAction));
sendBroadcast(staticIntent);
Intent dynamicIntent = new Intent();
dynamicIntent.setAction(getString(R.string.DynamicAction));
sendBroadcast(dynamicIntent);
}
public void configureDynamicReceiver() {
if( dynamicReceiver == null ) {
dynamicReceiver = new MyDynamicReceiver();
}
IntentFilter filter = new IntentFilter(getString(R.string.DynamicAction));
registerReceiver(dynamicReceiver, filter);
}
}
MyStaticReceiver.java (MyDynamicReceiver is the same ...)
public class MyStaticReceiver extends BroadcastReceiver {
public final static boolean Debug = true;
public final static String TAG = "TagDebug";
public MyStaticReceiver() {
if (Debug) Log.i(TAG, "MyStaticReceiver");
}
#Override
public void onReceive(Context context, Intent intent) {
if (Debug) Log.i(TAG, "MyStaticReceiver:onReceive");
}
}
You are actually sending an implicit broadcast, therefore the receiver declared in the manifest will not work.
If your app targets Android 8.0 (API level 26) or higher, you cannot use the manifest
to declare a receiver for most implicit broadcasts (broadcasts that
don't target your app specifically). You can still use a
context-registered receiver when the user is actively using your app. Link
You don't face any issue with MyDynamicReceiver because it is context-registered receiver.
But to make it work for MyStaticReceiver, you can try sending an explicit broadcast by passing the component name in the constructor of the Intent.
Intent staticIntent = new Intent(this, MyStaticReceiver.class);
staticIntent.setAction(getString(R.string.StaticAction));
sendBroadcast(staticIntent);

Prevent a new Activity from spawning when a Bluetooth device connects

Goals
If a bluetooth device connects, and no Activity is running, start Activity
If a bluetooth device connects, and an Activity is already running, connect to the already running Activity
Problem
As soon as a device connects, a new Activity starts. I have not been able to make the app reuse the same Activity.
What I have managed to solve
If a bluetooth device connects, and no Activity is running, start Activity
The problem manifests itself in the use of BroadCastReceivers which in turn starts the Activity using intents. For some reason the Activity keep running through its lifecycle, spawning up new windows, when a new device connects.
I've tested this solely on a Nexus 6P with Android N. I have no idea yet what kind of implications this implementation means for any other devices yet. But I at least need to get this working on one device.
Manifest
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
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>
<activity android:name=".BtActivity" />
<receiver android:name=".BtConnectionBroadcastReceiver" android:priority="100000">
<intent-filter>
<action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED" />
<action android:name="android.intent.action.MEDIA_BUTTON" />
<action android:name="android.media.VOLUME_CHANGED_ACTION" />
</intent-filter>
</receiver>
</application>
BtConnectionBroadcastReceiver
public class BtConnectionBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "BT";
public static final String BROADCAST_ACTION_CONNECTED = "CONNECTED";
public static final String BROADCAST_ACTION_DISCONNECTED = "DISCONNECTED";
SharedPreferences mSharedPreferences;
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
// Get the BluetoothDevice object from the Intent
Log.d(TAG, "DEVICE CONNECTED");
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d("DEVICE NAME", device.getName());
Log.d("DEVICE ADDRESS", device.getAddress());
Intent i = new Intent(context, BtActivity.class);
context.startActivity(i);
} else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
Log.d(TAG, "DEVICE DISCONNECTED");
intent = new Intent();
intent.setAction(BtConnectionBroadcastReceiver.BROADCAST_ACTION_DISCONNECTED);
context.sendBroadcast(intent);
}
}
BtActivity
public class BtActivity extends AppCompatActivity {
private static final String TAG = "BT";
Window mWindow;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bt);
Log.d(TAG, "onCreate");
IntentFilter filter = new IntentFilter(BtConnectionBroadcastReceiver.INTENT_FILTER);
filter.addAction(BtConnectionBroadcastReceiver.BROADCAST_ACTION_CONNECTED);
filter.addAction(BtConnectionBroadcastReceiver.BROADCAST_ACTION_DISCONNECTED);
//registerReceiver(mReceiver, filter);
mWindow = getWindow();
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
//params.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF;
params.screenBrightness = 0.2f;
mWindow.setAttributes(params);
mWindow.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
mWindow.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
mWindow.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
mWindow.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
mWindow.getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_IMMERSIVE);
}
#Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
}
When I run this code, I get the following chain:
Start MainActivity (not included, it only contains an activity with the default main layout, so that the applications receiver is registered)
Switch on a bluetooth device (This has been paired earlier, so android knows about it)
Wait until it connects and get this:
DEVICE CONNECTED
onCreate
onResume
I can't grasp why the activity is restarting at this point. The activity is already running, the BroadcastReceiver only sends a broadcast to an already running activity. I can't figure out why there's a reason for the Activity to kill itself and then restart again.
Try by setting launch mode to the activity which is being started.
android:launchMode="singleTop"
This delivers the intent to the same activity instance if this activity is currently the top most activity in that task and onNewIntent() method of the activity will be invoked instead of onCreate(). And manage the functionality by passing intent extras. If this activity is not the top most activity in its task or if there is no activity running at all, then new instance of activity will be created and onCreate() followed by onResume() will be invoked.
Other launch modes like "singleTask"/"singleInstance" also can be used based on the need.
Hope this helps.
I had the same issue - something was calling onDestroy upon Bluetooth connection state changed (of the barcode scanner). I have fallowed author`s other post (as mentioned) and it was solved: https://stackoverflow.com/a/52165268/12762397
Posting this to speed up solution for someone else in the future.
It is necessary to add
<activity
...
android:configChanges="keyboard|keyboardHidden"/>
Works like a charm!

Starting the Main activity from another activity

I am trying to achieve following case on Android, but no success:
1) Launch Application (Launcher Activity which is a subclass of Base Activity). The Base Activity has code as follows:
///This is in BaseActivity
#Override
public void onCreate(Bundle instance)
{
super.onCreate(instance);
//Config.isLoggedIn() is a static function.
if(! Config.isLoggedIn())
{
////Config.startLoginActivity is a static function
Config.startLoginActivity(this, getIntent());
finish();
}
}
The Config.startLoginActivity functions is defined as
public static void startLoginActivity(final Context ctx, final Intent finishIntent)
{
Intent i = new Intent(ctx, ItemListActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("FINISH_INTENT", finishIntent);
ctx.startActivity(i);
}
Now, the ItemListActivity contains a list of Items as {Item1, Item2, Item3}. In ItemListActivity, I am saving the passed "finishIntent" as
///This is ItemListActivity onCreate Method
if(getIntent().hasExtra("FINISH_INTENT"))
mFinishIntent = getIntent().getParcelableExtra("FINISH_INTENT");
and the onItemListSelected method is described as follows :
#Override
public void onItemSelected(String id) {
Config.setLogInState(true);
if(mFinishIntent != null)
{
Log.i("ITEMLISTACTIVITY", "Class Name = " + mFinishIntent.getClass().getName());
Log.i("ITEMLISTACTIVITY", "Starting mFinishIntent Activity");
startActivity(mFinishIntent);
finish();
}
}
But the issue is the Main Activity is not being launched again, Android takes me to the home screen instead. While looking for a solution, I saw that Google I/O app has the same implementation and that works flawlessly but in my case it is not. I am unable to figure it out. Please help.
Thanks in Advance.
Manifest File is as follows :
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.app.myapplication.ItemListActivity"
android:label="#string/app_name" >
</activity>
<activity
android:name="com.app.myapplication.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Ok Here is a quick help which works for 100 percent which I'm using not mostly but EVERYTIME! you must past it through intent and in your case here it is how it must look like.
Intent intent = new intent(//name of your activity in which you are at the moment.this, //name of activity to which you want to go.class);
startActivity(intent);
Hope this will help

Android - activity launched at startup + moveTaskToBack = killed

I work on app that acts like phone guard and should run on startup (or when launched by user) and keep running until user manually won't finish it. When application started (after device boot completed) i use moveTaskToBack for hiding it in background. After about ~12 seconds my application stop working (killed by system i suspect) without any notice, no logs at all (but still stay in history stack). Checked by app timer with log, and also when i start programm by clicking icon - new instance runs. As i noticed, if i execute moveTaskToBack from Handler which delayed even by 500ms - app won't be killed! Tested on galaxy tab 2 (4.1.2) and on alcatel one touch (2.3.6). Here the sample code for reproduce:
MainActivity
public class MainActivity extends Activity
{
Timer timerCheck;
int ticks = 0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timerCheck = new Timer();
timerCheck.schedule(taskCheck, 0, 1000);
if (IsStartup())
moveTaskToBack(true);
// if (IsStartup())
// {
// new Handler().postDelayed(new Runnable()
// {
// #Override
// public void run()
// {
// moveTaskToBack(true);
// }
// }, 1000);
// }
}
TimerTask taskCheck = new TimerTask()
{
#Override
public void run()
{
runOnUiThread(timerTickCheck);
}
private Runnable timerTickCheck = new Runnable()
{
public void run()
{
Log.e("testapp", "alive for " + ++ticks * 1000 + " ms");
}
};
};
private boolean IsStartup()
{
return getIntent().hasExtra("startup");
}
}
StartupReceiver
public class StartupReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context c, Intent i)
{
Intent in = new Intent();
in.setClassName("com.example.startuptest",
"com.example.startuptest.MainActivity");
in.putExtra("startup", "1");
in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
c.startActivity(in);
}
}
manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.startuptest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name="com.example.startuptest.StartupReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity
android:name="com.example.startuptest.MainActivity"
android:label="#string/app_name"
android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
So there is my questions - why android system has such behavior? Anyway to instantly hide app on startup?
The android OS can kill any background process if it needs it's resources. In your case, the system boot is a highly resource-consuming period, and activities in background have quite low priority when it comes to what to keep.
Anyway, if you want something to run in background for a prolonged time, I suggest you to check out services:
http://developer.android.com/guide/components/services.html

Remove or hide notification bar in android

i am developing an application, when the app is open there may be any missed call the notification is displayed,how i hide or remove the notification bar & is there any way to implement it.
i have put all codes like below in my application,
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
and
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen"
but i open an activity file using broadcast receiver, then the notification is seen when missed call or message arrives
You can use this code:
public class FullScreen
extends android.app.Activity
{
#Override
public void onCreate(android.os.Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
}
}
I was having the exact same problem as yours, but I hade it for both incoming and outgoing calls. I found the solution for the incoming calls/ missed calls but not yet for the outgoing calls.
What you are going to do is the following: 1.Create a BroadCastReceiver Class to listen to incoming calls with the highest priority:
a.In the Manifest.xml add:
<receiver android:name=".MyPhoneBroadcastReceiver">
<intent-filter android:priority="99999">
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
b.Then the Class
#Override
public void onReceive(final Context context, Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
String state = extras.getString(TelephonyManager.EXTRA_STATE);
final String incomingNumber = extras.getString("incoming_number");
Handler callActionHandler = new Handler();
Runnable runRingingActivity = new Runnable(){
#Override
public void run() {
//Notice the intent, cos u will add intent filter for your class(CustomCallsReceiver)
Intent intentPhoneCall = new Intent("android.intent.action.ANSWER");
intentPhoneCall.putExtra("INCOMING_NUM", incomingNumber);
intentPhoneCall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intentPhoneCall);
}
};
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
//increase the delay amount if problem occur something like -the screen didn't show up- that's the key about this method(the delay).
callActionHandler.postDelayed(runRingingActivity, 100);
}
if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
callActionHandler.removeCallbacks(runRingingActivity);
}
}
}
2.a.In the Manifest.xml file add this intent filter for the class you will use as a custome call receiver.
<activity android:name="CustomCallsReceiver" android:noHistory="true" android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.ANSWER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
2.b.The CustomeCallsReceiver Class:
public class CustomCallsReceiver extends Activity {
private String TAG = "CustomCallsReceiver";
String incomingNumber, caller;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custome_calls_receiver);
TextView number = (TextView) findViewById(R.id.number);
number.setGravity(Gravity.CENTER);
incomingNumber = getIntent().getExtras().getString("INCOMING_NUM");
caller = getCallerName(incomingNumber);
if (caller != null) {
number.setText(caller + "\n" + incomingNumber); } }
3.And finally of course don't forget to add the Theme for not title or notification bar at the Manifest.XML file
<application
android:theme="#android:style/Theme.NoTitleBar.Fullscreen">
You need to set the theme in Android manifest .xml.. .
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen"
Hope this will help you..
if you set this as application theme it will give effect all the pages of your app..
<application
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
>

Categories

Resources