5

मैंने this डेवलपर ट्यूटोरियल का पालन किया, और मेरे ऐप के भीतर जियोफेनिंग काम कर रहा है, जैसा कि अपेक्षित है।एंड्रॉइड, ऐप खुला होने पर अधिसूचना के बजाय चेतावनी डिस्प्ले करें

सूचना भेज दी जाती है जब एक Geofence संक्रमण होता है, एक IntentService के भीतर से:

@Override 
protected void onHandleIntent(Intent intent) { 
    GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent); 

    ...   

    sendNotification(geofenceTransitionDetails); 
} 

private void sendNotification(String notificationDetails) { 
    // Create an explicit content Intent that starts the main Activity. 
    Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class); 

    // Construct a task stack. 
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); 

    // Add the main Activity to the task stack as the parent. 
    stackBuilder.addParentStack(MainActivity.class); 

    // Push the content Intent onto the stack. 
    stackBuilder.addNextIntent(notificationIntent); 

    // Get a PendingIntent containing the entire back stack. 
    PendingIntent notificationPendingIntent = 
      stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); 

    // Get a notification builder that's compatible with platform versions >= 4 
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this); 

    // Define the notification settings. 
    builder.setSmallIcon(R.mipmap.ic_launcher) 
      // In a real app, you may want to use a library like Volley 
      // to decode the Bitmap. 
      .setLargeIcon(BitmapFactory.decodeResource(getResources(), 
        R.mipmap.ic_launcher)) 
      .setColor(Color.RED) 
      .setContentTitle(notificationDetails) 
      .setContentText("Return to app") 
      .setContentIntent(notificationPendingIntent); 

    // Dismiss notification once the user touches it. 
    builder.setAutoCancel(true); 

    // Get an instance of the Notification manager 
    NotificationManager mNotificationManager = 
      (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 

    // Issue the notification 
    mNotificationManager.notify(0, builder.build()); 
} 

इस ट्यूटोरियल से कुकी कटर है। इरादे सेट अप है मुख्य गतिविधि में:

private PendingIntent getGeofencePendingIntent() { 
    // Reuse the PendingIntent if we already have it. 
    if (mGeofencePendingIntent != null) { 
     return mGeofencePendingIntent; 
    } 
    Intent intent = new Intent(this, GeofenceTransitionsIntentService.class); 
    // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling 
    // addGeofences() and removeGeofences(). 
    return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
} 

मैं अगर एप्लिकेशन खुला है, और बजाय उपयोगकर्ता के लिए एक AlertDialog को प्रदर्शित करता है कि सूचनाओं को दबा कार्यक्षमता कैसे जोड़ सकते हैं? आदर्श रूप में, मैं भौगोलिक संक्रमण होने पर उपयोगकर्ता वर्तमान में किस दृश्य में है, इस पर निर्भर करता हूं कि मैं अलग-अलग कार्यों को निष्पादित करने में सक्षम होना चाहता हूं। क्या मैं प्रत्येक दृश्य, या किसी भी तरह से वैश्विक रूप से संक्रमण को मॉनिटर/रोक सकता हूं?

अग्रिम धन्यवाद।

उत्तर

5

कुछ जवाब अधूरे थे, और इसलिए मैं जो खोज रहा था उसका पूरा समाधान यहां है।

पहले, MyApplication वर्ग की स्थापना की, कि ActivityLifecycleCallbacks लागू करता है:

<application 
    android:name=".MyApplication" 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme" 
    android:hardwareAccelerated="true"> 

:

public class MyApplication extends Application implements Application.ActivityLifecycleCallbacks { 

    private static boolean isActive; 

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

     registerActivityLifecycleCallbacks(this); 
    } 

    public static boolean isActivityVisible(){ 
     return isActive; 
    } 

    @Override 
    public void onActivityResumed(Activity activity) { 
     isActive = true; 
    } 

    @Override 
    public void onActivityPaused(Activity activity) { 
     isActive = false; 
    } 

    ... no other methods need to be used, but there are more that 
    ... must be included for the ActivityLifecycleCallbacks 
} 

अपने मेनिफ़ेस्ट में इस नाम के लिए सुनिश्चित करें (केवल नाम लाइन जोड़ा गया है, बाकी डिफ़ॉल्ट है) ऊपर किए गए कार्यों का उपयोग आपके ऐप के जीवन चक्र को ट्रैक करने के लिए किया जाता है। आप यह जांचने के लिए इसका उपयोग कर सकते हैं कि आपका ऐप वर्तमान में अग्रभूमि में है या नहीं।

अगला BroadcastReceiver सेट अप करना है, जहां भी आप कोड चलाने के लिए चाहते हैं (यदि ट्रिगर होता है तो ऐप खुला होता है)।इस मामले में, यह है मेरी MainActivity:

protected BroadcastReceiver mNotificationReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     ... Do whatever you want here 

     Toast.makeText(...).show(); 
    } 
}; 

एक ही गतिविधि के अपने onCreate में रिसीवर रजिस्टर:

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    ... 

    LocalBroadcastManager.getInstance(this).registerReceiver(mNotificationReceiver, new IntentFilter("some_custom_id")); 
} 

और भूल नहीं है यह पंजीकरण रद्द करना:

@Override 
protected void onDestroy() { 
    LocalBroadcastManager.getInstance(this).unregisterReceiver(mNotificationReceiver); 
    super.onDestroy(); 
} 

जब कोई प्रसारण प्राप्त होता है, तो रिसीवर के भीतर कोड निष्पादित किया जाता है।

अब, यह जांचने के लिए कि ऐप अग्रभूमि में है या नहीं, और यदि प्रसारण हो तो उसे भेजें। IntentService के अंदर:

@Override 
protected void onHandleIntent(Intent intent) { 
    GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent); 
    if (geofencingEvent.hasError()) { 
     String errorMessage = getErrorString(this, 
       geofencingEvent.getErrorCode()); 
     return; 
    } 

    int geofenceTransition = geofencingEvent.getGeofenceTransition(); 

    // Test that the reported transition was of interest. 
    if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || 
      geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { 

     ... 

     if(MyApplication.isActivityVisible()){ 
      Intent intnt = new Intent("some_custom_id"); 
      intnt.putExtra("message", geofenceTransitionDetails); 
      LocalBroadcastManager.getInstance(this).sendBroadcast(intnt); 
     }else{ 
      sendNotification(geofenceTransitionDetails); 
     } 

    } else { 
     // Log the error. 
    } 
} 

महत्वपूर्ण बिट पिछले नेस्टेड अगर-कथन है:

if(MyApplication.isActivityVisible()){ 
    Intent intnt = new Intent("some_custom_id"); 
    intnt.putExtra("message", geofenceTransitionDetails); 
    LocalBroadcastManager.getInstance(this).sendBroadcast(intnt); 
}else{ 
    sendNotification(geofenceTransitionDetails); 
} 

जांच करें कि अनुप्रयोग, ऊपर परिभाषित अग्रभूमि MyApplication.isActivityVisible() का उपयोग करने में है, और फिर नहीं भेजती है अधिसूचना, या एक प्रसारण भेजें। बस सुनिश्चित करें कि आपका इरादा कोड (यानी "some_custom_id") आपके प्रेषक और रिसीवर पर मेल खाता है।

और यह इसके बारे में है। यदि ऐप अग्रभूमि (विशेष रूप से मुख्य गतिविधि) में है, तो मैं कुछ कोड निष्पादित करता हूं। यदि ऐप अग्रभूमि में नहीं है, तो मैं एक अधिसूचना भेजता हूं।

+1

मैंने अभी धन्यवाद देने के लिए लॉग इन किया है। –

0

ए) आप गतिविधि की जीवन चक्र घटनाओं की अपनी सेवा को सूचित कर सकते हैं।

बी) आप गतिविधि में स्थिर क्षेत्र में अपने यूआई की वर्तमान स्थिति को रख सकते हैं और अधिसूचना दिखाने से पहले सेवा से इसकी जांच कर सकते हैं।

+0

मुझे यकीन नहीं है कि मुझे यह अधिकार मिल रहा है, लेकिन वे ध्वनि जैसे ही वे अधिसूचनाओं को दबाएंगे। जियोफ़ेंस संक्रमण होने पर मैं सतर्क डायलॉग को प्रदर्शित करने के लिए उन लोगों का उपयोग कैसे कर सकता हूं? या दृश्य को अद्यतन करने के लिए? कृपया अपने उत्तर के साथ कुछ कोड प्रदान करें। – Birrel

1

सबसे आसान तरीका LocalBroadcastManager या कुछ event bus का उपयोग करना सबसे आसान तरीका होगा।

तो जब संक्रमण होता है आप IntentService से स्थानीय प्रसारण भेजें और IntentService और अपने Activity के में से किसी के बीच में कुछ component X साथ इसे पकड़ चाहिए। Component X ट्रैक चाहिए अगर आपके Activity के के किसी भी अग्रभूमि में चल रही और

  • यदि हाँ - अन्य स्थानीय प्रसारण, (अग्रभूमि Activity के) पास
  • नहीं करता है, तो - शो अधिसूचना।

कृपया ध्यान दें कि एंड्रॉयड में आप आसानी से ट्रैक नहीं कर सकते कि आपके ऐप या नहीं अग्रभूमि में (और यदि आप 1 से अधिक गतिविधि है, तो आप इसे ठीक तरह से मेरी राय में ऐसा नहीं कर सकते) लेकिन you can try

+0

अभी, मैं 'लोकलबॉडकास्ट प्रबंधक' के साथ सबसे अच्छा सोच सकता हूं, मेरी प्रत्येक गतिविधि में एक रिसीवर शामिल करना है। क्या एक ही रिसीवर के साथ सभी गतिविधियों को कंबल करने का कोई तरीका है? साथ ही, ऐप खुला होने पर 'IntentService' के भीतर से अधिसूचनाओं को कैसे दबाया/रोकूं? – Birrel

+0

जो मैंने पाया है वह सबसे अच्छा काम करता है जो आपके उत्तर के बीच एक संयोजन है, जो मुझे अलर्ट दिखाने और कार्यों को करने देता है, और [यह] (http://stackoverflow.com/questions/3667022/checking-if-an-android- एप्लिकेशन -इस-रन-इन-द-बैकग्राउंड/138099 9 1 # 138099 9 1) उत्तर, जो मुझे यह निर्धारित करने की अनुमति देता है कि ऐप चल रहा है या नहीं। – Birrel

संबंधित मुद्दे