Виджеты и setOnClickPendingIntent

Полный новичок в разработке Android здесь, будьте осторожны.

Я пытаюсь разработать виджет для домашнего экрана, который позволяет вам нажимать на виджет, чтобы позвонить по заранее определенному номеру. Я могу создать виджет и просто добавить его на рабочий стол, однако, когда я пытаюсь сделать виджет доступным для клика с помощью setOnClickPendingIntent, он не запускает активность. Код, который я использую, приведен ниже:

public void onUpdate(Context context, AppWidgetManager appWidgetManager,
          int[] appWidgetIds) {
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
              R.layout.callwidget_layout);
    Log.d("stuff", "remoteview defined");
    Intent callIntent = new Intent(Intent.ACTION_CALL);
    Log.d("stuff", "intent created");
    callIntent.setData(Uri.parse("tel:"+8888888));
    Log.d("stuff", "intent data added");
    PendingIntent clickPI=PendingIntent
            .getBroadcast(context, 0,
                          callIntent,
                          PendingIntent.FLAG_UPDATE_CURRENT);
    Log.d("stuff", "pending intent created");

    remoteViews.setOnClickPendingIntent(R.layout.callwidget_layout, clickPI);
    Log.d("stuff", "setonclickpendingintent created");

}

Методы Log.d работают нормально, поскольку они отображаются на выходе logcat, но нажатие на виджет ничего не делает. В logcat нет других сообщений об ошибках. Есть ли что-то, что я делаю неправильно?

ОБНОВЛЕНИЕ. Изменил setOnClickPendingIntent так, чтобы он ссылался на кнопку с идентификатором callbutton (remoteViews.setOnClickPendingIntent(R.id.callbutton, clickPI);), а также попытался добавить эти три строки кода в метод onUpdate:

ComponentName myWidget = new ComponentName(context, WidgetProvider.class);
appWidgetManager.getInstance(context).updateAppWidget(myWidget, remoteViews);
Log.d("stuff", "widget updated");

Опять же, метод Log.d работает, предполагая, что виджеты обновляются нормально, но тап по кнопке все равно ничего не делает.

ОБНОВЛЕНИЕ 2: изменение PendingIntent clickPI=PendingIntent.getBroadcast на PendingIntent clickPI=PendingIntent.getActivity также ничего не дает.


person Something Or Other    schedule 28.06.2013    source источник


Ответы (3)


Итак, у меня есть обходной путь к этой проблеме, который придется использовать, пока я не найду реальное решение. Это включает в себя запуск действия, которое, в свою очередь, запускает намерение, которое я хочу. Я изначально хотел этого избежать, ну да ладно.

Мой новый код, для тех, кому он может понадобиться:

public void onUpdate(Context context, AppWidgetManager appWidgetManager,
          int[] appWidgetIds) {
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
              R.layout.callwidget_layout);
    Log.d("stuff", "remoteview defined");
    Intent callIntent = new Intent(context, CallActivity.class);
    PendingIntent clickPI=PendingIntent
            .getActivity(context, 0,
                          callIntent,
                          PendingIntent.FLAG_UPDATE_CURRENT);
    Log.d("stuff", "pending intent created");

    remoteViews.setOnClickPendingIntent(R.id.callbutton, clickPI);
    Log.d("stuff", "setonclickpendingintent created");
    ComponentName myWidget = new ComponentName(context, WidgetProvider.class);
    appWidgetManager.getInstance(context).updateAppWidget(myWidget, remoteViews);
    Log.d("stuff", "widget updated");

}

CallActivity.java:

package com.example.callzepolice;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;

public class CallActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call);
        Intent callIntent = new Intent(Intent.ACTION_CALL);
        Log.d("stuff", "intent created");
        callIntent.setData(Uri.parse("tel:"+8888888));
        Log.d("stuff", "intent data added");
        startActivity(callIntent);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.call, menu);
        return true;
    }

}
person Something Or Other    schedule 02.08.2013
comment
Я только что попробовал это без везения. Хотя я пытаюсь запустить службу, а не деятельность... Какие-нибудь советы? - person Vidia; 07.01.2014

remoteViews.setOnClickPendingIntent(R.layout.callwidget_layout, clickPI);

Вы должны ссылаться на представление в макете. Не макет.

РЕДАКТИРОВАТЬ: Если это весь метод, вам также не хватает вызова appWidgetmanager.updateWidgetAppWidget(...).

РЕДАКТИРОВАТЬ 2: Вы используете getBroadcast(...), когда действительно хотите передать сообщение получателю. Для действий по вызову вам нужно getActivity(...).

person Joel Bodega    schedule 28.06.2013
comment
Я попробовал еще раз, на этот раз используя кнопку с идентификатором callbutton внутри виджета и изменив строку, которую вы цитируете, на remoteViews.setOnClickPendingIntent(R.id.callbutton, clickPI);. Получение тех же результатов. - person Something Or Other; 28.06.2013
comment
Если это весь код обновления, кажется, вам не хватает самого вызова обновления через объект appWidgetManager, который вы получаете в этом методе. - person Joel Bodega; 29.06.2013
comment
Добавление вызова обновления по-прежнему ничего не дает. Однако я использовал метод public void updateAppWidget (ComponentName provider, RemoteViews views), если это имеет значение. - person Something Or Other; 30.06.2013

Используйте ACTION_DIAL, а не ACTION_CALL.

См. документацию. Например. руководство по общим намерениям, чтобы получить требования к намерению системы, например. как инициировать телефонный звонок и документация по ACTION_CALL гласит:

Примечание: будут ограничения на то, какие приложения могут инициировать вызов; большинство приложений должны использовать ACTION_DIAL.

Также:

... метод Log.d работает, предполагая, что виджеты обновляются нормально ...

Успешный Log.d() демонстрирует, что код туда попал (другим способом определить это была бы точка останова), но это не свидетельствует об успешном обновлении виджетов. У вас есть полезная гипотеза, что виджеты обновились, и после этого проблема, например. неправильное намерение. Один из способов проверить эту гипотезу — заставить ваше обновление заметно изменить виджет, например. текст в TextView.

person Jerry101    schedule 20.02.2014