【问题标题】:view.reapply of RemoteView of bigContentView notification crashingbigContentView 通知崩溃的 RemoteView 的 view.reapply
【发布时间】:2014-01-26 18:28:09
【问题描述】:

我正在尝试构建一个应用程序来向我的智能手表发布通知。我找到了一个很棒的通知示例应用程序,我已经针对我的测试进行了修改,它可以按预期工作。我发现我需要显示的扩展信息在 RemoteViews bigContentView 中。我找到了一个名为 Botification 的程序,它能够放大我正在寻找的视图。它在他的应用程序中按预期工作。我正在尝试将他的方法与我的方法结合起来,但没有运气。我还找到了 Notify Me! 的一些来源,它使用相同类型的方法来拉取通知远程视图。

这是我的第一个真正的 Android 应用程序,我是 Java 新手。我已经工作了大约一个月,并且从这个网站上的帖子和浏览网页中学到了很多东西。我浏览了 Lynda.com 的 Java Essentials 和 Android Essentials 课程。还发现这对我很有用,我是 Java 新手,对 C++ 仅有一点背景:http://chortle.ccsu.edu/java5/index.html

我使用的一些信息来源: Extract notification text from parcelable, contentView or contentIntenthttp://www.kpbird.com/2013/07/android-notificationlistenerservice.html

任何帮助将不胜感激。 Botification 应用程序使用处理程序和不同的方式来处理 onPosted 请求,这让我想知道这是否是我的问题。欢迎任何文档或教程来增肥我的大脑。

我将包含使用此远程视图功能的代码部分,希望足以说明我如何使其工作。

MainActivity.java 公共类 MainActivity 扩展 Activity {

private TextView txtView;
private NotificationReceiver nReceiver;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    txtView = (TextView) findViewById(R.id.textView);
    nReceiver = new NotificationReceiver();
    IntentFilter filter = new IntentFilter();
    filter.addAction("com.example.snotify.NOTIFICATION_LISTENER");
    registerReceiver(nReceiver,filter);
}

nlservice.java 公共类 NLService 扩展 NotificationListenerService {

private String TAG = "NLService";
private NLServiceReceiver nlreceiver;

@Override
public void onCreate() {
    super.onCreate();
    nlreceiver = new NLServiceReceiver();
    IntentFilter filter = new IntentFilter();
    filter.addAction("com.example.snotify.NOTIFICATION_LISTENER_SERVICE");
    registerReceiver(nlreceiver,filter);
}


@Override
public void onDestroy() {
    super.onDestroy();
    unregisterReceiver(nlreceiver);
}


@Override
public void onNotificationPosted(StatusBarNotification sbn) {
    Notification n = sbn.getNotification();
    Log.i(TAG,"!!!onNotificationPosted");
    Log.i(TAG,"ID :" + sbn.getId() + "Ticker:" + n.tickerText + "Pkg:" + sbn.getPackageName());
    String text = NotiCrunch.extractTextFromNotification(NLService.this, n);
    String description = "";
    if (n.tickerText != null) {
        description = n.tickerText.toString();
    }
    Intent i = new  Intent("com.example.snotify.NOTIFICATION_LISTENER");
    i.putExtra("notification_event","Notification Posted\nPackage:" + sbn.getPackageName() + "\nID:" + sbn.getId() 
            + "\nText:" + text
            + "\nTag:" + sbn.getTag() + "\nTicker:" + description + "\n\n");
    sendBroadcast(i);

}

noticrunch.java

公共类 NotiCrunch {

private static String TAG = "NotiCrunch";
private static final int TIMESTAMPID = 16908388;

private static void extractViewType(ArrayList<View> outViews, Class<TextView> viewtype, View source) {
    if (ViewGroup.class.isInstance(source)) {
        ViewGroup vg = (ViewGroup) source;
        for (int i = 0; i < vg.getChildCount(); i++) {
            extractViewType(outViews, viewtype, vg.getChildAt(i));

        }
    } else if(viewtype.isInstance(source)) {
        outViews.add(source);
    }
}

public static String extractTextFromNotification(Service service, Notification notification) {
    ArrayList<String> result = null;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        result = extractTextFromNotification(service, notification.bigContentView);
        Log.d(TAG, "It tried Big View");
        Log.d(TAG, "Ticker:" + notification.tickerText);
    }
    if (result == null) {
        result = extractTextFromNotification(service, notification.contentView);
        Log.d(TAG, "It tried little view");
    }
    if (result == null){
        Log.d(TAG, "It is returning null");
        return "";
    }
    return TextUtils.join("\n", result);

}

private static ArrayList<String> extractTextFromNotification(Service service, RemoteViews view) {
    LayoutInflater inflater = (LayoutInflater) service.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    ArrayList<String> result = new ArrayList<String>();
    if (view == null) {
        Log.d(TAG, "Initial view is Empty");
        return null;
    }
    try {
        ViewGroup localView = (ViewGroup) inflater.inflate(view.getLayoutId(), null);
        view.reapply(service.getApplicationContext(), localView);
        ArrayList<View> outViews = new ArrayList<View>();
        extractViewType(outViews, TextView.class, localView);
        for (View  ttv: outViews) {
            TextView tv = (TextView) ttv;
            String txt = tv.getText().toString();
            if (!TextUtils.isEmpty(txt) && tv.getId() != TIMESTAMPID) {
                result.add(txt);
            }
        }
    } catch (Exception e) {
        Log.d(TAG, "FAILED to load notification! " + e.toString());
        Log.wtf(TAG, e);
        return null;
    }
    Log.d(TAG, "Return result" + result);
    return result;
}

谢谢。

【问题讨论】:

  • 您找到解决方案了吗?

标签: android android-notifications layout-inflater android-remoteview


【解决方案1】:

代码在哪里崩溃?我在任何地方都没有看到重新申请的电话。

【讨论】:

  • view.reapply(service.getApplicationContext(), localView);在 try/catch 循环中的 noticrunch.java 中。感谢您的关注。
  • 我没有看到代码框被滚动。哇,这段代码看起来做了很多假设,并且相信了很多它发现的东西。您将不得不进行大量试验和错误才能在这里找到答案,但是为了防止重新应用调用崩溃,我建议您看一下 RemoteView 文档,重新应用看起来应该会被调用在应用调用(我没有看到)之后,重新应用说它可以抛出。我会先将 reapply 更改为 apply,如果您甚至需要它(是吗?)
  • 我在这个远程视图上看到的所有示例都重新应用。我不能说我明白为什么。我仍然在学习。我不确定为什么这段代码可以在其他地方工作,但我认为这是我调用所有内容的方式。我可能需要更多的灯泡来点亮我的脑袋。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-17
  • 1970-01-01
  • 1970-01-01
  • 2018-07-24
  • 1970-01-01
相关资源
最近更新 更多