I'm trying to use build-in android's Application.class, but every time I want to use it, I get a NullPointerException. I'm going to share some pieces of code to show how I'm accessing my custom class, which extends Application:
This is the class I'm using:
public class SharedProperties extends Application {
private String currentCategory;
private String dataNews;
public SharedProperties() {
super();
}
public String getCurrentCategory() {
return currentCategory;
}
public void setCurrentCategory(String currentCategory) {
this.currentCategory = currentCategory;
}
public String getDataNews() {
return dataNews;
}
public void setDataNews(String dataNews) {
this.dataNews = dataNews;
}
}
...and this how I set and get values from it:
SharedProperties shared = ((SharedProperties)getApplication());
shared.setCurrentCategory(categories[currentCategory]);
shared.setDataNews(rssList.get(position).getData());
......
SharedProperties shared = ((SharedProperties)getApplication());
String category = shared.getCurrentCategory();
String newstext = shared.getDataNews();
Is the way I'm accessing it wrong or I miss something into the SharedProperties.class?
Here is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.news.reader"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="4" />
<application android:name="SharedProperties" android:icon="#drawable/logo" android:label="#string/app_name">
<activity android:name="Splash"
android:label="#string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="Home"
android:label="#string/app_name"
android:screenOrientation="sensor"
android:configChanges="keyboardHidden|orientation" />
<activity android:name="News"
android:label="#string/app_name"
android:screenOrientation="sensor"
android:configChanges="keyboardHidden|orientation" />
</application>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
</manifest>
Put the android:name attribute in the <application> entry which contains all your activities, not as a separate entity. Change it to be the fully-qualified name of the class (e.g., com.this.is.your.package.SharedPreferences).
Also, don't do this. Use a singleton. Please.
For starters, the name of your Application class is SharedProperties, not MyApp, so it should be cast to that.
Secondly, in order for Android to know to use your custom Application, you need to say so in your AndroidManifest.xml like so:
<application
android:name="SharedProperties"
android:icon="#drawable/icon"
android:label="#string/app_name">
I had similar problem, don exactly remember what i did , but do try adding
public SharedProperties()
{
super();
}
Related
I built an app and I have different classes, and first I got an error like this when I tried to run the app
Cannot fit requested classes in a single dex file (# methods: 66087 > 65536)
I followed some instructions from Google and I added to my build.gradle
this dependency
implementation 'com.android.support:multidex:1.0.3'
and to the defaultConfig this
multiDexEnabled true
In my manifest xml I added this
android:name="android.support.multidex.MultiDexApplication"
but its highlighted with red color and when I move the cursor over it says
Unresolved class MultiDexApplication
When I try to run the app again it throws me
No file known for: classes2.dex
Known maps: {RelativeFile{base=/Users/***/AndroidStudioProjects/****/app/build/intermediates/dex/debug/mergeDexDebug/out/classes.dex, path=classes.dex, type=DIRECTORY}=classes.dex, RelativeFile{base=/Users/****/AndroidStudioProjects/****/app/build/intermediates/dex/debug/mergeProjectDexDebug/out/classes.dex, path=classes.dex, type=DIRECTORY}=classes3.dex, RelativeFile{base=/Users/*****/AndroidStudioProjects/****/app/build/intermediates/dex/debug/mergeExtDexDebug/out/classes2.dex, path=classes2.dex, type=DIRECTORY}=classes4.dex}
This is the MainActivity Class
package com.example.drivieapp;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Intent i = new Intent(this, screenNotLogged.class );
Thread timer = new Thread() {
public void run() {
try {
sleep(3100);
}
catch(InterruptedException e) {
e.printStackTrace();
}
finally {
startActivity(i);
finish();
}
}
};
timer.start();
}
}
Can you please explain me what I have to do? I google the solution but didn't understand too much. Thank you very much!
Manifest xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="****">
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="Drivie"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
android:name="android.support.multidex.MultiDexApplication"
>
<activity android:name=".SignupCarrier"></activity>
<activity android:name=".carrierSignupHint" />
<activity android:name=".home" />
<activity android:name=".SignupSender" />
<activity android:name=".signup" />
<activity android:name=".screenNotLogged" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Sorry if this one is a stupid question.
I am trying to do this Android global variable
I added a new class but I cannot call the methods inside the class. I get:
inconvertible types; cannot cast 'android.app.Application' to 'com.app.android.appname.classname'
here is the code inside the new class:
public class GlobalVars extends Application {
private static int lvl;
public int getLvl() {
return lvl;
}
public void setLvl(int lvl) {
lvl = this.lvl;
}
}
my manifest is:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.app.android.guessinggame">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
android:screenOrientation="sensorLandscape"
<activity android:name=".MainActivity">
android:screenOrientation="sensorLandscape"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".enterword"></activity>
<activity android:name=".player1turn"></activity>
<activity android:name=".aiturn"></activity>
<activity android:name=".chooselevel"></activity>
<application android:name=".GlobalVars"/>
</application>
</manifest>
then in the activity:
protected void select1 (View view) {
((GlobalVars) this.getApplication()).setLvl(1); <-------- error
Intent intent = new Intent(this, enterword.class);
startActivity(intent);
}
this produces:
inconvertible types; cannot cast 'android.app.Application' to 'com.app.android.guessinggame.GlobalVars'
Caused by: java.lang.ClassCastException: android.app.Application cannot be cast to com.app.android.guessinggame.GlobalVars
Solved
in the manifest, the name must be defined. not add. changed it to:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.app.android.guessinggame">
<application
android:name=".GlobalVars"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
android:screenOrientation="sensorLandscape"
<activity android:name=".MainActivity">
android:screenOrientation="sensorLandscape"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".enterword"></activity>
<activity android:name=".player1turn"></activity>
<activity android:name=".aiturn"></activity>
<activity android:name=".chooselevel"></activity>
</application>
</manifest>
now it works.
If you want to make GlobalVars your Application class in Android you have to make it extend android.app.Application.
You also have to declare this in the Manifest.
On a side note, there is only one instance of Application. You may not need to make lvl static.
public class GlobalVars extends Application{
private static int lvl;
public int getLvl() {
return lvl;
}
public void setLvl(int lvl) {
lvl = this.lvl;
}
}
In the manifest you have to have:
<application
android:name=".GlobalVars"
...
</application>
In your activity, in onCreate() for example:
((GlobalVars) getApplication()).getLvl();
I have tried this on a few android phones with no luck (i did start the app once).
This was mostly generated from android studio 1.3.2 and from some questions like this and that and the other.
Perhaps someone can point out what i am doing wrong.
Thanks
edit: moved receiver inside app, but no joy.
edit2: added missing permissions for receiver. now seems to work on a nexus 4. but not on the kindle fire or the at&t tablets. although it seems to come right away if i press the circle icon on the azpen.
edit3: seems to work sometimes on the fires now.
package acme.startup;
import android.content.*;
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent activityIntent = new Intent(context, MainActivity.class);
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(activityIntent);
}
}
}
package acme.startup;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id=item.getItemId();
if(id==R.id.action_settings)
return true;
return super.onOptionsItemSelected(item);
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="acme.startup" >
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver
android:name=".BootReceiver"
android:label="BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<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>
</application>
</manifest>
Every Component must be declared inside application tag into manifest. Here you declared receiver outside of application tag. Read Structure of the Manifest File.
Correct manifest wil be
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="acme.startup" >
<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=".BootReceiver"
android:label="BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
You have to add permission to manifest file. Add this before your <application> tag :
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
I want to add a service to my manifest but it gives a warning in.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.aura_apps.tygo_asbroek.intentexample" >
<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>
<activity
android:name=".SecondActivity"
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=".TygoIntentService"
>
</service>
</application>
Here is the Java code:
package com.aura_apps.tygo_asbroek.intentexample;
public class TygoIntentService extends IntentService {
private static final String TAG = "com.bluelionapps.intentexample";
public TygoIntentService(String name) {
super("TygoIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
//This is what the service does
Toast toast = Toast.makeText(getApplicationContext(), "Service Lauched", Toast.LENGTH_SHORT);
toast.show();
}
}
Here you see my complete Manifest but .TygoIntentService says TygoIntentService.java doesn't have a default constructor of my app. If i run it, it's just working but I want to know if this can give any problems in the future and if it gives one what i need to do.
Remove String name parameter from the constructor:
public TygoIntentService() {
super("TygoIntentService");
}
If you do not use/need the name String there, just remove the constructor, and let the compiler add it behind scenes by default.
I want to do a simple exercise with permissions. I need to define and enforce a custom permission for my app called "DangerousApp" And after that I need to set up another app, "PermissionsLab" in such a way that it could use the "DangerousApp" but when I try to start the "DangerousApp" using "PermissionLab" I get an error: "Unfortunately, PermissionsLab has stopped"
AndroidManifest.xml of PermissionsLab:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="course.labs.permissionslab"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<!-- TODO - add uses-permission elements -->
<uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
<uses-permission android:name="course.labs.permissions.DANGEROUS_ACTIVITY_PERM"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".ActivityLoaderActivity"
android:label="#string/title_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".BookmarksActivity"
android:label="#string/title_permissions" >
</activity>
<activity
android:name=".GoToDangerousActivity"
android:label="#string/title_activity_customization" >
</activity>
</application>
</manifest>
AndroidManifest.xml of DangerousApp:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="course.labs.permissionslab"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<!-- TODO - add uses-permission elements -->
<uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
<uses-permission android:name="course.labs.permissions.DANGEROUS_ACTIVITY_PERM"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".ActivityLoaderActivity"
android:label="#string/title_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".BookmarksActivity"
android:label="#string/title_permissions" >
</activity>
<activity
android:name=".GoToDangerousActivity"
android:label="#string/title_activity_customization" >
</activity>
</application>
</manifest>
And the activity used to start DangerousApp:
package course.labs.permissionslab;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class GoToDangerousActivity extends Activity {
private static final String TAG = "Lab-Permissions";
private static final String DANGEROUS_ACTIVITY_ACTION = "course.labs.permissions.DANGEROUS_ACTIVITY";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.go_to_dangerous_activity);
Button startDangerousActivityButton = (Button) findViewById(R.id.start_dangerous_activity_button);
startDangerousActivityButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
startDangerousActivity();
}
});
}
private void startDangerousActivity() {
Log.i(TAG, "Entered startDangerousActivity()");
startActivity(new Intent(DANGEROUS_ACTIVITY_ACTION));
}
}
Thanks for your clarifications.
Permission help you to protect service, application, activity, ...
Here documentation:
http://developer.android.com/guide/topics/security/permissions.html#declaring
http://developer.android.com/guide/topics/security/permissions.html#manifest
for instance, if you want to protect an activity with a permission, in AndroidManifest declare a permission and put it on activity as this:
<manifest [...] >
<permission android:name="com.mycompany.MY_PERMISSION" android:protectionLevel="normal"
android:description="#string/permission_desc"
android:label="#string/permission_label" />
<application [...] >
<activity [...] android:permission="com.mycompany.MY_PERMISSION">
</activity>
</application>
</manifest>
In another application, if you want to call activity protected by permission, you have to add in AndroidManifest:
<uses-permission android:name="com.mycompany.MY_PERMISSION" />