I'm trying pass over push data from receiver to the activity using an Intent and it doesn't seem to work. Any idea why? Here is my implementation:
AndroidManifest.xml
<?xml version="1.0" encoding="UTF-8"?><!--
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<permission android:protectionLevel="signature"
android:name="com.appName.permission.C2D_MESSAGE" />
<uses-permission android:name="com.appName.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="RB"
android:supportsRtl="true"
android:theme="#style/AppTheme"
android:name="com.appName.appExtension">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="API_KEY"
/>
<activity
android:name=".MainActivity"
android:label="RB"
android:theme="#style/AppTheme.NoActionBar"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="com.appNamw.RouteView"
android:label="#string/title_activity_route_view"
android:screenOrientation="landscape">
</activity>
<service android:name="com.parse.PushService" />
<receiver android:name="com.appName.ParseReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<receiver android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.appName" />
</intent-filter>
</receiver>
</application>
ParseReceiver
package com.appName;
import android.content.Context;
import android.content.Intent;
import android.nfc.Tag;
import android.util.Log;
import com.parse.ParseAnalytics;
import com.parse.ParsePushBroadcastReceiver;
import org.json.JSONException;
import org.json.JSONObject;
public class ParseReceiver extends ParsePushBroadcastReceiver {
private final String TAG = "Push_Notify";
#Override
public void onPushOpen(Context context, Intent intent) {
Log.i(TAG, "onPushOpen triggered!");
ParseAnalytics.trackAppOpenedInBackground(intent);
Intent mainIntent = new Intent(context, MainActivity.class);
mainIntent.putExtras(intent.getExtras());
mainIntent.putExtra("method", "updateStatus");
mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
JSONObject pushData;
String alert;
try {
pushData = new JSONObject(intent.getStringExtra(ParseSupplyReceiver.KEY_PUSH_DATA));
alert = pushData.getString("alert");
String name = pushData.getString("name");
String contactNumber = pushData.getString("contactNumber");
String durationText = pushData.getString("duration");
mainIntent.putExtra("alert", alert);
mainIntent.putExtra("pushData", new PushData(name, contactNumber, durationText));
} catch (JSONException e) {
Log.i(TAG,"JSONException: " + e.getLocalizedMessage());
}
context.startActivity(mainIntent);
}
}
PushData.java
package com.appName;
import android.os.Parcel;
import android.os.Parcelable;
public class PushData implements Parcelable{
String name;
String contactNumber;
String durationText;
public PushData (String name,String contactNumber,String durationText ){
/*
* Reconstruct from the Parcel. Keep same order as in writeToParcel()
*/
this.name = name;
this.contactNumber = contactNumber;
this.durationText = durationText;
}
public PushData(Parcel source) {
name = source.readString();
contactNumber = source.readString();
durationText = source.readString();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(contactNumber);
dest.writeString(durationText);
}
#Override
public int describeContents() {
return 0;
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public PushData createFromParcel(Parcel source) {
return new PushData(source);
}
public PushData[] newArray(int size) {
return new PushData[size];
}
};
}
Implementation of onNewIntent in MainActivity:
#Override
protected void onNewIntent(Intent intent){
super.onNewIntent(intent);
setIntent(intent);
if (intent.getStringExtra("method").equals("updateStatus")) {
alertString = intent.getStringExtra("alert");
pushData = intent.getParcelableExtra("pushData");
updateStatus();
}
}
public void updateStatus() {
if (pushData != null) {
SharedPreferences.Editor editor = preferences.edit();
editor.putString("name", pushData.name);
editor.putString("contactNumber", pushData.contactNumber);
editor.putString("duration", pushData.durationText);
}
}
May I know what is wrong here? I have done an similar implementation on another app and it works completely fine.
Add FLAG_ACTIVITY_SINGLE_TOP flag to your intent
(see onNewIntent(Intent intent)).
I think its not about your FLAG,but your activitys launchmode;
It seems like that this method only be called when it`s launchmode is singleTask or sigleTop;
You also have a spelling mistake in your Manifest. Change
<activity android:name="com.appNamw.RouteView"
android:label="#string/title_activity_route_view"
android:screenOrientation="landscape">
TO
<activity android:name="com.appName.RouteView"
android:label="#string/title_activity_route_view"
android:screenOrientation="landscape">
Related
I have a problem with my app. It's already running, but now I've added Bluetooth and since then the pages keep crashing.
All 10 classes have the same structure and all 10 have the same error:
This class should provide a default constructor (a public constructor
with no arguments)
(com.example.feuerwerkzndanlage.empfaenger_1_zuenden)
Code Activity:
package com.example.feuerwerkzndanlage;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.concurrent.atomic.AtomicInteger;
public class empfaenger_1_zuenden extends AppCompatActivity{
private final ConnectedThread mConnectedThread; // bluetooth background worker thread to send and receive data
public empfaenger_1_zuenden(ConnectedThread mConnectedThread){
this.mConnectedThread = mConnectedThread;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.empfaenger_1_zuenden);
Context context = getApplicationContext();
CharSequence back_txt = "Zurück!";
CharSequence rot_txt = "Zünden!";
CharSequence gruen_txt = "Reset!";
int a = 0;
AtomicInteger b = new AtomicInteger(0);
AtomicInteger c = new AtomicInteger(0);
AtomicInteger d = new AtomicInteger(0);
AtomicInteger e = new AtomicInteger(0);
AtomicInteger f = new AtomicInteger(0);
int duration = Toast.LENGTH_SHORT;
ImageView back = findViewById(R.id.back);
Button zuenden1_1 = findViewById(R.id.btn_zuenden1_1);
Button zuenden1_2 = findViewById(R.id.btn_zuenden1_2);
Button zuenden1_3 = findViewById(R.id.btn_zuenden1_3);
Button zuenden1_4 = findViewById(R.id.btn_zuenden1_4);
Button zuenden1_5 = findViewById(R.id.btn_zuenden1_5);
Button ruecksetzen = findViewById(R.id.btn_ruecksetzen);
ImageView kanal_1_1 = findViewById(R.id.kanal1_1);
ImageView kanal_1_2 = findViewById(R.id.kanal1_2);
ImageView kanal_1_3 = findViewById(R.id.kanal1_3);
ImageView kanal_1_4 = findViewById(R.id.kanal1_4);
ImageView kanal_1_5 = findViewById(R.id.kanal1_5);
back.setOnClickListener(view -> {
Toast.makeText(context, back_txt, duration).show();
startActivity(new Intent(empfaenger_1_zuenden.this, zuenden.class));
});
ruecksetzen.setOnClickListener(view -> {
Toast.makeText(context, gruen_txt, duration).show();
kanal_1_1.setImageResource(R.drawable.kanal_gruen);
kanal_1_2.setImageResource(R.drawable.kanal_gruen);
kanal_1_3.setImageResource(R.drawable.kanal_gruen);
kanal_1_4.setImageResource(R.drawable.kanal_gruen);
kanal_1_5.setImageResource(R.drawable.kanal_gruen);
b.set(a + 1);
c.set(a + 1);
d.set(a + 1);
e.set(a + 1);
f.set(a + 1);
});
zuenden1_1.setOnClickListener(view -> {
if (b.get() == 1) {
Toast.makeText(context, rot_txt, duration).show();
kanal_1_1.setImageResource(R.drawable.kanal_rot);
b.set(0);
if(mConnectedThread != null) //First check to make sure thread created
mConnectedThread.write("Kanal_1_1_Z");
}
});
zuenden1_2.setOnClickListener(view -> {
if (c.get() == 1) {
Toast.makeText(context, rot_txt, duration).show();
kanal_1_2.setImageResource(R.drawable.kanal_rot);
c.set(0);
if(mConnectedThread != null) //First check to make sure thread created
mConnectedThread.write("Kanal_1_2_Z");
}
});
zuenden1_3.setOnClickListener(view -> {
if (d.get() == 1) {
Toast.makeText(context, rot_txt, duration).show();
kanal_1_3.setImageResource(R.drawable.kanal_rot);
d.set(0);
if(mConnectedThread != null) //First check to make sure thread created
mConnectedThread.write("Kanal_1_3_Z");
}
});
zuenden1_4.setOnClickListener(view -> {
if (e.get() == 1) {
Toast.makeText(context, rot_txt, duration).show();
kanal_1_4.setImageResource(R.drawable.kanal_rot);
e.set(0);
if(mConnectedThread != null) //First check to make sure thread created
mConnectedThread.write("Kanal_1_4_Z");
}
});
zuenden1_5.setOnClickListener(view -> {
if (f.get() == 1) {
Toast.makeText(context, rot_txt, duration).show();
kanal_1_5.setImageResource(R.drawable.kanal_rot);
f.set(0);
if(mConnectedThread != null) //First check to make sure thread created
mConnectedThread.write("Kanal_1_5_Z");
}
});
}
}
Code Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.feuerwerkzndanlage">
<uses-feature android:name="android.hardware.bluetooth" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<permission android:name="android.permission.BLUETOOTH" android:label="BLUETOOTH" />
<permission android:name="android.permission.BLUETOOTH_ADMIN" />
<permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<permission android:name="android.permission.BLUETOOTH_CONNECT" />
<permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<application
android:allowBackup="true"
android:icon="#drawable/logo"
android:label="#string/app_name"
android:roundIcon="#drawable/logo"
android:supportsRtl="true"
android:theme="#style/Theme.Feuerwerkzündanlage">
<activity
android:name=".Musik_Auswahl"
android:exported="false" />
<activity
android:name=".Main_Bluetooth"
android:exported="false" />
<activity
android:name=".inArbeit"
android:exported="false" />
<activity
android:name=".zeit_laden_1"
android:exported="false" />
<activity
android:name=".zeit_speichern_auswahl"
android:exported="false" />
<activity
android:name=".zeit_ruecksetzen"
android:exported="false" />
<activity
android:name=".zeit_speichern_1"
android:exported="false" />
<activity
android:name=".empfaenger_1"
android:exported="false" />
<activity
android:name=".empfaenger_2"
android:exported="false" />
<activity
android:name=".empfaenger_3"
android:exported="false" />
<activity
android:name=".empfaenger_4"
android:exported="false" />
<activity
android:name=".empfaenger_5"
android:exported="false" />
<activity
android:name=".empfaenger_6"
android:exported="false" />
<activity
android:name=".empfaenger_7"
android:exported="false" />
<activity
android:name=".empfaenger_8"
android:exported="false" />
<activity
android:name=".empfaenger_9"
android:exported="false" />
<activity
android:name=".empfaenger_10"
android:exported="false" />
<activity
android:name=".empfaenger_1_zuenden"
android:exported="false" />
<activity
android:name=".empfaenger_2_zuenden"
android:exported="false" />
<activity
android:name=".empfaenger_3_zuenden"
android:exported="false" />
<activity
android:name=".empfaenger_4_zuenden"
android:exported="false" />
<activity
android:name=".empfaenger_5_zuenden"
android:exported="false" />
<activity
android:name=".empfaenger_6_zuenden"
android:exported="false" />
<activity
android:name=".empfaenger_7_zuenden"
android:exported="false" />
<activity
android:name=".empfaenger_8_zuenden"
android:exported="false" />
<activity
android:name=".empfaenger_9_zuenden"
android:exported="false" />
<activity
android:name=".empfaenger_10_zuenden"
android:exported="false" />
<activity
android:name=".Achtung_Scharf"
android:exported="false" />
<activity
android:name=".Test"
android:exported="false" />
<activity
android:name=".Biometric_Authentication"
android:exported="false" />
<activity
android:name=".test_arm"
android:exported="false" />
<activity
android:name=".vorschlaege"
android:exported="false" />
<activity
android:name=".gesp_feuerwerke"
android:exported="false" />
<activity
android:name=".Auswahl_Planer"
android:exported="false" />
<activity
android:name=".Planer_1"
android:exported="false" />
<activity
android:name=".Planer_2"
android:exported="false" />
<activity
android:name=".Planer_3"
android:exported="false" />
<activity
android:name=".Planer_4"
android:exported="false" />
<activity
android:name=".Planer_5"
android:exported="false" />
<activity
android:name=".Planer_6"
android:exported="false" />
<activity
android:name=".Planer_7"
android:exported="false" />
<activity
android:name=".Planer_8"
android:exported="false" />
<activity
android:name=".Planer_9"
android:exported="false" />
<activity
android:name=".Planer_10"
android:exported="false" />
<activity
android:name=".zuenden"
android:exported="false" />
<activity
android:name=".Sidebar"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Because you use the keywords final
private final ConnectedThread mConnectedThread; // final keywords in Java is a constant.
It's not recommanded create a constructor for Activity, casuse it no need to instantiated by new . to communicate between activitys is by using startActivity() or startActivityForResult().
Intent it = new Intent(FirstActivity.this, SecondActivity.class);
it.putExtra("data", "Hi is FirstAcitvity"); // if you need pass some data to SecondAcrivity
startActivity(it);
The bluetooth component you can create something like a BluetoothManager.java and extends from IntentService which is Thread Safty.
public class BluetoothMnager extends IntentService {
public static final String RESULT_RECEIVER = "RESULT_RECEIVER";
public static final int RESPONSE_CODE = 200;
// do anything you need
#Override
protected void onHandleIntent(#Nullable Intent intent) {
// Declare Result Receiver
ResultReceiver receiver = intent.getParcelableExtra(RESULT_RECEIVER);
String action = intent.getAction();
Bundle b = new Bundle();
b.putString("response", "data");
receiver.send(RESPONSE_CODE , b);
}
// The Activity Side
public MainActivity extends...{
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button bt = new Button(this);
bt.setText("send services");
bt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent it = new Intent(MainActivity.this, BluetoothMnager.class);
it.putExtra(BluetoothMnager.RESULT_RECEIVER, mReceiver);
startService(it);
}
});
#Override
protected void onResume(){
// Declare a ResultReceiver
mReceiver = new ResultReceiver(new Handler()){
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
if (resultCode == 200){
String response = resultData.getString("response");
Log.d(TAG, "response: " + response);
Toast.makeText(MainActivity.this, response,
Toast.LENGTH_SHORT).show();
}
}
I've created a custom deep link dispatcher in Java within a react native project.
The issue I'm having is that I can't get MainActivity to start from my dispatcher, and I can't quite figure out why.
I have AndroidManifest set up so that the deep link is captured in LinkDispatcherActivity effectively, but the startActivity(dispatchedIntent) never reaches MainActivity, which is where I assume it needs to go. Ordinarily in AndroidManifest.xml, deep links would be sent to MainActivity).
It does open the app, but I assume it's because LinkDispatcherActivity is part of the app? Not sure, if I say something dumb it's because this is only my 3rd day in a row writing Java 😰
Below is my code.
package com.example.app;
//Inspired by https://github.com/justeat/Android.Samples.Deeplinks, Licensed under Apache 2.0
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import net.openid.appauth.RedirectUriReceiverActivity;
public class LinkDispatcherActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
dispatchIntent(getIntent());
} catch (IllegalArgumentException iae) {
// Malformed URL
if (BuildConfig.DEBUG) {
Log.e("Deep links", "Invalid URI", iae);
}
} finally {
// Always finish the activity so that it doesn't stay in our history
finish();
}
}
public void dispatchIntent(Intent intent) {
final Uri uri = intent.getData();
final String host = uri.getHost().toLowerCase();
if (uri == null) throw new IllegalArgumentException("Uri cannot be null");
// Default intent
Intent dispatchedIntent = new Intent(LinkDispatcherActivity.this, MainActivity.class);
dispatchedIntent.setData(uri);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Log.d(dispatchedIntent.getDataString(), "dispatchIntent: intent string");
// Auth intent only, this is why I need the dispatcher
if ("login".equals(host)) {
dispatchedIntent = new Intent(this, RedirectUriReceiverActivity.class);
dispatchedIntent.putExtra("requestCode", 0);
Log.d("Login", "mapAppLink: ");
startActivityForResult(dispatchedIntent, 0);
return;
}
Log.d("Default", "mapAppLink: ");
startActivity(dispatchedIntent);
}
}
This is what my AndroidManifest.xml looks like:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
package="com.example.app">
<!-- < Only if you're using GCM or localNotificationSchedule() > -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
<!-- < Only if you're using GCM or localNotificationSchedule() > -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:name=".MainApplication"
android:allowBackup="false"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:theme="#style/AppTheme"
android:requestLegacyExternalStorage="true">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="<redacted>" />
<!-- < Notification Services > -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#mipmap/ic_notification" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
tools:replace="android:resource"
android:resource="#color/colorAccent" />
<!-- Change the value to true to enable pop-up for in foreground on receiving remote notifications (for prevent duplicating while showing local notifications set this to false) -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground"
android:value="true"/>
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
tools:replace="android:value"
android:value="rn-push-notification-channel-id" />
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name" android:value="Default Channel"/>
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_description" android:value="Default channel for push notifications"/>
<meta-data
android:name="com.dieam.reactnativepushnotification.notification_color"
android:resource="#color/colorAccent" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>
</receiver>
<!-- START: Add this-->
<service
android:name=".MainNotificationService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<receiver
android:name="com.intercom.reactnative.RNIntercomPushBroadcastReceiver"
tools:replace="android:exported"
android:exported="true"/>
<activity
android:name=".MainActivity"
android:configChanges="keyboard|keyboardHidden|screenSize|uiMode"
android:launchMode="singleTask"
android:label="#string/app_name"
android:screenOrientation="portrait"
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.DOWNLOAD_COMPLETE" />
</intent-filter>
</activity>
<activity android:name=".LinkDispatcherActivity"
tools:node="replace">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="example"
android:host="login" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>
Edit: for the intent, I've tried:
new Intent(getApplicationContext(), MainActivity.class)
new Intent(reactContext, MainActivity.class) (extending ReactActivity instead of Activity)
new Intent(this, MainActivity.class)
new Intent("MainActivity")
Try adding RedirectUriReceiverActivity to the manifest - I couldn't see it in there.
<activity android:name="com.facebook.react.devsupport.RedirectUriReceiverActivity" />
This is what I ended up with for the LinkDispatcherActivity. To summarize, what I did was dispatch the intents that the deep activities were eventually supposed to invoke directly, instead of trying to forward the intent. In other words, if you're trying to pass an intent from one activity to another, maybe don't and consider dispatching the activity/function/intent that you want to run afterwards. I still think forwarding the intent should have worked, but this is what ended up working.
In order to accomplish the above, I:
Called a function within the AppAuth package that generates an intent, and dispatch it
Used ReactContext to emit the url listener event that React Native uses to respond to deep links.
Below is the code:
//Inspired by https://github.com/justeat/Android.Samples.Deeplinks, Licensed under Apache 2.0
package com.example.app;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import net.openid.appauth.AuthorizationManagementActivity;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
public class LinkDispatcherActivity extends ReactActivity {
#Override
protected void onResume() {
super.onResume();
try {
dispatchIntent(getIntent());
} catch (IllegalArgumentException iae) {
// Malformed URL
if (BuildConfig.DEBUG) {
Log.e("Deep links", "Invalid URI", iae);
}
} finally {
// Always finish the activity so that it doesn't stay in our history
finish();
}
}
public void dispatchIntent(Intent intent) {
final Uri uri = intent.getData();
final String host = uri.getHost().toLowerCase();
if (uri == null) throw new IllegalArgumentException("Uri cannot be null");
// Default intent, e.g. settings, fitbit
// wait for react context
ReactInstanceManager reactInstanceManager = getReactInstanceManager();
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
Intent dispatchedIntent = new Intent(getApplicationContext(), MainActivity.class);
dispatchedIntent.setData(uri);
dispatchedIntent.putExtra("url", uri.toString());
dispatchedIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
// Auth intent only
if ("login".equals(host)) {
Intent authIntent = AuthorizationManagementActivity.createResponseHandlingIntent(getApplicationContext(), uri);
startActivity(authIntent);
return;
}
// Below from https://stackoverflow.com/questions/48445010/send-data-from-android-activity-to-react-native?rq=1
WritableMap uriMap = Arguments.createMap();
uriMap.putString("url", uri.toString());
if(reactContext != null) {
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("url", uriMap);
// If there's no context, create a listener to wait for it
} else {
reactInstanceManager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
#Override
public void onReactContextInitialized(ReactContext context) {
context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("url", uriMap);
reactInstanceManager.removeReactInstanceEventListener(this);
}
});
}
}
}
Hello I am working with parse push notification for android.I developed app using the following tutorial. http://www.androidhive.info/2015/06/android-push-notifications-using-parse-com/. I can able to get the notification onl in one device which is lollipop.I didin't get notification in kitkat and other devices. I didin't find the issue.
here is my manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android_new_user.testnotification" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name="com.example.android_new_user.testnotification.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.android_new_user.testnotification.permission.C2D_MESSAGE" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.android_new_user.testnotification.LoginActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.android_new_user.testnotification.MainActivity"
android:label="#string/app_name" />
<service android:name="com.parse.PushService" />
<receiver
android:name=".CustomPushReciver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<receiver android:name="com.parse.ParseBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
</application>
</manifest>
and my reciver File is looks like
package com.example.android_new_user.testnotification;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.parse.ParsePushBroadcastReceiver;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Created by Android_new_user on 11/25/2015.
*/
public class CustomPushReciver extends ParsePushBroadcastReceiver {
private final String TAG = CustomPushReciver.class.getSimpleName();
private NotificationUtils notificationUtils;
private Intent parseIntent;
public CustomPushReciver() {
super();
}
#Override
protected void onPushReceive(Context context, Intent intent) {
super.onPushReceive(context, intent);
if (intent == null)
return;
try {
JSONObject json = new JSONObject(intent.getExtras().getString("com.parse.Data"));
Log.e(TAG, "Push received: " + json);
parseIntent = intent;
parsePushJson(context, json);
} catch (JSONException e) {
Log.e(TAG, "Push message json exception: " + e.getMessage());
}
}
#Override
protected void onPushDismiss(Context context, Intent intent) {
super.onPushDismiss(context, intent);
}
#Override
protected void onPushOpen(Context context, Intent intent) {
super.onPushOpen(context, intent);
}
/**
* Parses the push notification json
*
* #param context
* #param json
*/
private void parsePushJson(Context context, JSONObject json) {
try {
boolean isBackground = json.getBoolean("is_background");
JSONObject data = json.getJSONObject("data");
String title = data.getString("title");
String message = data.getString("message");
if (!isBackground) {
Intent resultIntent = new Intent(context, MainActivity.class);
showNotificationMessage(context, title, message, resultIntent);
}
} catch (JSONException e) {
Log.e(TAG, "Push message json exception: " + e.getMessage());
}
}
private void showNotificationMessage(Context context, String title, String message, Intent intent) {
notificationUtils = new NotificationUtils(context);
intent.putExtras(parseIntent.getExtras());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
notificationUtils.showNotificationMessage(title, message, intent);
}
}
and my Application class
public class MyApplication extends Application {
private static MyApplication mInstance;
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
// register with parse
ParseUtils.registerParse(this);
}
public static synchronized MyApplication getInstance() {
return mInstance;
}
}
How can I resolve this problem. Please help Thanks in adavance
Have you added the application name to your manifest file?
And also check the following code in the manifest
<permission
android:name="yourpackagename.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="yourpackagename.permission.C2D_MESSAGE" />
<receiver
android:name="com.parse.ParsePushBroadcastReceiver"
android:exported="false" >
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<receiver
android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="yourpackagename" />
</intent-filter>
</receiver>
hello my problem is this .
I have an Android app that receives dotifiche for Google Cloud Messaging , until the screen of the phone is turned receive notifications , but as soon as I turn it off not getting anything , ye shall public code, for now you have some ideas ?
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.lucabigoni.progettoclientserverolbia" >
<uses-sdk
android:minSdkVersion="17"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.VIBRATE" />
<permission
android:name="com.example.lucabigoni.progettoclientserverolbia.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.lucabigoni.progettoclientserverolbia.C2D_MESSAGE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<uses-permission android:name="android.permission." />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".Activity.SplashScreen"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.Black.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Activity.Prova"
android:label="#string/ciao" >
</activity>
<activity
android:name=".Activity.MainActivity"
android:label="main" >
</activity>
<activity
android:name=".Activity.manu"
android:label="#string/title_activity_manu" >
</activity>
<activity
android:name=".Activity.Visualizza"
android:label="#string/title_activity_visualizza" >
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyADrZavHTaGfd8_pTyqOMQLMQg2jfJT_S4" />
<activity
android:name=".Activity.mapOlbia"
android:label="#string/title_activity_map_olbia" >
</activity>
<activity
android:name=".Activity.Immagine_nave"
android:label="#string/title_activity_immagine_nave" >
</activity>
<activity
android:name=".Activity.Splash_Scree_caricamento_Immagine"
android:label="#string/title_activity_splash__scree_caricamento__immagine" >
</activity>
<activity
android:name=".Activity.Splash_screen_caricamento_dati"
android:label="#string/title_activity_splash_screen_caricamento_dati" >
</activity>
<activity
android:name=".Activity.AscoltoNave"
android:label="#string/title_activity_ascolto_nave" >
</activity>
<activity
android:name=".Activity.Scegli"
android:label="#string/title_activity_scegli" >
</activity>
<activity
android:name=".Activity.SceltaTipologia"
android:label="#string/title_activity_scelta_tipologia" >
</activity>
<receiver
android:name=".ricevitorenotifiche.NotificationReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.android.recognition" />
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="it.html.googleservices.push" />
</intent-filter>
</receiver>
<intentservice
android:name=".ricevitorenotifiche.GcmIntentService"
android:enabled="true"
android:exported="false"
android:process=":questo" >
</intentservice>
<receiver
android:name=".ricevitorenotifiche.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.thanksandroid.example.gcmdemo" />
</intent-filter>
</receiver>
</application>
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// Explicitly specify that GcmIntentService will handle the intent.
Log.e("Ricevuto","CIAO SONO PRONTO");
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
package com.example.lucabigoni.progettoclientserverolbia.ricevitorenotifiche;
import com.example.lucabigoni.progettoclientserverolbia.Activity.MainActivity;
import com.example.lucabigoni.progettoclientserverolbia.R;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import android.app.Activity;
import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;
public class GcmIntentService extends IntentService /*implements WakefulBroadcastReceiver */{
Context context;
public static int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public static final String TAG = "GCM Demo";
public GcmIntentService() {
super("GcmIntentService");
// TODO Auto-generated constructor stub
}
/*
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}*/
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
Bundle extras = intent.getExtras();
String msg = intent.getStringExtra("message");
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
Log.e("qua arrivato","qua");
if (!extras.isEmpty()) {
if (GoogleCloudMessaging.
MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
sendNotification("Send error: " + extras.toString());
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_DELETED.equals(messageType)) {
sendNotification("Deleted messages on server: " +
extras.toString());
// If it's a regular GCM message, do some work.
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_MESSAGE.equals(messageType)) {
// This loop represents the service doing some work.
for (int i=0; i<5; i++) {
Log.i(TAG, "Working... " + (i+1)
+ "/5 # " + SystemClock.elapsedRealtime());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
Log.i(TAG, "Completed work # " + SystemClock.elapsedRealtime());
// Post notification of received message.
//sendNotification("Received: " + extras.toString());
sendNotification(msg);
Log.i(TAG, "Received: " + extras.toString());
}
}
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
private void sendNotification(String msg) {
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
Log.e("qua arrivato","qua2");
Intent myintent = new Intent(this, MainActivity.class);
myintent.putExtra("message", msg);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
myintent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("GCM Notification")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
NOTIFICATION_ID++;
}
}
I want to force my app to run the LoginActivity if there is no account present.
I've done the following but still when I launch the app in the emulator, I have MainActivityTest coming up.
For now I have no Account for my app on the emulator so I expect to simply see the Login screen. However, what I see seems like the MainActivityTest is running
public class AccountAuthenticator extends AbstractAccountAuthenticator {
private Context context;
private static final String TAG = "AccountAuthenticator";
public AccountAuthenticator(final Context context) {
super(context);
this.context = context;
}
#Override
public Bundle addAccount(final AccountAuthenticatorResponse response,
final String accountType, final String authTokenType,
final String[] requiredFeatures, final Bundle options) throws NetworkErrorException {
final Intent intent = new Intent(context, LoginActivity.class);
final Bundle bundle = new Bundle();
bundle.putParcelable(KEY_INTENT, intent);
return bundle;
}
...
}
public class AccountAuthenticatorService extends Service {
private static AccountAuthenticator AUTHENTICATOR;
public IBinder onBind(Intent intent) {
return intent.getAction().equals(ACTION_AUTHENTICATOR_INTENT) ? getAuthenticator()
.getIBinder() : null;
}
private AccountAuthenticator getAuthenticator() {
if (AUTHENTICATOR == null)
AUTHENTICATOR = new AccountAuthenticator(this);
return AUTHENTICATOR;
}
}
public class LoginActivity extends RoboSherlockAccountAuthenticatorActivity {
#Override
public void startActivity(Intent intent) {
if (intent != null && ACTION_VIEW.equals(intent.getAction()))
intent.addCategory(CATEGORY_BROWSABLE);
super.startActivity(intent);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
}
}
My AndroidManifest.xml is like below
<application
android:icon="#drawable/ic_launcher"
android:label="myapp" >
<activity
android:name=".ui.ui.MainActivityTest"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.myapp.AccountAuthenticatorService"
android:exported="false"
android:process=":auth" >
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="#xml/authenticator" />
</service>
<activity
android:name="com.myapp.LoginActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:excludeFromRecents="true" >
<!--
No intent-filter here! This activity is only ever launched by
someone who explicitly knows the class name
-->
</activity>
</application
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
It would be simple if you put value in shared preference once if you complete login process.
and every time when you launch application, once check the sharedpreference value and navigate to activities
Boolean mobile_register_flag = sharedpref.getBoolean("mobile_register_flag", false);
if (!mobile_register_flag) {
Intent intent = new Intent(FlashView.this,
RegisterActivity.class);
startActivity(intent);
} else {
Intent intent = new Intent(FlashView.this,
ActivityTwo.class);
startActivity(intent);
}
When you launch the app in the emulator, MainActivityTest coming up because your AndroidManifest has:
<activity
android:name=".ui.ui.MainActivityTest"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
If you want to launch LoginActivity by default, use
<activity
android:name="com.myapp.LoginActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:excludeFromRecents="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Else, if you want to display LoginActivity as the first activity based on some conditions, then
In android manifest, keep MainActivityTest as the default
activity
In MainActivityTest->onCreate, check the condition
and if condition is true, launch LoginActivity