我怎样才能在 android 中保持状态 'online'
How can i keep status 'online' in android
现在我正在尝试使用 firebase 制作一个类似 Instagram 的聊天程序
问题是我想显示会员登录状态
但是 android 生命周期有问题
这是我的代码 HomeActiviy
用户登录成功后,进入HomeActivty
从这里我确定在线或离线
这是我区分线上线下的代码
private void status(String status){
reference = FirebaseDatabase.getInstance().getReference("Users").child(firebaseUser.getUid());
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("status", status);
reference.updateChildren(hashMap);
}
@Override
protected void onResume() {
super.onResume();
status("online");
}
@Override
protected void onPause() {
super.onPause();
status("offline");
}
来自我的 HomeActivity.java 推送聊天时的 ImageButton
转到聊天 Activity
他们看到对方的在线图片按钮为绿色或灰色
这是我的问题
什么时候从家Activity去另一个activity
状态将显示离线
第二次是我按下聊天按钮
这是我的聊天记录Activity
package com.example.together.activities.chat;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.example.together.fragment.ChatFragment;
import com.example.together.fragment.UsersFragment;
import com.example.together.model.User;
import com.example.together.R;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.HashMap;
import de.hdodenhof.circleimageview.CircleImageView;
public class ChatsActivity extends AppCompatActivity {
CircleImageView image_profile;
TextView username;
FirebaseUser firebaseUser;
DatabaseReference reference;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("");
image_profile = findViewById(R.id.image_profile);
username = findViewById(R.id.username);
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
reference = FirebaseDatabase.getInstance().getReference("Users").child(firebaseUser.getUid());
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
username.setText(user.getUsername());
if (user.getImageurl().equals("default")){
image_profile.setImageResource(R.mipmap.ic_launcher);
}else {
Glide.with(ChatsActivity.this).load(user.getImageurl()).into(image_profile);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
TabLayout tabLayout = findViewById(R.id.tab_layout);
ViewPager viewPager = findViewById(R.id.view_pager);
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPagerAdapter.addFragment(new ChatFragment(), "채팅"); // `new ChatFragment()` should be inside `FragmentPagerAdapter.getItem()`
viewPagerAdapter.addFragment(new UsersFragment(), "친구찾기"); // `new UsersFragment()` should be inside `FragmentPagerAdapter.getItem()`
viewPager.setAdapter(viewPagerAdapter);
tabLayout.setupWithViewPager(viewPager);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragments; // this line can cause crashes
private ArrayList<String> titles;
ViewPagerAdapter(FragmentManager fm){
super(fm);
this.fragments = new ArrayList<>();
this.titles = new ArrayList<>();
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
public void addFragment(Fragment fragment, String title){
fragments.add(fragment); // this line can cause crashes
titles.add(title);
}
// Ctrl + O
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
}
}
这是我的错误
2019-07-09 16:46:29.993 13773-13773/com.example.blogapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.blogapp, PID: 13773
java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity
at com.bumptech.glide.manager.RequestManagerRetriever.assertNotDestroyed(RequestManagerRetriever.java:323)
at com.bumptech.glide.manager.RequestManagerRetriever.get(RequestManagerRetriever.java:132)
at com.bumptech.glide.Glide.with(Glide.java:741)
at com.example.together.activities.chat.ChatsActivity.onDataChange(ChatsActivity.java:66)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@17.0.0:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@17.0.0:63)
at com.google.firebase.database.core.view.EventRaiser.run(com.google.firebase:firebase-database@@17.0.0:55)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
我认为它与 activity
的生命周期相关
如何保持状态?
问题看起来是您的 ChatsActivity
在 Glide 尝试加载图像时被破坏了。您可以使用 getApplicationContext()
来获取当前上下文。
尝试替换,
Glide.with(ChatsActivity.this).load(user.getImageurl()).into(image_profile);
和
Glide.with(getApplicationContext()).load(user.getImageurl()).into(image_profile);
此外,您应该使用 firebase 提供的 .onDisconnect()
方法来检查用户是否存在
When you establish an onDisconnect() operation, the operation lives on the Firebase Realtime Database server. The server checks security to make sure the user can perform the write event requested, and informs the your app if it is invalid. The server then monitors the connection. If at any point the connection times out, or is actively closed by the Realtime Database client, the server checks security a second time (to make sure the operation is still valid) and then invokes the event.
你可以从这里了解更多doc
将此依赖项放入您的 build.gradle
文件中:
implementation "android.arch.lifecycle:extensions:*"
然后在您的应用程序 class 中使用:
public class MyApplication extends Application implements LifecycleObserver {
@Override
public void onCreate() {
super.onCreate();
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
private void onAppBackgrounded() {
Log.d("MyApp", "App in background");
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
private void onAppForegrounded() {
Log.d("MyApp", "App in foreground");
}
}
更新您的 AndroidManifest.xml 文件:
<application
android:name=".MyApplication"
....>
</application>
When your app is in background change status to offline
and when app is in foreground change it's status to online
.
Reference
只要用户在您的应用中,从技术上讲,他就是在线的。所以在你家 activity 使用这个:
@Override
protected void onStart() {
super.onStart();
myRef.child(uid).child("isOnline").setValue(true);
myRef.child(uid).child("isOnline").onDisconnect().setValue(false);
}
而且我建议添加以覆盖 onResume():
@Override
protected void onResume() {
super.onResume();
myRef.child(uid).child("isOnline").setValue(true); //User back online
}
确保添加一个 if 语句来检查用户是否连接到互联网!
现在我正在尝试使用 firebase 制作一个类似 Instagram 的聊天程序 问题是我想显示会员登录状态 但是 android 生命周期有问题
这是我的代码 HomeActiviy 用户登录成功后,进入HomeActivty 从这里我确定在线或离线
这是我区分线上线下的代码
private void status(String status){
reference = FirebaseDatabase.getInstance().getReference("Users").child(firebaseUser.getUid());
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("status", status);
reference.updateChildren(hashMap);
}
@Override
protected void onResume() {
super.onResume();
status("online");
}
@Override
protected void onPause() {
super.onPause();
status("offline");
}
来自我的 HomeActivity.java 推送聊天时的 ImageButton 转到聊天 Activity 他们看到对方的在线图片按钮为绿色或灰色
这是我的问题 什么时候从家Activity去另一个activity 状态将显示离线
第二次是我按下聊天按钮
这是我的聊天记录Activity
package com.example.together.activities.chat;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.example.together.fragment.ChatFragment;
import com.example.together.fragment.UsersFragment;
import com.example.together.model.User;
import com.example.together.R;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.HashMap;
import de.hdodenhof.circleimageview.CircleImageView;
public class ChatsActivity extends AppCompatActivity {
CircleImageView image_profile;
TextView username;
FirebaseUser firebaseUser;
DatabaseReference reference;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("");
image_profile = findViewById(R.id.image_profile);
username = findViewById(R.id.username);
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
reference = FirebaseDatabase.getInstance().getReference("Users").child(firebaseUser.getUid());
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
username.setText(user.getUsername());
if (user.getImageurl().equals("default")){
image_profile.setImageResource(R.mipmap.ic_launcher);
}else {
Glide.with(ChatsActivity.this).load(user.getImageurl()).into(image_profile);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
TabLayout tabLayout = findViewById(R.id.tab_layout);
ViewPager viewPager = findViewById(R.id.view_pager);
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPagerAdapter.addFragment(new ChatFragment(), "채팅"); // `new ChatFragment()` should be inside `FragmentPagerAdapter.getItem()`
viewPagerAdapter.addFragment(new UsersFragment(), "친구찾기"); // `new UsersFragment()` should be inside `FragmentPagerAdapter.getItem()`
viewPager.setAdapter(viewPagerAdapter);
tabLayout.setupWithViewPager(viewPager);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragments; // this line can cause crashes
private ArrayList<String> titles;
ViewPagerAdapter(FragmentManager fm){
super(fm);
this.fragments = new ArrayList<>();
this.titles = new ArrayList<>();
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
public void addFragment(Fragment fragment, String title){
fragments.add(fragment); // this line can cause crashes
titles.add(title);
}
// Ctrl + O
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
}
}
这是我的错误
2019-07-09 16:46:29.993 13773-13773/com.example.blogapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.blogapp, PID: 13773
java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity
at com.bumptech.glide.manager.RequestManagerRetriever.assertNotDestroyed(RequestManagerRetriever.java:323)
at com.bumptech.glide.manager.RequestManagerRetriever.get(RequestManagerRetriever.java:132)
at com.bumptech.glide.Glide.with(Glide.java:741)
at com.example.together.activities.chat.ChatsActivity.onDataChange(ChatsActivity.java:66)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@17.0.0:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@17.0.0:63)
at com.google.firebase.database.core.view.EventRaiser.run(com.google.firebase:firebase-database@@17.0.0:55)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
我认为它与 activity
的生命周期相关如何保持状态?
问题看起来是您的 ChatsActivity
在 Glide 尝试加载图像时被破坏了。您可以使用 getApplicationContext()
来获取当前上下文。
尝试替换,
Glide.with(ChatsActivity.this).load(user.getImageurl()).into(image_profile);
和
Glide.with(getApplicationContext()).load(user.getImageurl()).into(image_profile);
此外,您应该使用 firebase 提供的 .onDisconnect()
方法来检查用户是否存在
When you establish an onDisconnect() operation, the operation lives on the Firebase Realtime Database server. The server checks security to make sure the user can perform the write event requested, and informs the your app if it is invalid. The server then monitors the connection. If at any point the connection times out, or is actively closed by the Realtime Database client, the server checks security a second time (to make sure the operation is still valid) and then invokes the event.
你可以从这里了解更多doc
将此依赖项放入您的 build.gradle
文件中:
implementation "android.arch.lifecycle:extensions:*"
然后在您的应用程序 class 中使用:
public class MyApplication extends Application implements LifecycleObserver {
@Override
public void onCreate() {
super.onCreate();
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
private void onAppBackgrounded() {
Log.d("MyApp", "App in background");
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
private void onAppForegrounded() {
Log.d("MyApp", "App in foreground");
}
}
更新您的 AndroidManifest.xml 文件:
<application
android:name=".MyApplication"
....>
</application>
When your app is in background change status to
offline
and when app is in foreground change it's status toonline
.
Reference
只要用户在您的应用中,从技术上讲,他就是在线的。所以在你家 activity 使用这个:
@Override
protected void onStart() {
super.onStart();
myRef.child(uid).child("isOnline").setValue(true);
myRef.child(uid).child("isOnline").onDisconnect().setValue(false);
}
而且我建议添加以覆盖 onResume():
@Override
protected void onResume() {
super.onResume();
myRef.child(uid).child("isOnline").setValue(true); //User back online
}
确保添加一个 if 语句来检查用户是否连接到互联网!