How to getAssets in a service? - android

I fail to find out how to getAssets in a service.
for example the receiver:
public class BroadcastReceiverOnBootComplete extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) {
Intent serviceIntent = new Intent(context, AndroidServiceStartOnBoot.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(serviceIntent);
} else {
context.startService(serviceIntent);
}
}
}
}
In the AndroidServiceStartOnBoot class, how to get getContext().getAssets().open("server.crt"); ?
Thanks a lot.
Edited:
The question is not how to call getAssets in BroadcastReceiverOnBootComplete class, instead, the question is how to getAssets in the service AndroidServiceStartOnBoot class.
The reason why I posted BroadcastReceiverOnBootComplete class is because that is how I call AndroidServiceStartOnBoot class. Sorry that it's kinda misleading. Thanks.

onReceive gives you the context in your broadcast receiver class
public abstract void onReceive (Context context, Intent intent)
from there, you can use it directly or assign it to your class level variable and you'll be able to use it in other methods as well
Context myContext = null;
#Override
public void onReceive(Context context, Intent intent) {
//here you can access to context directly
context.getAssets().open("MY_FILE");
//or you can save it in your class level variable
myContext = context;
// now you can use this myContext to other methods of this class
}
Edit
Service is an inherent of Context
So in Service, you can directly do like this...
Context context = this;

You already have context
did you try this?
context.getAssets().open("FILE_NAME");
it works for me

Related

is there a difference between using activity context and using application context to sendBroadcast

sendBroadcast can be called on activity context or application context, is there any difference?
another side question if the context is already a application context, I guess doing context.getApplicationContext() would just return itself, right?
one scenario could be passing the activity context to a receiver object which later using this context to bind or lunch other service. This receiver is locally instantiated in a few different activities. The context are referred inside the receiver as below,
If there is no difference maybe it could just pass in the applicationConext to the receiver,
or better could it just get the passed in context in the
onReceive(Context context, Intent intent),
and do context.getApplicationContext there?
// inside the receiver it will the following with the context:
mContext.bindService(new Intent(mContext, OtherService.class), mInitServiceConnection, Context.BIND_AUTO_CREATE);
mContext.unbindService(mInitServiceConnection);
Intent newStartIntent = new Intent(mContext, InitService.class);
mContext.startService(newStartIntent);
the receiver is like:
class LocalBroadcastReceiver extends BroadcastReceiver {
private final Context mContext;
public LocalBroadcastReceiver(#NonNull Context context) {
mAppContext = context;
}
#Override
public void onReceive(Context context, Intent intent) {
// could it here use the context to get application context, like:
mContext = context.getApplicationContext()
//then do something like:
Intent newStartIntent = new Intent(mContext, InitService.class);
mContext.startService(startMailAccountInitIntent);
}
}
I my case using the context to get applicationContext from onReceive() works,
onReceive(Context context, Intent intent) {
var appContext = context.applicationContext
...
mContext.bindService(new Intent(appContext, OtherService.class), mInitServiceConnection, Context.BIND_AUTO_CREATE);
}
cannot use the context which will get
android.content.ReceiverCallNotAllowedException: BroadcastReceiver components are not allowed to bind to services

Clean way to handle multiple intent.getStringExtra within onReceive?

I created a WebService class that handles multiple different requests to a web service, this class Broadcast's and intent with a different key depending on what method was originally called in the WebService class. I'm stuck on how to properly handle this on the WebServiceReceiver...
Here's the important part from the WebService:
//Broadcast the intent with data received from service call.
broadcastIntent.putExtra(broadcastIntentKeyName, response.toString());
sendBroadcast(broadcastIntent);
Here's my onReceive:
public class WebServiceReceiver extends BroadcastReceiver
{
public WebServiceReceiver() {}
#Override
public void onReceive(Context context, Intent intent) {
Debug.waitForDebugger();
//NOTE: Not sure if i'm approaching this the right way, sure doesn't seem like it...
//Its possible that some of these will be NULL.
String GetRequestForRouteWithDriverId_DATA = intent.getStringExtra("Helper_GetRequestForRouteWithDriverId");
String StoreDataInServer_DATA = intent.getStringExtra("Helper_StoreDataInServer");
String SubmitDriverRouteData_DATA = intent.getStringExtra("Helper_SubmitDriverRouteData");
MainActivity.getInstance().updatetextViewControl(GetRequestForRouteWithDriverId_DATA);
}
}
What I have does work, But like I mentioned in my code comment, it doesn't feel like its the proper way.
Is there a better way to approach this? I simply want to re-use this onReceive to handle all WebService Broadcasts.
Maybe you can use Intent.setAction() method
broadcastIntent.setAction("Your action");
broadcastIntent.putExtra("Your Extra");
sendBroadcast(broadcastIntent);
Then on your receiver...
public class WebServiceReceiver extends BroadcastReceiver
{
public WebServiceReceiver() {}
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals("Your Action")){
String yourExtra = intent.getStringExtra("Your extra")
}
}
}

Why am I getting getApplicationcontext() null?

I'm not sure whats wrong in it! I read here that Intentservice is itself a subclass of Context.
public class GCMNotificationIntentService extends IntentService {
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
Context mainContext;
WriteFile writeFile;
public GCMNotificationIntentService() {
super("GcmIntentService");
mainContext = getApplicationContext();
writeFile = new WriteFile(mainContext);
}
// My rest of the code
}
but I'm getting null value for mainContext.
Any suggestions are most welcome.
In the constructor it is way too early to access the app context. Try to move this code into the onCreate method.
More datails about the life cycle can be found in the documentation
You should be calling this in your onCreate method, not the constructor. In the constructor, the application context has not been set up yet, so it will be null.
To get application context in a good way, you should use in following way.
Use following way
Step 1
Create an Application class
public class MyApplication extends Application{
private static Context context;
public void onCreate(){
super.onCreate();
MyApplication.context = getApplicationContext();
}
public static Context getAppContext() {
return MyApplication.context;
}
}
Step 2
In Android Manifest file declare following
<application android:name="com.xyz.MyApplication">
...
</application>
Step 3
Use following method to call Application context anywhere in your application.
MyApplication.getAppContext();
Like,
public class GCMNotificationIntentService extends IntentService {
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
Context mainContext;
WriteFile writeFile;
public GCMNotificationIntentService() {
super("GcmIntentService");
mainContext = MyApplication.getAppContext();
writeFile = new WriteFile(mainContext);
}
// My rest of the code
}
Use GCMNotificationIntentService.this or simply this instead of mainContext.
IntentService extends Service which is itself a subclass of Context

Updating Textview in an Activity with Local Service

I have an Activity with R.id.eventDistance and R.id.eventTime to display the distance & travel time based on current location. I calculate these values every 30 seconds using my Location Service class.
My question is: how do I update the TextView in Activity? I've tried looking up the question and found some possible solutions such as using a BroadcastReceiver and call TextView.setText() in the onReceive() method. I'm not sure how this is done. Am I supposed to pass in the Activity class like this:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, HomeActivity.class);
}
}
I'm not sure what to do after that. Any help is appreciated.
please see this flow.
1.in your LocationService class when you want to update UI. in your case it should be called every 30 seconds.
Intent i = new Intent("LOCATION_UPDATED");
i.putExtra("<Key>","text");
sendBroadcast(i);
2.in your UI (HomeActivity) class
in onCreate()
registerReceiver(uiUpdated, new IntentFilter("LOCATION_UPDATED"));
in class
private BroadcastReceiver uiUpdated= new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
TextView.setText(intent.getExtras().getString("<KEY>"))
}
};
in onDestroy()
unregisterReceiver(uiUpdated);
You should bind your Activity to your service so that they can directly communicate and message pass.
Ref
http://developer.android.com/guide/components/bound-services.html

Calling service method from its class

I have a service from which I instationate my ScreenReceiver class. How can I notify service when OnRecieve method of ScreenReceiver is triggered? I'd like the update() method to be called when 'onRecieve` is trigerred.
StateChecker.java (draft):
public class StateChecker extends Service {
//...
// setting TimeAlarm
TimeAlarm mTimeAlarm = new TimeAlarm();
mTimeAlarm.SetAlarm(this.getApplicationContext(),10);
public void update() {
//update sth
}
//...
}
ScreenReceiver.java (draft):
public class ScreenReceiver extends BroadcastReceiver {
//...
#Override
public void onReceive(Context context, Intent intent) {
//...
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
}
//...
}
You can probably do something like this:
Make a new Intent to your Service from the Receiver, passing off an Extra, then override onStartCommand() in the Service. Check the intent for the Extra, and if the Extra exists, call update().
Also, if you use this instead of this.getApplicationContext(), it is very likely that your Receiver's onReceive() Context parameter will be the service. Then you can just cast.
Eg
if (context instanceof StateChecker)
((StateChecker) context).update();
Define an interface and use a callback to let the activity know that a screen event has been received.
public Interface ScreenReceiverListener {
void onScreenReceive(int arg1, string arg2); ..<----add arguments you want to pass back
}
In your ScreenReceiver class
ArrayList<ScreenReceiveListener > listeners = new ArrayList<ScreenReceiveListener >();
...
public void setScreenReceiveListener(ScreenReceiveListener listener){
listeners.add(listener);
}
In your OnReceive
for (ScreenReceiveListener listener:listeners){
listener.onSCreenReceive(arg1, arg2);
}
In your Service:
public class StateChecker extends Service implements ScreenReceiveListener {
...
screenReceiver.setScreenReceiveListener(this);
...
}
public void onScreenReceive(int arg1, string arg2){
// do whatever you need to do
}
All from memory so please excuse typos and you should improve the ScreenReceiver class by adding removeScreenReceiveistener and checking that you do not add the same listener twice in setScreenReceiveListener.
Note. Because you use an interface, any class (not just a Service) can implement it so you can update anywhere in your app. The ScreenReceiver class doesn't know or care. It just calls the listeners, if any are registered.

Categories

Resources