This should be very simple and I'm really not sure what is going wrong. I have created a SMSReceiver java class that basically receives messages and then gives them to my MainActivity. When the onReceive() function fires, the app crashes because it is having issues sending the data back to MainActivity. It has been throwing a NullPointerException on the Zout() call in onReceive().
Here is the SmsReceiver class:
package ...; //you don't need to see my dumb package name.
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
import java.util.ArrayList;
public class SmsReceiver extends BroadcastReceiver {
ArrayList<String> phoneNumbers;
ArrayList<String> textMessages;
private Activity mainAct; //our reference to MainActivity
//very simple constructor
public SmsReceiver() {
}
//this function is called in onCreate() in MainActivity to provide reference to MainActivity
public void SetSMSReceiverActivity(Activity a){
mainAct = a;
//talk to our main activity
MainActivity mainComm = (MainActivity)mainAct;
mainComm.Zout("SMSReceiver initialized bro"); //this works just fine
}
#Override
public void onReceive(Context context, Intent intent) {
//THIS IS WHAT CAUSES ISSUES! This call to MainActivity does NOT work for whatever reason. Rude.
MainActivity mainComm = (MainActivity)mainAct;
mainComm.Zout("This message won't send"); //this does NOT work fine for whatever reason. Throws NullPointerException.
//...more code down here that actually works!
}
}
The function Zout() in my MainActivity is a simple print to TextView for debugging purposes. I will be using a function in MainActivity to receive the data once onReceive() stops being moody.
I'm sorry if this is a dumb question. I haven't programmed in Java for a few years and I'm quite rusty. I have no idea why this isn't working. I'll be tossing out +1's to whoever can help!
I believe it is because you have not initialized your mainAct variable.
for onCreate(){}
you do initialize
mainAct = a;
but not for onReceive.
Related
I am creating a hook using AndHook to test some functions getting called. I need to show a Toast inside a method without being able to get the context object (I can't directly import MainActivity because I am injecting the script without having the corresponding package when compiling so I can't use MainActivity.this). Here's the code sample:
import andhook.lib.HookHelper;
import android.widget.Toast;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
public class AndHookConfig {
#HookHelper.Hook(clazz = BitmapFactory.class)
private static Bitmap decodeFile(BitmapFactory thiz, String path) {
Toast.makeText(Class.forName("com.example.activity.MainActivity").this, "Bitmap.decodeFile("+path+")", Toast.LENGTH_LONG).show();
return (Bitmap)(HookHelper.invokeObjectOrigin(thiz, path));
}
}
I think the only way to do this is using reflection but the code sample doesn't compile and results in an error. Do you have any solutions ?
Thanks in advance.
I'm following this tutorial to get started with Bluetooth:
https://www.youtube.com/watch?v=y8R2C86BIUc
I want to outscource the bluetooth enable to an separated class and call it from the MainActivity.
I made the new Intent, but following the Video I'm not possible to start the Intent.
I tried importing:
android.support.v7.app.AppCompatActivity;
android.support.v4.content.ContextCompat;
But in both cases it didn't worked out.
Without any imports Android Studio is telling "Can't resolve method"
MAIN
package com.example.lenkzeitapplikation_01;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startBT.switch_BT_ON();
}
}
STARTBT
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.support.v4.content.ContextCompat;
import com.fleetboard.sdk.lib.android.log.Log;
public class startBT {
private static final String Tag ="StartBT";
static BluetoothAdapter mBluetoothAdapter;
public static void switch_BT_ON(){
if(mBluetoothAdapter == null){
Log.d(Tag, "No BT adapter");
}if(!mBluetoothAdapter.isEnabled()){
Intent enableBTIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(enableBTIntent);
//mBluetoothAdapter.enable();
}
}
}
Using
import android.support.v4.content.ContextCompat:
Error:
method startActivity in class ContextCompat cannot be applied to given types;
required: Context,Intent,Bundle
found: Intent
reason: actual and formal argument lists differ in length
Important
Ok, first things first:
Activity is one of the different types of Context.
AND:
startActivity is a method that Context objects have.
Explanation
If you want to start an Activity, you must use a Context object. That's why it was working in the first place, in your MainActivity.
Now that you moved the code to another class, if you wan to use the method startActivity, you must have a reference to a Context object.
But... How?
public class startBT {
public static void switch_BT_ON(Context context){
//... Your logic
context.startActivity(intent);
}
}
In your activity:
startBT.switch_BT_ON(this);
The this parameter is the MainActivity itself, which is a Context by definition.
It means that:
switch_BT_ON requires a Context.
MainActivity is saying: "Here, use me".
Recommendations
This is classic, basic OOP thinking. Study about Object-Oriented Programming, classes and inheritance to learn why the startActivity method worked on the Acivity and not outside of it, passing objects around and handling different scopes.
Read the quick answer about what is an Android Context. Or adventure yourself through the documentation.
My codenameone application crashes anything I use this native code
package com.mycompany.interfaces;
import android.app.Application;
import android.content.Context;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.messaging.FirebaseMessaging;
public class InitialiseApp extends Application{
private static Context context;
public static Context getContext() {
return context;
}
#Override
public void onCreate()
{
super.onCreate();
context = getApplicationContext();
try
{
FirebaseApp.initializeApp(this, new FirebaseOptions.Builder().
setApiKey("XXXXXXXXXXXXXX").
setApplicationId("XXXXXXXX").
setGcmSenderId("XXXXXXXXXX")
.build());
FirebaseInstanceId.getInstance().deleteInstanceId();
FirebaseInstanceId.getInstance().getToken("XXXXXXXXXX",FirebaseMessaging.INSTANCE_ID_SCOPE);
FirebaseMessaging.getInstance().subscribeToTopic("test");
}
catch(Exception c)
{
c.printStackTrace();
}
}
}
I declare the class in the android.xapplication_attr android:name="com.mycompany.interfaces.InitialiseApp"
Need a assistance
Are you putting this in the native interface stub or in the CN1 part of the code?
Also, I don’t think that’s how you get a context in CN1. Look in the developer guide and video tutorials for Native Interfaces. I also recall a series of blog posts about native interfaces that dive into writing the Android code. You’ll need to use something from the AndroidNativeUtil class like: AndroidNativeUtil.getActivity().
I an trying to create an application thet will catch the incoming calls to the cellphone using a BroadcastReciver. From my BroadcastReciver i whould like to sent the number as an event to my JS file using this method.
I have checked that my Java code is working and is catching the calls and number but my application craches with the error that mentions that the react context is null. I am guessing that this is because the manifest (or something) is creating a new instance of the class when the event from the android system is catched and that the new instance does not have a ReactContext. Is there any way to access the ReactContext from the Java code or send a ReactContext to the BroadcastReciver through the manifest?
This is my BroadcastReciver:
package com.bridgetest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.bridge.JavaScriptModule;
import android.widget.Toast;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;
import javax.annotation.Nullable;
/**
* Created by Erik on 2016-04-06.
*/
public class BroadcastReceiverCustom extends BroadcastReceiver {
ReactContext reactContext;
public BroadcastReceiverCustom (){
}
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)) {
// This code will execute when the phone has an incoming call
// get the phone number
String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
Toast.makeText(context, "Call from:" +incomingNumber, Toast.LENGTH_LONG).show();
sendCallEvent(incomingNumber);
} else if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_IDLE)
|| intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_OFFHOOK)) {
// This code will execute when the call is disconnected
Toast.makeText(context, "Detected call hangup event", Toast.LENGTH_LONG).show();
}
}
public void sendCallEvent(String incomingNumber){
WritableMap params = Arguments.createMap();
params.putString("Number", incomingNumber);
sendEvent("CallRecevied", params);
}
private void sendEvent(String eventName,
#Nullable WritableMap params) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
}
As Fury's solution did not work for me(got "cannot find symbol" for getApplication()) in the broadcast receiver, i tried applying a similar logic with what i knew is working. So:
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.ReactApplication;
...
// context - is the context you get from broadcastreceivers onReceive
ReactApplication rnApp = (ReactApplication) context.getApplicationContext();
rnApp.getReactNativeHost().getReactInstanceManager()
.getCurrentReactContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("test", Arguments.createMap());
This worked for me.
I faced a same problem and am using this.
((MainApplication)getApplication()).getReactNativeHost().getReactInstanceManager().getCurrentReactContext()
I solved the problem. I created a ReactContextBaseJavaModule with a singleton pattern and got access to ReactContext through it (This might be a huge "nono").
If there is another smarter way to solve this problem, please inform me.
You can access reactContext like this:
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
ReactInstanceManager reactInstanceManager = getReactNativeHost().getReactInstanceManager();
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
if(reactContext != null) {
// Use reactContext here
} else {
reactInstanceManager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
#Override
public void onReactContextInitialized(ReactContext context) {
// Use context here
reactInstanceManager.removeReactInstanceEventListener(this);
}
});
}
Method is undefined for the type in Eclipse. Can't seem to solve it. The error is in the lines: msg.setTimestamp( System.currentTimeMillis() ); and msg.setBody("this is a test SMS message");
package com.example.smsnotification;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
public class PopSMSActivity extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Retrieve serializable sms message object by the key "msg" used to pass to it
Intent in = this.getIntent();
PopMessage msg = (PopMessage) in.getSerializableExtra("msg");
//Case where we launch the app to test the UI EG: No incoming SMS
if(msg==null){
msg = new PopMessage();
con.setPhone("0123456789");
msg.setTimestamp( System.currentTimeMillis() );
msg.setBody("this is a test SMS message");
}
showDialog(msg);
}
Remove the code and write it back to eclipse. It worked for me....You can try copy and paste to after writing signature of function/class.
This means the PopMessage class doesn't provide the methods setTimestamp(long) and setBody(String).
There is no import statement for PopMessage in your code so I assume it is a class which you have implemented and is contained in the same package as the Activity which you have posted.
So you could either solve this by implementing those two methods in PopMessage or by removing the calls.
You may also extend your Eclipse Settings by activating the "save Actions" (Window->Preferences->Java->Editor->Save Actions) and use the Option "Organize Imports". This would at least add the propbably missing Import "...PopMessage" while you press Ctrl+S.