My Manifest:
<application
android:name=".AppClass"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<meta-data
android:name="AA_DB_NAME"
android:value="mydb.db" />
<meta-data
android:name="AA_DB_VERSION"
android:value="1" />
<activity
android:name=".ActivityMain"
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>
Here AppClass:
public class AppClass extends Application {
public static Context context;
#Override
public void onCreate() {
super.onCreate();
ActiveAndroid.initialize(this);
context = getApplicationContext();
}
}
Model:
#Table(name = "Books")
public class Book extends Model {
#Column(name = "Author")
public String author;
#Column(name = "Title")
public String title;
public Book() {
super();
}
}
Save book and retrieve that:
Book b = new Book();
b.title = "TheFaultInOurStar";
b.author = "JohnGreen";
b.save();
ArrayList<Book> books = new Select().all().from(Book.class).execute();
Log.e("Log", "SizeOfBooks:" + books.size());
but when run the app i got this error:
Error inserting Title=TheFaultInOurStar Author=JohnGreen rolling Id=null
android.database.sqlite.SQLiteException: no such table: Books (code 1): , while compiling: INSERT INTO Books(Title,Author,Id) VALUES (?,?,?)
why Id field add to table schema?
i increase AA_DB_VERSION in manifest but error still remain.
even app in fresh run on other emulator and mobile phone got that error again.
where is problem?
Try put this meta-data inside application tag on your AndroidManifest.
<meta-data
android:name="AA_MODELS"
android:value="com.yourpackage.yourmodeldir.Book" />
Or if it doesn't fix the problem. Try to uninstall your app then reinstall it.
Related
I'm learning how to handle OneSignal Push Notifications on Android devices. The problem is, while the application is closed, when I receive a notification, even though I defined the neccessary functions (I guess) it still opens the "Splash Activity", which is defined as MAIN LAUNCHER in manifest. I need to open a different activity with the payload data in it. The link I've referenced from creating these codes is this and I've seen the reference on this answer. I'm only showing the relevant code since this project is classified.
Here is my Manifest file.
<application
android:name="packageName.CustomAppName"
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.onesignal.NotificationOpened.DEFAULT"
android:value="DISABLED"/>
<activity
android:name="anotherPackageName.SplashActivity"
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="anotherPackageName.PaymentActivity"
android:screenOrientation="portrait" />
<service
android:name="somepackagename.NotificationsForPayment"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE">
<intent-filter>
<action android:name="com.onesignal.NotificationExtender" />
</intent-filter>
</service>
</application>
Here is my application class where I define OneSignal service.
public class CustomAppName extends Application {
private static CustomAppName instance;
public static CustomAppName getInstance() {
return instance;
}
public void onCreate() {
super.onCreate();
OneSignal.startInit(this)
.setNotificationOpenedHandler(new CustomNotificationOpening())
.init();
instance = this;
}
}
Here is my CustomNotificationOpening class.
public class CustomNotificationOpening implements OneSignal.NotificationOpenedHandler {
#Override
public void notificationOpened(OSNotificationOpenResult notification) {
notification.notification.payload.additionalData.names();
JSONObject data = notification.notification.payload.additionalData;
Intent intent = new Intent(CustomAppName.getInstance(), PaymentActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("paymentModel", data);
CustomAppName.getInstance().startActivity(intent);
}
And here is my NotificationsForPayment class which extends from NotificationExtenderService.
public class NotificationsForPayment extends NotificationExtenderService {
#Override
protected boolean onNotificationProcessing(OSNotificationReceivedResult notification) {
NotificationExtenderService.OverrideSettings overrideSettings = new NotificationExtenderService.OverrideSettings();
overrideSettings.extender = new NotificationCompat.Extender() {
#Override
public NotificationCompat.Builder extend(NotificationCompat.Builder builder) {
// Sets the background notification color to Red on Android 5.0+ devices.
Bitmap icon = BitmapFactory.decodeResource(CustomAppName.getInstance().getResources(),
R.drawable.ic_os_notification_fallback_white_24dp);
builder.setLargeIcon(icon);
return builder.setColor(new BigInteger("FF0000FF", 16).intValue());
}
};
OSNotificationDisplayedResult displayedResult = displayNotification(overrideSettings);
}
I don't really know where I'm doing wrong. While the application is open, when I click the notification I can see that "notificationOpened" function is firing. But when it's closed, since I can't debug the program and the notification opens the splash activity, I knew the time for me was to ask this question because none of the answers I've found worked. Is there any way to open the other activity with specific data from the notification while the application was closed? Any help is appreciated, thank you so much.
Found where the error was.
<meta-data android:name="com.onesignal.NotificationOpened.DEFAULT"
android:value="DISABLED"/>
The value was supposed to be "DISABLE", not "DISABLED".
so, the updated code is:-
<meta-data android:name="com.onesignal.NotificationOpened.DEFAULT"
android:value="DISABLE"/>
My application created files with a custom Mime type and stores them on Google Drive. The app can search and reopen these files just fine too. However, when I click the file in the Google Drive app (not my own app) the open flow does not work.
The Chooser Intent shows as expected with just my application listed, but when I select my application the Google Drive app briefly shows a downloading progress bar that never starts and then says there is an internal error.
My setup is below, I'm hoping somebody can tell me what causes this. although I would assume nothing is actually contacting my app by this point. The developer console has been filled in correctly as far as I know.
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="...">
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:icon="#drawable/logo" android:label="#string/app_name"
android:allowBackup="true" android:theme="#style/AppTheme">
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<activity android:name=".MainActivity" android:label="#string/app_name"
android:launchMode="singleTop" android:theme="#style/AppTheme">
<meta-data android:name="com.google.android.apps.drive.APP_ID" android:value="id=..." />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.apps.drive.DRIVE_OPEN" />
<data android:mimeType="#string/app_mime" />
<data android:mimeType="#string/file_mime" /> <!-- matches the file im clicking -->
</intent-filter>
</activity>
</application>
Activity
public class MainActivity extends Activity {
private static final String ACTION_DRIVE_OPEN = "com.google.android.apps.drive.DRIVE_OPEN";
private static final String EXTRA_DRIVE_OPEN_ID = "resourceId";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
#Override
protected void onResume() {
super.onResume();
handleIntent();
}
private void handleIntent() {
Intent intent = getIntent();
if (ACTION_DRIVE_OPEN.equals(intent.getAction())) {
if (intent.getType().equals(getString(R.string.file_mime))) {
String fileId = intent.getStringExtra(EXTRA_DRIVE_OPEN_ID);
if (fileId != null && !"".equals(fileId)) {
...
} else {
Log.e(TAG, "Drive_Open has no valid file id - " + fileId);
}
} else {
Log.e(TAG, "Drive_Open called on the wrong mime type - " + intent.getType() + " found, " + getString(R.string.file_mime) + " required");
}
}
}
After some testing this seems to happen after there is a timeout between the drive app connecting to the server to retrieve information and passing it to the other app (or any other fault).
The initial problem will give you a meaningful error but then the drive app seems to maintain a cache or something which cases the above error to be displayed on all future attempts.
The solution is to either clear the data of both apps (which can be problematic) or (I found easier) re-install the app you are developing/testing. Either method stops this problem reoccurring.
The question can be asked in two ways:
- How I can make some processing of variables and data before launching the main activity?
- How I set the main launcher activity based on some logic? i.e. before viewing an activity from a set of activities, I should retrieve data from preferences. And this should be done only for the 1st usage without preferences activity to be saved in the back button stack.
public static String getProfile(Context context) {
SharedPreferences mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
// String profile = mSharedPreferences.getString("pref_profile_list", "-1");
String profile = mSharedPreferences.getString("pref_login_list", "-1");
Log.i(TAG, profile);
return profile;
}
void init() {
String profile = getProfile(this);
Log.i(TAG, "getProfile " + profile);
switch (parseInt(profile)){
case 0:
startActivity(new Intent(this, firstActivity.class));
break;
case 2:
startActivity(new Intent(this, secondActivity.class));
break;
default:
Log.i(TAG, profile);
}
}
Thanks.
You can use the android:name="your class name" inside the <application> tag of the manifest file.
android:name :
The fully qualified name of an Application subclass implemented for the application. When the application process is started, this class is instantiated before any of the application's components.
The subclass is optional; most applications won't need one. In the absence of a subclass, Android uses an instance of the base Application class.
Example:
public class Platform extends Application {
public static String str="";
#Override
public void onCreate() {
super.onCreate();
str="I am executed first";
}
}
To execute Platform before any other application's component add this Platform class to manifest file of your project like below,
<application
android:name="com.example.Platform"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:largeHeap="true"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen" >
<activity
android:name="com.example.HomeActivity"
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>
Hope it helps.
For reference read http://developer.android.com/guide/topics/manifest/application-element.html
create a activity "UILApplication" for your resource initialization
and in the manifest include that
**android:name="com.example.UILApplication"**
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat.Light.DarkActionBar" >
<activity
android:name="com.example.HomePage"
android:label="#string/app_name"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
........
so that it will execute before your launch activity..
Hope this Helps you
The best option would be to use a Splash Screen.
The Splash Screen can be used for a variety of purposes including loading data, making calls to the server, showing the app logo and applying whatever logic you would want. You can think of it as an Activity which runs before your MainActivity and does the pre-processing, while showing a progress screen to the user.
You can create an Class by extends Application class
PreAppResources.Java
public class PreAppResources extends Application{
public static String execute="execute before mail activity";
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
System.out.println(execute);
}
}
AndroidManifest.xml
<application
android:allowBackup="true"
android:name="com.example.listtt.PreAppResources"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:largeHeap="true"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.listtt.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>
If its not working please let me know i will try to help you more.
To store values as global variables, I read that the Application class can be used. I intend to take username and password from the main activity, store them in application class variables and start a new activity, then fetch these values inside a service started in the new activity, however, I get null values on using the getter methods I defined in my application class.
My Application Class :
public class MyApp extends Application
{
private String uid;
private String upwd;
#Override
public void onCreate()
{
super.onCreate();
}
public void setUID(String value)
{
uid = value;
}
public void setPWD(String value)
{
upwd = value;
}
public String getUID()
{
return uid;
}
public String getPWD()
{
return upwd;
}
}
In My Main Activity:
public void setvalues()
{
unameval = Unametxtfield.getText().toString();
pswrdval = Pswrdtxtfield.getText().toString();
((MyApp)this.getApplicationContext()).setUID(unameval);
((MyApp)this.getApplicationContext()).setPWD(pswrdval);
}
Inside the Service My Second Activity:
public void fetchvalues()
{
String uname = ((MyApp).getApplicationContext()).getUID();
String upswrd = ((MyApp).getApplicationContext()).getPWD();
}
Android Manifest:
<application
android:name="MyApp"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<!-- A Service here -->
<service
android:name="Service1"
android:process=":myapp_service1" >
</service>
<!-- A service in which I do the fetching of uname and pswd -->
<service
android:name="Service2"
android:process=":myapp_Service2" >
</service>
<activity
android:name=".Second_Activity"
android:exported="false"
android:label="#string/activityname" >
<intent-filter>
<action android:name="android.intent.action.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="#string/Firstactivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Note: I read somewhere that application class wont work when you are using it over mutliple processes(which I think i'm doing), is this true?
Use SharedPreferences or a Singleton.
I am trying to open a new "activity" (C2M) in an Android app, and in that new activity open a socket with the ip address and port coming from the previous "activity" (called MeasActivity).
I have checked that the ip and address are correctly gotten in C2M (as strings), but the socket can not be created.
Part of the code is the following:
public class C2M extends Activity {
Socket socket;
private String serverIpAddress;
private String serverPort;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainmeas);
intentback = new Intent(this, MeasActivity.class);
Intent intent = getIntent();
serverIpAddress = intent.getStringExtra(MeasActivity.EXTRA_IP);
serverPort = intent.getStringExtra(MeasActivity.EXTRA_PORT);
try {
socket = new Socket(serverIpAddress, Integer.parseInt(serverPort));
} catch (Exception e) {
startActivity(intentback);
}
}
}
Also, the manifest file is the following:
<uses-permission android:name="android.permission.INTERNET" />
<uses-sdk android:minSdkVersion="14" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".MeasActivity"
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="C2M"></activity>
</application>
I am not sure if I missing something, but as I said, I have issues creating the socket.
Thanks in advance for the help and advice you can provide.
gus