Using Callback and OnnActivityResult with ReactContextBaseJavaModule in ReactNative - android

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.

Related

How to set data in Activity and get in java class

Updated :
I have build a image cropping app its running fine, but now I want to save cropped image name as textbox value.
In short I am trying to set textbox value in object and get object value in java Class. I have tried several techniques, recently I am trying to get,set data by using interface technique and the image is saved as ".jpg"only.
I would love to know where am I going wronk?
Following is the code I have tried.
MainActivity
public class TestActivity extends AppCompatActivity implements CropHandler, View.OnClickListener {
public static final String TAG = "TestActivity";
ImageView mImageView;
EditText formnumber;
String formid;
CropParams mCropParams;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
mCropParams = new CropParams(this);
mImageView = (ImageView) findViewById(R.id.image);
formnumber =(EditText)findViewById(R.id.FormNumber);
findViewById(R.id.bt_crop_capture).setOnClickListener(this);
findViewById(R.id.bt_crop_gallery).setOnClickListener(this);
}
#Override
public void onClick(View v) {
mCropParams.refreshUri();
formid=formnumber.getText().toString();
// Intent i = new Intent(TestActivity.this, CropHelper.class);
// i.putExtra("Id",formid);
if(formid.matches(""))
{
Toast.makeText(getApplicationContext(),"Please Enter Application Id",Toast.LENGTH_SHORT).show();
}
else
{
switch (v.getId()) {
case R.id.bt_crop_capture: {
mCropParams.enable = true;
mCropParams.compress = false;
Intent intent = CropHelper.buildCameraIntent(mCropParams);
startActivityForResult(intent, CropHelper.REQUEST_CAMERA);
}
break;
case R.id.bt_crop_gallery: {
mCropParams.enable = true;
mCropParams.compress = false;
Intent intent = CropHelper.buildGalleryIntent(mCropParams);
startActivityForResult(intent, CropHelper.REQUEST_CROP);
}
break;
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
CropHelper.handleResult(this, requestCode, resultCode, data);
if (requestCode == 1) {
Log.e(TAG, "");
}
}
#Override
public void onTaskComplete(String response) {
onTaskComplete(this.formid);
}
}
CropHelper Class
public class CropHelper {
public static final String TAG = "CropHelper";
/**
* request code of Activities or Fragments
* You will have to change the values of the request codes below if they conflict with your own.
*/
public static final int REQUEST_CROP = 127;
public static final int REQUEST_CAMERA = 128;
public static final int REQUEST_PICK = 129;
public static String AppId;
public static final String CROP_CACHE_FOLDER = "PhotoCropper";
public static Uri generateUri() {
File cacheFolder = new File(Environment.getExternalStorageDirectory() + File.separator + CROP_CACHE_FOLDER);
if (!cacheFolder.exists()) {
try {
boolean result = cacheFolder.mkdir();
Log.d(TAG, "generateUri " + cacheFolder + " result: " + (result ? "succeeded" : "failed"));
} catch (Exception e) {
Log.e(TAG, "generateUri failed: " + cacheFolder, e);
}
}
// String name = String.format("image-%d.jpg", System.currentTimeMillis());
String name = String.format(AppId.toString()+".jpg",System.currentTimeMillis());
return Uri
.fromFile(cacheFolder)
.buildUpon()
.appendPath(name)
.build();
}
#Override
public void onTaskComplete(String response) {
AppId=response;
}
}
Interface
public interface CropHandler
{
void onPhotoCropped(Uri uri);
void onCompressed(Uri uri);
void onTaskComplete(String response);
void onCancel();
void onFailed(String message);
void handleIntent(Intent intent, int requestCode);
CropParams getCropParams();
}
Set formid to EditText value and get the return value in your CropHelper class.
public static String formid=null;
formid=formnumber.getText().toString();
Now create an object of your Activity in a class where you want to call formid value.
MainActivity my_objec= new MainActivity();
String id= my_objec.formid;
String name = String.format(""+id+".jpg",System.currentTimeMillis());
thats all you need to do.
Implement this with your class and get return back your value in interface
public interface onTaskComplete {
void onComplete(String response);
}
Normally what i do is create different class which holds/save all data and values which can used across differnt classes in app.
For example:
// your activity
private CropHelper cropHelper;
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CropHelper.REQUEST_CROP) {
cropHelper.onReceivedImageData(data.get...)
}
}
public interface DataCallBack {
public void OnReceivedImageData(Data data);
}
....
// your crop helper
public class CropHelper implements YourActivity.DataCallBack {
#Override
public void OnReceivedImageData(Data data) {
// doing anything with data
}
}
Best Approach for this is using interface try to do as :
Create Interface
public interface MyListener {
// you can define any parameter as per your requirement
public void callback(View view, String result);
}
public class MyActivity extends Activity implements MyListener {
#override
public void onCreate(){
MyButton m = new MyButton(this);
}
// method invoke when mybutton will click
#override
public void callback(View view, String result) {
// do your stuff here
}
}
public class MyButton {
MyListener ml;
// constructor
MyButton(MyListener ml) {
this.ml = ml;
}
public void MyLogicToIntimateOthere() {
ml.callback(this, "success");
}
}
for more Go to this link:
Using Interface
Pass data through arguments in constructor..,
For example.. Create Constructor in your class.
public class CropHelper {
private Context context;
private String msg;
public CropHelper(Context context, String msg) {
this.context = context;
this.msg = msg;
if (msg != null) {
showMsg(msg);
}
}
//Replace with your logic
void showMsg(String msg) {
//Perform your operation
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
}
And then simple call it from any Activity by Creating instance of that class..
Like..
new CropHelper(this, "Hello from Activity");

Android make callback to an Activity from java class

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

starting BroadcastReceiver or IntentService from non-activity class

How to start BroadcastReceiver or IntentService from non-activity class
by start I mean send intent and make run BroadcastService or IntentService
I.e:
I have class:
public class NumberOne{
#Override
public int functionOne(){
int i = 1 + 4;
if(/*something is true*/){
Intent intent = new Intent(this,intetServiceOne.class);
intent.putExtra("id","path");
context.startService(intent);
}
else {/*continue*/
}
return i;
}
//other functions
}
and if a condition in functionOne is true start IntentService
public class IntentServiceClassOne extends IntentService {
public IntentServiceClassOne () {
super("IntentServiceClassOne ");
}
#Override
protected void onHandleIntent(Intent intent) {
String data = intent.getStringExtra("id");
Log.d("dataIs: ", data);
}
//more functions what to do
}
It dont depend if it is IntentService or BroadcastReceiver
Thanks
To start service You need context instance. You can pass it as constructor parameter:
public class NumberOne{
Context context;
public NumberOne(Context context){
this.context = context;
}
public int functionOne(Context context){
int i = 1 + 4;
if(/*something is true*/){
Intent intent = new Intent(this,intetServiceOne.class);
intent.putExtra("id","path");
context.startService(intent);
}
else {/*continue*/
}
return i;
}
//other functions
}
You don't have to pass Activity instance, Context is enough. It can be application context. You can get it by getApplicationContext() method
You can also create static instance in Application object and get it from them:
public class YourApplication extends Application {
public static YourApplication INSTANCE;
public void onCreate(){
super.onCreate();
INSTANCE = this;
}
}
And your class will be look like below.
public class NumberOne{
public int functionOne(Context context){
int i = 1 + 4;
if(/*something is true*/){
Intent intent = new Intent(this,intetServiceOne.class);
intent.putExtra("id","path");
YourApplication.INSTANCE.startService(intent);
}
else {/*continue*/
}
return i;
}
//other functions
}
But is not good solution.
And the last you can create callback listener and set it in your class like below:
public class NumberOne{
//add setter
YourListener yourListener;
public int functionOne(Context context){
int i = 1 + 4;
if(/*something is true*/){
if(yourListener != null){
yourListener.onFunctionOneCall();
}
}
else {/*continue*/
}
return i;
}
//other functions
public interface YourListener{
void onFunctionOneCall();
}
}
And some place where you have context - for example in activity:
numberOneInstance.setYourListener(new YourListener(){
#Override
public void onFunctionOneCall(){
Intent intent = new Intent(this,intetServiceOne.class);
intent.putExtra("id","path");
this.startService(intent);
}
});
or you can set context by setter
public class NumberOne{
Context context;
public setContext(Context context){
this.context = context;
}
public int functionOne(Context context){
int i = 1 + 4;
if(/*something is true*/){
if(context != null){
Intent intent = new Intent(this,intetServiceOne.class);
intent.putExtra("id","path");
context.startService(intent);
}
}
else {/*continue*/
}
return i;
}
//other functions
}

How to implement CordovaInterface so that I can use camera in the webview?

I am new to Android.
I embedded Cordova WebView on my Android app by following the tutorial.
I already successfully load a webpage from my server by using CordovaWebView.
Let's say that I have a button on that webPage called "Capture Photo", what should I do to call the local API so that I can use the camera?
The tutorial suggest that I need to implement the CordovaInterface to use camera in the way as follow.
#Override
public void setActivityResultCallback(CordovaPlugin plugin) {
this.activityResultCallback = plugin;
}
I don't know what exactly is activityResultCallback. Is there another tutorial to show me how to implement this interface?
Since nobody answer my question.
I find a tutorial that can solve this problem.
Update:
Given that the link is broken, I'll post my own code for implementing the Cordova Interface.
// Instance for CordovaInterface
private final ExecutorService threadPool = Executors.newCachedThreadPool();
private boolean mAlternateTitle = false;
private boolean bound;
private boolean volumeupBound;
private boolean volumedownBound;
private CordovaPlugin activityResultCallback;
private Object activityResultKeepRunning;
private Object keepRunning;
public Activity getActivity() {
return this;
}
#Deprecated
public Context getContext() {
return this;
}
public ExecutorService getThreadPool() {
return threadPool;
}
public void setActivityResultCallback(CordovaPlugin plugin) {
this.activityResultCallback = plugin;
}
public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) {
this.activityResultCallback = command;
this.activityResultKeepRunning = this.keepRunning;
// If multitasking turned on, then disable it for activities that return
// results
if (command != null) {
this.keepRunning = false;
}
// Start activity
super.startActivityForResult(intent, requestCode);
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
final CordovaPlugin callback = this.activityResultCallback;
if (callback != null) {
// Need to use background thread
this.getThreadPool().execute(new Runnable() {
public void run() {
callback.onActivityResult(requestCode, resultCode, intent);
}
});
}
}

How to start Activity from java class in Android

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);
}

Categories

Resources