2012-02-15 10 views
5

से टेक्स्ट पुनर्प्राप्त करें मुझे RemoteViews ऑब्जेक्ट से कुछ टेक्स्ट पुनर्प्राप्त करने की आवश्यकता है। मेरे लिए लेआउटआईडी प्राप्त करना संभव है, लेकिन मुझे नहीं पता कि TextView से टेक्स्ट पुनर्प्राप्त कैसे करें, जो इस RemoteView (अर्थात् अधिसूचना) में है।रिमोट व्यू ऑब्जेक्ट

इसके अलावा RemoteView में केवल सेटर्स हैं, लेकिन कोई गेटर्स नहीं है, इसलिए मुझे लगता है कि मुझे लेआउटआईडी (किसी भी तरह) का उपयोग करना है।

क्या आप इसके साथ मेरी मदद कर सकते हैं? धन्यवाद!

/संपादित करें: कारण मैं यह पूछ रहा हूं, क्योंकि मेरे पास AccessibilityService है जो अधिसूचना पुनर्प्राप्त करता है। इसलिए यह मूल्य पुनर्प्राप्त करने का एकमात्र तरीका है।

/EDIT2: मैं सूचना को प्राप्त करने के लिए इस कोड का उपयोग:

@Override 
public void onAccessibilityEvent(AccessibilityEvent event) { 
    if (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) { 
     List<CharSequence> notificationList = event.getText(); 
     for (int i = 0; i < notificationList.size(); i++) { 
      Toast.makeText(this.getApplicationContext(), notificationList.get(i), 1).show(); 
     } 
     if (!(parcel instanceof Notification)) { 
      return; 
     } 
     final Notification notification = (Notification) parcel; 
     doMoreStuff(); 

    } 
} 

notification वस्तु के साथ मैं एक RemoteViews (notification.contentView) के लिए उपयोग किया है और एक PendingIntent (notification.contentIntent) करने के लिए। layoutId पाने के लिए, मैं कॉल कर सकते हैं contentView.getLayoutId()

+0

यह शायद बेहतर होगा जानकारी कहीं बचाने के लिए ('SharedPreferences', आदि), और उसके बाद दोनों' RemoteViews' और अपने अन्य कोड का उपयोग वहाँ से जानकारी नहीं है। –

+0

ठीक है, मैं अधिसूचना को पुनः प्राप्त करने के लिए 'एक्सेसिबिलिटी सेवा' का उपयोग कर रहा हूं, इसलिए मैं कहीं भी मूल्य को संग्रहीत नहीं कर सकता, क्योंकि मेरे एप्लिकेशन ने अधिसूचना नहीं बनाई है ;-) – Force

+0

आप लेआउट आईडी कैसे प्राप्त करते हैं? क्या आप कोड पोस्ट कर सकते हैं जो अधिसूचना प्राप्त करता है? –

उत्तर

4

Extract notification text from parcelable, contentView or contentIntent से लिया:

Notification notification = (Notification) event.getParcelableData(); 
RemoteViews views = notification.contentView; 
Class secretClass = views.getClass(); 

try { 
    Map<Integer, String> text = new HashMap<Integer, String>(); 

    Field outerFields[] = secretClass.getDeclaredFields(); 
    for (int i = 0; i < outerFields.length; i++) { 
     if (!outerFields[i].getName().equals("mActions")) continue; 

     outerFields[i].setAccessible(true); 

     ArrayList<Object> actions = (ArrayList<Object>) outerFields[i] 
     .get(views); 
     for (Object action : actions) { 
      Field innerFields[] = action.getClass().getDeclaredFields(); 

      Object value = null; 
      Integer type = null; 
      Integer viewId = null; 
      for (Field field : innerFields) { 
       field.setAccessible(true); 
       if (field.getName().equals("value")) { 
        value = field.get(action); 
       } else if (field.getName().equals("type")) { 
        type = field.getInt(action); 
       } else if (field.getName().equals("viewId")) { 
        viewId = field.getInt(action); 
       } 
      } 

      if (type == 9 || type == 10) { 
       text.put(viewId, value.toString()); 
      } 
     } 

     System.out.println("title is: " + text.get(16908310)); 
     System.out.println("info is: " + text.get(16909082)); 
     System.out.println("text is: " + text.get(16908358)); 
    } 
} catch (Exception e) { 
    e.printStackTrace(); 
} 
+0

अधिसूचना.content देखें इसे बहिष्कृत करें AccessibilityEvent ऑब्जेक्ट से डेटा निकालने के लिए कोई वैकल्पिक समाधान है कृपया मेरी मदद करें। –

0

this question में CommonsWare का कहना है:

... अनुप्रयोग विजेट उपलब्ध नहीं लिखने केवल: आप उन्हें करने के लिए डेटा धक्का कर सकते हैं, लेकिन आप उन्हें नहीं पढ़ सकते हैं । इसके बजाय, जब आप नए टेक्स्ट के साथ अपना ऐप विजेट अपडेट करते हैं, तो आपको उस पाठ को कहीं भी फ़ाइल में स्टोर करने की आवश्यकता होगी।

उनका उत्तर तार्किक प्रतीत होता है।

7

मैं एक ऐसी ही समाधान here कि भी समस्या को हल करने प्रतिबिंब का उपयोग करता है का प्रस्ताव रखा, लेकिन एक और अधिक सुलभ फैशन में। यह मेरा समाधान है। इस संदर्भ में, रिमोट व्यू अधिसूचना से आया था, इसलिए यदि आपके पास पहले से ही रिमोट व्यू ऑब्जेक्ट तक पहुंच है तो पहले तीन पंक्तियों को अनदेखा किया जा सकता है। पृष्ठ पर लिंक वास्तव में क्या चल रहा है इसका एक और अधिक विस्तृत स्पष्टीकरण प्रदान करता है। मुझे उम्मीद है कि यह किसी भी समस्या के साथ किसी की भी मदद करेगा।

public static List<String> getText(Notification notification) 
{ 
    // We have to extract the information from the view 
    RemoteViews  views = notification.bigContentView; 
    if (views == null) views = notification.contentView; 
    if (views == null) return null; 

    // Use reflection to examine the m_actions member of the given RemoteViews object. 
    // It's not pretty, but it works. 
    List<String> text = new ArrayList<String>(); 
    try 
    { 
     Field field = views.getClass().getDeclaredField("mActions"); 
     field.setAccessible(true); 

     @SuppressWarnings("unchecked") 
     ArrayList<Parcelable> actions = (ArrayList<Parcelable>) field.get(views); 

     // Find the setText() and setTime() reflection actions 
     for (Parcelable p : actions) 
     { 
      Parcel parcel = Parcel.obtain(); 
      p.writeToParcel(parcel, 0); 
      parcel.setDataPosition(0); 

      // The tag tells which type of action it is (2 is ReflectionAction, from the source) 
      int tag = parcel.readInt(); 
      if (tag != 2) continue; 

      // View ID 
      parcel.readInt(); 

      String methodName = parcel.readString(); 
      if (methodName == null) continue; 

      // Save strings 
      else if (methodName.equals("setText")) 
      { 
       // Parameter type (10 = Character Sequence) 
       parcel.readInt(); 

       // Store the actual string 
       String t = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel).toString().trim(); 
       text.add(t); 
      } 

      // Save times. Comment this section out if the notification time isn't important 
      else if (methodName.equals("setTime")) 
      { 
       // Parameter type (5 = Long) 
       parcel.readInt(); 

       String t = new SimpleDateFormat("h:mm a").format(new Date(parcel.readLong())); 
       text.add(t); 
      } 

      parcel.recycle(); 
     } 
    } 

    // It's not usually good style to do this, but then again, neither is the use of reflection... 
    catch (Exception e) 
    { 
     Log.e("NotificationClassifier", e.toString()); 
    } 

    return text; 
} 
0

आप एंड्रॉयड 19+ पर लक्षित कर रहे हैं, तो आप किसी भी निजी एपीआई का उपयोग किए बिना एक अधिसूचना वस्तु से शीर्षक/पाठ प्राप्त करने के लिए निम्नलिखित कोड का उपयोग कर सकते हैं।

Notification noty = ...; 
Bundle extras = noty.extras; 
if (extras != null) { 
    String title = extras.getString(Notification.EXTRA_TITLE); 
    String text = extras.getString(Notification.EXTRA_TEXT); 
} 
संबंधित मुद्दे