With my basic knowledge on Android, I'm trying to play with the Google voice APIs and followed the example here and to write an app, which would allow me to call a hardcoded number. Unfortunately i'm getting an error saying < identifier > expected, so i'm unable to check if my app even works. Can someone see what is missing here and also if i'm even going in the right direction with my thinking and code.
Java file:
public class MyVoiceActivity extends Activity {
class Confirm extends VoiceInteractor.ConfirmationRequest {
public Confirm(String ttsPrompt, String visualPrompt) {
VoiceInteractor.Prompt prompt = new VoiceInteractor.Prompt(
new String[] {ttsPrompt}, visualPrompt);
super(prompt, null);
}
#Override public void onConfirmationResult(boolean confirmed, Bundle null) {
if (confirmed) {
call();
}
finish();
}
};
#Override public void onResume() {
if (isVoiceInteractionRoot()) {
call();
}
Intent intent = new Intent(this, MyVoiceActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
private void call () {
try {
final Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:12345678"));
startActivity(callIntent);
} catch (ActivityNotFoundException activityException) {
}
}
}
AndroidManifest file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ccvoice.bt.examplevoice">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MyVoiceActivity" >
<intent-filter>
<action android:name="android.intent.action.CALL" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.VOICE" />
</intent-filter>
</activity>
</application>
</manifest>
The < identifier > required error i'm getting is in this line of the code:
public void onConfirmationResult(boolean confirmed, Bundle null) {
Thank you in advance.
null is a reserved word and cannot be used as an identifier (eg. the name of a parameter). Use a different name for your Bundle parameter to that method.
public void onConfirmationResult(boolean confirmed, Bundle bundle) {
Related
I need help or guidance in resolving the issue that I have regarding React Native interacting with other native applications via intents. I know that React Native supports deeplinking out of the box but does not cater for intents, which means that one needs to create an android native module (https://reactnative.dev/docs/native-modules-android). I created a native module that calls 3rd party applications via intents and passing data using startActivityForResults and created onActivityResult that is supposed to handle data returned from 3rd party applications after closing. However, the onActivityResult executes prematurely before external applications open.
Starting the activity using startActivityForResults:
#ReactMethod
public void launchApp(String stringArgument, ReadableMap args, Promise promise) throws JSONException{
try {
final JSONObject options = convertMapToJson(args);
Bundle extras = new Bundle();;
int LAUNCH_REQUEST = 0;
if (options.has("extras")) {
extras = createExtras(options.getJSONArray("extras"));
Log.d(TAG,"Extras found");
Log.d(TAG, options.getString("extras"));
} else {
extras = new Bundle();
Log.d(TAG,"No extras");
}
if (options.has("launchRequestCode")) {
LAUNCH_REQUEST = options.getInt("launchRequestCode");
}
Intent packageIntent = this.reactContext.getPackageManager().getLaunchIntentForPackage(stringArgument);
if(packageIntent != null){
packageIntent.putExtras(extras);
//callback.invoke("Starting activity for: "+stringArgument);
Activity activity = getReactApplicationContext().getCurrentActivity();
//this.reactContext.startActivityForResult(packageIntent, LAUNCH_REQUEST, extras);
activity.startActivityForResult(packageIntent, LAUNCH_REQUEST);
return;
//mPromise.put(LAUNCH_REQUEST, promise);
}
else{
Log.d(TAG, stringArgument+" package not found");
//callback.invoke("Package not found: "+stringArgument);
}
} catch (JSONException e) {
//TODO: handle exception
Log.d(TAG, e.toString());
}
// TODO: Implement some actually useful functionality
}
Expecting the data back using onActivityResults
ActivityEventListener mActivityEventListener = new ActivityEventListener(){
#Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
//super.onActivityResult(requestCode, resCode, data);
Log.d(TAG,"On activity result");
if (mPromise != null && resultCode == activity.RESULT_OK) {
WritableMap result = new WritableNativeMap();
result.putInt("resultCode", resultCode);
result.putMap("data", Arguments.makeNativeMap(data.getExtras()));
mPromise.resolve(result);
}
else{
Log.d(TAG,"Promise and intent data are empty");
//mPromise.reject("Unable to get promise or intent data is empty");
}
if(resultCode == activity.RESULT_CANCELED ){
Log.d(TAG,"Result cancelled or no result or crashed with code");
}
}
#Override
public void onNewIntent(Intent intent){
Log.d(TAG,"New Intent");
}
};
Android Manifest file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.navapp">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".MainApplication"
android:label="#string/app_name"
android:icon="#mipmap/ic_launcher"
android:roundIcon="#mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>
By using Android Studio Logcat to debug, I found out that the onActivityResults executes immediately before the external app opens up.
Logcat screenshot
Thanks to this explanation here, I was able to drill down to what was causing the issue. In my React Native application, I used the package name of the external application instead of the action name to open it.
Manifest File of the external app:
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:launchMode="singleTask"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="com.bld.pushnotification.Main"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
I also modified the my code for launching the app:
#ReactMethod
public void launchApp(String stringArgument, ReadableMap args, Promise promise) throws JSONException{
try {
final JSONObject options = convertMapToJson(args);
Bundle extras = new Bundle();;
int LAUNCH_REQUEST = 0;
if (options.has("extras")) {
extras = createExtras(options.getJSONArray("extras"));
Log.d(TAG,"Extras found");
Log.d(TAG, options.getString("extras"));
} else {
extras = new Bundle();
Log.d(TAG,"No extras");
}
if (options.has("launchRequestCode")) {
LAUNCH_REQUEST = options.getInt("launchRequestCode");
}
Intent packageIntent = new Intent(stringArgument);
Activity activity = getReactApplicationContext().getCurrentActivity();
activity.startActivityForResult(packageIntent, LAUNCH_REQUEST);
} catch (JSONException e) {
//TODO: handle exception
Log.d(TAG, e.toString());
}
}
This is little snipet to try BroadcastReciever android but i dont understand wath's wrong.
In fact just callIntent return log. my little brain it's burning.
if somebody can tell me why ?
Sorry for my bad english !
```
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.plectre.broadcast">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MyReciever" >
<intent-filter>
<action android:name="com.plectre"/>
</intent-filter>
</receiver>
</application>
</manifest>
```
public void callIntent() {
Intent intent = new Intent();
intent.setAction("com.plectre");
intent.putExtra("frist", "Intent premier" );
sendBroadcast(intent);
Log.i("callIntent", "Tag");
}
```
public class MyReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//String result = intent.getStringExtra("first");
Toast.makeText(context, "Result", Toast.LENGTH_LONG).show();
Log.i("Broadcast", " Receiver");
}
```
No error, no crash, nothing !! :=(
Create an explicit intent by explicitly declaring the receiver when you create the intent. At present your intent is implicit.
public void callIntent() {
// Explicitly declare the receiver class
Intent intent = new Intent(this, MyReciever.class);
intent.setAction("com.plectre");
intent.putExtra("frist", "Intent premier" );
sendBroadcast(intent);
Log.i("callIntent", "Tag");
}
Additional reading: https://developer.android.com/guide/components/intents-filters#ExampleExplicit
Also. You declare the intent's Extra as "frist" and try to receive at as "first". This needs to be rectified.
You should ensure that the correct action is taken with the specified Intent Action in your receiver:
#Override
public void onReceive(Context context, Intent intent) {
if ("com.plectre".equals(intent.getAction())) {
final String result = intent.getStringExtra("first");
Toast.makeText(context, "Result", Toast.LENGTH_LONG).show();
Log.i("Broadcast", " Receiver");
}
}
I'm studying Android.
I try to implement a Custom static Broadcast Receiver but it is not working.
I search for some issue from Google but I can't find something to solve this.
I work on Android 7.0 Min Level 24 Target Level 28
In fact, MyStaticReceiver isn't launching when I start the Activity (no log)
MyDynamicReceiver work perfectly
Do you have a solution?
AndroidManifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="test.receiver">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name="test.receiver.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".MyStaticReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="#string/StaticAction" />
</intent-filter>
</receiver>
</application>
</manifest>
MainActivity.java :
public class MainActivity extends Activity {
public final static boolean Debug = true;
public final static String TAG = "TagDebug";
private MyDynamicReceiver dynamicReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ComponentName receiver = new ComponentName(this, MyStaticReceiver.class);
PackageManager pm = this.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
#Override
protected void onResume() {
super.onResume();
if (Debug) Log.i(TAG, "MainActivity:onResume");
configureDynamicReceiver();
}
#Override
protected void onDestroy(){
super.onDestroy();
if (Debug) Log.i(TAG, "MainActivity:onDestroy");
unregisterReceiver(dynamicReceiver);
}
public void onClickButton(View v) {
if (Debug) Log.i(TAG, "MainActivity:onClickButton");
Intent staticIntent = new Intent();
staticIntent.setAction(getString(R.string.StaticAction));
sendBroadcast(staticIntent);
Intent dynamicIntent = new Intent();
dynamicIntent.setAction(getString(R.string.DynamicAction));
sendBroadcast(dynamicIntent);
}
public void configureDynamicReceiver() {
if( dynamicReceiver == null ) {
dynamicReceiver = new MyDynamicReceiver();
}
IntentFilter filter = new IntentFilter(getString(R.string.DynamicAction));
registerReceiver(dynamicReceiver, filter);
}
}
MyStaticReceiver.java (MyDynamicReceiver is the same ...)
public class MyStaticReceiver extends BroadcastReceiver {
public final static boolean Debug = true;
public final static String TAG = "TagDebug";
public MyStaticReceiver() {
if (Debug) Log.i(TAG, "MyStaticReceiver");
}
#Override
public void onReceive(Context context, Intent intent) {
if (Debug) Log.i(TAG, "MyStaticReceiver:onReceive");
}
}
You are actually sending an implicit broadcast, therefore the receiver declared in the manifest will not work.
If your app targets Android 8.0 (API level 26) or higher, you cannot use the manifest
to declare a receiver for most implicit broadcasts (broadcasts that
don't target your app specifically). You can still use a
context-registered receiver when the user is actively using your app. Link
You don't face any issue with MyDynamicReceiver because it is context-registered receiver.
But to make it work for MyStaticReceiver, you can try sending an explicit broadcast by passing the component name in the constructor of the Intent.
Intent staticIntent = new Intent(this, MyStaticReceiver.class);
staticIntent.setAction(getString(R.string.StaticAction));
sendBroadcast(staticIntent);
Preconditions
1. App starts with LinkActivity, at this point we have no deep link intent, it's ok.
Main activity launched. There we are able to click the deep link.
By clicking on deep link opens LinkActivity, uri is correct, referringParams json is not empty (ok). But...
When we replaying step 2: uri is correct, but the reffering params are empty: "{}"; All other tries are with the same result.
Only when we pausing the app (for example switching to the recent apps menu) and then returning to the app - deep link works as expected, but only at first try. May be some issues with the session close (but in the current version of the sdk it self controls session close)
public class LinkActivity extends AppCompatActivity {
private static final String TAG = LinkActivity.class.getSimpleName();
#Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
}
#Override
protected void onStart() {
super.onStart();
Uri uri = getIntent().getData();
Log.w(TAG, "uri: " + uri);
Branch.getInstance().initSession(new Branch.BranchReferralInitListener() {
#Override
public void onInitFinished(JSONObject referringParams, BranchError error) {
Log.w(TAG, "json: " + referringParams);
startActivity(new Intent(LinkActivity.this, MainActivity.class));
}
}, uri, this);
}
}
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
public class BranchApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
Branch.enableLogging();
Branch.getAutoInstance(this);
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.myapp">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:name=".BranchApplication"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".LinkActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="myapp.link"
android:scheme="https" />
</intent-filter>
</activity>
<activity android:name=".MainActivity"/>
<meta-data
android:name="io.branch.sdk.BranchKey"
android:value="#string/branch_io_live_key" />
<meta-data
android:name="io.branch.sdk.BranchKey.test"
android:value="#string/branch_io_test_key" />
<meta-data
android:name="io.branch.sdk.TestMode"
android:value="false" />
</application>
</manifest>
implementation "io.branch.sdk.android:library:2.14.3"
Update:
Even with android:launchMode="singleInstance" for LinkActivity steel reproduces (I don't think this is the case).
Udpate2:
Bhardwaj mentioned that no need to call initSession when we initing Branch via getAutoInstance. But how to get refferingParams from uri in that case?
Update3:
From the Branch.checkIntentForSessionRestart doc:
Check for forced session restart. The Branch session is restarted if
the incoming intent has branch_force_new_session set to true. This is
for supporting opening a deep link path while app is already running
in the foreground. Such as clicking push notification while app in
foreground.
So, My desired behavior is matches this description. But how to force session restart?
You can try as mentioned below :-
Branch.getAutoInstance(this) -> Branch.getAutoInstance(this, true)
Branch.getInstance(context) -> Branch.getInstance()
Do not call initSession when you have getAutoInstance()
if(!initiatedBranchDeepLinks) {
// Configure Branch.io
initiatedBranchDeepLinks = true;
Branch branch = Branch.getInstance();
branch.initSession(new Branch.BranchReferralInitListener(){
#Override
public void onInitFinished(JSONObject referringParams, BranchError error) {
if (error == null) {
// params are the deep linked params associated with the link that the user clicked -> was re-directed to this app
// params will be empty if no data found
// ... insert custom logic here ...
String message = "Branch.io onInitFinished. Params: " + referringParams.toString();
Log.d(TAG, message);
} else {
Log.i(TAG, error.getMessage());
}
}
}, this.getIntent().getData(), this);
}
Here is Branch Test Bed app:
https://github.com/BranchMetrics/android-branch-deep-linking/tree/master/Branch-SDK-TestBed
You can use this as a reference and see what you are doing incorrectly.
This could be caused by your Manifest configuration. In your <activity> tag, you should include android:launchMode="singleTask". See this section of our docs. This may explain why you are receiving the parameters the first time, but not receiving them on a re-open.
I am trying to achieve following case on Android, but no success:
1) Launch Application (Launcher Activity which is a subclass of Base Activity). The Base Activity has code as follows:
///This is in BaseActivity
#Override
public void onCreate(Bundle instance)
{
super.onCreate(instance);
//Config.isLoggedIn() is a static function.
if(! Config.isLoggedIn())
{
////Config.startLoginActivity is a static function
Config.startLoginActivity(this, getIntent());
finish();
}
}
The Config.startLoginActivity functions is defined as
public static void startLoginActivity(final Context ctx, final Intent finishIntent)
{
Intent i = new Intent(ctx, ItemListActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("FINISH_INTENT", finishIntent);
ctx.startActivity(i);
}
Now, the ItemListActivity contains a list of Items as {Item1, Item2, Item3}. In ItemListActivity, I am saving the passed "finishIntent" as
///This is ItemListActivity onCreate Method
if(getIntent().hasExtra("FINISH_INTENT"))
mFinishIntent = getIntent().getParcelableExtra("FINISH_INTENT");
and the onItemListSelected method is described as follows :
#Override
public void onItemSelected(String id) {
Config.setLogInState(true);
if(mFinishIntent != null)
{
Log.i("ITEMLISTACTIVITY", "Class Name = " + mFinishIntent.getClass().getName());
Log.i("ITEMLISTACTIVITY", "Starting mFinishIntent Activity");
startActivity(mFinishIntent);
finish();
}
}
But the issue is the Main Activity is not being launched again, Android takes me to the home screen instead. While looking for a solution, I saw that Google I/O app has the same implementation and that works flawlessly but in my case it is not. I am unable to figure it out. Please help.
Thanks in Advance.
Manifest File is as follows :
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.app.myapplication.ItemListActivity"
android:label="#string/app_name" >
</activity>
<activity
android:name="com.app.myapplication.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>
Ok Here is a quick help which works for 100 percent which I'm using not mostly but EVERYTIME! you must past it through intent and in your case here it is how it must look like.
Intent intent = new intent(//name of your activity in which you are at the moment.this, //name of activity to which you want to go.class);
startActivity(intent);
Hope this will help