i am getting a lot of reports from users about my app crashing. The constant error appears to be associated with my parse.com initialisation, however, i have set it up as outlined in the parse tutorial.
here is the Stack Trace:
java.lang.RuntimeException: Unable to start receiver com.parse.ParseBroadcastReceiver: java.lang.RuntimeException: applicationContext is null. You must call Parse.initialize(context, applicationId, clientKey) before using the Parse library.
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2580)
at android.app.ActivityThread.access$1700(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1397)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: applicationContext is null. You must call Parse.initialize(context, applicationId, clientKey) before using the Parse library.
at com.parse.Parse.checkContext(Parse.java:606)
at com.parse.Parse.getApplicationContext(Parse.java:214)
at com.parse.ManifestInfo.getContext(ManifestInfo.java:322)
at com.parse.ManifestInfo.getPackageManager(ManifestInfo.java:330)
at com.parse.ManifestInfo.getPackageInfo(ManifestInfo.java:356)
at com.parse.ManifestInfo.deviceSupportsGcm(ManifestInfo.java:441)
at com.parse.ManifestInfo.getPushType(ManifestInfo.java:210)
at com.parse.PushService.startServiceIfRequired(PushService.java:168)
at com.parse.ParseBroadcastReceiver.onReceive(ParseBroadcastReceiver.java:19)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2573)
... 10 more
and here is my initialisation code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_screen);
Parse.initialize(this, "hGG5RdgNVdI7eCeZynV32lWYXywQRHkpp5zLdY7Q", "TwmNbpBYEt4u3euE3lzNIgwyroSl8RPGF2dJFsPv");
ParseInstallation.getCurrentInstallation().saveInBackground();
Can anybody see what is causing this error, and how to fix it?
below is my receiver code:
public static class Receiver extends ParsePushBroadcastReceiver {
private String notificationText;
private Boolean notificationreceived = false;
public Receiver(){
}
private static final String TAG = "MyNotificationsReceiver";
#Override
public void onPushOpen(Context context, Intent intent) {
Log.e("Push", "Clicked");
Intent i = new Intent(context, HomeScreen.class);
notificationreceived = true;
i.putExtra("alert",notificationText);
i.putExtra("alertreceived", notificationreceived);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
Scb998.scb988b=true;
try {
JSONObject json = new JSONObject(intent.getExtras().getString("com.parse.Data"));
Scb998.msg = json.getString("alert");
} catch (JSONException e) {
Log.d(TAG, "JSONException: " + e.getMessage());
}
}
}
Move you Parse initialization into your App class (extended from Application)
public class App extends Application {
#Override
public void onCreate() {
super.onCreate();
Parse.initialize(this, "hGG5RdgNVdI7eCeZynV32lWYXywQRHkpp5zLdY7Q", "TwmNbpBYEt4u3euE3lzNIgwyroSl8RPGF2dJFsPv");
ParseInstallation.getCurrentInstallation().saveInBackground();
}
}
And of course refer to it your AndroidManifest.xml
<application
android:name=".app.App"
....
</application>
Reason of crash is next. When your app is at background, it can be killed by system. From Google guide
A process holding an activity that's not currently visible to the user (the activity's onStop() method has been called). These processes have no direct impact on the user experience, and the system can kill them at any time to reclaim memory for a foreground, visible, or service process. Usually there are many background processes running, so they are kept in an LRU (least recently used) list to ensure that the process with the activity that was most recently seen by the user is the last to be killed. If an activity implements its lifecycle methods correctly, and saves its current state, killing its process will not have a visible effect on the user experience, because when the user navigates back to the activity, the activity restores all of its visible state. See the Activities document for information about saving and restoring state.
When you app receives push notification, then parse will not be initialized, because you initialize it at activity onCreate method, which won't be called.
Related
I think im not clear at all, i do want the service to persist even if the main activity is destroyed via user action or android system does it, it does it well, but when the app is reopened at certain point i will want to check if a bg activity exists and stop it using a action button, THX in advance.
I launch a background service, in my MainActivity I can stop it and rerun it, the service persists when the app is closed from the running apps list, the problem is when I relaunch the closed app an try to stop the service with a button I have the app crashes cause it obviously tries to stop a service from which it no longer has a reference.
private void startBg(){
if (!hasPermissions() || mScanning) {
return;
}
clearLogs();
BgServiceIntent = new Intent(MainActivity.this, BgScanService.class);
startService(BgServiceIntent);
}
private void stopBg(){
stopService(BgServiceIntent);
}
Calling stopBg() after reopening the app fails, because BgServiceIntent no longer points to this service and thus I get this:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: mobile.link.imbera.apsys.imberalink, PID: 20104
java.lang.NullPointerException
at android.app.ContextImpl.validateServiceIntent(ContextImpl.java:1568)
at android.app.ContextImpl.stopServiceCommon(ContextImpl.java:1628)
at android.app.ContextImpl.stopService(ContextImpl.java:1589)
at android.content.ContextWrapper.stopService(ContextWrapper.java:499)
at mobile.link.imbera.apsys.imberalink.MainActivity.stopBg(MainActivity.java:180)
at mobile.link.imbera.apsys.imberalink.MainActivity.lambda$onCreate$1$MainActivity(MainActivity.java:124)
at mobile.link.imbera.apsys.imberalink.MainActivity$$Lambda$1.onClick(Unknown Source)
at android.view.View.performClick(View.java:4463)
at android.view.View$PerformClick.run(View.java:18770)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5333)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
at dalvik.system.NativeStart.main(Native Method)
If the service already running in background then you need to call stopSelf() on same instance of that service .
Now as per service life Cycle onCreate() only call once in the lifetime of service .
WhereAs onStartCommand get called each time you call startService() with new intent. So what you can do is to pass a flag in intent to stop it .
Intent BgServiceIntent = new Intent(MainActivity.this, BgScanService.class);
BgServiceIntent.putExtra("close",true);
startService(BgServiceIntent);
And in Service .
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
boolean shouldClose=intent.getBooleanExtra("close",false);
if(shouldClose){
stopSelf();
} else {
// Continue to action here
}
return START_STICKY;
}
Maybe all you need to do is check to see if it's null before attempting to stop it:
private void stopBg(){
if(BgServiceIntent != null)
stopService(BgServiceIntent);
}
First of all start a service in START_NOT_STICKY.
Override this method in your Service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
and add this in your MainActivity.class
#override
private onDestroy() {
stopService(YourActiveService);
finishAffinity();
super.onDestroy()
}
I want to call the activity method from broadcast receiver onReceive method which will be called once the alarm gets triggered.
Below is my Home Activity code snippet
public class HomeActivity extends Activity{
public static HomeActivity mHomeActivity = null;
protected void onCreate(Bundle savedInstanceState) {
}
public void startLocationReporting(){
...........//Logic to start the location reporting
}
public void stopLocationReporting(){
...........//Logic to stopthe location reporting
}
}
Below Broadcast receiver will be triggered based on the alarm we configured
public class AlarmReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
// Here context is application context not an HomeActivity instance
//Below code works fine when the app is in foreground
if (HomeActivity.mHomeActivity != null) {
HomeActivity.mHomeActivity.startLocationReporting();
}
//Static references are cleared once the app quits.
//How to start location reporting when the app is quitted
}
}
Please help me on this.
How to the call the methods of an Activity from broadcast receiver
once the app is quited?
Calling methods from class by creating object of class which extends Activity class will cause following major issues:
1. token android.os.BinderProxy#43756de8 is not valid; is your activity running? when trying to accessing any service using Activity context with is not running
2. NullPointerException when accessing views in calling methods.
or may other issues are also possible...
Try to implement logic using IntentService :
A. Create separate class with startLocationReporting and stopLocationReporting by passing all required parameters.
By doing this you will access both methods from Activity or from any other components
B. Create a IntentService for doing task and start it when onReceive method called. By this application will do long running task in background so call startLocationReporting and stopLocationReporting by passing all required parameters in IntentService
I want to know if the service was terminated from a particular activity, so I'm passing a string from that activity while calling stopServivce(service).
Here's the code :
Intent service = new Intent(Activity.this,
service.class);
service.putExtra("terminate", "activity terminated service");
stopService(service);
But I can seem to access this variable with getIntent().getExtras().getString("terminate); in the onDestroy() method.
[EDIT]
I found a way around this obstacle, but I'd like my question to still be answered. I just did whatever I had to do in the onDestroy() method in the activity and then called stopService(service). I was lucky that my situation didn't need anything more complicated.
There is no way of accessing the Intent in onDestroy. You have to signal the service some other way (Binder, Shared Preferences, Local Broadcast, global data, or Messenger). A nice example of using broadcast is given in this answer. You can also get this to work by calling startService instead of stopService. startService only starts a new services if one does not already exist, so multiple calls to startService is mechanism yo send Intents to the service. You see this trick is use by BroadcastReceivers. Since you have access to the Intent in onStartCommand, so you can implement termination by check the Intent extras and calling stopSelf if instructed to terminate. Here is a sketch of it in action --
public int onStartCommand(Intent intent, int flags, int startId) {
final String terminate = intent.getStringExtra("terminate");
if(terminate != null) {
// ... do shutdown stuff
stopSelf();
}
return START_STICKY;
}
Just to illustrate what iagreen suggests;
In Activity
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.package.yourfilter");
broadcastIntent.putExtra("activity_name", "your_activity");
sendBroadcast(broadcastIntent);
In Service
private YourActionReceiver abc;
this.abc = new YourActionReceiver();
registerReceiver(this.abc, new IntentFilter("com.package.yourfilter"));
public class YourActionReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Get the name of activity that sent this message
}
}
Global State
is your friend. :)
Check a Global String whenever you need to (say before terminating). You may also want to have an enumeration state. Or a flag to see if state is valid.
Recipe:
The more general problem you are encountering is how to save state across several Activities and all parts of your application. A static variable (for instance, a singleton) is a common Java way of achieving this. I have found however, that a more elegant way in Android is to associate your state with the Application context.
As you know, each Activity is also a Context, which is information about its execution environment in the broadest sense. Your application also has a context, and Android guarantees that it will exist as a single instance across your application.
The way to do this is to create your own subclass of android.app.Application, and then specify that class in the application tag in your manifest. Now Android will automatically create an instance of that class and make it available for your entire application. You can access it from any context using the Context.getApplicationContext() method (Activity also provides a method getApplication() which has the exact same effect):
class MyApp extends Application {
private String myState;
public String getState(){
return myState;
}
public void setState(String s){
myState = s;
}
}
class Blah extends Activity {
#Override
public void onCreate(Bundle b){
...
MyApp appState = ((MyApp)getApplicationContext());
String state = appState.getState();
...
}
}
class BlahBlah extends Service {
#Override
public void onCreate(Bundle b){
...
MyApp appState = ((MyApp)getApplicationContext());
String state = appState.getState();
...
}
}
This has essentially the same effect as using a static variable or singleton, but integrates quite well into the existing Android framework. Note that this will not work across processes (should your app be one of the rare ones that has multiple processes).
Credits go to #Soonil
I am trying to get this Service to open another app upon start up using the URI in the code. My BroadcastReciever and manifest have the correct code so I suspect it is something in this mainActivity.
I am using Eclipse and there are no errors or warning but when run on the phone i get the following error:
Unfortunately anyConnectService has stopped
The LogCat has the following as the first error:
FATAL EXCEPTION MAIN
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.anyconnect/com.anyconnectservice,MainActivity}
Please glance at the following code and offer a solution.
Thanks
public abstract class MainActivity extends Service
{
#override
public void onCreate()
{
super.onCreate();
Toast.makeText(this, “Service created”,Toast.LENGTH_LONG).show();
Uri anyConnectUri = Uri.parse(“anyconnect://connect/name= TestVPN”);
Intent arg0 = new Intent(Intent.ACTION_VIEW, anyConnectUri);
this.startActivity(arg0);
}
}
I guess you should have to set component:
intent.setComponent(new ComponentName("com.package.address","com.package.address.MainActivity"));
You are calling an Activity that can VIEW the content of data you put in the Intent.
But if you do not have any installed applications that listens for a message of type: Intent.ACTION_VIEW, and accepts a Uri, then most probably the application will throw an exception.
From your description: service to open **another app**.
Well, it seems that "another app" can not be found.
Shouldn't that be (no abstract):
public class MainActivity extends Service
{
#override
public void onCreate()
{
super.onCreate();
Toast.makeText(this, “Service created”,Toast.LENGTH_LONG).show();
Uri anyConnectUri = Uri.parse(“anyconnect://connect/name= TestVPN”);
Intent arg0 = new Intent(Intent.ACTION_VIEW, anyConnectUri);
this.startActivity(arg0);
}
}
Though you might want to change the name of the class to better reflect its use, as this is as services and not an activity.
I have an intentservice that gets qued by the user and by my app automatically. I need to be able to kill all pending intents that are qued when the user logs out of my application, but I cannot seem to get that to work. I have tried stopService() and stopself(), but the intents continue to fire off the intentservice after the user has logged out. I would try to get the id of the intent but that is difficult as everytime the intentservice starts, the variable holding the intent id's is empty. Here is my intentservice code:
public class MainUploadIntentService extends IntentService {
private final String TAG = "MAINUPLOADINTSER";
private GMLHandsetApplication app = null;
private SimpleDateFormat sdf = null;
public boolean recStops = true;
public MainUploadIntentService() {
super("Main Upload Intent Service");
GMLHandsetApplication.writeToLogs(TAG,
"GMLMainUploadIntentService Constructor");
}
#Override
protected void onHandleIntent(Intent intent) {
GMLHandsetApplication.writeToLogs(TAG, "onHandleIntent Started");
if (app == null) {
app = (GMLHandsetApplication) getApplication();
}
uploadData(app);
GMLHandsetApplication.writeToLogs(TAG, "onHandleIntent Finished");
}
#Override
public void onDestroy() {
GMLHandsetApplication.writeToLogs(TAG, "onDestroy Started");
app = null;
stopSelf();
GMLHandsetApplication.writeToLogs(TAG, "onDestroy completed");
}
public void uploadData(GMLHandsetApplication appl) {
//All of my code that needs to be ran
}
Unfortunately, I don't think it's possible to accomplish that with the standard IntentService methods since it doesn't offer a way to interrupt it while it's already going.
There are a few options I can think of that you can try to see if they fit your need.
Copy the IntentService code to make your own modifications to it that would allow you to remove pending messages. Looks like someone had some success with that here: Android: intentservice, how abort or skip a task in the handleintent queue
Instead of copying all the IntentService code, you might also be able to Bind to it like a normal Service (since IntentService extends Service) so you can write your own function to remove pending messages. This one is also mentioned in that link.
Rewrite the IntentService as a regular Service instead. With this option, you'd have more control over adding and removing messages.
I had what sounds like a similar situation where I was using an IntentService, and I eventually just converted it to a Service instead. That let me run the tasks concurrently and also cancel them when I needed to clear them.
Here
When should I free the native (Android NDK) handles? is the HangAroundIntentService class that has the method cancelQueue().
The class also has the method
public static Intent markedAsCancelIntent(Intent intent)
that converts an intent into a cancel intent, and
public static boolean isCancelIntent(Intent intent).
The class is based on the open-sourced Google's code.
Just a thought but inside of your onhandleintent can you have an argument that checks to see if app is running if not then don't run the code? example. In the start of your app you could have a static var
boolean appRunning;
Next in your onhandle of the intent, when you set the appRunning to false, after an onPause or onDestroy of activity, you could wrap the onhandleintent code in a boolean:
protected void onHandleIntent(final Intent intent) {
if(MainActivity.appRunning){
...
}
}
Just a thought