I have a LoginActivity that has a button with a listener method,
<Button
android:id="#+id/view_anonymous_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/action_view_anonymous"
android:onClick="startMain"/>
and the method is,
public void startMain(View v) {
Intent intent = new Intent(this, Navigation.class);
intent.putExtra("token", "TEST");
startActivity(intent);
}
When clicking that button I try to start another activity 'Navigation'. The problem is the new activity is being called but never gets focus. The LoginAcivity is appearing again. To debug, I did print the life cycle methods of Navigation, and the flow is,
onStart -> onResume -> onPause -> onStop. I am not sure why Navigation activity is getting stopped. To give some more information, the onCreate() of Navigation sets up a Fragment and loads some data using AsyncTask that is being called properly. Here is my manifest content,
<application
android:allowBackup="true"
android:icon="#drawable/bee"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".LoginActivity"
android:label="#string/title_activity_login"
android:windowSoftInputMode="adjustResize|stateVisible" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Navigation"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:launchMode="singleTask"
>
</activity>
</application>
I would like to get some pointers to fix this issue.
Update
Activity manager seems to start LoginActivity again instead of displaying Navigation. The onCreate() of Navigation sets up a DrawerLayout that has framelayout and fragment. If I change that to a simple LinearLayout with a textview, it works right.
7-29 03:18:35.302 293-293/system_process I/ActivityManager﹕ START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.knackforge.pithpicker/.LoginActivity} from pid 970
07-29 03:18:35.832 293-554/system_process I/ActivityManager﹕ Start proc com.knackforge.pithpicker for activity com.knackforge.pithpicker/.LoginActivity: pid=980 uid=10046 gids={50046, 3003, 1028}
07-29 03:18:40.822 293-309/system_process I/ActivityManager﹕ Displayed com.knackforge.pithpicker/.LoginActivity: +5s101ms (total +12s951ms)
07-29 03:18:47.052 293-393/system_process I/ActivityManager﹕ START u0 {cmp=com.knackforge.pithpicker/.Navigation (has extras)} from pid 980
07-29 03:18:49.524 293-304/system_process I/ActivityManager﹕ START u0 {cmp=com.knackforge.pithpicker/.LoginActivity (has extras)} from pid 980
07-29 03:18:50.052 293-310/system_process W/ActivityManager﹕ Activity pause timeout for ActivityRecord{41aa4538 u0 com.knackforge.pithpicker/.Navigation}
My bad, I had a another call that started LoginActivity from Navigation based on some condition, so its just my code that had bug :)
Related
How can we handle deep links in flutter with Get X for go to Custom pages of the application ?
By default, by adding the desired address to the Android Manifest file:
<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" android:host="flutterbooksample.com" />
<data android:scheme="https" android:host="flutterbooksample.com"/>
</intent-filter>
when the application opens, the main page of application will be displayed to us.
I am looking to implement this I can direct the user to any page of the application that is needed. A practical example is to pay on the web page and return to the application. When we return, we should show the user a message about the status of the payment, not direct the user to the first page of the application.
Do the page routing in your app, when you process the deeplink.
In my apps, I usually use uni_links (https://pub.dev/packages/uni_links) and in my main.dart, I have something like this:
StreamSubscription<String> _subUniLinks;
#override
initState() {
super.initState();
// universal link setup
initUniLinks();
}
Future<void> initUniLinks() async {
try {
final String initialLink = await getInitialLink();
await processLink(initialLink);
} on PlatformException {
}
_subUniLinks = linkStream.listen(processLink, onError: (err) {});
}
processLink(String link) async {
// parse link and decide what to do:
// - use setState
// - or use Navigator.pushReplacement
// - or whatever mechanism if you have in your app for routing to a page
}
#override
dispose() {
if (_subUniLinks != null) _subUniLinks.cancel();
super.dispose();
}
I have a problem that I have not been able to solve yet
It happens that I need to use the click action of the firebase push notifications both in the foreground and in the background
in the foreground I used the flutter_local_notifications library and everything worked fine
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
///HERE SHOW THE NOTIFICATION IN THE NOTIFICATION CENTER WITH flutter_local_notifications
_showNotification(message);
},
onBackgroundMessage: myBackgroundMessageHandler,
onLaunch: (Map<String, dynamic> message) async {
_openScreen(message);
},
onResume: (Map<String, dynamic> message) async {
_openScreen(message);
},
);
but in the background I couldn't use the "onBackgroundMessage" so searching in forums I found that I needed to register the plugin from kotlin and I did it this way:
File Application.kt
class Application : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this);
FlutterMain.startInitialization(this)
}
override fun registerWith(registry: PluginRegistry?) {
if (!registry!!.hasPlugin("io.flutter.plugins.firebasemessaging")) {
FirebaseMessagingPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
}
}
}
File MainActivity.kt
class MainActivity: FlutterActivity() {
}
File AndroidManifest.xml
<application
android:name=".Name"
android:label="Negocio TinBin"
android:icon="#mipmap/launcher_icon">
<activity
android:name=".MainActivity">
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
With this change it works without problems in the background and when you click if the "myBackgroundMessageHandler" function is executed, but it stopped working in the foreground, I check the log and not even go through "onMessage" of the firebase configuration
Anyone have any idea what I could do to make it work both in the foreground and in the background?
https://github.com/FirebaseExtended/flutterfire/issues/2311
https://pub.dev/packages/firebase_messaging#receiving-messages
You have to specify the click_action inside your js script, in which you have written the cloud functions, without specifying it, you would not be able to get onResume() and onLaunch() callbacks.
"data": {"click_action": "FLUTTER_NOTIFICATION_CLICK", }
Make sure have this line of code in your Manifests.xml file.
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
I have a requirement, when user clicks on a button in my flutter app, i will redirect user to other app with which i don't have access. Then from that app user needs to share a file. Using intent filters i am receiving the file in my ReceiveIntent.java class
AndroidManifest.xml
<activity
android:label="SampleApp"
android:exported="true"
android:name="com.sampleapp.example.ReceiveIntent"
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:theme="#style/LaunchTheme"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.VIEW"/>
</intent-filter>
<intent-filter tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/zip"/>
</intent-filter>
</activity>
Java Code
private void handleIntent(Intent intent){
// Get intent, action and MIME type
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
if (type.equalsIgnoreCase("application/zip")) {
handleSharedZIP(intent); // Handle text being sent
} else if (type.startsWith("image/*")) {
handleSendImage(intent); // Handle single image being sent
}
}
}
private void handleSharedZIP(Intent intent) {
try {
// pass the the path received from the intent filters to password unlock screen. So
that we can verify and Extract the data there.
Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
sharedZIP = uri.toString();
sharedZIPMethodChannel.invokeMethod("getSharedZIP",sharedZIP);
}catch (Exception e){
e.printStackTrace();
e.getMessage();
Log.d("error",e.getMessage().toString());
}
}
Everything is OK till here. But i want t redirect user to password unlock screen from here.I struck here.
I tried Method Channels but flutter widget which listening to that method channel not getting triggered,
Any help is appreciated.
Thanks in Advance.
In AndroidManifext.xml, I have :
<activity
android:name=".mypackage.ChildActivity"
android:label="Child"
android:parentActivityName=".mypackage.ParentActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden|adjustResize">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".view.activities.ParentActivity" />
</activity>
Inside ParentActivity, I have a few fragements, A, B, C. At fragment C, I launch ChildActivity when clicking a button. When backing to ParentActivity, I am not landing on Fragment C, but Fragment A. It appears that ParentActivity is relaunched or initialized again.
In ChildActivity, I have:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
As a comparison, I also tried to replace ChildActivity with a Fragment D and backing from fragment D correctly lands on fragment C.
Where did I miss for the ChildActivity implementation?
Edited:
Just noticed that when clicking "Back" button on device, it properly backs to Fragment C of ParentActivity, but if hitting the "<" button at the left top corner in Child Activity, that's where issue arises.
Thanks in advance!
Shawn
Remove the mentioning parent from your childActivity. Like below. Because android already maintains the stack of navigations
<activity
android:name=".mypackage.ChildActivity"
android:label="Child"
android:parentActivityName=".mypackage.ParentActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden|adjustResize">
</activity>
I want to start activities when users click on push notifications. It works fine for activity A, but does not work for another activity B, it does not fully work. What happened to activity B is that if the app is not running, clicking on the push notification will correctly start activity B. However, if the app is already running, clicking on the push notification just open the current screen.
Here is how I set up the push notification:
Intent rewardsIntent = new Intent(this, ActivityRewards.class);
rewardsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
NotificationUtils.createNotification(this, R.string.reward_notification, getResources().getString(R.string.reward_notification), "You have been rewarded", rewardsIntent);
And the static method in NotificationUtils to create the Push Notification:
public static void createNotification(Context context, int notificationId, String title, String text, Intent resultIntent) {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ico_launcher)
.setContentTitle(title)
.setContentText(text);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
context,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
mBuilder.setAutoCancel(true);
mBuilder.setOngoing(true);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(notificationId, mBuilder.build());
}
In AndroidManifest.xml, I declared the activity as follows:
<activity android:name=".ActivityRewards"
android:label="#string/my_rewards"
android:exported="true">
</activity>
This has puzzled me for few days. Any help would be very much appreciated. Thanks.
I managed to make this work by adding launchMode declaration for ActivityRewards as below:
<activity android:name=".ActivityRewards"
android:label="#string/my_rewards"
android:launchMode="singleTask"
android:exported="true">