Executing Code in system process - android

i like to know is there way to execute code in system app process in android.
i found through pending intent we can assign our job to execute in foreign application like alarm manager or notification but still i found job gets execute in same application process .for clear understanding
Here i'm creating alarm manager on buttonclick event.
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Log.d("processstatus", "pid="+android.os.Process.myPid());
//creating an alarm manager
alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, customreciever.class);
pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,SystemClock.elapsedRealtime() +10*1000, pendingIntent );
}
});
Through below code, i receive the broadcast event which gets triggered every interval of 10 sec through alarmmanager.
public class customreciever extends BroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
// Same app process id expecting alaramanager process id
Log.d("processstatus", "pid="+android.os.Process.myPid());
}
}
inside onReceive method i expect different process id other than application process.if this is not possible through pending intent,suggest me any other approach to achieve this.

You cannot run code in a system process. That would be a huge security hole.
Using a PendingIntent lets you delegate the triggering of code to another user/process/application, but the code still runs in your application with your user ID and your permissions.

Related

Keep service alive after app has been destroyed

I'm developing an app that need to do some check in the server every certain amount of time. The check consist in verify if there are some notification to display. To reach that goal I implemented Service, Alarm Manager and Broadcast Reciever. This is the code that I'm using so far:
public class MainActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
setRecurringAlarm(this);
}
/**
*
* #param context
*/
private void setRecurringAlarm(Context context) {
Calendar updateTime = Calendar.getInstance();
Intent downloader = new Intent(context, MyStartServiceReceiver.class);
downloader.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, downloader, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), 60000, pendingIntent);
}
...
}
Receiver class
public class MyStartServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent dailyUpdater = new Intent(context, MyService.class);
context.startService(dailyUpdater);
Log.e("AlarmReceiver", "Called context.startService from AlarmReceiver.onReceive");
}
}
Service class
public class MyService extends IntentService {
public MyService() {
super("MyServiceName");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.e("MyService", "Service running!");
// TODO Do the hard work here
this.sendNotification(this);
}
private void sendNotification(Context context) {
// TODO Manage notifications here
}
}
Manifest.xml
<!--SERVICE AND BROADCAST RECEIVER-->
<service
android:name=".MyService"
android:exported="false"/>
<receiver
android:name=".MyStartServiceReceiver"
android:process=":remote"/>
The code works fine, the task in the service will be excecuted periodically. The problem is that the service is destroyed when the app is forced to close. I need to keep alive the service, capable to execute the task, even if the user has closed the app, so the user can be updated via notifications. Thank you for your time!
You can't. If the app is forced closed, that means either its crashed (in which case the service has to be stopped as it may no longer work correctly) or the user force closed it in which case the user wants the app to stop- which means the user doesn't want the service to run. Allowing a service to be automatically restarted even if the user stops it would be basically writing malware into the OS.
In fact, Android went the exact opposite (and correct) way- if the user force stops an app, NOTHING of the app can run until the user runs it again by hand.
You may go through this. I hope this will solve your problem. If you want to keep awake your service it is practically not possible to restart the app which is forced close. So if you disable force stop your problem may be solved.

IntentService is killed when app is stopped

I've this IntentService:
public class ServiceUpdateNewResults extends IntentService{
private void setAlarmToCheckUpdates() {
Calendar calendar = Calendar.getInstance();
//calendar.add(Calendar.DAY_OF_YEAR, 1); //dema
//calendar.set(Calendar.HOUR_OF_DAY, 22); //a les 10
calendar.add(Calendar.SECOND, 20);
Intent myIntent = new Intent(this.getApplicationContext(), ReceiverCheckUpdates.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, myIntent,0);
AlarmManager alarmManager = (AlarmManager)this.getApplicationContext().getSystemService(this.getApplicationContext().ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
}
public ServiceUpdateNewResults() {
super("ServiceUpdateNewResults");
}
#Override
protected void onHandleIntent(Intent intent) {
//fem les coses.
//Toast.makeText(this.getApplicationContext(), "holaa", Toast.LENGTH_LONG).show();
setAlarmToCheckUpdates();
Log.d("debugging","hello");
}
}
And this is calling a BroadCastReceiver every 20 seconds, which ends up calling this service, and this is going to happen "forever". (in a future it will be 1 day, not 20 seconds).
This is the Receiver:
public class ReceiverCheckUpdates extends BroadcastReceiver{
Context context;
#Override
public void onReceive(Context context, Intent intent){
this.context = context;
Intent service1 = new Intent(context, ServiceUpdateNewResults.class);
context.startService(service1);
}
}
This is working perfectly, but if I stop the app from Android settings, the service is also stopped. I want to avoid this. I want that if the App is closed, the service should keep working.
Is it possible?
Actually, when is a service killed ?
if I stop the app from Android settings, the service is also stopped
If by "stop the app from Android settings", you mean that you press the Force Stop button, your app will not run again until something manually runs one of your components (e.g., user launches your activity). More specifically in this case, your alarms are unscheduled.
I want to avoid this.
Then do not press the "Force Stop" button.
I want that if the App is closed, the service should keep working.
In any non-"Force Stop" scenario, the alarms will keep firing (at least until the device falls asleep, given your current implementation).
The IntentService is part of your app. If the system destroys your app, it will destroy the IntentService. You can reduce the chances of this happening by putting the IntentService in a separate process, but you can't stop the system from destroying an IntentService. You can make it highly unlikely that the system will destroy a Service; to do that, you use a "foreground" Service. However, you should avoid doing this unless you really really need to. In addition, you can't have a foreground IntentService, so you'll have to add your own background Handler and HandlerThread.

delay in alarmmanager .. when two alarms exists simultaneously

I have scheduled multiple alarm managers to send intents at different times.
I took care to pass unique ID, context and extras to both the pending intents.
below func handles the alarm calls.
.
public void handle(int duration, int id){
Intent intent = new Intent("package.SET");
intent.putExtra ("package.id", Id);
AlarmManager amg = (AlarmManager)Context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pis = PendingIntent.getBroadcast(Context,Id, intent, FLAG_ONE_SHOT);
amg.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + time, pis); }
there are 2 functions calling the alarm
public void callalarm(int time){
handle(time, UNIQUE_ID1);}
and
public void callalarm2(int time){
handle(time, UNIQUE_ID2);}
I took care that unique ID1 and Unique_ID2 are different.
The broadcast receiver handles the alarm and executes another code.
Is there a possibility that Callalarm1 and callalarm2 interfere with eachother .
I have registered the receiver using registerReceiver function and not in android manifest file.
IntentFilter ARFilter = new IntentFilter();
ARFilter.addAction("package.SET");
context.registerReceiver(AR, ARFilter);
In the AR that extends broadcast receiver, i use the id to define the action.
public BroadcastReceiver AR= new BroadcastReceiver()
{ public void onReceive(Context context, Intent intent)
{ // i do some stuff here which is confidential
}}
The problem is that, I get a delay in the alarms. Is there a reason why there is a delay ?
As of What I know, The Alarm MAnager cannot fire at right times when the task burden on the processor is heavy.
In other words, the broadcast receiver does not receive intent on time since the alarm manager adds the broadcast to the queue which is sent with some delay..
Precise information is helpful.

Android AlarmManager execution time problem

I have set a AlarmManager which will give alarm repeatedly after certain time. I used following code for that.
Intent intent = new Intent(ViewDoughnut.this, NotificationMessage.class);
PendingIntent sender = PendingIntent.getBroadcast(ViewDoughnut.this, 0, intent,PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP,nextAlarmTime, alarmInterval, sender);
Now to execute proper work at the alarm time I have created the following class extending BroadcastReceiver. Now I need the time in millisecond when the Alarm work should execute in that class. How to get it?
public class NotificationMessage extends BroadcastReceiver {
// Display an alert that we've received a message.
// #Override
public void onReceive(Context context, Intent intent) {
// here I need the time when the alarm should execute.
}
}
Here I like to add, system time is not working for me, because if the device is switch off at the alarm time, it execute that when the device is on after that time. But I need the time when it should execute.
You could create a class that derives from Application which holds all global variables. Then just set a long variable to hold the time before initialising the alarm

Android-Broadcast Receiver

I am new to android. I what to know the difference between Intent and BroadcastReceiver. I am more confused with BroadcastReceiver than Intent.
Please help me out. Simple code will be helpful.
Ok, I will explain it with an example.
Let's suppose I want to create an app to check subway status from it's webpage. I also want a system notification if the subway is not working ok.
I will have:
An Activity to show results.
A Service to check if the subway is working and show a notification if it's not working.
A Broadcast Receiver called Alarm Receiver to call the service every 15 minutes.
Let me show you some code:
/* AlarmReceiver.java */
public class AlarmReceiver extends BroadcastReceiver {
public static final String ACTION_REFRESH_SUBWAY_ALARM =
"com.x.ACTION_REFRESH_SUBWAY_ALARM";
#Override
public void onReceive(Context context, Intent intent) {
Intent startIntent = new Intent(context, StatusService.class);
context.startService(startIntent);
}
}
Explanation:
As you can see you can set an alarm. and when the alarm is received we use an intent to start the service. Basically the intent is a msg which can have actions, an serialized stuff.
public class StatusService extends Service {
#Override
public void onCreate() {
super.onCreate();
mAlarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intentToFire = new Intent(AlarmReceiver.ACTION_REFRESH_ALARM);
mAlarmIntent = PendingIntent.getBroadcast(this, 0, intentToFire, 0);
}
#Override
public void onStart(Intent intent, int arg1) {
super.onStart(intent, arg1);
Log.d(TAG, "SERVICE STARTED");
setAlarm();
Log.d(TAG, "Performing update!");
new SubwayAsyncTask().execute();
stopSelf();
}
private void setAlarm() {
int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;
mAlarms.setInexactRepeating(alarmType, SystemClock.elapsedRealtime() + timeToRefresh(),
AlarmManager.INTERVAL_HALF_DAY, mAlarmIntent);
}
}
Explanation:
The service starts and:
Set the alarm for the next call. (Check the intent it's used. Just a msg)
Calls an AsyncTask which takes care of updating an notifying the Activity
It doesn't make sense to paste the AsyncTask but when it finished it calls:
private void sendSubwayUpdates(LinkedList<Subway> subways) {
Intent intent = new Intent(NEW_SUBWAYS_STATUS);
intent.putExtra("subways", subways);
sendBroadcast(intent);
}
This creates a new Intent with a certain NEW_SUBWAYS_STATUS action, put inside the intent the subways and sendBroadcast. If someone is interested in getting that info, it will have a receiver.
I hope I made myself clear.
PS: Some days ago someone explained broadcast and intents in a very cool way.
Someone wants to share his beer, so he sends a broadcast
with an intent having action:"FREE_BEER" and with an extra: "A glass of beer".
The API states:
A BroadcastReceiver is a base class for code that will receive intents sent by sendBroadcast().
An intent is an abstract description of an operation to be performed.
So, a BroadcastReceiver is just an Activity that responds to Intents. You can send your own broadcasts or even the Android Device can send these system wide broadcasts including things like the battery is low, or the device just booted-up.

Categories

Resources