آموزش معرفی برنامه ها در Push Notification
سلام! اگه شما هم مثل من تعداد زیادی برنامه داشته باشید و آموزش Push Notification رو مطالعه کرده باشید این فکر به ذهنتون میخوره :دی
بریم سر اصل مطلب :|
کد های اینجا طبق آموزش Push Notification استاد هستن و من فقط چند تا تغییر توی کد سرور و دریافتشون دادم :)
G.java
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Application;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.RemoteViews;
public class G extends Application {
public static Context context;
public static C2D service;
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
startPushNotification();
}
private void startPushNotification() {
service = new C2D()
.key("instatag")
.url("http://c2d.yekteam.com/service.php")
.interval(1000)
// .network(C2D.NETWORK_ALWAYS)
.listener(new C2D.Listener() {
@Override
public void onDataReceive(String data) {
try {
JSONObject object = new JSONObject(data);
String title = object.getString("title");
String title_first = object.getString("title_first");
String matn = object.getString("matn");
String link = object.getString("link");
boolean status = object.getBoolean("status");
if (status == true){
Notification(title,matn,link,title_first);
}
else {}
} catch (JSONException e) {
e.printStackTrace();
}
}
}).start();
}
public void Notification(String title, String matn, String link, String title_first) {
Uri uri = Uri.parse("market://details?id=" + link);
Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, goToMarket,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSound(alarmSound)
.setSmallIcon(R.drawable.attention)
.setTicker(title_first)
.setContentTitle(title)
.setContentText(matn)
.setContentIntent(pIntent)
.setAutoCancel(true);
NotificationManager notificationmanager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationmanager.notify(0, builder.build());
}
}
C2D.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class C2D {
public static final int PROTOCOL_EXCEPTION = -1;
public static final int IO_EXCEPTION = -2;
public static final int UNKNOWN_EXCEPTION = -3;
public static final int NETWORK_ALWAYS = 1;
public static final int NETWORK_JUST_WIFI = 2;
public static interface Listener {
public void onDataReceive(String data);
}
private Listener listener;
private String key;
private long interval;
private int network;
private String url;
private ArrayList<NameValuePair> inputArguments = new ArrayList<NameValuePair>();
private boolean enable = true;
public C2D listener(Listener value) {
listener = value;
return this;
}
public C2D interval(long value) {
interval = value;
return this;
}
public C2D network(int value) {
network = value;
return this;
}
public C2D url(String value) {
url = value;
return this;
}
public C2D key(String value) {
key = value;
return this;
}
public void disable() {
enable = false;
}
public void enable() {
if (enable) {
return;
}
enable = true;
start();
}
public C2D start() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (enable) {
try {
check();
Thread.sleep(interval);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread.start();
return this;
}
public void check() {
int status = readNetworkStatus();
if (status == DISCONNECTED) {
return;
}
if (network == NETWORK_JUST_WIFI && status == MOBILE) {
return;
}
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 1000);
HttpConnectionParams.setSoTimeout(params, 1000);
HttpClient client = new DefaultHttpClient(params);
HttpPost request = new HttpPost(url);
inputArguments.clear();
inputArguments.add(new BasicNameValuePair("key", key));
request.setEntity(new UrlEncodedFormEntity(inputArguments));
HttpResponse httpResponse = (HttpResponse) client.execute(request);
String data = streamToString(httpResponse.getEntity().getContent());
if (listener != null) {
listener.onDataReceive(data);
return;
}
}
catch (ClientProtocolException e) {}
catch (IOException e) {}
catch (Exception e) {}
}
});
thread.start();
}
private String streamToString(InputStream inputStream) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuffer = new StringBuilder();
String line = null;
try {
while ((line = bufferedReader.readLine()) != null) {
stringBuffer.append((line + "\n"));
}
}
catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
return stringBuffer.toString();
}
private static final int DISCONNECTED = 0;
private static final int WIFI = 1;
private static final int MOBILE = 2;
private int readNetworkStatus() {
ConnectivityManager connectivityManager = (ConnectivityManager) G.context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
boolean isConnected = networkInfo.isConnected();
if (isConnected) {
int networkType = networkInfo.getType();
if (networkType == ConnectivityManager.TYPE_WIFI) {
return WIFI;
} else if (networkType == ConnectivityManager.TYPE_MOBILE) {
return MOBILE;
}
}
return DISCONNECTED;
}
}
service.php
<?php
$key = $_REQUEST['key'];
if ($key = 'instatag') {
$array = array();
$array["status"] = false;
$array["title_first"] = "برنامه بستنی";
$array["title"] = "بستنی";
$array["matn"] = "کاملترین برنامه بستنی در کافه بازار! برای دریافت کلیک کنید";
$array["link"] = "com.yekteam.bastani";
echo json_encode($array);
}
?>
همه چیش واضحه! با استفاده از JSON یک سری فیلد از سرور میخونیم که ازشون برای ساخت ناتیفیکیشن استفاده میکنیم :) میدونم کدم خیلی استاندارد نیست و اینکه ۷۰ درصد بچه های اینجا اینکار رو بلدن اما گفتم هم مطلبی به اشتراک گذاشته باشم هم اون ۳۰٪ هم یاد بگیرن :دی














در ادامه آموزش :دی
حالا میخوایم به جای روش استاد ( که ارتباط با سرور از طریق برنامه برقرار میشه ) از روشی استفاده کنیم که Push Notification ها حتی وقتی برنامه باز نیست هم اجرا بشن :) برای اینکار باید از BroadcastReceiver استفاده کنیم!
توی AndroidManifest این کد رو قرار بدید :
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" /> // برای آلارم منیجر
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
حالا یه کلاس به اسم MyReceiver بسازید و این کد ها رو توش کپی کنید :
import java.util.Calendar;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Calendar cal = Calendar.getInstance();
Intent srvIntent = new Intent(context, PushNo.class);
PendingIntent pIntent = PendingIntent.getService(context, 0, srvIntent, 0);
AlarmManager alarm = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
21600000, pIntent);
}
}
در اینجا ما از AlarmManager استفاده کردیم، اونم واسه اینکه بعد از روشن شدن دستگاه! هر چند وقت یکبار یک سرویس اجرا شه، به سرور متصل شیم، ببینیم خبر جدیدی هست یا نه، اگر هست ناتیفیکیشن بده! برای قسمت "بعد از روشن شدن دستگاه" در Receiver استفاده کردیم، حالا باید برای قسمت "هر چند وقت یکبار یک سرویس اجرا شه" از AlarmManagerـی که توی MyReceiver هست استفاده کنیم! با اینکار کلاس PushNo اجرا میشه!PushNo یک سرویسه! برای تعریف کردنش توی AndroidManifest این رو قرار بدید :
<service
android:name=".PushNo"
android:process=":remote" />
حالا یه کلاس به اسم PushNo بسازید که محتویاتش اینه :
import org.json.JSONException;
import org.json.JSONObject;
import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.RingtoneManager;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
public class PushNo extends IntentService{
public static Context context;
public static C2D service;
public static SharedPreferences preferences;
private static final String TAG = "MyService";
public PushNo() {
super("MyWebRequestService");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.i("LOG", "Started :))");
context = getApplicationContext();
preferences = PreferenceManager.getDefaultSharedPreferences(context);
startPushNotification();
Log.d(TAG, "onStart");
}
private void startPushNotification() {
service = new C2D()
.key("flashlight")
.url("http://c2d.yekteam.com/service.php")
.interval(21600000)
// .network(C2D.NETWORK_ALWAYS)
.listener(new C2D.Listener() {
@Override
public void onDataReceive(String data) {
try {
SharedPreferences settings = getSharedPreferences("id", MODE_PRIVATE);
SharedPreferences.Editor prefEditor = settings.edit();
JSONObject object = new JSONObject(data);
String title = object.getString("title");
String title_first = object.getString("title_first");
String matn = object.getString("matn");
String link = object.getString("link");
Integer id = object.getInt("id");
int id2 = settings.getInt("id", 0);
Log.i("LOG", "ID2 is " + id2);
if (id2 != id){
prefEditor.putInt("id", id);
prefEditor.commit();
boolean status = object.getBoolean("status");
if (status == true){
Notification(title,matn,link,title_first);
}
else {}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}).start();
}
public void Notification(String title, String matn, String link, String title_first) {
Uri uri = Uri.parse("market://details?id=" + link);
Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, goToMarket,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSound(alarmSound)
.setSmallIcon(R.drawable.attention)
.setTicker(title_first)
.setContentTitle(title)
.setContentText(matn)
.setContentIntent(pIntent)
.setAutoCancel(true);
NotificationManager notificationmanager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationmanager.notify(0, builder.build());
}
}
با اینکار شما دیگه به تغییر فایل G.java که در پست اول هست نیاز ندارید! و با دادن فاصله زمانی در Receiver هر وقت خبر جدیدی بود به صورت Push Notification نشون میده :)
فایل سرویس در نهایت به این شکل شد :)
<?php
$key = $_REQUEST['key'];
if ($key == 'instatag') {
$array = array();
$array["id"] = 2;
$array["status"] = true;
$array["title_first"] = "برنامه بستنی";
$array["title"] = "بستنی";
$array["matn"] = "کاملترین برنامه بستنی در کافه بازار! برای دریافت کلیک کنید";
$array["link"] = "com.yekteam.bastani";
echo json_encode($array);
}
اگه امتحان کردید دیدید فقط یکبار PushNotification نشون داده میشه واسه اینه که بعد از هر نمایش باید id در قسمت service.php رو عوض کنید :)

آقا این خطای اتصال به اینترنت رو میده بدجور رفته روی اعصاب من
دسترسی به اینترنت هم تعریف شده است
09-08 13:19:05.224: W/System.err(30635): java.net.UnknownHostException: Unable to resolve host "192.168.1.10": No address associated with hostname
09-08 13:19:05.224: W/System.err(30635): at java.net.InetAddress.lookupHostByName(InetAddress.java:400)
09-08 13:19:05.224: W/System.err(30635): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
09-08 13:19:05.235: W/System.err(30635): at java.net.InetAddress.getAllByName(InetAddress.java:220)
09-08 13:19:05.244: W/System.err(30635): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
09-08 13:19:05.244: W/System.err(30635): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
09-08 13:19:05.244: W/System.err(30635): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
09-08 13:19:05.244: W/System.err(30635): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
09-08 13:19:05.254: W/System.err(30635): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
09-08 13:19:05.254: W/System.err(30635): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
09-08 13:19:05.254: W/System.err(30635): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
09-08 13:19:05.265: W/System.err(30635): at com.negahetazehco.push_notification.C2D$2.run(C2D.java:142)
09-08 13:19:05.265: W/System.err(30635): at java.lang.Thread.run(Thread.java:856)

سلام
طبق آموزش استاد، کاملا پیاده کردم، و همه چی حله ولی یه مشکلی برخوردم، در متد startPushNotification
public static void startPushNotification() {
service = new C2D()
.key("ertebatBaMa")
.url("http://192.168.1.140/note-server-s/servicePN.php")
.interval(1000)
.network(C2D.NETWORK_ALWAYS)
.listener(new C2D.Listener() {
@Override
public void onDataReceive(String data) {
Log.i("LOG", "Data: " + data);
Toast.makeText(context.getApplicationContext(),
"Data : " + data, Toast.LENGTH_SHORT).show();
}
}).start();
service.enable();
}
در onDataReceive یه Toast گذاشتم تا پیام بدهد، بعد از اجرا اصلا پیام Taost نمایش نمیده، فقط در LogCat نمایش میده!!!
چرا؟

دوستان یک مشکل هست و اونم اینه که چرا حتمآ باید ریست بشه گوشی تا نوتیفیکیشن دریافت بشه ؟؟؟ راه حلی هست که برنامه به محض نصب شدن وقتی سرور و آپدیت کردیم نوتیفیکیشن بیاد ؟

سلام به همه
چطوری میشه بجای نمایش پکیج یک برنامه بصورت زیر
"market://details?id="+ link
با استفاده از شناسه توسعه دهنده تمام برنامه هارو نمایش داد ؟ به این صورت
https://cafebazaar.ir/developer/yekteam/

درجهت تکمیل این بخش و تجربه ای که من در نوشتن این بخش داشتم باید عرض کنم که پس از قطع wifi این ارتباط قطع میشه و باید این خط رو هم توی منیفست اضافه کنید تا زمانی که کاربر قطع میکنه وای فایش رو هم کار کنه و اتصال با سرور برقرار بمونه
این خطوط رو در منیفیست اضافه کنید .
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.net.wifi.STATE_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .