Here is the code.
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
MyClass myClass = new MyClass(this);
Cursor cursor = myClass.getCursor();
startManagingCursor(cursor);
}
}
public class MyClass Extends ImageButton {
private Context context;
public MyClass(Context context) {
this.context = context;
}
public Cursor getOncreate() {
Intent intent = new Intent();
intent.setClassName(MyClass.this,MyActivity.class);
context.startActivity(intent);
}
}
I want to start MyActivity from MyClass. I am getting NullPointer exception at
ctx.startActvity(intent);
Could you please suggest me how to make it correct.
try calling
startActivity(intent);
instead of
ctx.startActivity(intent);
Let one of the parameters of the start activity method be of type Context:
public void methodStartActivity(Context context) {
Intent intent = new Intent(context, MyActivity.class);
context.startActivity(intent);
}
Related
I am working on ReactNative-Native bridging.
I have Module as below
public class DemoModules extends ReactContextBaseJavaModule {
private Callback mCallback;
private static ReactApplicationContext reactContext = null;
private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {
#Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data)
{
String transactionId = data.getStringExtra("TEST_ID");
mCallback.invoke(transactionId);
}
};
DemoModules(ReactApplicationContext context) {
super(context);
reactContext = context;
reactContext.addActivityEventListener(mActivityEventListener);
}
#Override
public String getName() {
return "DemoModules";
}
#ReactMethod
public void navigate(String mData,Callback mCallback) {
Activity currentActivity = getCurrentActivity();
Intent mIntent= new Intent(reactContext, TestActivity.class);
mIntent.putExtra("TOKEN",mData);
mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.mCallback = mCallback;
currentActivity.startActivityForResult(mIntent,2, null);
}
}
I am calling navigate method as below from my ReactNative code
DemoModules.navigate("TestToken",mCallback => {
console.log(`Created a new event with id ${mCallback}`);
},)}
This navigates to another activity which is TestActivity from which I need to revert with some result so In next Activity I am doing as below
val resultIntent = Intent()
resultIntent.putExtra("TEST_ID", "TEST")
setResult(Activity.RESULT_OK, resultIntent)
finish()
So Summarising it
From React Native>Demo Modules>TestActivity>OnActivityResultback to DemoModules>The final result should be delivered to ReactNative code.
But I am not getting any callback in onActivityResult
What I am missing here?
Update
The main issue currently is onActivityResult is not called in DemoModules.
I have a fragment MyFragment
public class MyFragment extends Fragment {
//Some code here like to constructor
//Trying to pass an object to another Activity
Intent i = new Intent(getActivity(), NextActivity.class);
startActivity(i);
i.putExtra("test", parcableObject);
getActivity().finish();
}
And I have an activity NextActivty
public class NextActivity extends AppCompatActivity {
//Some code here like to constructor
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.next_activity);
Intent intent = getIntent();
mBoard = intent.getParcelableExtra("test");
Log.d(TAG, "onCreate: " + mBoard);
}
Here is my Board class
public class Board implements Parcelable {
//Implements all the Parcelable methods.
protected Board(Parcel in) {
//Auto-generated code here
}
public static final Creator<Board> CREATOR = new Creator<Board>() {
//Auto-generated code here
}
#Override
public int describeContents() {
//Auto-generated code here
}
#Override
public void writeToParcel(Parcel dest, int flags) {
//Auto-generated code here
}
}
My mBoard is always null.
Is there something I am not doing right here ?
You put your extra in wrong order. Put it before you start your activity.
public class MyFragment extends Fragment {
//Some code here like to constructor
//Trying to pass an object to another Activity
Intent i = new Intent(getActivity(), NextActivity.class);
i.putExtra("test", parcableObject);
startActivity(i);
getActivity().finish();
}
How can i make a callback to an Activity form a Java Class?
Example:
public class TestClass{
String text = "Test";
public TestClass(Context context){
startActivity(new Intent(context, SomeActivity.class));
}
private void sendToSomeActivity(){
//Call some method of SomeActivity and pas text as string
}
}
When sendToSomeActivity() is called, i want to make a callback to the already started SomeActivity and pass some text to the Activity. In SomeActivity i want to use the text.
Note: The TestClass object that i want to use is already created in another class.
How can this be done?
The solution I chose is as follows:
Use BroadcastReceivers to communicate between Java classes and Activities.
Example:
public class SomeActivity extends Activity{
private MyBroadcastReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
receiver = new MyBroadcastReceiver();
this.registerReceiver(receiver, new IntentFilter(MyBroadcastReceiver.ACTION));
}
#Override
public void onDestroy() {
super.onDestroy();
this.unregisterReceiver(receiver);
}
private class MyBroadcastReceiver extends BroadcastReceiver{
public static final String ACTION = "com.example.ACTION_SOMETHING"
#Override
public void onReceive(Context context, Intent intent) {
String test = intent.getStringExtra("dataToPass");
}
}
}
public class TestClass{
private String test = "TEST";
private Context context;
public TestClass(Context context){
this.context = context;
}
private void sendToSomeActivity(){
Intent intent = new Intent();
intent.setAction(SomeActivity.MyBroadcastReceiver.ACTION);
intent.putExtra("dataToPass", test);
context.sendBroadcast(intent);
}
}
Try this..
public class TestClass{
interface Implementable{
public void passData(String text);
}
Implementable imple;
String text = "Test";
public TestClass(Context context){
startActivity(new Intent(context, SomeActivity.class));
}
private void sendToSomeActivity(){
if(imple != null){
imple.passData(text);
}
}
public void setListener(Implementable im){
imple = im;
}
}
class SomeActivity implements Implementable{
new TestClass().setListener(this);
#override
public void passData(String text){
//here is your text
}
}
In your java class create an interface like this
public class TestClass{
private MyInterface myInterface;
public interface OnSendSomething {
public void onSending(String sendWhateverYouWant);
}
public void setOnSendListener(MyInterface myInterface) {
this.myInterface = myInterface;
}
}
private void sendToSomeActivity(){
//Call some method of SomeActivity and pas text as string
myInterface.onSending(sendWhateverYouWant);
}
And in your activity do something like this:
TestClass tclass = new TestClass(context);
tclass.setOnSendListener(new OnSendSomething () {
#Override
public void onSending(String sendWhateverYouWant) {
//sendWhateverYouWant is here in activity
}
});
You can also visit these links for better understanding.
How to create our own Listener interface in android?
Observer Design Pattern in Java
How to call an activity from another class to a non-Activity class?
My code is as follows (Activity Class)
public void onCreate(Bundle savedInstanceState){super.onCreateSavedInstanceState);
this.mp();
}
public MediaPlayer mp(){//insert method here// }
Then in my non activity class i call
Intent i = new Intent();
i.setClassName(".......process", ".....ActualRenderingMedia");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
however if I try to use context.startActivity it will give an error asking me to create the activity method. I can't use getApplicationContext.startActivity either.
Is your non-Activity class instantiable? If so, you can add a constructor to the class that accepts a Context Object, and instantiate it from your main Activity.
For example, in you non-Activity class:
public class MyClass {
Context context;
public MyClass(Context context) {
this.context = context;
}
public void someOtherMethod() {
Intent i = new Intent(...);
context.startActivity(i);
}
}
And in your main Activity:
MyClass myclass = new MyClass(this);
...
myclass.someOtherMethod();
Here's a BroadcastReceiver from my project, which I'm looking to unit test. When the user makes a phone call, it grabs the phone number, and sets up an intent to start a new activity, passing in the phone number.
public class OutgoingCallReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context xiContext, Intent xiIntent)
{
if (xiIntent.getAction().equalsIgnoreCase(Intent.ACTION_NEW_OUTGOING_CALL))
{
String phoneNum = xiIntent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Intent intent = new Intent(xiContext, MyActivity.class);
intent.putExtra("phoneNum", phoneNum);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
xiContext.startActivity(intent);
setResultData(null);
}
}
}
So far, my unit test looks like this:
public class OutgoingCallReceiverTest extends AndroidTestCase
{
private OutgoingCallReceiver mReceiver;
#Override
protected void setUp() throws Exception
{
super.setUp();
mReceiver = new OutgoingCallReceiver();
}
public void testStartActivity()
{
Intent intent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL);
intent.putExtra(Intent.EXTRA_PHONE_NUMBER, "01234567890");
mReceiver.onReceive(getContext(), intent);
}
}
This runs through the code, but I want my test to be able to check that the intent was sent out, and to check the phone number on it. How do I do this?
Can I also test that the phone call gets cancelled (because of the setResultData(null) line)?
corlettk pointed me at the MockContext object in Android, which does the trick. I've made a subclass of it, TestContext, which looks like this:
public class TestContext extends MockContext
{
private List<Intent> mReceivedIntents = new ArrayList<Intent>();
#Override
public String getPackageName()
{
return "com.mypackage.test";
}
#Override
public void startActivity(Intent xiIntent)
{
mReceivedIntents.add(xiIntent);
}
public List<Intent> getReceivedIntents()
{
return mReceivedIntents;
}
}
And my test case now looks like this:
public class OutgoingCallReceiverTest extends AndroidTestCase
{
private OutgoingCallReceiver mReceiver;
private TestContext mContext;
#Override
protected void setUp() throws Exception
{
super.setUp();
mReceiver = new OutgoingCallReceiver();
mContext = new TestContext();
}
public void testStartActivity()
{
Intent intent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL);
intent.putExtra(Intent.EXTRA_PHONE_NUMBER, "01234567890");
mReceiver.onReceive(mContext, intent);
assertEquals(1, mContext.getReceivedIntents().size());
assertNull(mReceiver.getResultData());
Intent receivedIntent = mContext.getReceivedIntents().get(0);
assertNull(receivedIntent.getAction());
assertEquals("01234567890", receivedIntent.getStringExtra("phoneNum"));
assertTrue((receivedIntent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0);
}
}
Matt,
Sounds like you need to mock-up a Context ... and then swap your methods over to accepting interfaces instead of concrete classes: public void onReceive(IContext c, IIntent i), just for the purposes of testing. But then the Context and Intent classes aren't yours are they... they're Android's... so you can't "just" make them implement your interfaces, so you'd have to "wrap" them in order to expose a your interface, which is RATHER a lot of code for not much gain. Very Yucky!!!
So I started to wonder if someone's been through all this before, and done the hard-yards for us... and tada: http://developer.android.com/reference/android/test/mock/package-summary.html
Cheers. Keith.
Since this question was asked mocking Frameworks have evolved pretty much. With mockito you can now mock not only interfaces but as well classes. So I would suggest to solve this problem by mocking a context and using ArgumentCapture:
import static org.mockito.Mockito.*;
public class OutgoingCallReceiverTest extends AndroidTestCase {
private OutgoingCallReceiver mReceiver;
private Context mContext;
#Override
protected void setUp() throws Exception {
super.setUp();
//To make mockito work
System.setProperty("dexmaker.dexcache",
mContext.getCacheDir().toString());
mReceiver = new OutgoingCallReceiver();
mContext = mock(Context.class);
}
public void testStartActivity() {
Intent intent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL);
intent.putExtra(Intent.EXTRA_PHONE_NUMBER, "01234567890");
mReceiver.onReceive(mContext, intent);
assertNull(mReceiver.getResultData());
ArgumentCaptor<Intent> argument = ArgumentCaptor.forClass(Intent.class);
verify(mContext, times(1)).startActivity(argument.capture());
Intent receivedIntent = argument.getValue();
assertNull(receivedIntent.getAction());
assertEquals("01234567890", receivedIntent.getStringExtra("phoneNum"));
assertTrue((receivedIntent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0);
}
}