- 浏览: 5820214 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (890)
- WindowsPhone (0)
- android (88)
- android快速迭代 (17)
- android基础 (34)
- android进阶 (172)
- android高级 (0)
- android拾遗 (85)
- android动画&效果 (68)
- Material Design (13)
- LUA (5)
- j2me (32)
- jQuery (39)
- spring (26)
- hibernate (20)
- struts (26)
- tomcat (9)
- javascript+css+html (62)
- jsp+servlet+javabean (14)
- java (37)
- velocity+FCKeditor (13)
- linux+批处理 (9)
- mysql (19)
- MyEclipse (9)
- ajax (7)
- wap (8)
- j2ee+apache (24)
- 其他 (13)
- phonegap (35)
最新评论
-
Memories_NC:
本地lua脚本终于执行成功了,虽然不是通过redis
java中调用lua脚本语言1 -
ZHOU452840622:
大神://处理返回的接收状态 这个好像没有监听到 遇 ...
android 发送短信的两种方式 -
PXY:
拦截部分地址,怎么写的for(int i=0;i<lis ...
判断是否登录的拦截器SessionFilter -
maotou1988:
Android控件之带清空按钮(功能)的AutoComplet ...
自定义AutoCompleteTextView -
yangmaolinpl:
希望有表例子更好。。。,不过也看明白了。
浅谈onInterceptTouchEvent、onTouchEvent与onTouch
写在最前:Android实现推送是比较困难的,我这里虽然实现了推送,但是当服务器需要发送的对象一多,就会发生延迟或干脆Down机。很多软件看似实现了推送,其实不然,它们只不过是有一个Service一直在监听网络状态,当手机联网了就主动向服务器请求了数据,给人的感觉像“推送”了一样。这是障眼法,老板们哪管这些,还以为真的推送,非得实现它。殊不知,真正的推送跟服务器的数量有关!再细想一下,如果这么容易就能实现推送,那早就垃圾信息满天飞了,还要发垃圾短信干什么!至少,发垃圾短信还要收费,可是推送就不需要花钱。当别人都是傻子,用免费的不用还用收费的?所以,一味的追求“推送”不可取!
看了以上这些话,你是不是觉得不想再看下去了?这很正常!权当参考罢了.
请先参考:Android推送通知指南
这里使用了IBM提供的MQTT协议实现了推送。有一个wmqtt.jar包需要导入到工程,见附件。
然后编写PushService类实现一个服务,其中有个内部类:
MQTTConnection 实现了 MqttSimpleCallback接口,重写其中的publishArrived方法,我这里是当接受到推送的数据后显示一个Notification,点击该Notification后跳转到一个Activity上。
具体看PushService类,关键的地方我都用中文字说明了:
PushService是根据你的设备号来准确定位你的手机的,它是从SharedPreferences取得该设备号的,所以你得事先将你的设备号保存在SharedPreferences中,如下:
如果要关闭服务,只需要将下面的代码添加到想要的地方:
至于服务器端代码,我们使用php写的,这里请参考Android推送通知指南
另一篇关于推送:
Android Push Notification实现信息推送使用
http://www.cnblogs.com/hanyonglu/archive/2012/03/16/2399655.html
http://www.apkbus.com/android-48367-1-1.html
那google不就成了中转站了吗?
要么就是使用Stocket长连接一直维持这个连接,但显然是不妥的。(长连接需要不断的发心跳包,以维持这个连接不断掉。google会疯掉的!)
看了以上这些话,你是不是觉得不想再看下去了?这很正常!权当参考罢了.
请先参考:Android推送通知指南
这里使用了IBM提供的MQTT协议实现了推送。有一个wmqtt.jar包需要导入到工程,见附件。
然后编写PushService类实现一个服务,其中有个内部类:
MQTTConnection 实现了 MqttSimpleCallback接口,重写其中的publishArrived方法,我这里是当接受到推送的数据后显示一个Notification,点击该Notification后跳转到一个Activity上。
具体看PushService类,关键的地方我都用中文字说明了:
package com.ata.push; import org.json.JSONException; import org.json.JSONObject; import android.R; import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.IBinder; import android.util.Log; import com.ata.view.NewMesageInfoActivity; import com.ibm.mqtt.IMqttClient; import com.ibm.mqtt.MqttClient; import com.ibm.mqtt.MqttException; import com.ibm.mqtt.MqttPersistence; import com.ibm.mqtt.MqttPersistenceException; import com.ibm.mqtt.MqttSimpleCallback; /* * PushService that does all of the work. * Most of the logic is borrowed from KeepAliveService. * http://code.google.com/p/android-random/source/browse/trunk/TestKeepAlive/src/org/devtcg/demo/keepalive/KeepAliveService.java?r=219 */ public class PushService extends Service { // this is the log tag public static final String TAG = "PushService"; // the IP address, where your MQTT broker is running. private static final String MQTT_HOST = "172.16.26.41";//需要改成服务器IP // the port at which the broker is running. private static int MQTT_BROKER_PORT_NUM = 1883;//需要改成服务器port // Let's not use the MQTT persistence. private static MqttPersistence MQTT_PERSISTENCE = null; // We don't need to remember any state between the connections, so we use a clean start. private static boolean MQTT_CLEAN_START = true; // Let's set the internal keep alive for MQTT to 15 mins. I haven't tested this value much. It could probably be increased. private static short MQTT_KEEP_ALIVE = 60 * 15; // Set quality of services to 0 (at most once delivery), since we don't want push notifications // arrive more than once. However, this means that some messages might get lost (delivery is not guaranteed) private static int[] MQTT_QUALITIES_OF_SERVICE = { 0 } ; private static int MQTT_QUALITY_OF_SERVICE = 0; // The broker should not retain any messages. private static boolean MQTT_RETAINED_PUBLISH = false; // MQTT client ID, which is given the broker. In this example, I also use this for the topic header. // You can use this to run push notifications for multiple apps with one MQTT broker. public static String MQTT_CLIENT_ID = "ata";//需要改成自己需要的名称 // These are the actions for the service (name are descriptive enough) private static final String ACTION_START = MQTT_CLIENT_ID + ".START"; private static final String ACTION_STOP = MQTT_CLIENT_ID + ".STOP"; private static final String ACTION_KEEPALIVE = MQTT_CLIENT_ID + ".KEEP_ALIVE"; private static final String ACTION_RECONNECT = MQTT_CLIENT_ID + ".RECONNECT"; // Connection log for the push service. Good for debugging. //private ConnectionLog mLog; // Connectivity manager to determining, when the phone loses connection private ConnectivityManager mConnMan; // Notification manager to displaying arrived push notifications private NotificationManager mNotifMan; // Whether or not the service has been started. private boolean mStarted; // This the application level keep-alive interval, that is used by the AlarmManager // to keep the connection active, even when the device goes to sleep. private static final long KEEP_ALIVE_INTERVAL = 1000 * 60 * 28; // Retry intervals, when the connection is lost. private static final long INITIAL_RETRY_INTERVAL = 1000 * 10; private static final long MAXIMUM_RETRY_INTERVAL = 1000 * 60 * 30; // Preferences instance private SharedPreferences mPrefs; // We store in the preferences, whether or not the service has been started //判断Service是否已经启动,不要重复启动! public static final String PREF_STARTED = "isStarted"; // We also store the deviceID (target) //需要提供手机设备号,该设备号应该事先保存在SharedPreferences中 public static final String PREF_DEVICE_ID = "deviceID"; // We store the last retry interval public static final String PREF_RETRY = "retryInterval"; // Notification title public static String NOTIF_TITLE = "ata"; //需要改成自己需要的title // Notification id private static final int NOTIF_CONNECTED = 0; // This is the instance of an MQTT connection. private MQTTConnection mConnection; private long mStartTime; // Static method to start the service //在需要的地方直接调用该方法就启动监听了 public static void actionStart(Context ctx) { Intent i = new Intent(ctx, PushService.class); i.setAction(ACTION_START); ctx.startService(i); } // Static method to stop the service public static void actionStop(Context ctx) { Intent i = new Intent(ctx, PushService.class); i.setAction(ACTION_STOP); ctx.startService(i); } // Static method to send a keep alive message public static void actionPing(Context ctx) { Intent i = new Intent(ctx, PushService.class); i.setAction(ACTION_KEEPALIVE); ctx.startService(i); } @Override public void onCreate() { super.onCreate(); log("Creating service"); mStartTime = System.currentTimeMillis(); /*try { //mLog = new ConnectionLog(); //Log.i(TAG, "Opened log at " + mLog.getPath()); } catch (IOException e) { Log.e(TAG, "Failed to open log", e); }*/ // Get instances of preferences, connectivity manager and notification manager mPrefs = getSharedPreferences(TAG, MODE_PRIVATE); mConnMan = (ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE); mNotifMan = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); /* If our process was reaped by the system for any reason we need * to restore our state with merely a call to onCreate. We record * the last "started" value and restore it here if necessary. */ handleCrashedService(); } // This method does any necessary clean-up need in case the server has been destroyed by the system // and then restarted private void handleCrashedService() { if (wasStarted() == true) { log("Handling crashed service..."); // stop the keep alives stopKeepAlives(); // Do a clean start start(); } } @Override public void onDestroy() { log("Service destroyed (started=" + mStarted + ")"); // Stop the services, if it has been started if (mStarted == true) { stop(); } /* try { if (mLog != null) mLog.close(); } catch (IOException e) {} */ } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); log("Service started with intent=" + intent); // Do an appropriate action based on the intent. if (intent.getAction().equals(ACTION_STOP) == true) { stop(); stopSelf(); } else if (intent.getAction().equals(ACTION_START) == true) { start(); } else if (intent.getAction().equals(ACTION_KEEPALIVE) == true) { keepAlive(); } else if (intent.getAction().equals(ACTION_RECONNECT) == true) { if (isNetworkAvailable()) { reconnectIfNecessary(); } } } @Override public IBinder onBind(Intent intent) { return null; } // log helper function private void log(String message) { log(message, null); } private void log(String message, Throwable e) { if (e != null) { Log.e(TAG, message, e); } else { Log.i(TAG, message); } /*if (mLog != null) { try { mLog.println(message); } catch (IOException ex) {} } */ } // Reads whether or not the service has been started from the preferences private boolean wasStarted() { return mPrefs.getBoolean(PREF_STARTED, false); } // Sets whether or not the services has been started in the preferences. private void setStarted(boolean started) { mPrefs.edit().putBoolean(PREF_STARTED, started).commit(); mStarted = started; } private synchronized void start() { log("Starting service..."); // Do nothing, if the service is already running. if (mStarted == true) { Log.w(TAG, "Attempt to start connection that is already active"); return; } // Establish an MQTT connection connect(); // Register a connectivity listener registerReceiver(mConnectivityChanged, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); } private synchronized void stop() { // Do nothing, if the service is not running. if (mStarted == false) { Log.w(TAG, "Attempt to stop connection not active."); return; } // Save stopped state in the preferences setStarted(false); // Remove the connectivity receiver unregisterReceiver(mConnectivityChanged); // Any existing reconnect timers should be removed, since we explicitly stopping the service. cancelReconnect(); // Destroy the MQTT connection if there is one if (mConnection != null) { mConnection.disconnect(); mConnection = null; } } // private synchronized void connect() { log("Connecting..."); // fetch the device ID from the preferences. String deviceID = mPrefs.getString(PREF_DEVICE_ID, null); // Create a new connection only if the device id is not NULL if (deviceID == null) { log("Device ID not found."); } else { try { mConnection = new MQTTConnection(MQTT_HOST, deviceID); } catch (MqttException e) { // Schedule a reconnect, if we failed to connect log("MqttException: " + (e.getMessage() != null ? e.getMessage() : "NULL")); if (isNetworkAvailable()) { scheduleReconnect(mStartTime); } } setStarted(true); } } private synchronized void keepAlive() { try { // Send a keep alive, if there is a connection. if (mStarted == true && mConnection != null) { mConnection.sendKeepAlive(); } } catch (MqttException e) { log("MqttException: " + (e.getMessage() != null? e.getMessage(): "NULL"), e); mConnection.disconnect(); mConnection = null; cancelReconnect(); } } // Schedule application level keep-alives using the AlarmManager private void startKeepAlives() { Intent i = new Intent(); i.setClass(this, PushService.class); i.setAction(ACTION_KEEPALIVE); PendingIntent pi = PendingIntent.getService(this, 0, i, 0); AlarmManager alarmMgr = (AlarmManager)getSystemService(ALARM_SERVICE); alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + KEEP_ALIVE_INTERVAL, KEEP_ALIVE_INTERVAL, pi); } // Remove all scheduled keep alives private void stopKeepAlives() { Intent i = new Intent(); i.setClass(this, PushService.class); i.setAction(ACTION_KEEPALIVE); PendingIntent pi = PendingIntent.getService(this, 0, i, 0); AlarmManager alarmMgr = (AlarmManager)getSystemService(ALARM_SERVICE); alarmMgr.cancel(pi); } // We schedule a reconnect based on the starttime of the service public void scheduleReconnect(long startTime) { // the last keep-alive interval long interval = mPrefs.getLong(PREF_RETRY, INITIAL_RETRY_INTERVAL); // Calculate the elapsed time since the start long now = System.currentTimeMillis(); long elapsed = now - startTime; // Set an appropriate interval based on the elapsed time since start if (elapsed < interval) { interval = Math.min(interval * 4, MAXIMUM_RETRY_INTERVAL); } else { interval = INITIAL_RETRY_INTERVAL; } log("Rescheduling connection in " + interval + "ms."); // Save the new internval mPrefs.edit().putLong(PREF_RETRY, interval).commit(); // Schedule a reconnect using the alarm manager. Intent i = new Intent(); i.setClass(this, PushService.class); i.setAction(ACTION_RECONNECT); PendingIntent pi = PendingIntent.getService(this, 0, i, 0); AlarmManager alarmMgr = (AlarmManager)getSystemService(ALARM_SERVICE); alarmMgr.set(AlarmManager.RTC_WAKEUP, now + interval, pi); } // Remove the scheduled reconnect public void cancelReconnect() { Intent i = new Intent(); i.setClass(this, PushService.class); i.setAction(ACTION_RECONNECT); PendingIntent pi = PendingIntent.getService(this, 0, i, 0); AlarmManager alarmMgr = (AlarmManager)getSystemService(ALARM_SERVICE); alarmMgr.cancel(pi); } private synchronized void reconnectIfNecessary() { if (mStarted == true && mConnection == null) { log("Reconnecting..."); connect(); } } // This receiver listeners for network changes and updates the MQTT connection // accordingly private BroadcastReceiver mConnectivityChanged = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Get network info NetworkInfo info = (NetworkInfo)intent.getParcelableExtra (ConnectivityManager.EXTRA_NETWORK_INFO); // Is there connectivity? boolean hasConnectivity = (info != null && info.isConnected()) ? true : false; log("Connectivity changed: connected=" + hasConnectivity); if (hasConnectivity) { reconnectIfNecessary(); } else if (mConnection != null) { // if there no connectivity, make sure MQTT connection is destroyed mConnection.disconnect(); cancelReconnect(); mConnection = null; } } }; // Display the topbar notification private void showNotification(String content) { Notification n = new Notification(); n.flags |= Notification.FLAG_SHOW_LIGHTS; n.flags |= Notification.FLAG_AUTO_CANCEL; n.defaults = Notification.DEFAULT_ALL; n.icon = R.drawable.ic_dialog_info; n.when = System.currentTimeMillis(); Log.i("PushService", "json==="+content); String alert=null; String id=null; try { JSONObject json = new JSONObject(content); alert = json.optString("alert"); id = json.optString("id"); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } Intent intent = new Intent(this,NewMesageInfoActivity.class); intent.putExtra("url", "http://testing.portal.ataudc.com/message/"+id); intent.putExtra("id", id); PendingIntent pi = PendingIntent.getActivity(this, 0,intent, PendingIntent.FLAG_ONE_SHOT); // Change the name of the notification here n.setLatestEventInfo(this, NOTIF_TITLE, alert, pi); mNotifMan.notify(NOTIF_CONNECTED, n); } // Check if we are online private boolean isNetworkAvailable() { NetworkInfo info = mConnMan.getActiveNetworkInfo(); if (info == null) { return false; } return info.isConnected(); } // This inner class is a wrapper on top of MQTT client. private class MQTTConnection implements MqttSimpleCallback { IMqttClient mqttClient = null; // Creates a new connection given the broker address and initial topic public MQTTConnection(String brokerHostName, String initTopic) throws MqttException { // Create connection spec String mqttConnSpec = "tcp://" + brokerHostName + "@" + MQTT_BROKER_PORT_NUM; // Create the client and connect mqttClient = MqttClient.createMqttClient(mqttConnSpec, MQTT_PERSISTENCE); String clientID = MQTT_CLIENT_ID + "/" + mPrefs.getString(PREF_DEVICE_ID, ""); mqttClient.connect(clientID, MQTT_CLEAN_START, MQTT_KEEP_ALIVE); // register this client app has being able to receive messages mqttClient.registerSimpleHandler(this); // Subscribe to an initial topic, which is combination of client ID and device ID. initTopic = MQTT_CLIENT_ID + "/" + initTopic; subscribeToTopic(initTopic); log("Connection established to " + brokerHostName + " on topic " + initTopic); // Save start time mStartTime = System.currentTimeMillis(); // Star the keep-alives startKeepAlives(); } // Disconnect public void disconnect() { try { stopKeepAlives(); mqttClient.disconnect(); } catch (MqttPersistenceException e) { log("MqttException" + (e.getMessage() != null? e.getMessage():" NULL"), e); } } /* * Send a request to the message broker to be sent messages published with * the specified topic name. Wildcards are allowed. */ private void subscribeToTopic(String topicName) throws MqttException { if ((mqttClient == null) || (mqttClient.isConnected() == false)) { // quick sanity check - don't try and subscribe if we don't have // a connection log("Connection error" + "No connection"); } else { String[] topics = { topicName }; mqttClient.subscribe(topics, MQTT_QUALITIES_OF_SERVICE); } } /* * Sends a message to the message broker, requesting that it be published * to the specified topic. */ private void publishToTopic(String topicName, String message) throws MqttException { if ((mqttClient == null) || (mqttClient.isConnected() == false)) { // quick sanity check - don't try and publish if we don't have // a connection log("No connection to public to"); } else { mqttClient.publish(topicName, message.getBytes(), MQTT_QUALITY_OF_SERVICE, MQTT_RETAINED_PUBLISH); } } /* * Called if the application loses it's connection to the message broker. */ public void connectionLost() throws Exception { log("Loss of connection" + "connection downed"); stopKeepAlives(); // null itself mConnection = null; if (isNetworkAvailable() == true) { reconnectIfNecessary(); } } /* * Called when we receive a message from the message broker. * 在这里处理服务器推送过来的数据 */ public void publishArrived(String topicName, byte[] payload, int qos, boolean retained) { // Show a notification String s = new String(payload); showNotification(s); } public void sendKeepAlive() throws MqttException { log("Sending keep alive"); // publish to a keep-alive topic publishToTopic(MQTT_CLIENT_ID + "/keepalive", mPrefs.getString(PREF_DEVICE_ID, "")); } } }
PushService是根据你的设备号来准确定位你的手机的,它是从SharedPreferences取得该设备号的,所以你得事先将你的设备号保存在SharedPreferences中,如下:
class PushTask extends AsyncTask<Void, Integer, Boolean> { @Override protected Boolean doInBackground(Void... params) { // 启动PUSH服务 Editor editor = getSharedPreferences(PushService.TAG, MODE_PRIVATE) .edit(); String deviceID = Secure.getString(getContentResolver(),Secure.ANDROID_ID); editor.putString(PushService.PREF_DEVICE_ID, deviceID); editor.commit(); try { PushService.actionStart(getApplicationContext()); } catch (Exception e) { // TODO: handle exception // Log.i(tag, "启动PUSH服务失败."); return false; } return true; } @Override protected void onCancelled() { super.onCancelled(); } @Override protected void onPostExecute(Boolean result) { Log.i(tag, result?"启动PUSH服务成功.":"启动PUSH服务失败."); } @Override protected void onPreExecute() { // 预处理 } @Override protected void onProgressUpdate(Integer... values) { // 更新进度 } }
PushTask task=new PushTask(); task.execute();
如果要关闭服务,只需要将下面的代码添加到想要的地方:
PushService.actionStop(getApplicationContext());
至于服务器端代码,我们使用php写的,这里请参考Android推送通知指南
另一篇关于推送:
Android Push Notification实现信息推送使用
http://www.cnblogs.com/hanyonglu/archive/2012/03/16/2399655.html
http://www.apkbus.com/android-48367-1-1.html
- wmqtt.jar (47.5 KB)
- 下载次数: 375
评论
5 楼
Yunba云巴
2016-12-13
云巴https://yunba.io/是基于MQTT协议、采用Erlang/OTP架构设计的实时通信系统。
实现Android推送方面,客户端在集成我们的 Android SDK后,服务端便可通过 SDK 或使用 RESTful API,向 Android 客户端发消息。
为了保证消息的实时性,我们Android SDK 会启动一个后台的 Service,创建并保持到云巴服务器的长连接,从而保证了消息推送的实时性。
同样为了保证消息能够被送达,我们 SDK 支持 离线消息 的功能,可保证消息送达客户端。 也就是说,在推送消息时,如果客户端当前不在线,消息将暂存在云巴服务器上(多达 50 条,长达 15 天)。
当客户端上线并成功连接到云巴https://yunba.io的服务器后,服务器会把离线消息推送给该客户端。客户端成功接收后,服务器才会删除保存的离线消息。
iOS推送同理,除此以外,我们的 SDK 集成了 APNs,这样开发者就无需开发与 APNs 对接的模块,也不必自己负责 Device Token 的更新。
实现Android推送方面,客户端在集成我们的 Android SDK后,服务端便可通过 SDK 或使用 RESTful API,向 Android 客户端发消息。
为了保证消息的实时性,我们Android SDK 会启动一个后台的 Service,创建并保持到云巴服务器的长连接,从而保证了消息推送的实时性。
同样为了保证消息能够被送达,我们 SDK 支持 离线消息 的功能,可保证消息送达客户端。 也就是说,在推送消息时,如果客户端当前不在线,消息将暂存在云巴服务器上(多达 50 条,长达 15 天)。
当客户端上线并成功连接到云巴https://yunba.io的服务器后,服务器会把离线消息推送给该客户端。客户端成功接收后,服务器才会删除保存的离线消息。
iOS推送同理,除此以外,我们的 SDK 集成了 APNs,这样开发者就无需开发与 APNs 对接的模块,也不必自己负责 Device Token 的更新。
4 楼
wuhui520
2013-08-26
请问怎么修改 windows 版本下服务端的默认 1883 端口?
3 楼
gundumw100
2013-05-16
test_any 写道
有没有不需要通过activity,service,receiver的推送方式。简单的说就android会连接到一个标准的服务器,如:谷歌,然后应用开发者只需要把数据发送给个谷歌,然后谷歌就自动推送到应用了。这样,用户的手机也就不需要启动service,activity等来维护连接了。
那google不就成了中转站了吗?
要么就是使用Stocket长连接一直维持这个连接,但显然是不妥的。(长连接需要不断的发心跳包,以维持这个连接不断掉。google会疯掉的!)
2 楼
test_any
2013-05-16
有没有不需要通过activity,service,receiver的推送方式。简单的说就android会连接到一个标准的服务器,如:谷歌,然后应用开发者只需要把数据发送给个谷歌,然后谷歌就自动推送到应用了。这样,用户的手机也就不需要启动service,activity等来维护连接了。
1 楼
liushuoboco
2013-04-02
发表评论
-
NestedScrollView滚动到顶部固定子View悬停挂靠粘在顶端
2018-10-31 20:45 6993网上有一个StickyScrollView,称之为粘性Scro ... -
自定义Behavior实现AppBarLayout越界弹性效果
2017-03-31 09:33 10369一、继承AppBarLayout.Beha ... -
Android - 一种相似图片搜索算法的实现
2017-03-31 09:33 2622算法 缩小尺寸。 将图片缩小到8x8的尺寸,总共64个 ... -
使用SpringAnimation实现带下拉弹簧动画的 ScrollView
2017-03-30 11:30 2848在刚推出的 Support Library 25.3.0 里面 ... -
Android为应用添加角标(Badge)
2017-03-30 11:21 61771.需求简介 角标是什么意思呢? 看下图即可明了: 可 ... -
Android端与笔记本利用局域网进行FTP通信
2017-03-23 10:17 978先看图 打开前: 打开后: Activity类 ... -
PorterDuffColorFilter 在项目中的基本使用
2017-03-03 10:58 1354有时候标题栏会浮在内容之上,而内容会有颜色的变化,这时候就要求 ... -
ColorAnimationView 实现了滑动Viewpager 时背景色动态变化的过渡效果
2017-02-24 09:41 2220用法在注释中: import android.anima ... -
迷你轻量级全方向完美滑动处理侧滑控件SlideLayout
2017-01-16 16:53 2594纯手工超级迷你轻量级全方向完美滑动处理侧滑控件(比官方 sup ... -
Effect
2017-01-05 09:57 0https://github.com/JetradarMobi ... -
动态主题库Colorful,容易地改变App的配色方案
2016-12-27 14:49 2565Colorful是一个动态主题库,允许您很容易地改变App的配 ... -
对视图的对角线切割DiagonalView
2016-12-27 14:23 1118提供对视图的对角线切割,具有很好的用户定制 基本用法 ... -
仿淘宝京东拖拽商品详情页上下滚动黏滞效果
2016-12-26 16:53 3494比较常用的效果,有现成的,如此甚好!:) import ... -
让任意view具有滑动效果的SlideUp
2016-12-26 09:26 1707基本的类,只有一个: import android.a ... -
AdvancedWebView
2016-12-21 09:44 16https://github.com/delight-im/A ... -
可设置圆角背景边框的按钮, 通过调节色彩明度自动计算按下(pressed)状态颜色
2016-11-02 22:13 1920可设置圆角背景边框的的按钮, 通过调节色彩明度自动计算按下(p ... -
网络请求库相关
2016-10-09 09:35 62https://github.com/amitshekhari ... -
ASimpleCache一个简单的缓存框架
2015-10-26 22:53 2178ASimpleCache 是一个为android制定的 轻量级 ... -
使用ViewDragHelper实现的DragLayout开门效果
2015-10-23 10:55 3415先看一下图,有个直观的了解,向下拖动handle就“开门了”: ... -
保证图片长宽比的同时拉伸图片ImageView
2015-10-16 15:40 3733按比例放大图片,不拉伸失真 import android. ...
相关推荐
在Android平台上,实现即时通知通常会借助Google的云消息推送服务(Google Cloud Messaging,简称GCM),但在iOS系统中,对应的则是Apple Push Notification service(APNs)。然而,这里提到的"android apns"可能是...
Android推送通知服务(Demo)详解 在移动应用开发中,推送通知是不可或缺的功能,它能够实时地将服务器端的信息推送给用户,即使应用在后台运行或者完全关闭。本篇文章将详细解析“Android Push Notification Service...
这个“android push notification 下载即可运行”项目表明,它提供了一个已经配置和调试好的环境,允许开发者快速体验和集成Android推送通知功能。 一、Android Push Notification基础 1. GCM(Google Cloud ...
百度推送是一款免费的云推送服务,它能够帮助开发者高效、稳定地实现消息推送,适用于各种类型的Android应用。 首先,我们需要了解百度推送的基本概念。百度推送主要由两部分组成:服务器端和客户端SDK。服务器端...
在Android系统中,本地推送(Local Push)是一种应用程序在不依赖远程服务器的情况下,实现消息推送的技术。它允许应用在特定时间或满足特定条件时向用户显示通知,无需持续连接到互联网,因此对于节省数据流量和...
例如,AndroidPN是一个基于XMPP的开源Android推送实现。尽管XMPP提供了丰富的功能,但它也有一些挑战: - 重连机制:服务器重启后,客户端需要重新启动才能恢复推送。 - 复杂性:使用XMPP协议可能会显得过于复杂,...
Laravel Push Notification是Laravel开发者实现跨平台推送通知的理想工具,它简化了与多个推送服务的交互,让开发者能够专注于构建功能丰富的应用程序,而无需关注底层推送技术的复杂性。通过学习和掌握这个包的使用...
本文将深入探讨如何利用REST API实现从客户端进行Android推送,特别关注百度云推送这一服务。首先,我们需要了解REST(Representational State Transfer)架构风格,它是一种通过HTTP协议进行数据交互的方式,简洁且...
在Android开发中,为了实现实时的消息推送功能,开发者经常会选择使用第三方服务,其中百度云推送(Baidu Cloud Push)是一个常见的选择。本教程将详细讲解如何在Android应用中集成百度云推送,以实现高效、稳定的...
至此,你已经成功地在 Laravel 项目中实现了 Push Notification 的服务端支持,可以向 iOS 和 Android 设备发送自定义通知了。别忘了在实际应用中处理错误,如设备 Token 或 Registration ID 无效、推送服务响应错误...
"anroid完美实现 push推送 源码奉送" 提供的开源框架AndroidPN(Android Push Notification)是一个专门针对Android设备设计的Push服务解决方案。下面将详细介绍这个框架以及其核心知识点。 AndroidPN是一个基于...
这个"Android Push Notification客户端源码包"显然是一个包含示例代码的资源,帮助开发者理解和实现Android设备上的推送通知功能。 一、Android Push Notification工作原理 Android Push Notification基于Google的...
极光推送通过SDK集成到Android应用中,可以让开发者轻松实现向用户发送通知或自定义消息,同时具备高到达率、低延迟、多平台支持等特性。 【Android Studio集成极光推送】 在Android Studio中集成极光推送,首先...
总结,Android消息推送通过`NotificationManager`和相应的服务器推送服务相结合,实现了在后台向用户展示通知的功能。开发者需要创建`Notification`对象,处理接收到的推送消息,并适当地配置`PendingIntent`以响应...
本篇文章将深入探讨如何在Android应用中集成JPush(极光推送)服务,通过一个具体的示例来阐述其工作原理和实现步骤。 JPush是极光公司提供的一款高效、稳定、易用的移动推送服务,支持Android、iOS以及Web平台。它...
在Android开发中,为了实现应用的消息实时推送功能,开发者经常会选择使用第三方服务,其中百度推送(Baidu Push)是一个常用的选择。本篇文章将详细讲解如何在Android应用中集成百度推送服务,实现消息的即时更新。...
总结来说,这个macOS应用程序是为移动应用开发者设计的,旨在简化和优化iOS和Android推送通知的测试过程,从而提高开发效率并减少调试时间。使用这样的工具,开发者可以更快地发现并修复与推送通知相关的错误,确保...
二、Android推送通知(FCM) 1. **FCM介绍**:Firebase Cloud Messaging是谷歌提供的云到设备消息传递服务,用于向Android、iOS甚至Web应用发送消息。 2. **Google API项目**:在Google Cloud Console上创建项目,...
android:name="cn.jpush.android.service.PushService" android:exported="false" > <action android:name="com.jiguang.sdk.push.service.RECEIVE_MESSAGE" /> </service> android:name=...