Hello fellow programmers,
I cant find a proper way to route my application, I would like one file to decide which activity has to be started
I am building an android application that in general contains:
-2 ways to start up
-3 activity's
The application can be launched by clicking the icon (standard launch)
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
And an activity is started when there is an incoming call
<action android:name="android.intent.action.PHONE_STATE" />
In the first setup there was 2 activity's one to register and one to use the application. In this
setup I added an extra activity to check if a token was present and route to the right activity.
In the setup that I have now, all the actions are in the of a broadcast receiver. I tried implementing the logic of the extra activity.
The problem I am facing is the check of the incoming call, it is always launching the same activity CallHandler,
I think routing the application within a broadcast receiver might be bad practice, but I can not find a better way of routing the application, and the current code does not work.
Your help is very much appreciated, the following pieces of code might help explain my issue:
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name=".RoutingCallReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</receiver>
<activity
android:name=".RegisterActivity"
android:label="#string/app_name"
android:windowSoftInputMode="adjustResize|stateVisible" >
</activity>
<activity
android:name=".CallHandler"
android:label="#string/title_activity_main" >
</activity>
<activity
android:name=".CreateCallActivity"
android:label="#string/title_activity_create_call" >
</activity>
</application>
RoutingCallReceiver:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
public class RoutingCallReceiver extends BroadcastReceiver {
TelephonyManager telephony;
Intent in;
public void onReceive(Context context, Intent intent) {
PrimePhoneStateListener phoneListener = new PrimePhoneStateListener();
telephony = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
if(telephony.getCallState()== 1){
in = new Intent(context, CallHandler.class);
in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(in);
}
else {
TokenIO tokenHandler = new TokenIO();
String token = tokenHandler.getToken(context);
Log.d("AAfter", "Token");
if(token.equals("") || token.equals(null)){
in = new Intent(context, RegisterActivity.class);
in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(in);
}
else{
in = new Intent(context, CreateCallActivity.class);
in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(in);
}
}
}
// when finish your job, stop listen to changes
public void onDestroy() {
telephony.listen(null, PhoneStateListener.LISTEN_NONE);
}
}
you can make change in your xml file
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name=".RoutingCallReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
<activity
android:name=".RegisterActivity"
android:label="#string/app_name"
android:windowSoftInputMode="adjustResize|stateVisible" >
</activity>
<activity
android:name=".CallHandler"
android:label="#string/title_activity_main" >
</activity>
<activity
android:name=".CreateCallActivity"
android:label="#string/title_activity_create_call" >
</activity>
</application>
and put this tag into main activity
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
and i hope that will work fine.
Related
I created my broadcast receiver AnprEventReciever that should be triggered when connectivity state changes, however it doesn't.
AnprEventReciever:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
import bi.anpr.layouts.SplashActivity;
public class AnprEventReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("test","event recieved");
Toast.makeText(context, "event recieved" , Toast.LENGTH_LONG).show();
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sxx.vlctest">
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:name="bi.anpr.vlc.VLCApplication"
android:allowBackup="false"
android:icon="#mipmap/ic_anpr_launcher_round"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<receiver
android:name="bi.anpr.core.AnprEventReciever"
android:enabled="true"
android:exported="true"
android:label="StartMyServiceAtBootReceiver">
<intent-filter>
<action android:name="android.intent.action.CONNECTIVITY_CHANGE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<activity
android:name="bi.anpr.layouts.MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait" />
<activity
android:name="bi.anpr.layouts.VideoResourceActivity"
android:screenOrientation="portrait" />
<activity
android:name="bi.anpr.layouts.ZoneActivity"
android:label="Zone Setter"
android:screenOrientation="portrait" />
<activity
android:name="bi.anpr.layouts.SettingsActivity"
android:label="#string/title_activity_settings"
android:screenOrientation="portrait" />
<activity
android:name="bi.anpr.layouts.SplashActivity"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="preloaded_fonts"
android:resource="#array/preloaded_fonts" />
</application>
</manifest>
Please note that i'd tested almost every possible action that all failed except the BOOT_COMPLETED, where my BroadcastReceiver was successfully fired.
Thanks for #TheWanderer who helped me through his comment to find the answer. In the Android 8.0 Behavior Changes Note developers mentioned the following:
Apps cannot use their manifests to register for most implicit
broadcasts (that is, broadcasts that are not targeted specifically at
the app).
So i tried to programatically registering my BroadcastReceiver like this below instead of creating a manifest entry for it:
private AnprEventReciever myReceiver;
private IntentFilter filter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_resource);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
myReceiver = new AnprEventReciever();
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(myReceiver, filter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(myReceiver);
}
It works perfectly, however unfortunately the action "android.intent.action.CONNECTIVITY_CHANGE" seems to be deprecated where i couldn't find it in the Intent class and i don't know if it is found elsewhere.
Note: as i go through reading i found that it is necessary to un-register the broadcast receiver when the activity pauses or destroys, otherwise you might get an error when trying to register or re-register it.
UPDATE:
Create intent filter with ConnectivityManager.CONNECTIVITY_ACTION instead of "android.intent.action.CONNECTIVITY_CHANGE" in order to receive connectivity changed broadcasts.
I've seen a lot of question like this around and I've tried a bunch of things without success...
I just want to log a sms received using a subclass of BroadcastReceiver like I've seen in so many tutorial...
so here is my code and config
BroadcastReceiver
package com.example.koki.mysms;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
public class SmsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("MainActivity", "test");
Toast.makeText(context, "ON RECEIVE BROADCAST", Toast.LENGTH_LONG).show();
}
}
there's nothing in my MainActivity beside what you get when creating a new projet with android studio.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.koki.mysms" >
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<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=".SmsReceiver" android:exported="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
the way I test it (not very familiar in android development yet), is that I have two emulator and I sent sms to one another. They both receive the sms but nothing in the logcat nor the Toast appear. what am I doing wrong?
This my Androidmanifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.abc.testapp"
android:versionCode="1"
android:versionName="Pm61" >
<uses-sdk android:minSdkVersion="15"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<supports-screens android:anyDensity="true" />
<application android:label="#string/app_name" android:debuggable="true" android:largeHeap="true">
<activity android:name="com.abc.testapp.MainClass" android:label="#string/app_name" android:theme="#android:style/Theme.Translucent" android:hardwareAccelerated="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
.
.
.
.
.
.
<activity android:name="com.abc.testapp.BootLoad"
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen" >
</activity>
<activity android:name="com.abc.testapp.Rxmain" android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen" android:launchMode="singleTask">
</activity>
<receiver android:name="com.abc.testapp.MyReceiver" android:enabled="true">
<intent-filter android:priority="500">
<action android:name= "android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MEDIA_MOUNTED"/>
<data android:scheme="file" />
</intent-filter>
</receiver>
</application>
</manifest>
This is my MyReceiver class for broadcasting
package com.abc.testapp;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class MyReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if(Intent.ACTION_MEDIA_MOUNTED.equals(action))
{
Log.d("MYReceiver","Mounting Successfull");
Intent serviceActivity = new Intent(context, Rxmain.class);
serviceActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(serviceActivity);
}
if(Intent.ACTION_BOOT_COMPLETED.equals(action))
{
Log.d("MYReceiver","Boot Successfull");
Intent serviceActivity = new Intent(context, BootLoad.class);
serviceActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(serviceActivity);
}
}
}
My device is stand alone device, only my app will come on boot.
I want when boot complete it shall launch BootLoad activity and after MEDIA_MOUNTED it should launch Rxmain Activity.
But my bootLoad activity is not coming
So I have some doubts in this:
It is working sometimes but sometimes not?
2.what is this Priority in Intent-filter?
what this data scheme does?
what I am doing is correct or not?
please suggest me
The problem is the way you've defined the intent filter for the broadcast receiver. This is your definition:
<receiver android:name="com.abc.testapp.MyReceiver" android:enabled="true">
<intent-filter android:priority="500">
<action android:name= "android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MEDIA_MOUNTED"/>
<data android:scheme="file" />
</intent-filter>
</receiver>
You've defined a single intent filter that will be triggered if the ACTION is either BOOT_COMPLETED or MEDIA_MOUNTED. But, by specifying the <data> tag, you will only receive broadcast Intents that have data with scheme=file.
The BOOT_COMPLETED Intent doesn't have any data, so your receiver won't get it.
You need to specify 2 separate intent filters, like this:
<receiver android:name="com.abc.testapp.MyReceiver" android:enabled="true">
<intent-filter android:priority="500">
<action android:name= "android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
<intent-filter android:priority="500">
<action android:name="android.intent.action.MEDIA_MOUNTED"/>
<data android:scheme="file" />
</intent-filter>
</receiver>
i'm having trouble with the auto-start feature of my APP.
I've searched trhough the forums, seen many suggestions, none seems to work and I don't know why.
Here's the BootUpReciver.java
package com.???.???;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
public class BootUpReciver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
//Intent pushIntent = new Intent(context, BackgroundService.class);
//context.startService(pushIntent);
Toast.makeText(context, "Device Booted", Toast.LENGTH_LONG).show();
Log.d("TAG","Device Booted");
}
}
}
And here's my Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.???.???"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="17" />
<application
android:theme="#android:style/Theme.Holo"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<receiver android:name=".BootUpReciver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<activity
android:name="com.???.???.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>
</application>
When i restart my phone i don't even see the Toast, why? what should i do? I need to auto-start to get some sharedprefs and write a value to a file every boot.
Thanks.
While testing I found that If I show toast in onReceive then it is not showing. But if I start an activity in onReceive then it is working. So you can also check this. Start an activity or service and perform your task there.
I am new to android development, and
I have an app that when run from the app icon in the menu / home screens runs just fine. However when I try to make it run on boot completion it crashes (Keeping in mind that if I go back to the Icon it will still work) I am wondering what is wrong here. Keep in mind I am doing testing on my personal phone which is android 2.3 and it is ROOTED. Some how I don't think this should be as hard as it is to do, since 9/10 most android apps work in this way or in a way similar to this. Simply put: What am I doing wrong?
In the mean time here is my code for the Broadcast Receiver:
package path.to.file;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class autoBot extends BroadcastReceiver {
private static final String LOG_TAG = "StartAtBootServiceReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.e(LOG_TAG, "onReceive:");
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent i = new Intent();
i.setAction("path.to.file.MainActivity");
context.startActivity(i);
}
}
}
As well as the Manifest file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
installlocation="internalOnly"
package="path.to.file"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="autoBot" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" >
</action>
<category android:name="android.intent.category.HOME" >
</category>
</intent-filter>
</receiver>
</application>
</manifest>
Is there a specific reason you are adding an action to your intent? If your only aim is to launch your activity at start-up, do this in your BroadcastReceiver:
Intent i = new Intent(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
Also, remove these lines from your manifest under receiver tag, you won't need them there:
<category android:name="android.intent.category.HOME" ></category>