I want to automatically launch my app on TV startup. i.e. when the user power on the TV, TV will powerup and my app will start.
I have followed multiple links on internet and tried to implement it but no activity is shown on startup.
Followed
How to start/ launch application at boot time Android
As I was not getting any response on start, followed Android-Boot Completed is not working in Broadcastreceiver
I have extensively searched web and stackoverflow, it is strange that I cannot find a solution to make it work till now. Don't know what am I doing wrong...
here is my code...
MainActivity.java
public class MainActivity extends FragmentActivity {
public WebView mWebview;
private android.content.Context Context;
private ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
String url = "http://www.test.com";
if (!DetectConnection.checkInternetConnection(this)) {
Toast.makeText(getApplicationContext(), "No Internet Connection!", Toast.LENGTH_LONG).show();
finish(); //Calling this method to close this activity when internet is not available.
} else {
WebView webView = (WebView) findViewById(R.id.main_fragment);
webView.getSettings().setJavaScriptEnabled(true);
CookieManager.getInstance().setAcceptCookie(true);
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
WebSettings webSettings = webView.getSettings();
webSettings.setDomStorageEnabled(true);
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
webSettings.setUseWideViewPort(true);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl(url);
}
}
StartAppOnBoot.java
public class StartAppOnBoot extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() == null) {
return;
}
//if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean startupAfterBoot = prefs.getBoolean("serenity_boot_startup", false);
if (startupAfterBoot) {
Intent i = new Intent(context, MainActivity.class);
//i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.test.tv2"
tools:ignore="MissingLeanbackLauncher">
<uses-feature
android:name="android.software.leanback"
android:required="false" />
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<application
android:usesCleartextTraffic="true"
android:allowBackup="true"
android:icon="#drawable/ic_banner"
android:label="TV2"
android:supportsRtl="true"
tools:ignore="GoogleAppIndexingWarning"
android:banner="#mipmap/tv_banner_foreground">
<activity android:name="com.test.tv2.MainActivity"
android:screenOrientation="landscape"
android:theme="#style/Theme.Leanback"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.test.tv2.StartAppOnBoot"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<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" />
</manifest>
Related
I'm currently working on a simple android app. The idea is, it changes the wallpaper automatically after 12 A.M or when the date is changed. It's working on android Oreo and lower versions, however, it doesn't work on android 9(Pie). However, if I change the date manually from the setting of the phone, it calls the broadcast. I have googled a lot, and some suggested to register the broadcast on your java codes instead of Manifest. Unfortunately, it didn't work.
I have tested this question in Stackoverflow.
First of all, changing the date is not part of implicit broadcasts, secondly, I assumed it is. then I changed the codes but it didn't work.
Now I'm gonna provide some codes of my broadcast:
DailyBroadcastReceiverService
public class DailyBroadcastReceiverService extends Service {
private BroadcastReceiver dailyZekrBr;
private Context context;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
registerDailyZekrReceiver();
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(dailyZekrBr);
dailyZekrBr = null;
}
private void registerDailyZekrReceiver() {
context= this.getApplicationContext();
Log.d("Register", "onStart: Now gonna register the broadcast receiver on Daily Boadcast receiver");
dailyZekrBr = new DailyZekrBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addCategory(Intent.CATEGORY_DEFAULT);
filter.addAction("android.intent.action.ACTION_TIME_CHANGED");
filter.addAction("android.intent.action.TIME_SET");
filter.addAction("android.intent.action.DATE_CHANGED");
filter.addAction("android.intent.action.TIMEZONE_CHANGED");
this.registerReceiver(dailyZekrBr, filter);
}
}
DailyZekrBroadcastReceiver
public class DailyZekrBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("DailyZekrBroadcast", "onReceive:The broadcast is called ");
DailyZekrHandler.setTodayImage(context);
}
}
setTodayImage
public static void setTodayImage(Context context) {
int todayImage = DailyZekrHandler.nameOfTheWeek();
DisplayMetrics metrics = new DisplayMetrics();
WindowManager window = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
window.getDefaultDisplay().getMetrics(metrics);
Log.d("DailyZekrBroadCast", "trying to change imge: " + todayImage);
if(todayImage != DailyZekrHandler.getTodayImage(context)) {
DailyZekrHandler.storeTodayImage(context);
Bitmap tempbitMap = BitmapFactory.decodeResource(context.getResources(), todayImage);
Bitmap bitmap = Bitmap.createScaledBitmap(tempbitMap, metrics.widthPixels, metrics.heightPixels, true);
WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
wallpaperManager.setWallpaperOffsetSteps(1, 1);
wallpaperManager.suggestDesiredDimensions(metrics.widthPixels, metrics.heightPixels);
try {
wallpaperManager.setBitmap(bitmap);
Log.d("DailyZekrBroadCast", "today_image: " + todayImage);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ellia.dailyzekr">
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-9778979220370457~9773548477"/>
<receiver android:name=".core.DailyZekrBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_TIME_CHANGED"/>
<action android:name="android.intent.action.TIME_SET"/>
<action android:name="android.intent.action.DATE_CHANGED"/>
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
</intent-filter>
</receiver>
<service android:name=".core.DailyBroadcastReceiverService"/>
<activity android:name=".SplashActivity" android:theme="#style/Theme.AppCompat.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
</activity>
</application>
</manifest>
I'm trying to test an Android app I'm working on, I can see the app on the emulator but I get an error whenever I try to install it on the phone.
I've already tried all the methods listed on other similar posts but the solutions don't seem to work on my situation.
A big part of me tells me the problem is there's repetition in the activity name as in Error: Activity class {**com.example.thejourney/**com.example.thejourney.WelcomeActivity} does not exist. instead of com.example.thejourney.WelcomeActivity. If that's the case, I don't know where it's coming from, I've checked.
Welcome Activity
public class WelcomeActivity extends Activity {
public static int SPLASH_TIME_OUT = 5000;
LinearLayout l1,l2;
ImageView logo;
Animation uptodown,downtoup;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_welcome);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent mainIntent = new Intent(WelcomeActivity.this, MainActivity.class);
startActivity(mainIntent);
finish();
}
}, SPLASH_TIME_OUT);
logo = (ImageView) findViewById(R.id.logo);
l1 = (LinearLayout) findViewById(R.id.l1);
l2 = (LinearLayout) findViewById(R.id.l2);
uptodown = AnimationUtils.loadAnimation(this,R.anim.uptodown);
downtoup = AnimationUtils.loadAnimation(this,R.anim.downtoup);
l1.setAnimation(uptodown);
l2.setAnimation(downtoup);
}}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.thejourney">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"
/>
<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"
android:usesCleartextTraffic="true">
<activity
android:name=".WelcomeActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ProfileActivity"
android:parentActivityName=".MainActivity" />
<activity
android:name=".AboutActivity"
android:parentActivityName=".MainActivity" />
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main"
android:theme="#style/AppTheme.NoActionBar" />
<meta-data
android:name="preloaded_fonts"
android:resource="#array/preloaded_fonts" />
</application>
</manifest>
Your device might not work because developer mode and USB debugging might not be enabled. Try following the steps in https://developer.android.com/studio/run/device#setting-up.
My LocalBroadcastManager callback function dosen' receive messeges. Can someone tell my why?
I try to do it on my Samsung Galaxy S3 mini (4.1.2 -Jelly Bean, API 16).
SenderClass:
public static final String BROADCAST = "com.android.SOME_BROADCAST";
private Context context;
public SenderClass(Context context) {
this.context = context;
//...
Intent intent = new Intent(BROADCAST);
//intent.putExtra(EXTRA_SOMEEXTRA, "some extra");
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
//just to keep it simple i do it here
}
MainActivity
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive"); //this is never called!
}
};
#Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume()");
LocalBroadcastManager.getInstance(this).registerReceiver(
broadcastReceiver,
new IntentFilter(SenderClass.BROADCAST)
);
}
#Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause()");
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
}
edit: here the manifest
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android....">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".Activities.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".Services.MyService"
android:enabled="true"
android:exported="false"></service>
</application>
</manifest>
Try this step:-
Register your broadcast in onCreate and Unregister broadcast in onDestroy of Activity.
Thanks,
It may helpful for you.
I'm developing an app that should detect NFC tags.
My problem is that my activity reopens every time the app scans a tag. It should just open when the app is closed. But when it is active, I just want the data from the tag.
Manifest:
?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.corinna.nfc_testapp" >
<uses-permission android:name="android.permission.NFC" />
<uses-sdk android:minSdkVersion="14"/>
<uses-feature android:name="android.hardware.nfc" android:required="true" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name"
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="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
</application>
</manifest>
Activity onCreate & handleIntent
rotected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Fragment ReadOrWrite
fRead = (Fragment_Read) Fragment.instantiate(getApplicationContext(), Fragment_Read.class.getName(), null);
Fragment_ReadOrWrite fReadOrWrite = (Fragment_ReadOrWrite) Fragment.instantiate(getApplicationContext(), Fragment_ReadOrWrite.class.getName(), null);
fReadOrWrite.setFragment_Read(fRead);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.id_activity_main, fReadOrWrite);
fragmentTransaction.commit();
//NFC
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
handleIntent(getIntent());
}
private void handleIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
String type = intent.getType();
if (MIME_TEXT_PLAIN.equals(type)) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NdefReaderTask ndefReader = new NdefReaderTask(fRead);
ndefReader.execute(tag);
} else {
System.out.println("Wrong mime type: " + type);
}
}
}
Just use launchMode="singleTop" in your main activity manifest.
This will ensure that if your activity is at the top of your task stack, it will not be recreated.
Be aware that onCreate is no longer called in this case, so if you want to read the content from intent, you need to override the onNewIntent Activity method.
I want to force my app to run the LoginActivity if there is no account present.
I've done the following but still when I launch the app in the emulator, I have MainActivityTest coming up.
For now I have no Account for my app on the emulator so I expect to simply see the Login screen. However, what I see seems like the MainActivityTest is running
public class AccountAuthenticator extends AbstractAccountAuthenticator {
private Context context;
private static final String TAG = "AccountAuthenticator";
public AccountAuthenticator(final Context context) {
super(context);
this.context = context;
}
#Override
public Bundle addAccount(final AccountAuthenticatorResponse response,
final String accountType, final String authTokenType,
final String[] requiredFeatures, final Bundle options) throws NetworkErrorException {
final Intent intent = new Intent(context, LoginActivity.class);
final Bundle bundle = new Bundle();
bundle.putParcelable(KEY_INTENT, intent);
return bundle;
}
...
}
public class AccountAuthenticatorService extends Service {
private static AccountAuthenticator AUTHENTICATOR;
public IBinder onBind(Intent intent) {
return intent.getAction().equals(ACTION_AUTHENTICATOR_INTENT) ? getAuthenticator()
.getIBinder() : null;
}
private AccountAuthenticator getAuthenticator() {
if (AUTHENTICATOR == null)
AUTHENTICATOR = new AccountAuthenticator(this);
return AUTHENTICATOR;
}
}
public class LoginActivity extends RoboSherlockAccountAuthenticatorActivity {
#Override
public void startActivity(Intent intent) {
if (intent != null && ACTION_VIEW.equals(intent.getAction()))
intent.addCategory(CATEGORY_BROWSABLE);
super.startActivity(intent);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
}
}
My AndroidManifest.xml is like below
<application
android:icon="#drawable/ic_launcher"
android:label="myapp" >
<activity
android:name=".ui.ui.MainActivityTest"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.myapp.AccountAuthenticatorService"
android:exported="false"
android:process=":auth" >
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="#xml/authenticator" />
</service>
<activity
android:name="com.myapp.LoginActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:excludeFromRecents="true" >
<!--
No intent-filter here! This activity is only ever launched by
someone who explicitly knows the class name
-->
</activity>
</application
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
It would be simple if you put value in shared preference once if you complete login process.
and every time when you launch application, once check the sharedpreference value and navigate to activities
Boolean mobile_register_flag = sharedpref.getBoolean("mobile_register_flag", false);
if (!mobile_register_flag) {
Intent intent = new Intent(FlashView.this,
RegisterActivity.class);
startActivity(intent);
} else {
Intent intent = new Intent(FlashView.this,
ActivityTwo.class);
startActivity(intent);
}
When you launch the app in the emulator, MainActivityTest coming up because your AndroidManifest has:
<activity
android:name=".ui.ui.MainActivityTest"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
If you want to launch LoginActivity by default, use
<activity
android:name="com.myapp.LoginActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:excludeFromRecents="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Else, if you want to display LoginActivity as the first activity based on some conditions, then
In android manifest, keep MainActivityTest as the default
activity
In MainActivityTest->onCreate, check the condition
and if condition is true, launch LoginActivity