I've made a few apps in the past but none of them have had this issue. It works while debugging in Android Studio, but if I stop debugging and attempt to open the app directly from the phone (after it's already been installed from debugging) I get "[app name]" has stopped working"
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.[HIDDEN].[HIDDEN]">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
android:fullBackupContent="#xml/backup_descriptor">
<activity
android:name=".MainActivity"
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=".WebActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:configChanges="keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service
android:name=".[HIDDEN]FirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
</application>
</manifest>
Gradle (project)
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.3'
classpath 'com.google.gms:google-services:4.0.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Gradle (app)
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.[HIDDEN].[HIDDEN]"
minSdkVersion 22
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false // keeps unused methods instead of removing them
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.google.firebase:firebase-messaging:17.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-
core:3.0.2'
api 'com.google.android.gms:play-services-gcm:15.0.1'
api 'com.google.firebase:firebase-core:16.0.1'
api 'com.google.firebase:firebase-messaging:17.1.0'
}
apply plugin: 'com.google.gms.google-services'
MainActivity
package com.[HIDDEN].[HIDDEN];
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdReceiver;
import org.json.JSONStringer;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
private TextView mTextMessage;
private Button mOpen_uOrder;
private BottomNavigationView.OnNavigationItemSelectedListener
mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
mTextMessage.setText(R.string.title_home);
return true;
case R.id.navigation_dashboard:
mTextMessage.setText(R.string.title_dashboard);
return true;
case R.id.navigation_notifications:
mTextMessage.setText(R.string.title_notifications);
return true;
}
return false;
}
};
private void mOpen_uOrderClicked() {
Intent intent = new Intent(this, WebActivity.class);
startActivity(intent);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextMessage = (TextView) findViewById(R.id.message);
mOpen_uOrder = (Button) findViewById(R.id.open_uOrder);
mOpen_uOrder.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mOpen_uOrderClicked();
}
});
BottomNavigationView navigation = (BottomNavigationView)
findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
//TODO: Open activity specified in key `click_action`
Log.println(Log.ASSERT, "Click Action: ",
bundle.getString("click_action"));
}
[HIDDEN]FirebaseMessagingService service = new
[HIDDEN]FirebaseMessagingService();
}
}
I had to do it the hard way and commented out everything on MainActivity and then go through line by line uncommenting 1 line, install the apk and then open from my phone to see which line is causing the error, and it was this:
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
//TODO: Open activity specified in key `click_action`
// THE CULPRIT:::Apparently you cannot have log statements in the app when not debugging?
// Because bundle.getString("click_action") works.
Log.println(Log.ASSERT, "Click Action: ", bundle.getString("click_action"));
}
Related
My java file
package com.example.sunona;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import com.karumi.dexter.Dexter;
import java.util.jar.Manifest;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setContentView(R.layout.activity_main);
Dexter.withContext(this) // cannot resolve withContext method.
.withPermission(Manifest.permission.Read_External_Storage) //cannot resolve permission Symbol
.withListener()
.check();
}
}
build gradle file
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.example.sunona"
minSdkVersion 16
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'com.karumi:dexter:4.1.0'
}
Mainfest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sunona">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.SunoNa">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I tried many things like using withActivity, capital small arrangements also. I visited many websites and many posts on StackOverflow. but I not found any satisfactory answer. finally, I am asking this question on StackOverflow. if anyone knows why this issue has? please help me.
It seems like the doc here is not updated: https://github.com/Karumi/Dexter
Because i was able achieve it with usage of withActivity instead of withContext because library does not contain that method.
Also make sure you have the right imports.
//manifest import should be this
import android.Manifest;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
// dexter imports
import com.karumi.dexter.Dexter;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.PermissionListener;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Dexter.withActivity(this) // change this
.withPermission(Manifest.permission.READ_EXTERNAL_STORAGE) //change this
.withListener(new PermissionListener() {
#Override
public void onPermissionGranted(PermissionGrantedResponse response) {
}
#Override
public void onPermissionDenied(PermissionDeniedResponse response) {
}
#Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
}
})
.check();
}
}
use this to get withContext() method
implementation 'com.karumi:dexter:6.2.2'
change the import to following:
import android.Manifest;
and it works fine.
I can't solve this 'intent'problem!
When notification received my phone stop working with a message "System UI Stoped"
I'm using Android Studio 3.0.1
FirebaseMessagingService File>
Here I'm getting an error for "PendingIntend.FLAG_ONE_SHOT" line. The "intent" has and red underlind and asking for an arry!
package firebase.com.firebasecloudmessaging;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.IBinder;
import android.app.LoaderManager.LoaderCallbacks;
import android.support.v4.app.NotificationCompat;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
public MyFirebaseMessagingService() {
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
sendNotification(remoteMessage.getNotification().getBody());
}
private void sendNotification(String messageBody)
{
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivities(this,0,intent,PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder.setSmallIcon(R.drawable.ic_stat_name);
notificationBuilder.setContentTitle("LiveCricket");
notificationBuilder.setContentText(messageBody);
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSound(defaultSoundUri);
notificationBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0,notificationBuilder.build());
}
}
Manifest File>
Please check this file also,
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="firebase.com.firebasecloudmessaging">
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyFirebaseInstanceIdService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service
android:name=".MyFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
</application>
FirebaseInstanceId File>
This file is not showing any error!
package firebase.com.firebasecloudmessaging;
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
import static android.content.ContentValues.TAG;
public class MyFirebaseInstanceIdService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(refreshedToken);
}
private void sendRegistrationToServer(String token)
{
}
}
Build.gradle(Project)>
Please check the gradle file!
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath 'com.google.gms:google-services:3.1.0'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Build.gradle(App level)>
Please check the gradle file!
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "firebase.com.firebasecloudmessaging"
minSdkVersion 18
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint- layout:1.0.2'
implementation 'com.google.firebase:firebase-messaging:11.0.4'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
apply plugin: 'com.google.gms.google-services'
I've watched a tutorial on YouTube about how to integrate Firebase to android applications. Registered Firebase, add my facebook and app info, and add the necessary changes to my app but somehow my main interface which should show login screens does not show up. There is no build errors.
Here are my codes;
My build.gradle inside my app:
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
defaultConfig {
applicationId "com.bogroup.ucuncuprogram"
minSdkVersion 16
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.google.firebase:firebase-core:9.4.0'
compile 'com.google.firebase:firebase-auth:9.4.0'
compile 'com.google.firebase:firebase-database:9.4.0'
//compile 'com.google.firebase:firebase-storage:9.4.0'
compile 'com.firebaseui:firebase-ui:0.4.4'
compile 'com.google.android.gms:play-services-auth:9.4.0'
compile 'com.android.support:animated-vector-drawable:25.0.0'
compile 'com.android.support:design:25.0.0'
compile 'com.android.support:support-v4:25.0.0'
compile 'com.android.support:cardview-v7:25.0.0'
compile 'com.android.support:customtabs:25.0.0'
compile 'com.android.support:recyclerview-v7:25.0.0'
//compile 'com.android.support:customtabs:25.2.0'
testCompile 'junit:junit:4.12'
}
apply plugin: 'com.google.gms.google-services'
My main java code:
package com.bogroup.ucuncuprogram;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import com.firebase.ui.auth.AuthUI;
import com.google.firebase.auth.FirebaseAuth;
public class MainActivity extends AppCompatActivity {
private static final int RC_SIGN_IN = 0;
EditText et;
private FirebaseAuth auth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
auth = FirebaseAuth.getInstance();
if(auth.getCurrentUser() != null){
//USER ALREADY SIGNED IN
Log.d("AUTH", auth.getCurrentUser().getEmail());
}else{
startActivityForResult(AuthUI.getInstance()
.createSignInIntentBuilder()
.setProviders(AuthUI.FACEBOOK_PROVIDER,
AuthUI.EMAIL_PROVIDER,
AuthUI.GOOGLE_PROVIDER)
.build(),RC_SIGN_IN);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==RC_SIGN_IN){
if(resultCode==RESULT_OK){
//user logged in
Log.d("AUTH", auth.getCurrentUser().getEmail());
}else{
// user not authenticated
Log.d("AUTH", "NOT AUTHENTİCATED");
}
}
}
public void tikla(View v){
if (v.getId()==R.id.button){
Intent intent = new Intent(getApplicationContext(),ikinciekren.class);
CharSequence charlarim = et.getText();
intent.putExtra("anahtar",charlarim);
startActivity(intent);
//
}
/*
else if (v.getId()==R.id.button){
//
}
*/
}
}
My main build.gradle file (not under app)
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.2'
classpath 'com.google.gms:google-services:3.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
My android.manifest.xml file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bogroup.ucuncuprogram">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ikinciekren">
<intent-filter>
<action android:name="android.intent.action.IKINCIEKREN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
Also added google-services.json file under app and facebook id under in string.xml file
Any help is appreciated. Thanks in advance.
Try changing startActivityForResult() to:
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setProviders(Arrays.asList(
new AuthUI.IdpConfig.Builder(AuthUI.FACEBOOK_PROVIDER).build(),
new AuthUI.IdpConfig.Builder(AuthUI.EMAIL_PROVIDER).build(),
new AuthUI.IdpConfig.Builder(AuthUI.GOOGLE_PROVIDER).build()
))
.build(),
RC_SIGN_IN);
To learn more about authentication on Firebase UI library look at:
https://github.com/firebase/FirebaseUI-Android/tree/master/auth
I am using the Firebase Console to send notifications.
I am testing my app so my app is installed only in my phone.
I am able to send only one notification to my app in a day, the rest of the notifications are showing as Completed, but not delivered.
My selected options are => User segment > app > and my app package name.
Is there a limit in the free plan?
build.gradle (PROJECT)
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'com.google.gms:google-services:3.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
build.gradle (MODULE)
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "25.0.1"
defaultConfig {
applicationId "com.example.myfirstapp"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.google.firebase:firebase-core:9.0.1'
compile 'com.google.firebase:firebase-messaging:9.0.1'
testCompile 'junit:junit:4.12'
}
apply plugin: 'com.google.gms.google-services'
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myfirstapp" >
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".TokenService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<service
android:name=".FCMMessageReceiverService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
</application>
</manifest>
TOKEN SERVICE
public class TokenService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d("notification", refreshedToken);
sendRegistrationToServer(refreshedToken);
}
private void sendRegistrationToServer(String token) {
}
}
FCMMessageReceiverService
package com.example.myfirstapp;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class FCMMessageReceiverService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.w("fcm", "received notification");
sendNotification(remoteMessage.getNotification().getTitle());
}
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 , intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(messageBody)
.setAutoCancel(false)
.setSound(defaultSoundUri);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, notificationBuilder.build());
}
}
I believe for testing purpose, there is an initial limit with multiple devices, and instances. the rest is fine.
I am new to this, but trying to get a v simple example working of sending a message from my Wearable to my Phone. I have read other similar questions, but I can't find the solution amongst the answers I have read.
My problem is the onMessageReceived method in my Listener (running on my Mobile) is never called.
I am using real devices, Sony SmartWatch 3 and Samsung S5
What I have working is
My wearable sends the message (using Wearable.MessageApi.sendMessage) and outputs to the log that the message is successfully sent to the correct node.
What I have tried based on other similar questions I have read :-
Package in AndroidManifest is same between Mobile and Wearable
applicationId is same in build.gradle file between Mobile and Wearable
Uninstalling the apps from both Mobile and Wearable and running apps from Android Studio (not in debug mode)
Any guidance very gratefully received, please see my code below.
Thanks
Mobile Code
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.davidson.anothermessagetest" >
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name=".MainActivity"
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=".ListenerService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
</application>
</manifest>
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.davidson.anothermessagetest"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
wearApp project(':wear')
compile 'com.android.support:appcompat-v7:23.2.0'
compile 'com.google.android.gms:play-services:8.4.0'
}
ListenerService
package com.davidson.anothermessagetest;
import android.util.Log;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.WearableListenerService;
/**
* Created by ddavidson on 09/03/2016.
*/
public class ListenerService extends WearableListenerService {
#Override
public void onMessageReceived(MessageEvent messageEvent) {
Log.v("myTag", "onMessageReceived:");
if (messageEvent.getPath().equals("/message_path")) {
final String message = new String(messageEvent.getData());
Log.v("myTag", "Message path received on watch is: " + messageEvent.getPath());
Log.v("myTag", "Message received on watch is: " + message);
}
else {
super.onMessageReceived(messageEvent);
}
}
#Override
public void onPeerConnected(Node peer) {
Log.v("myTag", "onPeerConnected:");
}
}
Wearable Code
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.davidson.anothermessagetest" >
<uses-feature android:name="android.hardware.type.watch" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.DeviceDefault" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
</manifest>
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.davidson.anothermessagetest"
minSdkVersion 20
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.google.android.support:wearable:1.3.0'
compile 'com.google.android.gms:play-services-wearable:8.4.0'
}
MainActivity
package com.davidson.anothermessagetest;
import android.app.Activity;
import android.os.Bundle;
import android.support.wearable.view.WatchViewStub;
import android.util.Log;
import android.widget.TextView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.MessageApi;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.Wearable;
public class MainActivity extends Activity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
GoogleApiClient googleClient;
private TextView mTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.v("myTag", "Wearable: onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
#Override
public void onLayoutInflated(WatchViewStub stub) {
mTextView = (TextView) stub.findViewById(R.id.text);
}
});
// Build a new GoogleApiClient for the Wearable API
googleClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
// Connect to the data layer when the Activity starts
#Override
protected void onStart() {
super.onStart();
googleClient.connect();
}
// Send a message when the data layer connection is successful.
#Override
public void onConnected(Bundle connectionHint) {
String message = "Hello wearable\n Via the data layer";
//Requires a new thread to avoid blocking the UI
new SendToDataLayerThread("/message_path", message).start();
}
// Disconnect from the data layer when the Activity stops
#Override
protected void onStop() {
if (null != googleClient && googleClient.isConnected()) {
googleClient.disconnect();
}
super.onStop();
}
// Placeholders for required connection callbacks
#Override
public void onConnectionSuspended(int cause) { }
#Override
public void onConnectionFailed(ConnectionResult connectionResult) { }
public class SendToDataLayerThread extends Thread {
String path;
String message;
// Constructor to send a message to the data layer
SendToDataLayerThread(String p, String msg) {
path = p;
message = msg;
}
public void run() {
NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleClient).await();
for (Node node : nodes.getNodes()) {
MessageApi.SendMessageResult result = Wearable.MessageApi.sendMessage(googleClient, node.getId(), path, message.getBytes()).await();
if (result.getStatus().isSuccess()) {
Log.v("myTag", "Message: {" + message + "} sent to: " + node.getDisplayName());
}
else {
// Log an error
Log.v("myTag", "ERROR: failed to send Message");
}
}
}
}
}
you should add MESSAGE_RECEIVED action into the manifest.xml rather than BIND_LISTENER or DATA_CHANGED (DATA_CHANGED only used for onDataChange), as for high version of gms e.g. 9.6.1
<service android:name=".MyWearService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data android:scheme="wear" android:host="*"
android:path="/sensor_test" />
</intent-filter>
</service>
Your .ListenerService-declaration in your Mobile-AndroidManifest must be within the <application> tag. In your code it's outside.
Hope this fixes it.