How to use a CustomApplication class in a Flutter Plugin - android

I am generating a plugin in Flutter that will integrate a native library *.aar and this library needs to be initialized in the Application class of android, since it will extend the Application class of the library. The problem I am having is that at no time does it seem that the Application class is used in the Flutter plugin, I have tried to create the application class and define it in the plugin manifest, but at no time does it seem to enter the onCreate. I do not see how to solve this situation, any indication is welcome.
My class Application:
public class App extends SDKApplication{
#Override
public void onCreate() {
super.onCreate();
Log.e("App", "onCreate");
}
}
My manifest
<application
android:name=".App">
</application>
and the plugin class:
public class SdkPlugin implements FlutterPlugin, MethodCallHandler {
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private MethodChannel channel;
private EMTingSDK sdk = EMTingSDK.getInstance();
private Context context;
public SdkPlugin(){
Log.e("PRUEBAS","onMethodCall");
new App();
}
#Override
public void onAttachedToEngine(#NonNull FlutterPluginBinding flutterPluginBinding) {
context = flutterPluginBinding.getApplicationContext();
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), Constants.CHANNEL);
channel.setMethodCallHandler(this);
}
#Override
public void onMethodCall(#NonNull MethodCall call, #NonNull Result result) {
Log.e("PRUEBAS","onMethodCall");
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
}else {
result.notImplemented();
}
}
#Override
public void onDetachedFromEngine(#NonNull FlutterPluginBinding binding) {
channel.setMethodCallHandler(null);
}
}
P.D: I need to start it in the Application because the developers of the native library told us that it had to be spent in this way, then I will put a little more code regarding the application.
public class SDKApplication extends CompanyApplication implements ActivityLifecycleCallbacks {
public SDKApplication() {
}
public void onCreate() {
SDK.getInstance().setContext(this.getApplicationContext());
super.onCreate();
Log.i("InfoSDK", "SDKApplication - init from App ");
this.registerActivityLifecycleCallbacks(this);
}
public void onActivityCreated(Activity activity, Bundle bundle) {
SDK.getInstance().setHostActivity(activity);
}
public void onActivityStarted(Activity activity) {
}
public void onActivityResumed(Activity activity) {
SDK.getInstance().setHostActivity(activity);
}
public void onActivityPaused(Activity activity) {
}
public void onActivityStopped(Activity activity) {
}
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
public void onActivityDestroyed(Activity activity) {
}
}
And the Company Application is:
public class CompanyApplication extends Application {
public CompanyApplication () {
}
public void onCreate() {
super.onCreate();
RequestQueue mainQueue = null;
if (SDK.getInstance().isDevelopEnviroment()) {
mainQueue = Volley.newRequestQueue(this.getApplicationContext(), new HurlStack((UrlRewriter)null, this.newSslSocketFactory()));
} else {
mainQueue = Volley.newRequestQueue(this.getApplicationContext());
}
CompanyHttpClient.getInstance().setMainQueue(mainQueue);
}
}

Related

Get #PermissionCallback in another class than Plugin

I build a capacitor plugin with permission requests. This plugin uses a native library that should actually request the permission. Therefore, the capacitor plugin implements the PermissionManagerInterface for the library.
My trouble: The PermissionCallback doesn't work within the PermissionManager class. It needs to be in MyPlugin, I think. That's not what I need. Is there a way to get the callback within the PermissionManager?
(I know, I could implement the PermissionManagerInterface within MyPlugin, but it is not very pretty to do everything in one class)
public class MyPlugin extends Plugin {
private MyPluginImpl implementation = new MyPluginImpl(this);
#PluginMethod
public void start(PluginCall call) {
implementation.start(call);
}
public void requestPermission (String alias, PluginCall call, String aliasCallback) {
this.requestPermissionForAlias(alias, call, aliasCallback);
}
}
public class MyPluginImpl {
private PermissionManager permissionManager;
private MyPlugin plugin;
private myFrameworkObject;
public DAAssistantPlugin (MyPlugin plugin) {
this.plugin = plugin;
}
public void start(PluginCall call) {
this.permissionManager = new PermissionManager(plugin, call);
this.myFrameworkObject = new MyFrameworkClass(plugin.getActivity(), this.permissionManager);
this.myFrameworkObject.start();
}
}
public class PermissionManager implements PermissionManagerInterface {
private MyPlugin plugin;
private PluginCall call;
private CompletableFuture<Boolean> microphonePermissionFuture;
public PermissionManager(MyPlugin plugin, PluginCall call) {
this.plugin = plugin;
this.call = call;
}
#Override
public Future<Boolean> requestMicrophonePermission() {
this.microphonePermissionFuture = new CompletableFuture<>();
if (this.plugin.getPermissionState("microphone") != PermissionState.GRANTED) {
this.plugin.requestPermission("microphone", this.call, "microphoneCallback");
} else {
this.microphonePermissionFuture.complete(true);
}
return this.microphonePermissionFuture;
}
#PermissionCallback
private void microphoneCallback(PluginCall call) { // not called
if (this.plugin.getPermissionState("microphone") == PermissionState.GRANTED) {
this.microphonePermissionFuture.complete(true);
} else {
this.microphonePermissionFuture.complete(false);
}
}
}

Android - Use the Activity callback in a standard java class

I'm developing an .aar library and I really need to interact with the lifecycle of an activity (so the callback onCreate(), on onResume(), etc...) in a standard java class.
I tried a lot of things but nothing works.
Is there a way I can do that?
From my understanding you need some thing like this,
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
/**
* #Krish
*/
public class LifeCycleObserver {
private LifeCycleObserver() {}
private static LifeCycleObserver sLifeCycleObserver;
public static LifeCycleObserver getInstance()
{
if (sLifeCycleObserver == null)
{
sLifeCycleObserver = new LifeCycleObserver();
}
return sLifeCycleObserver;
}
public static void init(Application application)
{
application.registerActivityLifecycleCallbacks(sLifeCycleObserver.lifecycleCallbacks);
}
private Application.ActivityLifecycleCallbacks lifecycleCallbacks = new Application.ActivityLifecycleCallbacks() {
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
#Override
public void onActivityStarted(Activity activity) {
}
#Override
public void onActivityResumed(Activity activity) {
}
#Override
public void onActivityPaused(Activity activity) {
}
#Override
public void onActivityStopped(Activity activity) {
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
#Override
public void onActivityDestroyed(Activity activity) {
}
};
}
and use it like this in Application class,
import android.app.Application;
/**
* Created by krish
*/
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
LifeCycleObserver.init(this);
}
}

Opening android application from background

Whenever my android application goes into the background i always wants to open my password activity every time application comes from background, How can i implement this functionality in my code?
Please follow these steps:
Add New Class Global
public class Global extends Application
{
private static Global mInstance;
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
ApplicationLifeCycleHandler handler = new ApplicationLifeCycleHandler();
registerActivityLifecycleCallbacks(handler);
registerComponentCallbacks(handler);
}
public static Global getInstance(){
return mInstance;
}
}
Add this line in your manifest in application tag like
<application
android:name=".Global"
</application>
Add this class and open your password intent when app come background to foreground like
public class ApplicationLifeCycleHandler implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {
public static Activity activity;
private static final String TAG = ApplicationLifeCycleHandler.class.getSimpleName();
public static boolean isInBackground = true;
#Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
#Override
public void onActivityStarted(Activity activity) {
this.activity = activity;
}
#Override
public void onActivityResumed(Activity activity) {
this.activity = activity;
if (isInBackground) {
Intent intent = new Intent(activity, PasswordActivity.class);//set your password activity
activity.startActivity(intent);
Log.d(TAG, "app went to foreground");
isInBackground = false;
}
}
#Override
public void onActivityPaused(Activity activity) {
}
#Override
public void onActivityStopped(Activity activity) {
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
#Override
public void onActivityDestroyed(Activity activity) {
}
#Override
public void onConfigurationChanged(Configuration configuration) {
}
#Override
public void onLowMemory() {
}
#Override
public void onTrimMemory(int i) {
if (i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
Log.d(TAG, "app went to background");
isInBackground = true;
}
}
}
Hope it will help you and please let me know if you are facing any issue. Thanks

Can't send broadcast from worker thread to main thread

I am trying to implement an architecture similar to the one presented at the Android Developer Summit 2015: https://github.com/yigit/dev-summit-architecture-demo. My application has a simple class that handles the network requests. The class uses Retrofit 2 for the requests. I am also using Dagger 2 for dependency injection.
I am trying to achieve something very simple. My activity tells a controller to fetch data. The controller then makes a call to my REST client to perform a network request. When the request completes successfully I want to broadcast an event to my Activity so that it can update the UI. However, the event is not being broadcast.
I am using the LocalBroadcastManager to broadcast events. My activity registers/unregisters for broadcasts in the onResume/onPause methods. My REST client has an instance of the application context which is provided through dependency injection. The REST client uses the application context to send the broadcast.
My first suspicion was that the broadcasts were not being sent because the network requests are executed on a worker thread whereas the activity is expecting broadcasts on the main thread. However, this type of scenario shouldn't be a problem if the Android documentation is correct.
This is my activity.
public class BaseActivity extends AppCompatActivity {
private ApplicationComponent mApplicationComponent;
private EventBroadcastReceiver mEventBroadcastReceiver = new EventBroadcastReceiver();
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mApplicationComponent = getMovieManagerApplication().getApplicationComponent();
}
#Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("now_playing");
LocalBroadcastManager.getInstance(this).registerReceiver(mEventBroadcastReceiver, intentFilter);
}
#Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mEventBroadcastReceiver);
}
protected MovieManagerApplication getMovieManagerApplication() {
return (MovieManagerApplication) getApplication();
}
protected ApplicationComponent getApplicationComponent() {
return mApplicationComponent;
}
protected void update(Intent intent) {
}
private class EventBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
update(intent);
}
}
}
And this is my REST client.
public class MovieRestClient extends BaseRestClient implements Callback<MovieResponse> {
#Inject
public MovieApiService mMovieApiService;
#Inject
public Context mApplicationContext;
public MovieRestClient(ApplicationComponent applicationComponent) {
super(applicationComponent);
getApplicationComponent().inject(this);
}
#Override
public void onResponse(Response<MovieResponse> response) {
if (response.isSuccess()) {
Parcelable parcelable = Parcels.wrap(response.body());
MovieResponse movieResponse = Parcels.unwrap(parcelable);
Intent intent = new Intent("now_playing");
intent.putExtra(MovieResponse.class.getName(), parcelable);
LocalBroadcastManager.getInstance(mApplicationContext).sendBroadcast(intent);
}
}
#Override
public void onFailure(Throwable t) {
}
public void getNowPlaying() {
mMovieApiService.getNowPlaying(API_KEY).enqueue(this);
}
public void getPopular() {
mMovieApiService.getPopular(API_KEY).enqueue(this);
}
public void getTopRated() {
mMovieApiService.getTopRated(API_KEY).enqueue(this);
}
public void getUpcoming() {
mMovieApiService.getUpcoming(API_KEY).enqueue(this);
}
}
Any help would be greatly appreciated.

Android comunicate between library and app

I'm creating a library in Android and I want to pass some values (strings) from the library to the app that is using the library after some events. The app that uses the library has only one screen to display the strings sent by the library.
My app has a MainActivity that will populate an listView with the events received by the library.
It also have an MyApp that extends Application.
Here I'm doing this:
public class MyApp extends Application{
private static MyApp sMyApp;
public MyApp() {
}
#Override
public void onCreate() {
super.onCreate();
sMyApp= this;
MyLibrary.getInstance().setApplication(sMyApp);
}
public static MyApp getInstance() {
return sMyApp;
}
}
In my library:
public class MyLibrary {
private static MyLibrary sInstance = new MyLibrary();
private Application mMyApp;
public static MyLibrary getInstance() {
return sInstance;
}
private MyLibrary() {
}
public void setApplication(Application myApp) {
mMyApp = myApp;
}
public void sendEventMessage(String message) {
mMyApp.setEvent(message);
}
}
I've tried to implement an interface in MainActivity so that mMyApp.setEvent(message); could send a message that MainActivity could receive but with no success.
How can I achieve what I pretend?
You could try callback as this sample:
Firstly, declare your callback inside library
public interface ILibrary {
public void onStart(String msg);
public void onProcess(String msg);
public void onFish(String msg);}
public class SDK {
private static final String START = "I'm started";
private static final String PROCESSING = "I'm running";
private static final String STOP = "I'm done";
private ILibrary mCallback;
// Make it easy for demo
public SDK(ILibrary callback) {
mCallback = callback;
}
public void start() {
mCallback.onStart(START);
}
public void process() {
mCallback.onProcess(PROCESSING);
}
public void stop() {
mCallback.onFish(STOP);
}}
And then do something like that:
SDK sdk = new SDK(new ILibrary() {
#Override
public void onStart(String msg) {
Log.d("TAG", msg);
}
#Override
public void onProcess(String msg) {
Log.d("TAG", msg);
}
#Override
public void onFish(String msg) {
Log.d("TAG", msg);
}
});
AsyncTask<Void, Void, Void> asyncTask = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
sdk.process();
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
sdk.stop();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
sdk.start();
}
};
asyncTask.execute();

Categories

Resources