如何让 Android 应用程序在 ui 线程关闭后推送通知

How to get Android Application to push notifications after ui thread is closed

如何在 Android 上手动关闭 UI 后让推送通知正常工作?

嗨,我需要一些帮助,无法通过搜索找到任何解决方案。

应用程序基本上与任何其他消息传递应用程序一样,例如。 Whatsapp.

我有 MessageService 运行ning 作为自己的进程 ,即使 UI 关闭,它仍然存在。

这是我的应用程序的基本工作方式:

  1. MainActivity 启动服务
  2. MessageService 发送广播到
  3. messageReceiver 获取 broadCast 和 运行 messageLoader
  4. MessagesLoader 扩展 AsyncTask 从数据库获取更改
  5. MessagesLoader 推送通知。

UI 运行ning

时,每个这些部分 正常工作

当我关闭 UI 时,messageService 再次重新启动,但 UI 关闭后没有推送通知。

如能帮助完成这项工作,我们将不胜感激。

谢谢

这里有一些代码片段可以帮助你理解我的东西是如何工作的..

MainActivity.java

    ...........................
    @Override
    protected void onResume() {
        super.onResume();
        serviceIntent = new Intent(getApplicationContext(), MessageService.class);
        startService(serviceIntent);

        registerReceiver(messageReceiver, new IntentFilter(MessageService.MESSAGES_BROADCAST_ACTION));
    }
    ...........................

MessageService.java

public class MessageService extends Service {
    Updater updater;
    BroadcastReceiver messageBroadcaster;
    Intent intent;
    Context context;
    static final public String MESSAGES_BROADCAST_ACTION = "com.<Your Package>";

    public MessageService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        this.intent = intent;
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        this.updater = new Updater();
        this.context = getApplicationContext();
        this.intent = new Intent(this, NotificationActivity.class);
        Toast.makeText(this, "Message Service Created", Toast.LENGTH_LONG).show();
    }

    @Override
    public synchronized int onStartCommand(Intent intent, int flags, int startId) {

        if (!updater.isRunning()) {
            updater.start();
            updater.isRunning = true;
        }

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public synchronized void onDestroy() {
        super.onDestroy();

        if (updater.isRunning) {
            updater.interrupt();
            updater.isRunning = false;
            updater = null;
        }
        Toast.makeText(this, "Message Service Destroyed", Toast.LENGTH_LONG).show();
    }
    class Updater extends Thread {

        public boolean isRunning = false;
        public long DELAY = 2500;

        @Override
        public void run() {
            super.run();

            isRunning = true;
            while (isRunning) {
                sendResult();
                try {
                    Thread.sleep(DELAY);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    isRunning = false;
                }
            }
        }

        public boolean isRunning() {
            return this.isRunning;
        }
    }

    public void sendResult() {
        sendBroadcast(intent);
    }
}

MessageReceiver.java

public class MessageReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {

        Intent serviceIntent = new Intent(context, MessageService.class);
        context.startService(serviceIntent);
        new MessagesLoader(context).execute();
    }
}

MessageLoader.java

public class MessagesLoader extends AsyncTask<String,Void,String> {
    public MessagesLoader(Context context) {
        this.context = context;
        this.intent = new Intent(this.context, ChatsActivity.class);
        this.prev_count = prev_count;

        Intent intent = new Intent(context, ChatsActivity.class);
        PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent, 0);


        this.mBuilder = new android.support.v4.app.NotificationCompat.Builder(context)
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setContentTitle("YOUR APP");
    }

    protected void onPreExecute(){
    }

    @Override
    protected String doInBackground(String... arg0) {
        StringBuffer result = new StringBuffer("");

        try {

            URL url = new URL("http://yourURL.com/get_data.php");
            HttpURLConnection con = (HttpURLConnection)url.openConnection();

            con.setRequestMethod("POST");
            con.setRequestProperty("User-Agent", "");
            con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

            con.setDoOutput(true);

            String urlParameters = "<OWN PARAMETERS>";
            DataOutputStream wr = new DataOutputStream(con.getOutputStream());
            wr.writeBytes(urlParameters);
            wr.flush();
            wr.close();

            int responseCode = con.getResponseCode();

            con.connect();

            InputStream inputStream = con.getInputStream();

            BufferedReader rd = new BufferedReader(new InputStreamReader(inputStream));
            String line = "";

            while ((line = rd.readLine()) != null) {
                result.append(line);
            }
            return new String(result);
        } catch(Exception e){
            return new String("Exception: " + e.getMessage());
        }
    }

    @Override
    protected void onPostExecute(String result) {
        initData(result);
    }

    public void initData(String result) {
        // Actually Store Data to sharedPreferences
        String error = "";
        JSONObject obj = new JSONObject();
        // ...ETC

        int count = 5;
        showNotification(5);
    }


    public void showNotification(int count) {

        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        Intent mIntent = new Intent(this.context, ChatsActivity.class);
        PendingIntent pIntent = PendingIntent.getActivity(this.context, 0, mIntent, 0);

        Intent cIntent = new Intent(this.context, NotificationActionService.class);
        PendingIntent cPIntent = PendingIntent.getService(this.context, 0, cIntent, 0);
        NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle();
        bigTextStyle.bigText("YOUR BIG TEXT");
        Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        mBuilder
            .setContentIntent(pIntent)
            .setContentText("YOUR CONTENT TEXT")
            .setAutoCancel(true)
            .setLights(R.color.white, 1000, 500)
            .setSound(soundUri)
            .setGroup("YOUR GROUP")
            .setTicker("YOUR TICKER TEXT")
            .setWhen(System.currentTimeMillis())
            .setCategory("YOUR CATEGORY")

             .setStyle(bigTextStyle)
             .addAction(0, "Show Messages", pIntent);

        TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
        stackBuilder.addParentStack(MainActivity.class);
        stackBuilder.addNextIntent(mIntent);
        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        mBuilder.setContentIntent(resultPendingIntent);
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yourpackage" >
android:versionCode="1"
android:versionName="1.0"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-feature android:name="android.hardware.camera" android:required="true" />
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:configChanges="orientation"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.yourpackage.MainActivity"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
        </intent-filter>
    </activity>

    <service android:name="com.yourpackage.MessageService"
        android:process=":messageService"
        android:enabled="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/messageService">
        <intent-filter>
            <action android:name="com.yourpackage.MessageService" />
        </intent-filter>
    </service>

    <receiver android:name="com.yourpackage.MessageReceiver">
        <intent-filter>
            <action android:name="com.yourpackage.MessageReceiver" />
        </intent-filter>
    </receiver>

</application>
</manifest>

我找到了解决办法。现在,即使没有 UI 运行.

,我的应用程序也总是向我显示新消息信息

这是解决这个问题的方法。

MainActivity.java

@Override
protected void onResume() {
    super.onresume();

    serviceIntent = new Intent(getApplicationContext(), MessageService.class);
    startService(serviceIntent);

    /* COMMENTED OUT LINE BELOW */
    //registerReceiver(messageReceiver, new IntentFilter(MessageService.MESSAGES_BROADCAST_ACTION));
}

MessageService.java

@Override
public void onCreate() {
    super.onCreate();
    updater = new Updater();
    context = getApplicationContext();

    /* AND ADDED THAT LINE HERE AND */
    registerReceiver(messageReceiver, new IntentFilter(MESSAGES_BROADCAST_ACTION));
    intent = new Intent(MESSAGES_BROADCAST_ACTION);
    Toast.makeText(this, "Message Service Created", Toast.LENGTH_LONG).show();
}