1

i have some functionality in my program i want to expose but i did't seem to get the receiver working.

i tried the Manifest/Receiver:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.nohkumado.intstringsynchro" >

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:resizeableActivity = "true">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name=".IntStringReceiver" android:exported="true"  android:enabled="true">
            <intent-filter>
                <action android:name="com.nohkumado.intstringsynchro.EDIT_STRINGXML"/>
            </intent-filter>
            <intent-filter>
                <action android:name="com.nohkumado.intstringsynchro.ADD_STRINGXML"/>
                <action android:name="com.nohkumado.intstringsynchro.DEL_STRINGXML"/>
                <data android:mimeType="text/plain"/>
            </intent-filter>
        </receiver>
    </application>
</manifest>

package com.nohkumado.intstringsynchro;
import android.content.*;
import android.widget.*;
import android.util.*;

public class IntStringReceiver extends BroadcastReceiver
{
  public static final String TAG = "Receiver";
  @Override
  public void onReceive(Context context, Intent intent)
  {
    Toast.makeText(context, "Intent Detected:"+intent.getAction(), Toast.LENGTH_LONG).show();

    switch (intent.getAction())
    {
      case "com.nohkumado.intstringsynchro.EDIT_STRINGXML":
        {
          Intent intentStartMainActivity = new Intent(context, MainActivity.class);
          intentStartMainActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
          context.startActivity(intentStartMainActivity);
          break;
        }
      case("com.nohkumado.intstringsynchro.ADD_STRINGXML"):
        {
          Toast.makeText(context, "add token "+intent.getExtras(), Toast.LENGTH_LONG).show();
          break;
        }
      case("com.nohkumado.intstringsynchro.DEL_STRINGXML"):
        {
          Toast.makeText(context, "del token "+intent.getExtras(), Toast.LENGTH_LONG).show();
          break;
        }
      default:
        {
          Toast.makeText(context, "no idea what to do with  "+intent, Toast.LENGTH_LONG).show();
          Log.d(TAG,"no idea what to do with  "+intent);
        }//default
    }//    switch (intent.getAction())
  }//  public void onReceive(Context context, Intent intent)
}//class

as pointed out,i had, erroneously, in the receiver part put a

<category android:name="android.intent.category.DEFAULT"/>

which meant that in the best case only the first intent filter got fired, and not the others.... removed that

now as an other app, i created a small Tester, it has only 3 buttons to trigger the 3 actions i want to pass on as intents, since it was only a small test, i bound the onClick event in the layout file:

package com.nohkumado.istester;

import android.app.*;
import android.content.*;
import android.net.*;
import android.os.*;
import android.view.*;
import android.widget.*;

public class MainActivity extends Activity 
{
  @Override
  protected void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
  }//onCreate
  public void callIntString()
  {
    callIntString(null);
  }
  public void callIntString(View but)
  {
    Toast.makeText(this, "call int string", Toast.LENGTH_SHORT).show(); 

    String name="com.nohkumado.intstringsynchro.EDIT_STRINGXML";
    Intent callIt = new Intent(name);
    try
    {
      startActivity(callIt);
    }
    catch (ActivityNotFoundException e)
    {
      Toast.makeText(this, "no available activity"+callIt, Toast.LENGTH_SHORT).show();

      //callGooglePlayStore();
    }
  }

  private void callGooglePlayStore()
  {
    Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.android.vending");
    ComponentName comp = new ComponentName("com.android.vending", "com.google.android.finsky.activities.LaunchUrlHandlerActivity"); // package name and activity
    launchIntent.setComponent(comp);
    launchIntent.setData(Uri.parse("market://details?id=com.nohkumado.intstringsynchro"));

    startActivity(launchIntent);
  }//callIntString
}

and here was my understanding problem, instead of using startActivity, i should have tried sendBroadcast(launchIntent);

Ok, to close this up... first, i was not completely aware, that the activity contract in the manifest, opens a way for anyone to call on this activity.

Next, i have a specific application, that i want to open up to others, meaning editing the strings.xml files of android projects, and i wanted to propose the equivalent of a REST API, with LIST/EDIT, ADD, DEL.

Now, if we work with activities, the easiest way to get a handle on my activity from outside is, i think, like this:

Intent call = pm.getLaunchIntentForPackage("com.nohkumado.intstringsynchro");

followed by some putExtra calls to insert a token identifying a specific action, and an eventual value to perform on.... finished by a startActivity

this way, the default activity is started, regardless of its name, and the intent passed on, that can be read in the onCreate method of the MainActivity.

To implement my REST API, i tryed to make 3 entry points to my app, one for each type of access, only the LIST/EDIT firing up a UI, the 2 others spawning a series of Asynctasks doing the work in background. But this meant, that an eventual user has to know wich activities to address.

So i reverted to using the putExtra of the intent with a token/value pair to implement my REST-like API.....

For educations sake i tryed out the way over the broadcast mechanism, the advantage beeing that on the client side there seems no risk of crash, no need to catch a ActivityNotFound Exception, and, from a typo in my code, i noticed that the intent activity doesn't need to be bound to my actual app, i can choose any name i want.

For this, on the client side i needed to :

String name="com.nohkumado.intstringsynchro.EDIT_STRINGXML";
Intent callIt = new Intent(name);
sendBroadcast(callIt);

but on my app side i need to implement a complete BroadCastreceiver....

On the other side, this mechanism was extremely slow, giving the whole operation a very sluggish feel

Please correct me if i got it right this time, and i am open to suggestions if there a better ways to achieve my goal to propose to others those LIST/EDIT, ADD and REMOVE functionalities?

Noh Kumado
  • 35
  • 2
  • 9

1 Answers1

1

the reports back an activity not found exception

Apparently, you do not have an activity with an <intent-filter> for an action string of com.nohkumado.intstringsynchro.EDIT_STRINGXML. Your manifest in the question certainly does not have such an activity. Your manifest in the question has a <receiver> element with an odd <intent-filter> that, among other things includes that action. However, <receiver> and <activity> are not the same thing.

Either change your code to send a broadcast, or change your code to have an activity with that action string.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • ok, then i have an understanding problem.... first, what do you call odd? i took this from the documentation? and then i want to call from an external app the equivalent of edit/add/delete which is better? by passing intents to activity or by broadcast? they seem to do the same thing then? – Noh Kumado Jan 16 '17 at 13:12
  • @NohKumado: "what do you call odd?" -- an `` on a `` rarely uses ``, particularly `DEFAULT`. For whatever reason, when you call `startActivity()`, Android automatically adds `DEFAULT` to the `Intent` if no other categories are specified, but it does not do that for `sendBroadcast()`. "which is better?" -- if you are going to be presenting a UI to the user, use activities. If you are not going to be presenting a UI to the user, do not use activities (though broadcasts may not be the "better" answer, either). – CommonsWare Jan 16 '17 at 13:45
  • i will accept this answer, even it it it was way too cryptic for me to understand what you meant, a simple change startActivity to sendBroadcast would have send me much faster onto the right track, caustic replies to non-english native speakers may appear to them only way after they finally understood what you meant in the first place.... – Noh Kumado Jan 18 '17 at 09:53
  • @NohKumado: "a simple change startActivity to sendBroadcast would have send me much faster onto the right track" -- I had no way of knowing if that was the correct solution to what you were trying to do, given your original question. That is why I elected to explain a bit more about why you are getting the error. This is typical for Stack Overflow. "to non-english native speakers" -- note that there are [many Android development support sites](http://www.andglobe.com), in a variety of languages. – CommonsWare Jan 18 '17 at 12:46