Android小部件启动应用程序并检测应用程序未找到

问题描述:

我需要一个简单的家庭小部件来启动外部应用程序(例如:whatsapp)。Android小部件启动应用程序并检测应用程序未找到

在我的MainActivity中扩展AppWidgetProvider(onUpdate)我使用这段代码来创建一个挂起的意图,如果应用程序安装,它的工作效果很好。

Intent intent = new Intent(); 
ComponentName cn = new ComponentName("com.whatsapp", "com.whatsapp.Main"); 
intent.setComponent(cn); 

PendingIntent pending = PendingIntent.getActivity(context, 0, intent, 0); 

RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.activity_main); 
views.setOnClickPendingIntent(R.id.imageView, pending); 

appWidgetManager.updateAppWidget(currentWidgetId, views); 

在(的onReceive)第I使用此代码为检测是否安装了应用程序

PackageManager pm = context.getPackageManager(); 

     List<ApplicationInfo> list = pm.getInstalledApplications(0); 

     for (int aa = 0; aa < list.size(); aa++) {   
      if(list.get(aa).packageName.equals("com.whatsapp")){ 
       //app istalled 
       noapp = 0; 
      } 
      else{ 
       //app not istalled 
       noapp1 = 1;   
      } 
     }   
    if(noapp1==1){ 
    Toast.makeText(context, "Whatsapp not installed", Toast.LENGTH_SHORT).show(); 
    } 

我的问题是: 如果未安装App这个代码检测并显示吐司消息但只有小部件第一次定位在家中。 如果应用程序未安装,我需要在任何时候触摸图像视图时显示消息。 请帮忙!

Karakuri我尝试应用您的建议。 这是我的意图连接到ImageView的主要活动代码:

public class MainActivity extends AppWidgetProvider{ 

public void onUpdate(Context context, AppWidgetManager appWidgetManager, 
     int[] appWidgetIds) { 
    for(int i=0; i<appWidgetIds.length; i++){ 
     int currentWidgetId = appWidgetIds[i]; 

     Intent intent = new Intent(LaunchExternalAppReceiver.ACTION); 
     PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0); 

     RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.activity_main); 
     views.setOnClickPendingIntent(R.id.imageView, pendingIntent); 
     // Tell the AppWidgetManager to perform an update on the current App Widget 
     appWidgetManager.updateAppWidget(currentWidgetId, views); 

    }  
    } 
} 

这与广播接收器的新类(我把我的simpele代码中,以检查是否安装了应用程序,只是为了测试) :

public class LaunchExternalAppReceiver extends BroadcastReceiver { 
public static final String ACTION = "control"; 

@Override 
public void onReceive(Context context, Intent intent) { 

    PackageManager pm = context.getPackageManager(); 

    List<ApplicationInfo> list = pm.getInstalledApplications(0); 

    for (int aa = 0; aa < list.size(); aa++) { 

     if(list.get(aa).packageName.equals("com.whatsapp")){ 
      //app istalled 

     } 
     else{ 
      //app not istalled    
      Toast.makeText(context, "Whatsapp not installed", Toast.LENGTH_SHORT).show(); 
     } 
    }    
    } 
} 

这是我的清单:

<uses-sdk 
    android:minSdkVersion="11" 
    android:targetSdkVersion="19" /><application 
    android:allowBackup="true" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" > 
    <receiver android:name=".MainActivity" > 
     <intent-filter> 
      <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
     </intent-filter> 

     <meta-data 
      android:name="android.appwidget.provider" 
      android:resource="@xml/mywidget" /> 
    </receiver> 
    <receiver android:name=".LaunchExternalAppReceiver" > 
     <intent-filter> 
      <action android:name="control" > 
      </action> 
     </intent-filter> 
    </receiver> 
</application> 

非常感谢你的帮助。

我找到了一种替代解决方案。打招呼,但有一个恼人的小问题。 我在我的主要活动中附加了imageView的意图,以在此类中启动一个新类“控件”,我检查该应用程序是否已安装并启动她或发送消息并提供下载按钮。 问题是...如果安装了应用程序,控制类将启动她,但在应用程序打开前第一秒会显示活动(控制)屏幕。很烦人。 有人可以帮助我做出这个最终修复?谢谢。

在的onUpdate(主要活动):

Intent controlIntent = new Intent(context, Control.class);   
    PendingIntent pendingc1 = PendingIntent.getActivity(context, 0, controlIntent, 0); 
    RemoteViews views1 = new RemoteViews(context.getPackageName(), R.layout.activity_main); 
    views1.setOnClickPendingIntent(R.id.imageView, pendingc1); 
    appWidgetManager.updateAppWidget(currentWidgetId, views1); 

我的新类(控制):

public class Control extends Activity { 
private TextView testo; 

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

    PackageManager pm = this.getPackageManager(); 

    List<ApplicationInfo> list = pm.getInstalledApplications(0); 

    for (int aa = 0; aa < list.size(); aa++) { 

     if (list.get(aa).packageName.equals("com.whatsapp")) { 
      // app istalled 

      Intent launchIntent = getPackageManager() 
        .getLaunchIntentForPackage("com.whatsapp"); 
      startActivity(launchIntent); 
      Control.this.finish(); 

     } else { 
      setContentView(R.layout.control); 
      // app not istalled 
      testo = (TextView) findViewById(R.id.message); 
      String text = "WhatsApp is Not Installed\nPlease Download Whatsapp from Play Store"; 
      testo.setText(text); 

      Button button = (Button) findViewById(R.id.exit); 
      button.setOnClickListener(new View.OnClickListener() { 

       public void onClick(View v) { 
        Control.this.finish(); 
       } 
      }); 

      Button button2 = (Button) findViewById(R.id.download); 
      button2.setOnClickListener(new View.OnClickListener() { 

       public void onClick(View v) { 
        startActivity(new Intent(Intent.ACTION_VIEW, Uri 
          .parse("market://details?id=" + "com.whatsapp"))); 
        Control.this.finish(); 
       } 
      }); 

     } 
    } 
    } 
} 

让ImageView单击发送广播到您的应用程序中的接收器(使用PendingIntent.getBroadcast())。在该接收器中,您可以检查外部应用程序是否已安装并从此处启动。

编辑

建立一个新的广播接收器。

public class LaunchExternalAppReceiver extends BroadcastRecevier { 
    public static final String ACTION = "some-unique-string-here"; 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     // check if the external app is installed and launch it 
     PackageManager pm = context.getPackageManager(); 
     try { 
      pm.getApplicationInfo("com.whatsapp", 0); // throws if not found 
      Intent intent = pm.getLaunchIntentForPackage("com.whatsapp"); 
      if (intent != null) { 
       context.startActivity(intent); 
      } 
     } catch (NameNotFoundException e) { 
      // package not found, you can show the Toast here 
     } 
    } 
} 

添加到您的AndroidManifest。确保意图过滤器操作符合上面的操作。

<receiver android:name=".LaunchExternalAppReceiver"> 
    <intent-filter> 
     <action android:name="some-unique-string-here"> 
    </intent-filter> 
</receiver> 

使您的ImageView通过此操作发送广播,而不是尝试启动外部应用程序。

Intent intent = new Intent(LaunchExternalAppReceiver.ACTION); 
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0); 
remoteViews.setOnClickPendingIntent(R.id.imageView, pendingIntent); 
+0

谢谢Karakury。我尝试在我的onUpdate部分.... if(PendingIntent.getBroadcast(context,0,intent,0)!= null){要做的事情}但是当widget未打开时仍然出现Toast消息。你能解释更多吗? – Daniel

+0

使imageView发送广播意图,而不是启动其他应用程序的意图。 – Karakuri

+0

这是我的代码知识。你能告诉我这样做的代码吗?我的代码将意图附加到imageView是在这篇文章的顶部。 – Daniel