简体   繁体   English

应用程序关闭时如何显示通知?

[英]How i can Show notifications when app is close?

I have a video calling application (it's called FtoF and it's currently on the play store).我有一个视频通话应用程序(它称为 FtoF,目前在 Play 商店中)。 I would like to show a notification when one user calls another, and this I did (lines 110-132 and 255), the problem is that this only works when the app is open.我想在一个用户呼叫另一个用户时显示通知,我这样做了(第 110-132 和 255 行),问题是这仅在应用程序打开时才有效。 How could I make notifications work even when the app is closed?即使应用程序关闭,我如何才能使通知正常工作? I leave you the code:我给你留下代码:

CallingActivity.java调用Activity.java

public class CallingActivity extends AppCompatActivity {
    private TextView nameContact;
    private ImageView profileImage;
    private ImageView cancelCallBtn, acceptCallBtn; //private ImageView cancelCallBtn, acceptCallBtn;
    private String callingId="", ringingId="";
    private String reciverUserId="", receiverUserImage="", receiverUserName="";
    private String senderUserId="", senderUserImage="", senderUserName="", checker="";
    private DatabaseReference userRef;
    private MediaPlayer mediaPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_calling);
        senderUserId = FirebaseAuth.getInstance().getCurrentUser().getUid();
        reciverUserId = getIntent().getExtras().get("visit_user_id").toString();
        userRef = FirebaseDatabase.getInstance().getReference().child("Users");
        nameContact = findViewById(R.id.name_calling);
        profileImage = findViewById(R.id.profile_image_calling);
        cancelCallBtn = findViewById(R.id.cancel_call);
        acceptCallBtn = findViewById(R.id.make_call);
        cancelCallBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                checker = "clicked";
                cancelCallingUser();
            }
        });
        acceptCallBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final HashMap<String, Object> callingPickUpMap = new HashMap<>();
                callingPickUpMap.put("picked", "picked");
                userRef.child(senderUserId).child("Ringing")
                        .updateChildren(callingPickUpMap)
                        .addOnCompleteListener(new OnCompleteListener<Void>() {
                            @Override
                            public void onComplete(@NonNull Task<Void> task) {
                                Intent intent = new Intent(CallingActivity.this, VideoCallActivity.class);
                                startActivity(intent);
                            }
                        });
            }
        });
        getAndSetUserProfileInfo();
    }

    private void addNotification() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            NotificationChannel channel =
                    new NotificationChannel("MyNotifications", "MyNotifications", NotificationManager.IMPORTANCE_DEFAULT);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
        }
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "MyNotifications")
                .setContentTitle("Chiamata in arrivo da "+ receiverUserName)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setAutoCancel(true)
                .setContentText("Apri FtoF per partecipare alla videochiamata");
        NotificationManagerCompat manager = NotificationManagerCompat.from(this);
        manager.notify(999, builder.build());
    }

    private void getAndSetUserProfileInfo() {
        userRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if(dataSnapshot.child(reciverUserId).exists()){
                    receiverUserImage = dataSnapshot.child(reciverUserId).child("image").getValue().toString();
                    receiverUserName = dataSnapshot.child(reciverUserId).child("name").getValue().toString();
                    nameContact.setText(receiverUserName);
                    Picasso.get().load(receiverUserImage).placeholder(R.drawable.profile_image).into(profileImage);
                }
                if(dataSnapshot.child(senderUserId).exists()){
                    senderUserImage = dataSnapshot.child(senderUserId).child("image").getValue().toString();
                    senderUserName = dataSnapshot.child(senderUserId).child("name").getValue().toString();
                }
                TextView info_txt = (TextView) findViewById(R.id.txt);
                info_txt.setText("in attesa che " + receiverUserName + " accetti l'invito..."); //concatenazione per testo sotto al nome
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) { }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        userRef.child(reciverUserId)
                .addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        if (!checker.equals("clicked") && !dataSnapshot.hasChild("Calling") && !dataSnapshot.hasChild("Ringing")){
                            final HashMap<String, Object> callingInfo = new HashMap<>();
                            callingInfo.put("calling", reciverUserId);
                            userRef.child(senderUserId)
                                    .child("Calling")
                                    .updateChildren(callingInfo)
                                    .addOnCompleteListener(new OnCompleteListener<Void>() {
                                        @Override
                                        public void onComplete(@NonNull Task<Void> task) {
                                            if (task.isSuccessful()){
                                                final HashMap<String, Object> ringingInfo = new HashMap<>();
                                                ringingInfo.put("ringing", senderUserId);
                                                userRef.child(reciverUserId)
                                                        .child("Ringing")
                                                        .updateChildren(ringingInfo);
                                            }
                                        }
                                    });
                        }
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) { }
                });

        userRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if(dataSnapshot.child(senderUserId).hasChild("Ringing") && !dataSnapshot.child(senderUserId).hasChild("Calling")){
                    addNotification();
                    acceptCallBtn.setVisibility(View.VISIBLE);
                }
                if (dataSnapshot.child(reciverUserId).child("Ringing").hasChild("picked"))
                {
                    Intent intent = new Intent(CallingActivity.this, VideoCallActivity.class);
                    startActivity(intent);
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) { }
        });
    }

    private void cancelCallingUser() {
        //sender
        userRef.child(senderUserId)
                .child("Calling")
                .addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        if (dataSnapshot.exists() && dataSnapshot.hasChild("calling"))
                        {
                            callingId = dataSnapshot.child("calling").getValue().toString();
                            userRef.child(callingId)
                                    .child("Ringing")
                                    .removeValue()
                                    .addOnCompleteListener(new OnCompleteListener<Void>() {
                                        @Override
                                        public void onComplete(@NonNull Task<Void> task) {
                                            if (task.isSuccessful()){
                                                userRef.child(senderUserId)
                                                        .child("Calling")
                                                        .removeValue()
                                                        .addOnCompleteListener(new OnCompleteListener<Void>() {
                                                            @Override
                                                            public void onComplete(@NonNull Task<Void> task) {
                                                                startActivity(new Intent(CallingActivity.this, RegistrationActivity.class));
                                                                finish();
                                                            }
                                                        });
                                            }
                                        }
                                    });
                        } else {
                            startActivity(new Intent(CallingActivity.this, RegistrationActivity.class));
                            finish();
                        }
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {
                    }
                });
        //receiver
        userRef.child(senderUserId)
                .child("Ringing")
                .addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        if (dataSnapshot.exists() && dataSnapshot.hasChild("ringing"))

                        {
                            ringingId = dataSnapshot.child("ringing").getValue().toString();
                            userRef.child(ringingId)
                                    .child("Calling")
                                    .removeValue()
                                    .addOnCompleteListener(new OnCompleteListener<Void>() {
                                        @Override
                                        public void onComplete(@NonNull Task<Void> task) {
                                            if (task.isSuccessful()){
                                                userRef.child(senderUserId)
                                                        .child("Ringing")
                                                        .removeValue()
                                                        .addOnCompleteListener(new OnCompleteListener<Void>() {
                                                            @Override
                                                            public void onComplete(@NonNull Task<Void> task) {
                                                                startActivity(new Intent(CallingActivity.this, RegistrationActivity.class));
                                                                finish();
                                                            }
                                                        });
                                            }
                                        }
                                    });
                        }
                        else {
                            startActivity(new Intent(CallingActivity.this, RegistrationActivity.class));
                            finish();
                        }
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {
                    }
                });
    }
}

AndroidManifest.xml AndroidManifest.xml

<?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.conta.ftof">

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />

    <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=".donate" />
        <activity android:name=".VideoCallActivity" />
        <activity android:name=".CallingActivity" />
        <activity android:name=".ProfileActivity" />
        <activity android:name=".FindPeopleActivity" />
        <activity android:name=".NotificationsActivity" />
        <activity android:name=".SettingsActivity" />
        <activity
            android:name=".ContactsActivity"
            android:label="@string/title_activity_main" />
        <activity android:name=".RegistrationActivity">
            <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.ads.APPLICATION_ID"
            android:value="ca-app-pub-3400243939195187~6852949310"/>

        <receiver android:name=".ReminderBroadcast"/>
    </application>
</manifest>

According to the NotificationCompat documentation:根据NotificationCompat文档:

public Builder (Context context, String channelId)

Constructs a new Builder with the defaults:使用默认值构造一个新的 Builder:

  • context A Context that will be used by the Builder to construct the RemoteViews . context Builder 将使用的 Context 来构造RemoteViews
  • channelId String: The constructed Notification will be posted on this NotificationChannel. channelId String:构造的通知将发布在此 NotificationChannel 上。

The Context is an interface to global information about an application environment.上下文是有关应用程序环境的全局信息的接口。 This is an abstract class whose implementation is provided by the Android system.这是一个抽象类,其实现由Android系统提供。 It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.它允许访问特定于应用程序的资源和类,以及调用应用程序级操作,例如启动活动、广播和接收意图等。

In this way, the Android operating system controls through Context what the application may or may not present to the user, thus preventing any application from displaying what it wants at the time it wants.这样,Android 操作系统通过 Context 控制应用程序可以或不可以向用户呈现什么,从而防止任何应用程序在它想要​​的时候显示它想要的东西。

So the way you can present a notification is passing a Context do builder that have permission to construct Remote Views, and your app receives this context when the user open it or the app receives a broadcast message like a push notification .因此,您可以呈现通知的方式是传递一个Context do 构建器,该构建器有权构建远程视图,并且您的应用程序会在用户打开它或应用程序收到诸如推送通知之类的广播消息时接收此上下文。

public class PushNotificationReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        //at this point the context has the permission to create remote views
        addNotification(context);
        setResultCode(Activity.RESULT_OK);
    }

    private void addNotification(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            NotificationChannel channel =
                    new NotificationChannel("MyNotifications", "MyNotifications", NotificationManager.IMPORTANCE_DEFAULT);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
        }
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "MyNotifications")
                .setContentTitle("Chiamata in arrivo")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setAutoCancel(true)
                .setContentText("Apri FtoF per partecipare alla videochiamata");
        NotificationManagerCompat manager = NotificationManagerCompat.from(context);
        manager.notify(999, builder.build());
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当用户在 Android 中关闭应用程序时,我如何重新启动应用程序 - how can i restart app when user close the app in Android 如何让我的 ForegroundService 在 Android 13 上显示通知? - How can I make my ForegroundService to show notifications on Android 13? 当我在应用浏览器中的android webview中打开链接时,如何在左上方放置关闭按钮 - when i open a link in android webview in app browser how can i put close button on top left 如何向我的新闻应用 ANDROID 添加通知? - How can I add notifications to my news App ANDROID? 如何显示通知即使手机处于打盹或应用程序处于应用程序待机模式? - How to show notifications EVEN when phone is in Doze or app is in App Standby mode? 即使应用程序关闭,如何暂时禁用按钮? - How do I disable a button temporarily even when the app is close? 如何创建在单击后关闭应用程序的通知? - How can I create notification which will close the app after clicking? 如何以编程方式关闭并重新启动应用程序? - How can i close and start again app programmatically? 我如何在后台关闭我的 android 应用程序的所有活动 - How i can close all activities of my android app in background 我怎样才能让双击关闭我的应用程序 - How can i make double press back to close my app
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM