<option name="linkedExternalProjectsSettings"> | <option name="linkedExternalProjectsSettings"> | ||||
<GradleProjectSettings> | <GradleProjectSettings> | ||||
<option name="testRunner" value="PLATFORM" /> | <option name="testRunner" value="PLATFORM" /> | ||||
<option name="disableWrapperSourceDistributionNotification" value="true" /> | |||||
<option name="distributionType" value="DEFAULT_WRAPPED" /> | <option name="distributionType" value="DEFAULT_WRAPPED" /> | ||||
<option name="externalProjectPath" value="$PROJECT_DIR$" /> | <option name="externalProjectPath" value="$PROJECT_DIR$" /> | ||||
<option name="gradleJvm" value="JDK" /> | <option name="gradleJvm" value="JDK" /> |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
package="com.example.fcm"> | package="com.example.fcm"> | ||||
<uses-permission android:name="android.permission.INTERNET" /> | <uses-permission android:name="android.permission.INTERNET" /> | ||||
<uses-permission android:name="android.permission.VIBRATE" /> | |||||
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> | <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> | ||||
<application | <application | ||||
android:allowBackup="true" | android:allowBackup="true" | ||||
android:roundIcon="@mipmap/ic_launcher_round" | android:roundIcon="@mipmap/ic_launcher_round" | ||||
android:supportsRtl="true" | android:supportsRtl="true" | ||||
android:theme="@style/Theme.App"> | android:theme="@style/Theme.App"> | ||||
<service android:name=".MyFirebaseMessagingService" | |||||
<service android:name="com.example.fcm.MyFirebaseMessagingService" | |||||
android:exported="false"> | android:exported="false"> | ||||
<intent-filter> | <intent-filter> | ||||
<action android:name="com.google.firebase.MESSAGING_EVENT" /> | <action android:name="com.google.firebase.MESSAGING_EVENT" /> | ||||
</intent-filter> | </intent-filter> | ||||
</service> | </service> | ||||
<activity android:name=".MainActivity"> | |||||
<activity android:name="com.example.fcm.MainActivity"> | |||||
<intent-filter> | <intent-filter> | ||||
<action android:name="android.intent.action.MAIN" /> | <action android:name="android.intent.action.MAIN" /> | ||||
import android.annotation.SuppressLint; | import android.annotation.SuppressLint; | ||||
import android.app.NotificationChannel; | import android.app.NotificationChannel; | ||||
import android.app.NotificationManager; | import android.app.NotificationManager; | ||||
import android.content.Context; | |||||
import android.os.Build; | import android.os.Build; | ||||
import android.os.Bundle; | import android.os.Bundle; | ||||
import android.os.VibrationEffect; | |||||
import android.os.Vibrator; | |||||
import android.util.Log; | import android.util.Log; | ||||
import android.widget.Button; | import android.widget.Button; | ||||
import android.widget.EditText; | |||||
import android.widget.Toast; | import android.widget.Toast; | ||||
import com.android.volley.toolbox.JsonObjectRequest; | import com.android.volley.toolbox.JsonObjectRequest; | ||||
import com.example.fcm.databinding.ActivityMainBinding; | import com.example.fcm.databinding.ActivityMainBinding; | ||||
final private String FCM_API = "https://fcm.googleapis.com/fcm/send"; | final private String FCM_API = "https://fcm.googleapis.com/fcm/send"; | ||||
final private String serverKey = "key=" + "AAAA446tEwQ:APA91bEAqpEFQ0ufbp9WSFIGV68P8kUgNlnKzuEHIcWLeS1YlMwJewRdnAGRae0VpDzriag7ZQbMUMPDiT-LD1kTXLQFM73C9DC13iN4nn9gEYCPVp4MN8JHFm20m1BxS8zWZcKDYFcz"; | final private String serverKey = "key=" + "AAAA446tEwQ:APA91bEAqpEFQ0ufbp9WSFIGV68P8kUgNlnKzuEHIcWLeS1YlMwJewRdnAGRae0VpDzriag7ZQbMUMPDiT-LD1kTXLQFM73C9DC13iN4nn9gEYCPVp4MN8JHFm20m1BxS8zWZcKDYFcz"; | ||||
final private String contentType = "application/json"; | final private String contentType = "application/json"; | ||||
final private String topic = "vibration"; | |||||
private static final String TAG = "MainActivity"; | private static final String TAG = "MainActivity"; | ||||
String NOTIFICATION_TITLE; | String NOTIFICATION_TITLE; | ||||
setContentView(binding.getRoot()); | setContentView(binding.getRoot()); | ||||
Button buttonSend = findViewById(R.id.sendButton); | Button buttonSend = findViewById(R.id.sendButton); | ||||
EditText level = findViewById(R.id.level); | |||||
EditText delay = findViewById(R.id.delay); | |||||
EditText duration = findViewById(R.id.duration); | |||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
// Create channel to show notifications. | // Create channel to show notifications. | ||||
binding.subscribeButton.setOnClickListener(v -> { | binding.subscribeButton.setOnClickListener(v -> { | ||||
Log.d(TAG, "Subscribing to topic"); | Log.d(TAG, "Subscribing to topic"); | ||||
// [START subscribe_topics] | // [START subscribe_topics] | ||||
FirebaseMessaging.getInstance().subscribeToTopic("testForMDT") | |||||
FirebaseMessaging.getInstance().subscribeToTopic(topic) | |||||
.addOnCompleteListener(task -> { | .addOnCompleteListener(task -> { | ||||
String msg = getString(R.string.msg_subscribed); | String msg = getString(R.string.msg_subscribed); | ||||
if (!task.isSuccessful()) { | if (!task.isSuccessful()) { | ||||
}); | }); | ||||
buttonSend.setOnClickListener(v -> { | buttonSend.setOnClickListener(v -> { | ||||
TOPIC = "/topics/testForMDT"; //topic must match with what the receiver subscribed to | |||||
NOTIFICATION_TITLE = "Test"; | |||||
NOTIFICATION_MESSAGE = "Gregor"; | |||||
TOPIC = "/topics/" + topic; //topic must match with what the receiver subscribed to | |||||
NOTIFICATION_TITLE = "Test values"; | |||||
NOTIFICATION_MESSAGE = "von Gregor"; | |||||
JSONObject notification = new JSONObject(); | JSONObject notification = new JSONObject(); | ||||
JSONObject notifcationBody = new JSONObject(); | JSONObject notifcationBody = new JSONObject(); | ||||
try { | try { | ||||
notifcationBody.put("title", NOTIFICATION_TITLE); | notifcationBody.put("title", NOTIFICATION_TITLE); | ||||
notifcationBody.put("message", NOTIFICATION_MESSAGE); | notifcationBody.put("message", NOTIFICATION_MESSAGE); | ||||
notifcationBody.put("level", level.getText().toString()); | |||||
notifcationBody.put("delay", delay.getText().toString()); | |||||
notifcationBody.put("duration", duration.getText().toString()); | |||||
notification.put("to", TOPIC); | notification.put("to", TOPIC); | ||||
notification.put("data", notifcationBody); | notification.put("data", notifcationBody); | ||||
}; | }; | ||||
MySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonObjectRequest); | MySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonObjectRequest); | ||||
} | } | ||||
} | } |
import android.media.RingtoneManager; | import android.media.RingtoneManager; | ||||
import android.net.Uri; | import android.net.Uri; | ||||
import android.os.Build; | import android.os.Build; | ||||
import android.os.VibrationEffect; | |||||
import android.os.Vibrator; | |||||
import android.util.Log; | import android.util.Log; | ||||
import androidx.annotation.RequiresApi; | import androidx.annotation.RequiresApi; | ||||
PendingIntent pendingIntent = PendingIntent.getActivity(this , 0, intent, | PendingIntent pendingIntent = PendingIntent.getActivity(this , 0, intent, | ||||
PendingIntent.FLAG_ONE_SHOT); | PendingIntent.FLAG_ONE_SHOT); | ||||
String title = remoteMessage.getData().get("title"); | |||||
String message = remoteMessage.getData().get("message"); | |||||
String level = remoteMessage.getData().get("level"); | |||||
String delay = remoteMessage.getData().get("delay"); | |||||
String duration = remoteMessage.getData().get("duration"); | |||||
String wholeMessage = message + "," + level + "," + delay + "," + duration; | |||||
//MainActivity main = new Vibration(); | |||||
assert level != null; | |||||
assert delay != null; | |||||
assert duration != null; | |||||
try { | |||||
triggerVibration(Integer.parseInt(level), Integer.parseInt(delay), Integer.parseInt(duration)); | |||||
} catch (InterruptedException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
Uri notificationSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); | Uri notificationSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); | ||||
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, ADMIN_CHANNEL_ID) | NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, ADMIN_CHANNEL_ID) | ||||
.setSmallIcon(R.drawable.ic_stat_ic_notification) | .setSmallIcon(R.drawable.ic_stat_ic_notification) | ||||
.setContentTitle(remoteMessage.getData().get("title")) | |||||
.setContentText(remoteMessage.getData().get("message")) | |||||
.setContentTitle(title) | |||||
.setContentText(wholeMessage) | |||||
.setAutoCancel(true) | .setAutoCancel(true) | ||||
.setSound(notificationSoundUri) | .setSound(notificationSoundUri) | ||||
.setContentIntent(pendingIntent); | .setContentIntent(pendingIntent); | ||||
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build()); | notificationManager.notify(0 /* ID of notification */, notificationBuilder.build()); | ||||
} | } | ||||
//public static void sendNotificationToUser(String user, final String message) { | |||||
// Firebase ref = new Firebase(FIREBASE_URL); | |||||
// final Firebase notifications = ref.child("notificationRequests"); | |||||
//Map notification = new HashMap<>(); | |||||
// notification.put("username", user); | |||||
// notification.put("message", message); | |||||
// notifications.push().setValue(notification); | |||||
//} | |||||
@RequiresApi(api = Build.VERSION_CODES.O) | @RequiresApi(api = Build.VERSION_CODES.O) | ||||
private void setupChannels(NotificationManager notificationManager){ | private void setupChannels(NotificationManager notificationManager){ | ||||
CharSequence adminChannelName = "New notification"; | CharSequence adminChannelName = "New notification"; | ||||
} | } | ||||
} | } | ||||
public void triggerVibration(int level, int delay, int duration) throws InterruptedException { | |||||
Log.i("Vibration","triggerVibration"); | |||||
Log.i("Vibration","level:" + level); | |||||
Log.i("Vibration","delay:" + delay + "ms"); | |||||
Log.i("Vibration","duration:" + duration + "ms"); | |||||
Vibrator a = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); | |||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | |||||
try { | |||||
Thread.sleep(delay); | |||||
} catch(InterruptedException ex){ | |||||
Thread.currentThread().interrupt(); | |||||
} | |||||
a.vibrate(VibrationEffect.createOneShot(duration, level)); | |||||
} else { | |||||
//deprecated in API 26 | |||||
a.vibrate(2000); | |||||
} | |||||
} | |||||
} | } |
package com.example.fcm; | |||||
import android.content.Context; | |||||
import android.os.Build; | |||||
import android.os.VibrationEffect; | |||||
import android.os.Vibrator; | |||||
import android.util.Log; | |||||
import androidx.appcompat.app.AppCompatActivity; | |||||
public class Vibration extends AppCompatActivity { | |||||
public void triggerVibration(int level, int delay, int duration) throws InterruptedException { | |||||
Log.i("Vibration","triggerVibration"); | |||||
Log.i("Vibration","level:" + level); | |||||
Log.i("Vibration","delay:" + delay); | |||||
Log.i("Vibration","duration:" + duration); | |||||
Vibrator a = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); | |||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | |||||
try { | |||||
Thread.sleep(delay); | |||||
} catch(InterruptedException ex){ | |||||
Thread.currentThread().interrupt(); | |||||
} | |||||
a.vibrate(VibrationEffect.createOneShot(duration, level)); | |||||
} else { | |||||
//deprecated in API 26 | |||||
a.vibrate(2000); | |||||
} | |||||
} | |||||
} |
android:paddingTop="@dimen/activity_vertical_margin" | android:paddingTop="@dimen/activity_vertical_margin" | ||||
tools:context=".MainActivity"> | tools:context=".MainActivity"> | ||||
<TextView | |||||
android:id="@+id/informationTextView" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_gravity="center_horizontal" | |||||
android:gravity="center_horizontal" | |||||
android:text="@string/quickstart_message" /> | |||||
<Button | <Button | ||||
android:id="@+id/subscribeButton" | android:id="@+id/subscribeButton" | ||||
android:layout_width="@dimen/standard_field_width" | android:layout_width="@dimen/standard_field_width" | ||||
android:layout_gravity="center_horizontal" | android:layout_gravity="center_horizontal" | ||||
android:text="@string/log_token" /> | android:text="@string/log_token" /> | ||||
<EditText | |||||
android:id="@+id/level" | |||||
android:layout_width="200dp" | |||||
android:layout_height="wrap_content" | |||||
android:layout_gravity="center_horizontal" | |||||
android:hint="Level (1-255)" | |||||
/> | |||||
<EditText | |||||
android:id="@+id/delay" | |||||
android:layout_width="200dp" | |||||
android:layout_height="wrap_content" | |||||
android:layout_gravity="center_horizontal" | |||||
android:hint="Delay (ms)" | |||||
/> | |||||
<EditText | |||||
android:id="@+id/duration" | |||||
android:layout_width="200dp" | |||||
android:layout_height="wrap_content" | |||||
android:layout_gravity="center_horizontal" | |||||
android:hint="Duration (ms)" | |||||
/> | |||||
<Button | <Button | ||||
android:id="@+id/sendButton" | android:id="@+id/sendButton" | ||||
android:layout_width="@dimen/standard_field_width" | android:layout_width="@dimen/standard_field_width" | ||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
android:layout_gravity="center_horizontal" | android:layout_gravity="center_horizontal" | ||||
android:text="Send message" /> | |||||
android:text="Send Command" /> | |||||
</LinearLayout> | </LinearLayout> |
<string name="quickstart_message">Quickstart message</string> | <string name="quickstart_message">Quickstart message</string> | ||||
<string name="log_token">Log token</string> | <string name="log_token">Log token</string> | ||||
<string name="subscribe_to_weather">Subscribe</string> | <string name="subscribe_to_weather">Subscribe</string> | ||||
<string name="msg_subscribed">Subscribed to testForMDT topic</string> | |||||
<string name="msg_subscribed">Subscribed to vibration topic</string> | |||||
<string name="msg_token_fmt" translatable="false">InstanceID Token: %s</string> | <string name="msg_token_fmt" translatable="false">InstanceID Token: %s</string> | ||||
<string name="default_notification_channel_id" translatable="false">fcm_default_channel</string> | <string name="default_notification_channel_id" translatable="false">fcm_default_channel</string> | ||||
It should describe the category of notifications that will be sent through this channel | It should describe the category of notifications that will be sent through this channel | ||||
--> | --> | ||||
<!-- [START fcm_default_icon_string] --> | <!-- [START fcm_default_icon_string] --> | ||||
<string name="default_notification_channel_name" translatable="true">testForMDT</string> | |||||
<string name="default_notification_channel_name" translatable="true">vibration</string> | |||||
<!-- [END fcm_default_icon_string] --> | <!-- [END fcm_default_icon_string] --> | ||||
<string name="msg_subscribe_failed">Failed to subscribe to testForMDT topic</string> | |||||
<string name="msg_subscribe_failed">Failed to subscribe to vibration topic</string> | |||||
<string name="fcm_message">FCM Message</string> | <string name="fcm_message">FCM Message</string> | ||||
<string name="subscribe">Subscribe</string> | <string name="subscribe">Subscribe</string> | ||||
</resources> | </resources> |