Встраиваем локальные уведомления

от автора

Что самое ужасное в случае удаления приложения? Правильно, потеря связи с аудиторией и невозможность проинформировать о том, что у приложения сменился адрес прописки и имя пакета. Задачу решают Push уведомления, но это довольно хлопотно и не всегда удобно.

Поэтому мы напишем свои, простые как барабан и надежные как танк — локальные push уведомления. Код получился универсальным, и впринципе, его можно использовать как альтернативу обычным «пушам», например для новостной рассылки о том, что вышла новая версия приложения или для клянчанья рейтинга, да для чего угодно.

Начнем с конфига. Это обычный текстовый файл в json-формате.

{     "notifications":         [         {             "id": 1 ,             "title": "Sorry we are deleted from GPlay" ,             "text": "Please click for download new app" ,             "version": 105 ,             "action": "market://search?q=freemp" ,             "locale": "ru_Ru"         }         ]  }  

где
— id: unique number of message
— title: title of message
— text: text of message
— version: if not set message for all (optional)
— action: default action (optional)
— locale: optional

Данный файл размещаем, например на гитхабе и добавляем на него ссылку:

public static final String MESSAGEURL = «github.com/recoilme/freemp/blob/master/message.json?raw=true»;

Затем где нибудь в районе onCreate основного активити вызываем:
new UpdateUtils(activity);

Готово. С настройкой покончено. Теперь как это работает.

При старте приложение чекает массив уведомлений и показывает следующее сообщение из тех, что не были показаны ранее.
При последующем старте — показывает следующее и так, пока уведомления не кончатся. Таким образом можно организовывать очередь сообщений. Я не знаю пока точно зачем, но наверняка пригодится.

Существуют два вида фильтров:
version — если задать, например 105 — то будет показываться только в 105 версии приложения. Можно, например, написать для пользователей версии 105, что вышла версия 106)
locale — локаль текста, если например необходимо сделать сообщение на русском, для русскоязычных пользователей

Параметр action — опциональный, это Uri, который будет вызван при клике на уведомлении. Можно, например, направить в маркет ну или в другое активити (в том числе свое).

Собственно это все. Довольно просто, ив то же время позволит нивелировать ущерб от возможного удаления. Ну или наладить диалог с пользователями.

Код, в действии можно посмотреть тут: https://github.com/recoilme/freemp
Но собственно пока это один файл. Возможно библиотека будет развиваться, добавлю возможность скачивания обновления или что то вроде того. Пока же код комфортно поместится и тут:

package org.freemp.android;  import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.AsyncTask; import android.preference.PreferenceManager; import android.support.v4.app.NotificationCompat; import android.text.TextUtils; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject;  import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Locale;  /**  * Created by recoil on 06.08.14.  * example file:   {  "notifications": [{ id":1, "title":"Sorry we are deleted from GPlay", "text":"Please click for download new app",  "version":105 , "action":"market://search?q=freemp", "locale":"ru_Ru"}]  }    - id: unique number of message   - title: title of message   - text: text of message   - version: if not set message for all (may be not set)   - action: default action (may be not set)   - locale: may be not set   */  public class UpdateUtils {      public static final String MESSAGEURL = "https://github.com/recoilme/freemp/blob/master/message.json?raw=true";     private Context context;     private Activity activity;     private int versionCode;     private String locale;      public UpdateUtils(Activity activity) {         this.activity = activity;         context = activity.getApplicationContext();         new Update().execute();     }      private class Update extends AsyncTask<Void,Void,String> {          @Override         protected String doInBackground(Void... params) {             try {                 versionCode = context.getPackageManager()                         .getPackageInfo(context.getPackageName(), 0).versionCode;             } catch (PackageManager.NameNotFoundException e) {                 e.printStackTrace();             }             locale = Locale.getDefault().toString();             String response = "";             DefaultHttpClient client = new DefaultHttpClient();             HttpGet httpGet = new HttpGet(MESSAGEURL);             try {                 HttpResponse httpResponse = client.execute(httpGet);                 InputStream content = httpResponse.getEntity().getContent();                 BufferedReader buffer = new BufferedReader(new InputStreamReader(content));                 String s = "";                 while ((s = buffer.readLine()) != null) {                     response += s;                 }             }             catch (Exception e) {                 e.printStackTrace();             }             return response;         }          @Override         protected void onPostExecute(String result) {             if (!TextUtils.equals("",result)) {                 JSONObject jsonResult = null;                 try {                     jsonResult = new JSONObject(result);                 }                 catch (JSONException e) {                     e.printStackTrace();                     return;                 }                 //process notifications if exists                 JSONArray notifications = jsonResult.optJSONArray("notifications");                 if (notifications==null) {                     return;                 }                  if (context==null) {                     return;                 }                 //string with showed messages                 String showedMessages = PreferenceManager.getDefaultSharedPreferences(context).getString(MESSAGEURL,"");                 for (int i=0;i<notifications.length();i++) {                     JSONObject jsonNotification = notifications.optJSONObject(i);                      if (jsonNotification==null) break;                      final int version = jsonNotification.optInt("version",-1);                     if (version>0 && version!=versionCode) {                         continue;                     }                      final String localeTarget = jsonNotification.optString("locale","all");                     if (!TextUtils.equals("all",localeTarget) && !TextUtils.equals(localeTarget,locale)) {                         continue;                     }                      final int id = jsonNotification.optInt("id");                     if (showedMessages.contains(id+";")) {                         continue;                     }                     else {                         showedMessages+=id+";";                         PreferenceManager.getDefaultSharedPreferences(context).edit().putString(MESSAGEURL,showedMessages).commit();                          Intent intent = null;                         if (!TextUtils.equals("",jsonNotification.optString("action",""))) {                             // if has action add it                             intent = new Intent(Intent.ACTION_VIEW, Uri.parse(                                     jsonNotification.optString("action","")));                             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                          }                         else {                             // if no - just inform                             intent = new Intent(activity,activity.getClass());                         }                         PendingIntent pIntent = PendingIntent.getActivity(context, id, intent, 0);                          // if you don't use support library, change NotificationCompat on Notification                         Notification noti = new NotificationCompat.Builder(context)                                 .setContentTitle(jsonNotification.optString("title",""))                                 .setContentText(jsonNotification.optString("text",""))                                 .setSmallIcon(R.drawable.icon)//change this on your icon                                 .setContentIntent(pIntent).build();                         NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);                         // hide the notification after its selected                         noti.flags |= Notification.FLAG_AUTO_CANCEL;                          notificationManager.notify(id, noti);                         break;                     }                 }              }         }      } }  

Буду рад если кому то пригодится.

ссылка на оригинал статьи http://habrahabr.ru/company/freeamp/blog/232453/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *