Flutter - Is possible to import a Fragment inside a Flutter App? - android

In Flutter is possible to call Java code from Dart. Also, the plugin android_intent allows to start a Java Android Activity using Dart code
But, if we want to use an Android Fragment inside a Flutter Widget, is this possible? How can we do that?
Or the only way to use Fragments is declaring a new Activity in Java, and call to start the Activity in Flutter? (Like I said at the beginning)

So far I couldn't find any way to implement directly implement, in a straight forward manner, android components inside a flutter app. However is possible the opposite things, that is using a Flutter fragment inside an android application. So I can propose you a workaround for this problem that may lead to the same result:
use a method channel to start a new android activity:
void startAndroidActivity() async {
//TODO: fix result type, etc.
dynamic result = await MethodChannel("CHANNEL_X").invokeMethod('METHOD');
}
public class MainActivity extends FlutterActivity {
private MethodChannel.Result result;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new MethodChannel(getFlutterView(), "CHANNEL_X").setMethodCallHandler((call, result) -> {
if (call.method.equals("METHOD")) {
Intent intent = new Intent(this, MyActivity.class);
this.result = result;
startActivityForResult(intent, data);
}
});
GeneratedPluginRegistrant.registerWith(this);
}
//TODO: Handle result
}
Implement your android components and import the flutter fragment. For this topic, I leave you this reference: https://flutter.dev/docs/development/add-to-app/android/add-flutter-fragment
Another reference I can give you is this one, that maybe can allow you to import what you want in Flutter, but it requires a bit more time: https://medium.com/#KarthikPonnam/build-your-own-plugin-using-platformviews-flutter-5b42b4c4fb0a

Related

Get parameters from android to unity

I have a problem, i want to send a parameter (int) from an app of build in android studio and receive it in an app build it in unity.
The apps work like this, you open the android app, press a botom and open the second app, i send and intent when i open the unity app but idkhow to recieve the param.
I know that are some questions about this but didn't work or maybe idk how to implement it to my code.
This is how i send the param
Java app
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.bodyar");
if(user!=null){
launchIntent.putExtra(Constant.TYPE,user.getLearningStyleId());
}else{
launchIntent.putExtra(Constant.TYPE,Constant.VISUAL);
}
startActivity(launchIntent);
but i dont know how to receive the value. I tried the stuff of UnityPlayer.UnitySendMessage(), but u just get an error from that
And the funciton of the Script that it´s attached to GameObjectUI is this
public void TipoTest(string token){
prueba.text = token;
}
And when i export the unity project to android, in the method OnCreate I recieve the params like this
public class UnityPlayerActivity extends Activity {
protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code
// Setup activity layout
#Override protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
mUnityPlayer = new UnityPlayer(this);
setContentView(mUnityPlayer);
mUnityPlayer.requestFocus();
}
#Override protected void onNewIntent(Intent intent) {
// To support deep linking, we need to make sure that the client can get access to
// the last sent intent. The clients access this through a JNI api that allows them
// to get the intent set on launch. To update that after launch we have to manually
// replace the intent with the one caught here.
setIntent(intent);
}
}
And It works but idk how to pass the variable to unity script

Activity method gets call before oncreate in android from the other class

I have a scenario where I have created library project in which I am loading the layout as well defining the method which I want to call from the Application project.
public class LibraryActivity {
public LibraryActivity() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.barchart_layout);
bindViews();
}
public void bindViews() {
bChart = (BarChart)findViewById(R.id.barchart);
}
public void setData(int count, float range) {
//definition of the method
// I have to user bChart view here
System.out.println("part 1 "+bChart); <---- this is null
}
Now I have successfully created the AAR project and I want to use this setData from the other project.
So when I run this From the other project By using below code
Intent in = new Intent(MainActivity.this,LibraryActivity.class);
startActivity(in);
LibraryActivity barChartCallBack = new LibraryActivity();
LibraryActivity.setData(15,25);
I got the null pointer on the bChart because my method setData got call first before oncreate so findviewbyid gives me null for the bChart.
You are setting the data on a completely different LibraryActivity object. First you tell the system with the intent to start one, then you start another one that does not get displayed, but you use it to call setData.
Read up on the android developer site:
https://developer.android.com/training/basics/firstapp/starting-activity.html
Basically you need to pass the data via extras in with the intent.

Xamarin Forms and Facebook Android SDK issues

I'm working on Xamarin.Forms app with Parse backend. I am trying to integrate Facebook Android SDK into that. What I want to do is to get the access token natively on each device, and push that access token to Parse.com. For that I need to use official facebook sdk binding for Xamarin. I use dependency injection for that. so I have IFacebookService
public interface IFacebookService
{
Task<string> GetFacebookToken();
void LogOut();
}
And on each platform I implement FacebookService and inject that implementation. On iOS I had no problems. On Android the problem is that even though the facebook UI is shown, I don't receive the callbacks inside my implementation of FacebookService. I think that has something to do with how Android manages callbacks as well as how Xamarin.Forms creates activities. Let me go through the code. Here is the portion of code to request login from Facebook
var callbackManager = CallbackManagerFactory.Create();
//Here I instantiate my own implementation of IFacebookCallback
//nothing fancy here, I've just implemented the required methods with Console.WriteLine();
var loginCallback = new FacebookCallback(() => _loginInProgress = false);
//Register callbackManager and my instance of loginCallback
LoginManager.Instance.RegisterCallback (callbackManager, loginCallback);
//Here is the important part. I need an activity to show the login UI
//Xamarin forms provides me with this method.
var activity = Xamarin.Forms.Forms.Context as Activity;
//I request login
LoginManager.Instance.LogInWithReadPermissions(activity, new string[] { "public_profile", "email", "user_friends" });
So, I believe the problem is within this line
var activity = Xamarin.Forms.Forms.Context as Activity;
In the debugger I see that MainActivity is returned, which is my entry point (MainLauncher = true), and where I call Xamarin Form's initialisation methods
//Setup Xamarin forms
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new FormsApp());
The initial page that is registered in FormsApp is call LoginPage. So I believe that it is loaded as a fragment inside main activity. So, perhaps I'll need to do something like this
LoginManager.Instance.LogInWithReadPermissions(LOGIN_PAGE_FRAGMENT,......);
because in facebook sdk there are separate versions for activity and fragment. I don't know exactly how to get LOGIN_PAGE_FRAGMENT, perhaps even the issue is in some other place, which I don't understand.
Do you have any ideas what can cause the issue?
I've resolved the issue! I've found something similar here
Although my approach is a little different, but the main issue was that I needed to add the implementation of OnActivityResult to the MainActivity and create CallbackManager inside the MainActivity and delegate the OnActivityResult to that CallbackManager. So in MainActivity I added this property
public ICallbackManager CallbackManager { get; private set; }
Then I've overridden OnActivityResult like this
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
CallbackManager.OnActivityResult(requestCode, (int)resultCode, data);
}
Then I've replaced the previous login code with this
var loginCallback = new FacebookCallback(() => _loginInProgress = false);
var activity = Xamarin.Forms.Forms.Context as MainActivity;
LoginManager.Instance.RegisterCallback (activity.CallbackManager, loginCallback);
LoginManager.Instance.LogInWithReadPermissions(activity, new string[] { "public_profile", "email", "user_friends" });
And Everything worked! Hope this will help someone.

Android startActivityforResult from java which does NOT extend Activity

For a Bluetooth library I want to call a startActivityForResult to enable Bluetooth. I want to do this in my own library project. The problem is that sartActivityForResult only works for Activities, my library is not an activity, of course my project using this library project is having an activity. I tried two things
1.
Had my library to extend Activity, so I am creating the object like a normal POJO. Hence when calling startActivityForResult it throws a null pointer.
2.
Tried to get my Activity to pass it into the constructor of my library object. I am not able to to get an activity object, only context but that doesn't help.
What can I do?
EDIT: Some Code
I have the following class in my library project:
public class mylib
{
public mylib()
{
// Do some bluetooth setup thing here
// figure out that bluetooth is not enabled so try to enable it now
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
onActivityResult()
{
// Report back that BT is enabled now
}
}
Then I have of course my Android application using this library project in onCreate() I do something like this
public class Myactivity() extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
// do all the normal stuff
mylib pojo = new mylib(); // This creates a POJO which needs to startActivityForResults(...), see above code
}
}
The two options I mentioned above
I don't see how I can convince mylib to call startActivityForResult doing
public class mylib extends Activity
doesn't seem to do the trick.
I could overload my constructor of mylib to pass in the activity object, I have no idea how to create the activity object.
Hope that makes it a bit clearer.
You can create a constructor of your java class which has parameter of type Activity like below,
public class MyClass
{
private Activity activity;
public MyClass ( Activity activity )
{
this.activity = activity;
}
}
Now you can use this activity variable to call startAcvitiyForResult from your Java class.

java.lang.NullPointerException for static field in Android library project

First to explain how projects are setup:
Android Library project with two classes:
UserActivity - uses static field in HolderClass
HolderClass - this one has static field Data
Android Application that references Library project, has only one class:
StarterActivity - when app is started, in onCreate it sets static field Data to some value, and it starts UserActivity
Now, the problem is: sometimes I get java.lang.NullPointerException for that static field Data - as if I never initialized it (or value got deleted in meantime). It never happened on my test device, but I keep getting error reports from client devices. I can only guess how that happens - maybe user navigates away from app, then comes back and system recreates whole application context, but in that context HolderClass has empty static field Data?
My question:
Is initialization of that static field from Activity's onCreate wrong approach? Should I put data in ApplicationContext? Or do something else?
I am open for all suggestions.
P.S. If you have problem visualizing from description, here is how everything I've said would look in code:
// IN ANDROID APP PROJECT
public class StarterActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// just start activity in library
Intent myIntent = new Intent(this, AutolaunchActivity.class);
startActivityForResult(myIntent, 1);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// exit when activity from library exits
finish();
}
}
// IN LIBRARY PROJECT
public class HolderClass {
public static String Data;
}
public class UserActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// init layout
}
public void someButtonClicked() {
HolderClass.Data.trim();
}
}
The usual ways of sharing data between activities is documented here. The intermittent nature of the error suggests a timing problem to me. Are you using threads in some of your initialization? Also, do you know if the NPE happening in StarterActivity or UserActivity?
OK, this was basically the problem of global variables - in the end I've solved it by reading this answer: How to declare global variables in Android?

Categories

Resources