2015-05-19 10 views
8

मैं भौगोलिक स्थान और स्थानीय अधिसूचनाओं से संबंधित एंड्रॉइड के लिए अपना पहला सिस्टम एप्लिकेशन बनाने की कोशिश कर रहा हूं। मुझे इसकी कल्पना है ... मूल गतिविधि MainActivity है। शुरू करने के बाद यह एक सेवा TestService लॉन्च करता है जो समन्वयक परिवर्तन के मामले में उन्हें सर्वर पर भेजता है, और उत्तर में कुछ संदेश प्राप्त होता है जो स्थानीय अधिसूचना के रूप में प्रदर्शित होगा। और मुझे कुछ समस्याएं हैं।भौगोलिक स्थान, सेवा और स्थानीय सूचनाएं

  1. यदि मैं एप्लिकेशन को बंद करता हूं (टास्क मैनेजर का उपयोग करके) तो सेवा बंद हो जाएगी, इसलिए निर्देशांक बदलने के बाद कुछ भी नहीं होता है। मुझे उस सेवा को हर समय काम करने की क्या ज़रूरत है? या यह असंभव है?

  2. स्थानीय अधिसूचना के सक्रियण के बाद यह NotifyActivity लॉन्च करता है जो विस्तृत जानकारी दिखाता है। वहां मैं buttonDelete पर क्लिक करता हूं - यह NotifyActivity बंद कर देगा और MainActivity प्रारंभ करेगा। लेकिन अगर उसके बाद मैं ओएस स्क्रीन पर स्विच करता हूं (Back बटन का उपयोग करके) और वापस (टास्क मैनेजर का उपयोग करके) 'MainActivity' के बजाय फिर से 'NotifyActivity' प्रदर्शित किया जाएगा। ऐसा क्यों होता है और इससे कैसे बचें?

MainActivity

[Activity(Label = "LocationTest", MainLauncher = true, Icon = "@drawable/icon")] 
public class MainActivity : Activity 
{ 
    protected override void OnCreate(Bundle bundle) 
    { 
     base.OnCreate(bundle); 
     SetContentView(Resource.Layout.Main); 

     var button = FindViewById<Button>(Resource.Id.myButton); 
     button.Click += delegate { 
      StartService(new Intent(this, typeof(TestService))); 
      button.Text = "Started"; 
     }; 
    } 
} 

जियोलोकेशन सेवा

[Service] 
public class TestService : Service, ILocationListener 
{ 
    // Start service 
    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId) 
    { 
     locManager = (LocationManager)GetSystemService(LocationService); 
     locationCriteria = new Criteria(); 

     locationCriteria.Accuracy = Accuracy.Coarse; 
     locationCriteria.PowerRequirement = Power.Low; 

     string locationProvider = locManager.GetBestProvider(locationCriteria, true); 

     // Preferences.MinTime, for example, 60 (seconds) 
     // Preferences.MinDist, for example, 100 (meters) 
     locManager.RequestLocationUpdates(locationProvider, Preferences.MinTime * 1000, Preferences.MinDist, this); 

     return StartCommandResult.Sticky; 
    } 

    public void OnLocationChanged(Location loc) 
    { 
     // Send coordinates to the server, receive a response, and show local notification 
     var msg = new ReceivedMessage(counter++, "Test Title", loc.ToString()); 
     ShowNotification(msg); 
    } 

    // show local notification 
    void ShowNotification(ReceivedMessage msg) 
    { 
     var myContainer = new Bundle(); 
     myContainer.PutLong("msg_id", Convert.ToInt64(msg.Id)); 
     myContainer.PutStringArray("msg_data", new [] { msg.Title, msg.Text }); 
     var resultIntent = new Intent(this, typeof(NotifyActivity)); 
     resultIntent.PutExtras(myContainer); 

     TaskStackBuilder stackBuilder = TaskStackBuilder.Create(this); 
     stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(NotifyActivity))); 
     stackBuilder.AddNextIntent(resultIntent); 

     PendingIntent resultPendingIntent = stackBuilder.GetPendingIntent(Convert.ToInt32(msg.Id), PendingIntentFlags.UpdateCurrent); 

     Notification.Builder builder = new Notification.Builder(this) 
      .SetDefaults(NotificationDefaults.Sound | NotificationDefaults.Vibrate) 
      .SetAutoCancel(true) 
      .SetContentIntent(resultPendingIntent) 
      .SetContentTitle(msg.Title) 
      .SetContentText(msg.Text) 
      .SetSmallIcon(Resource.Drawable.Icon); 

     var nm = (NotificationManager)GetSystemService(NotificationService); 
     nm.Notify(Convert.ToInt32(msg.Id), builder.Build()); 
    } 

} 

स्थानीय सूचनाएं

[Activity(Label = "NotifyActivity")]    
public class NotifyActivity : Activity 
{ 
    protected override void OnCreate(Bundle savedInstanceState) 
    { 
     base.OnCreate(savedInstanceState); 

     SetContentView(Resource.Layout.NotifyActivity); 

     var msg_id = Intent.Extras.GetLong("msg_id"); 
     var msg_data = Intent.Extras.GetStringArray("msg_data"); 

     FindViewById<TextView>(Resource.Id.textTitle).Text = msg_data[0]; 
     FindViewById<TextView>(Resource.Id.textDescription).Text = msg_data[1]; 

     FindViewById<Button>(Resource.Id.buttonDelete).Click += delegate { 
      StartActivity(typeof(MainActivity)); 
      Finish(); 
     }; 
    } 
} 

उदाहरण परियोजना here

उत्तर

1

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

public override bool OnKeyDown (Keycode keyCode, KeyEvent e) 
{ 
    if (keyCode == Keycode.Back) { 
     MoveTaskToBack(true); 
     return true; 
    } 
    return base.OnKeyDown (keyCode, e); 
} 

एंड्रॉइड में मधुमक्खी की गतिविधियों में बहुत सारी समस्याएं हैं। इसलिए मेरा सुझाव है कि सेवा से मेनएक्टिविटी लॉन्च करें और फिर अधिसूचनात्मकता लॉन्च करें। फिर आप मेनएक्टिविटी को फिर से लॉन्च कर सकते हैं (इस मामले में आपको मुख्य एक्टिविटी के लिए लॉन्चमोड = लॉन्चमोड। सिंगलटॉप सेट करना होगा)।

पहली समस्या के लिए - क्या आपने [Service] के बजाय [Service (Process = ":remote")] को परिभाषित करने का प्रयास किया है?

1

मुझे xamarin के साथ अनुभव नहीं है, लेकिन मैं आम तौर पर एंड्रॉइड से संबंधित प्रश्नों का उत्तर देने का प्रयास कर सकता हूं।

प्रश्न 1

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

तो अपने प्रश्न का उत्तर देने के लिए, मुझे नहीं लगता कि आप इस स्थिति को पाने के लिए कुछ भी कर सकते हैं जहां उपयोगकर्ता बलपूर्वक आपके ऐप की प्रक्रिया को मार देता है। हालांकि, मुझे नहीं लगता कि आपको इस एज केस के बारे में चिंता करने की ज़रूरत है क्योंकि सामान्य परिस्थितियों में, आपके ऐप की प्रक्रिया तब तक नहीं मारेगी जब तक कि सिस्टम को लगता है कि यह ठीक है या बिल्कुल इसकी आवश्यकता नहीं है। इसलिए अगर ऐप सामान्य तरीके से बंद हो जाता है तो सेवा जारी रहनी चाहिए। डॉक्स कहते हैं:

प्रणाली सेवा के रूप में लंबे समय के रूप में या तो यह शुरू कर दिया है या वहाँ Context.BIND_AUTO_CREATE ध्वज के साथ यह करने के लिए एक या अधिक कनेक्शन हैं चलते रहेंगे। एक बार इन स्थितियों में से कोई भी नहीं, सेवा की ऑनस्ट्रोय() विधि को कॉल किया जाता है और सेवा प्रभावी रूप से समाप्त हो जाती है।

तो आपकी सेवा ठीक रहेगी।आम तौर पर, आपके ऐप से उन मामलों को संभालने की उम्मीद नहीं की जाती है जहां इसकी प्रक्रिया को मजबूती से मार दिया जाता है।

More information about Processes

More information about the Service lifecycle

प्रश्न 2

मैं बिल्कुल यकीन है कि यहाँ क्या हो रहा है नहीं कर रहा हूँ। हालांकि, आपके लिंक किए गए प्रोजेक्ट को देखते हुए, मुझे लगता है कि आपकी AndroidManifest.xml फ़ाइल मुश्किल से भर चुकी है। मेरा संदेह यह है कि इस फ़ाइल के बिना, एंड्रॉइड सिस्टम नहीं जानता कि आपके बैकस्टैक को कैसे प्रारंभ किया जाए, और यह नहीं पता कि आपकी कौन सी गतिविधियां मुख्य और लॉन्चर गतिविधि है।

आप AndroidManifest.xml में अपनी गतिविधियों को घोषित करना चाहिए, और उस में आप निर्दिष्ट करना चाहिए कि MainActivity अपने मुख्य और लॉन्चर गतिविधि है, और यह NotifyActivity की एक माता पिता है। इस तरह से सिस्टम को MainActivity खोलने के बारे में पता चल जाएगा जब ऐप शुरू होता है, और जब आप NotifyActivity से "वापस" दबाते हैं तो उसे वापस लौटना होगा। कुछ इस तरह:

<application android:label="LocationTest" android:icon="@drawable/icon"> 
    <activity android:name="MainActivity"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

    <activity android:name="NotifyActivity" 
     android:parentActivityName="MainActivity"/> 
</application> 

More information about how to use your Android Manifest

उम्मीद है कि आप अपनी समस्याओं को हल करने में मदद करता है!

+1

मुझे लगता है कि आप दोनों खातों पर कुछ गलत हैं। सबसे पहले, मुझे नहीं लगता कि ओपी प्रक्रिया को बंद करने के बल के बारे में बात कर रहा है, मुझे लगता है कि वे हालिया ऐप सूची से ऐप को स्वाइप करने का जिक्र कर रहे हैं, जो केवल उस कार्य स्टैक को बंद और हटा देना चाहिए, पूरी प्रक्रिया को रोकना नहीं चाहिए। दूसरा, xamarin में गतिविधियां गतिविधि कक्षाओं पर विशेषताओं का उपयोग करके घोषित की जाती हैं। वे बाद में (संकलन समय पर) स्वचालित रूप से प्रकट होते हैं। – irreal

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