Code style / correct structure android - android

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

BroadcastReceiver doesn't receive the broadcast event message

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.

android BroadcastReceiver doesn't get called

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?

Launch activity on Boot completed and another activity on Mount completion

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>

How to properly auto-start APP

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.

Android BroadcastReceiver not running when designated

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>

Categories

Resources