Suggest method to load libraries (.aar)dynamically in java application (.apk) - Android Studio

Pls Suggest method to load libraries (.aar) dynamically in android java application.
I have Tried below:
File file = Environment.getExternalStorageDirectory();
File jarFile = new File(file.getAbsolutePath()+File.separator + "myjarlib.jar");
dalvik.system.PathClassLoader myClassLoader = new dalvik.system.PathClassLoader("/storage/emulated/0/myjarlib.jar", ModuleLoader.class.getClassLoader());
myClassLoader.findLibrary("myjarliib.jar");
Enumeration<URL> en = myClassLoader.getResources("META-INF");
//Enumeration<URL> en = getClass().getClassLoader().getResources("META-INF");
List<String> profiles = new ArrayList<>();
while (en.hasMoreElements()) {
URL url = en.nextElement();
JarURLConnection urlcon = (JarURLConnection) (url.openConnection());
try (JarFile jar = urlcon.getJarFile() {
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
String entry = entries.nextElement().getName();
System.out.println(entry);
Log.d("tag" ,entry );
}
}
}
Class classToLoad = Class.forName("MyClass.class", true, myClassLoader); -----> I am getting ClassNotFound exception here. Pls suggest .
ModuleLoader.java
***************************************************************************************************************************************
package com.tel.myapplication;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import com.tel.myapplication.IPeripheral;
public class ModuleLoader {
private static List<URL> urls = new ArrayList<URL>();
// to retrieve the unknown list of jar files contained in the directory folder
// in my case it was in the SDCard folder
// link to create a SDCard directory on the Eclipse emulator
// http://blog.lecacheur.com/2010/01/14/android-avoir-acces-a-une-carte-memoire-dans-lemulateur/
// retrieve the classes of all this jar files and their URL (location)
private static List<String> getModuleClasses(String folder)
{
List<String> classes = new ArrayList<String>();
//we are listing the jar files
File[] files = new File(folder).listFiles(new ModuleFilter());
for(File f : files)
{
JarFile jarFile = null;
try
{
//we open the jar file
jarFile = new JarFile(f);
//we recover the manifest
Manifest manifest = jarFile.getManifest();
//we recover the class name of our peripherals thanks to ours manifest
String moduleClassName = manifest.getMainAttributes().getValue("Module-Class");
classes.add(moduleClassName);
urls.add(f.toURI().toURL());
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if(jarFile != null)
{
try
{
jarFile.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
return classes;
}
private static class ModuleFilter implements FileFilter {
@override
public boolean accept(File file) {
return file.isFile() && file.getName().toLowerCase().endsWith(".jar");
}
}
//This function loads the jar file into the dalvik system
// retrieves the associated classes using its name
// and try to know if the loaded classes are implementing our interface
public static List<IPeripheral> loadModules(String folder, Context CurrentContext) {
List<IPeripheral> modules = new ArrayList<IPeripheral>();
List<String> classes = getModuleClasses(folder);
int index = 0;
for(String c : classes)
{
try
{
dalvik.system.PathClassLoader myClassLoader = new dalvik.system.PathClassLoader(urls.get(index).toString(), ModuleLoader.class.getClassLoader());
Class<?> moduleClass = Class.forName(c, true, myClassLoader);
//check and cast to an interface, then use it
if(IPeripheral.class.isAssignableFrom(moduleClass))
{
@SuppressWarnings("unused")
Class<IPeripheral> castedClass = (Class<IPeripheral>)moduleClass;
IPeripheral module = (IPeripheral)moduleClass.newInstance();
modules.add(module);
}
index++;
}
catch (ClassNotFoundException e1)
{
e1.printStackTrace();
}
catch (InstantiationException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
}
return modules;
}
}
IPeripheral
package com.tel.myapplication;
public interface IPeripheral {
public boolean Initialize();
public boolean configure();
public boolean execute();
public String GetName();
}

To dynamically load libraries (.aar) in a Java application (.apk), you can use the following steps:
1# Download the library file (.aar) and save it in the "libs" folder of your Android project.
2# In your Java code, use the "DexClassLoader" class to load the library dynamically. You can use the following code snippet as an example:
String libraryPath = context.getFilesDir() + "/libs/your-library.aar";
DexClassLoader classLoader = new DexClassLoader(libraryPath, context.getCacheDir().getPath(), null, context.getClassLoader());
Class<?> libraryClass = classLoader.loadClass("com.your.library.ClassName");
In this example, "context" refers to the Android application context, "your-library.aar" is the name of the library file, and "com.your.library.ClassName" is the fully qualified name of the class you want to load from the library.
3# Once the library is loaded, you can use it in your Java code as you would with any other library. For example, you can call methods on objects from the library or create new objects from classes in the library.
Note that dynamically loading libraries can be more complex than using static libraries, and requires careful handling of class loading and versioning. You should ensure that the library you are loading is compatible with your application and has been thoroughly tested before using it in production.

Related

[Q] return a modified copy of original method

Hey guys,
I've just started experimenting with some coding, picked up a few tutorials and made some stuff work.
Now i'm stuck at a point where i want to return a modded version of a method which will replace the original method.
This is what i have so far.
Code:
package mjxl.xposed.cm11;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
public class CM11notifications implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
if (lpparam.packageName.equals("com.android.systemui")) {
ClassLoader classLoader = lpparam.classLoader;
XC_MethodReplacement methodreplacer = new XC_MethodReplacement() {
protected Object replaceHookedMethod(
XC_MethodHook.MethodHookParam paramAnonymousMethodHookParam)
throws Throwable {
return *WHAT DO I PUT HERE?? *;
}
};
XposedHelpers.findAndHookMethod("com.android.systemui.MmsConfig", classLoader, "applyLegacyRowBackground", methodreplacer);
}
}
}
I want to return a copy of "applyLegacyRowBackground" with some edits, so it will take my layouts.
Now i know i have to return it where "Integer.valueOf(255); is, but how to ?
Can anyone guide me ?
Here's the method which i want to place there.
Code:
protected void applyLegacyRowBackground(StatusBarNotification sbn, View content) {
if (sbn.getNotification().contentView.getLayoutId() !=
R.layout.notification_template_base_mjxl) {
int version = 0;
try {
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(sbn.getPackageName(), 0);
version = info.targetSdkVersion;
} catch (NameNotFoundException ex) {
Log.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex);
}
if (version > 0 && version < Build.VERSION_CODES.GINGERBREAD) {
content.setBackgroundResource(R.drawable.notification_row_legacy_bg_mjxl);
} else {
content.setBackgroundResource(R.drawable.notification_bg_mjxl);
}
}
}
Since the method you're replacing is void (it returns nothing): `return None;`.
PS. You're trying to hook `applyLegacyRowBackground()` instead of `applyLegacyRowBackground(StatusBarNotification, View)`. You should pass the arguments' classes to findAndHookMethod(…), for example:
Code:
XposedHelpers.findAndHookMethod("com.android.systemui.MmsConfig", classLoader, "applyLegacyRowBackground", StatusBarNotification.class, View.class, methodreplacer);
If you can't access the class directly (because it's not in the SDK, for example), pass its full class name as a string instead (e.g. "android.view.View" instead of `View.class`).

[Q] writing txt file

I want to write a text file. But I am not sure how writing down works in Android. Here is my code:
Code:
EditText textbox1 = (EditText) findViewById(R.id.editText);
EditText textbox2 = (EditText) findViewById(R.id.editText2);
EditText textbox3 = (EditText) findViewById(R.id.editText3);
public void writeToPhonebook(View v) {
Button button=(Button) v;
try {
File fajl = new File("phonebook.txt");
Writer writer;
writer= new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fajl, true), "UTF-8"));
writer.append(textbox1.getText() + "\t" + textbox2.getText() + "\t" + textbox3.getText());
writer.write("\r\n");
writer.close();
textbox1.setText("");
textbox2.setText("");
textbox3.setText("");
textbox1.requestFocus();
}
catch (IOException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
ex.printStackTrace();
}
}
can I just leave phonebook.txt or need to put something else? Because with this code apk can't even start on emulator.
OK I done this previus. I now need to load data from text file into table (table layout with 3 columns). Is it possible for application to determine number of needed rows without me adding certain number. Because that data will be changed.
You need permissions to write a file, you set them in the AndroidManifest xml (Every Android Studio project has their own manifest, set it in your project)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Then you need to open a file for input/output... You do this in whatever.java
Code:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import android.util.Log;
public class FileOperations {
public FileOperations() {
}
public Boolean write(String fname, String fcontent){
try {
String fpath = "/sdcard/"+fname+".txt";
File file = new File(fpath);
// If file does not exists, then create it
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(fcontent);
bw.close();
Log.d("Suceess","Sucess");
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public String read(String fname){
BufferedReader br = null;
String response = null;
try {
StringBuffer output = new StringBuffer();
String fpath = "/sdcard/"+fname+".txt";
br = new BufferedReader(new FileReader(fpath));
String line = "";
while ((line = br.readLine()) != null) {
output.append(line +"n");
}
response = output.toString();
} catch (IOException e) {
e.printStackTrace();
return null;
}
return response;
}
}
What is easier to display data from text file in: TableLayout or ViewList? If not sure total number of rows? Is there something for scrooling through it if can't fit the screen?
Scrollview
Grimspiller said:
What is easier to display data from text file in: TableLayout or ViewList? If not sure total number of rows? Is there something for scrooling through it if can't fit the screen?
Click to expand...
Click to collapse
1) Yes. Android provide scrollview to scroll on your query.
A. Horizontal scrollview
B. Vertical Scrollview.
Also you can you onTextwatcher() to check if the field size increase , onAfterTextchanged() method you can resize the box is.
private final TextWatcher passwordWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
textView.setVisibility(View.VISIBLE);
}
public void afterTextChanged(Editable s) {
if (s.length() == 0) {
textView.setVisibility(View.GONE);
} else{
textView.setText("You have entered : " + passwordEditText.getText());
}
}
};
I found this tutorial for multicolumn ListView on techlovejump.com ,but data for it is hardcoded. I am not sure is it suitable for dynamic data adding from text file.
Dynamic Data
Grimspiller said:
I found this tutorial for multicolumn ListView on techlovejump.com ,but data for it is hardcoded. I am not sure is it suitable for dynamic data adding from text file.
Click to expand...
Click to collapse
hey, As you see on after afterTextChanged(Editable s)
You can again call your table structure code to design it as per size.
I think you should try it once.
Share some amount of code if you find it difficult. I will help you afterTextChanged(Editable s).
I don't need to write text but to read it. Can you look at this code and tell me what is the problem? It can't find the file.
Code:
void showData(){
File fajl = new File("phonebook.txt");
try {
BufferedReader br = new BufferedReader(new FileReader(fajl));
String line;
try {
while ((line = br.readLine()) != null) {
TableRow tr = new TableRow(this);
tr.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
TextView im = new TextView(this);
im.setText(line);
im.setTextColor(Color.BLACK);
im.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
tr.addView(im);
tablel.addView(tr, new TableLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
button2.setOnClickListener(new View.OnClickListener() {
[user=439709]@override[/user]
public void onClick(View v) {
showData();
}
});
I have added to xml TableLayout and one row as header.
I use this for writing to text file:
Code:
button.setOnClickListener(new View.OnClickListener() {
[user=439709]@override[/user]
public void onClick(View v) {
try {
FileOutputStream fos = openFileOutput("phonebook.txt", Context.MODE_WORLD_READABLE);
OutputStreamWriter osw = new OutputStreamWriter(fos);
osw.append(textbox1.getText().toString() + "\t" + textbox2.getText().toString() + "\t" + textbox3.getText().toString());
osw.write("\r\n");
osw.close();
textbox1.setText("");
textbox2.setText("");
textbox3.setText("");
textbox1.requestFocus();
} catch (IOException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
ex.printStackTrace();
}
}
});
Debbuger says it's writting file and lines just fine. But why I can't read it?
It creates "files" folder inside my app folder. And inside files it is phonebook.txt.

Gmail No Email application installed error in logcat

So, I have written an app that emails a file on every boot iteration. I flashed a new ROM and now it isnt working. I reboot and run a logcat on boot and see that the logcat and or gmail is complaining about no e-mail application being installed.
The error seems to be:
Code:
05-06 11:53:52.813 2514 2624 I Gmail : getAccountsCursor
05-06 11:53:52.814 2514 2625 D ActivityThread: Loading provider com.google.android.gmail.provider;com.android.mail.notifier;com.google.android.gm.email.provider;com.google.android.gm.email.notifier: com.android.email.provider.EmailProvider
05-06 11:53:53.282 935 2233 W ActivityManager: Unable to start service Intent { cmp=me.bluemail.mail/com.android.emaileas.service.AttachmentService } U=0: not found
05-06 11:53:53.314 935 2081 W ActivityManager: Unable to start service Intent { cmp=me.bluemail.mail/com.android.emaileas.service.AttachmentService } U=0: not found
05-06 11:53:53.452 2514 2685 I Gmail : No Email application installed
05-06 11:53:53.452 2514 2685 I EmailMigration: No data to migrate
05-06 11:53:53.452 2514 2685 W EmailMigration: No Exchange migration, not the right Email provider version
I do in fact have gmail installed and i went as far as installing a 3rd party email client.
The code I have is an smtp client written by someone else that has been integrated with my code. Like i stated before, everything worked before the flash. I actually figured the issue out last time but cant remember the solution I implemented.
I came from DU 5.1 and moved to DU 6.0. I flashed 4 different ROMs in hopes that it was the ROM but this was not the case.
I am using a rooted Nexus 6 and developing on Linux with no IDE.
The SMTP Client:
GmailSender.java
Code:
package com.keysender;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.ByteArrayInputStream;
import android.util.Log;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import java.util.Properties;
import java.security.Security;
import javax.activation.DataSource;
import javax.activation.DataHandler;
import javax.mail.internet.MimeMessage;
import javax.mail.PasswordAuthentication;
import javax.mail.internet.InternetAddress;
public class GmailSender extends javax.mail.Authenticator {
private String mailhost = "smtp.gmail.com";
private String user;
private String password;
private Session session;
static {
Security.addProvider(new com.keysender.JSSEProvider());
}
public GmailSender(String user, String password) {
this.user = user;
this.password = password;
try {
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.host", mailhost);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.quitwait", "false");
session = Session.getDefaultInstance(props, this);
}
catch(Exception e) {
e.printStackTrace();
Log.d("ERROR ", e.getMessage(), e);
}
}
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, password);
}
public synchronized void sendMail(String subject, String body, String sender, String recipients) throws Exception {
try{
MimeMessage message = new MimeMessage(session);
DataHandler handler = new DataHandler(new ByteArrayDataSource(body.getBytes(), "text/plain"));
//DataHandler handler = new DataHandler(new ByteArrayDataSource(body.getBytes(), "message/rfc822"));
message.setSender(new InternetAddress(sender));
message.setSubject(subject);
message.setDataHandler(handler);
if (recipients.indexOf(',') > 0)
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients));
else
message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipients));
Transport.send(message);
}catch(Exception e){
e.printStackTrace();
}
}
public class ByteArrayDataSource implements DataSource {
private byte[] data;
private String type;
public ByteArrayDataSource(byte[] data, String type) {
super();
this.data = data;
this.type = type;
}
public ByteArrayDataSource(byte[] data) {
super();
this.data = data;
}
public void setType(String type) {
this.type = type;
}
public String getContentType() {
if (type == null)
return "application/octet-stream";
else
return type;
}
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(data);
}
public String getName() {
return "ByteArrayDataSource";
}
public OutputStream getOutputStream() throws IOException {
throw new IOException("Not Supported");
}
}
}
JSSEProvider.java
Code:
package com.keysender;
import java.security.AccessController;
import java.security.Provider;
public final class JSSEProvider extends Provider {
public JSSEProvider() {
super("HarmonyJSSE", 1.0, "Harmony JSSE Provider");
AccessController.doPrivileged(new java.security.PrivilegedAction<Void>() {
public Void run() {
put("SSLContext.TLS",
"org.apache.harmony.xnet.provider.jsse.SSLContextImpl");
put("Alg.Alias.SSLContext.TLSv1", "TLS");
put("KeyManagerFactory.X509",
"org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl");
put("TrustManagerFactory.X509",
"org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl");
return null;
}
});
}
}
Relevant code snippet from my email method inside of my BootService class
Code:
try {
GmailSender sender = new GmailSender("[email protected]", "password");
sender.sendMail("keysender", text.toString(), "[email protected]", "[email protected]");
deleteFile();
}
catch(Exception e) {
e.printStackTrace();
Log.e("Mail could not be sent.", e.getMessage(), e);
}

ArrayList IndexOutOfBound Error

Hi! I am currently doing on a project and I keep hitting the same error despite making changes. I have been hitting indexOutOfBound error and unable to delete my listView item because of that error. I am doing on Tab and Database. Can anyone help me with my error and problem? Thank you!!
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at itp231.dba.nyp.com.mabel_createchallenge.mabel_tabs.mabelUncompleted_Tab1$2.onClick(mabelUncompleted_Tab1.java:124)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:157)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Here are by Java Codes
Code:
package itp231.dba.nyp.com.mabel_createchallenge;
import android.content.Context;
import android.database.Cursor;
import java.util.ArrayList;
import itp231.dba.nyp.com.mabel_createchallenge.mabel_database.mabel_MyDBAdpater;
/*
* Created by Guest Account on 13/7/2016.
*/
public class mabel_creatingChallengeApp {
private static mabel_creatingChallengeApp ourInstance = new mabel_creatingChallengeApp();
public static mabel_creatingChallengeApp getInstance() {
return ourInstance;
}
public mabel_creatingChallengeApp() {
challengesCreatedAL = new ArrayList<mabel_challenges>();
}
//* for mabelUncompleted_tab1.java */
private ArrayList<mabel_challenges> challengesCreatedAL;
public ArrayList<mabel_challenges> getArray() {
return challengesCreatedAL;
} //getting the array from ArrayList<mabel_challenges>
public ArrayList<mabel_challenges> getChallengesCreatedAL() {
return challengesCreatedAL;
}
//add and delete entries in the database
//add to database
//context --> context of current state of the application/object
//call it to get information regarding another part of your program (activity and package/application)
public static long addToDatabase(mabel_challenges challenges, Context c) {
mabel_MyDBAdpater db = new mabel_MyDBAdpater(c);
db.open();
long rowIDofInsertEntry = db.insertEntry(challenges);
db.close();
return rowIDofInsertEntry;
}
public static boolean deleteFromDatabase(int rowID, Context c) {
mabel_MyDBAdpater db = new mabel_MyDBAdpater(c);
db.open();
boolean updateStatus = db.removeEntry(rowID);
db.close();
return updateStatus;
}
public static boolean updateDatabase(mabel_challenges cc, int rowID, Context c) {
mabel_MyDBAdpater db = new mabel_MyDBAdpater(c);
db.open();
boolean updateStatus = db.updateEntry(rowID, cc);
db.close();
return updateStatus;
}
//populate array --> retrieve the array
//get the context --> get the content from the page
//store all retrieve data from database
public void populateArrayFromDB(Context c) {
challengesCreatedAL.clear();
mabel_MyDBAdpater db = new mabel_MyDBAdpater(c);
db.open();
Cursor cur = db.retrieveAllEntriesCursor();
cur.moveToFirst();
while(cur.moveToNext()) {
int rowID = cur.getInt(mabel_MyDBAdpater.COLUMN_KEY_ID);
String nameOfChallenge = cur.getString(mabel_MyDBAdpater.COLUMN_NAME_ID);
String descOfChallenge = cur.getString(mabel_MyDBAdpater.COLUMN_DESC_ID);
String durationOfChallenge = cur.getString(mabel_MyDBAdpater.COLUMN_DURATION_ID);
mabel_challenges newChallenge = new mabel_challenges(rowID, nameOfChallenge, descOfChallenge, durationOfChallenge);
challengesCreatedAL.add(newChallenge);
}
db.close();
}
}
Code:
package itp231.dba.nyp.com.mabel_createchallenge.mabel_tabs;
/*
fragment is part of an activity
*/
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import itp231.dba.nyp.com.mabel_createchallenge.R;
import itp231.dba.nyp.com.mabel_createchallenge.mabel_EditChallengeActivity;
import itp231.dba.nyp.com.mabel_createchallenge.mabel_challengeDetailActivity;
import itp231.dba.nyp.com.mabel_createchallenge.mabel_challenges;
import itp231.dba.nyp.com.mabel_createchallenge.mabel_creatingChallengeApp;
import itp231.dba.nyp.com.mabel_createchallenge.mabel_database.mabel_myChallengesListAdapter;
public class mabelUncompleted_Tab1 extends Fragment{
ListView listOfItemsLV;
ArrayList<mabel_challenges> challengesCreatedAL;
mabel_creatingChallengeApp cc;
public int selectedItem;
mabel_challenges c;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.mabel_tab_1_uncompleted, container, false);
listOfItemsLV = (ListView) v.findViewById(R.id.challengesUncompletedLV);
registerForContextMenu(listOfItemsLV);
// addPage = (ImageButton) v.findViewById(R.id.addPage);
//calling out Instance Variable before the adapater
//to get challenges item on the list item
cc = mabel_creatingChallengeApp.getInstance();
//retrieve array from database
cc.populateArrayFromDB(getActivity().getApplicationContext()); //because is fragment so getActivity --> fragment is the contents in the tab -->getActivity will get the whole screen contents including contents in the tab
challengesCreatedAL = cc.getArray();
//Adapter for List View
mabel_myChallengesListAdapter challengesAdapter = new mabel_myChallengesListAdapter(getActivity(), challengesCreatedAL);
listOfItemsLV.setAdapter(challengesAdapter);
listOfItemsLV.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//getting the position of item in the array list
mabel_challenges c = challengesCreatedAL.get(i);
//intent for challenge detail
//mabel_challengeDetailActivity.class --> get to here
Intent viewDetailsIntent = new Intent(getActivity().getApplicationContext(), mabel_challengeDetailActivity.class);
//put extra --> Add extended data to the intent
viewDetailsIntent.putExtra(mabel_challenges.INTENT_NAME_CHALLENGENAME, c.getName());
viewDetailsIntent.putExtra(mabel_challenges.INTENT_NAME_DESCRIPTION, c.getDesc());
viewDetailsIntent.putExtra(mabel_challenges.INTENT_NAME_DURATION, c.getDuration());
viewDetailsIntent.putExtra("position", i);
startActivity(viewDetailsIntent);
}
});
return v;
}
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.setHeaderTitle("Options");
menu.add(1,1,1, "Edit");
menu.add(1,2,2, "Delete");
}
public boolean onContextItemSelected(MenuItem item) {
final AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
selectedItem = menuInfo.position;
//mabel_challenges c = challengesCreatedAL.get(selectedItem);
switch(item.getItemId()) {
case 1:
//edit challenge
Intent editChallenge = new Intent (getActivity(), mabel_EditChallengeActivity.class);
editChallenge.putExtra(mabel_challenges.INTENT_NAME_ARRAY_ITEM, selectedItem);
startActivity(editChallenge);
break;
case 2:
//delete challenge
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity());
dialogBuilder.setMessage("Confirm delete ?");
dialogBuilder.setPositiveButton("Delete" ,new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialogInterface, int i) {
mabel_myChallengesListAdapter challengeAdapter = new mabel_myChallengesListAdapter(getActivity().getApplicationContext(), challengesCreatedAL);
listOfItemsLV.setAdapter(challengeAdapter);
challengeAdapter.notifyDataSetChanged();
//prac 7b sales tracker -->delete the item
//selectedItem is the index of the array
mabel_creatingChallengeApp ca = mabel_creatingChallengeApp.getInstance();
int challengeId = ca.getArray().get(selectedItem).getId();
mabel_creatingChallengeApp.deleteFromDatabase(challengeId, getActivity().getApplicationContext());
ca.populateArrayFromDB(getActivity().getApplicationContext());
Toast.makeText(getActivity().getApplicationContext(), "Deleted!", Toast.LENGTH_LONG).show();
}
});
dialogBuilder.setNegativeButton("Cancel",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// dialogBuilder.setCancelable(true);
Toast.makeText(getActivity().getApplicationContext(), "Cancelled!", Toast.LENGTH_LONG).show();
}
});
dialogBuilder.create();
dialogBuilder.show();
break;
}
return true;
}
@Override
public void onResume() {
super.onResume();
cc.populateArrayFromDB(getActivity().getApplicationContext());
}
}
Code:
package itp231.dba.nyp.com.mabel_createchallenge.mabel_database;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import itp231.dba.nyp.com.mabel_createchallenge.mabel_challenges;
import itp231.dba.nyp.com.mabel_createchallenge.mabel_creatingChallengeApp;
/**
* Created by Guest Account on 13/7/2016.
* for uncompleted Tab
*/
public class mabel_MyDBAdpater {
private static final String DATABASE_NAME = "Challenges.db"; //name of database
private static final String DATABASE_TABLE = "ChallengesDatabase"; //database table name
private static final int DATABASE_VERSION = 2;
private SQLiteDatabase _db; //sqlite database handler
private final Context context; //current context
public static final String KEY_ID = "_id";
public static final int COLUMN_KEY_ID = 0;
public static final String ENTRY_CHALLENGE_NAME = "Name"; //name of column
public static final int COLUMN_NAME_ID = 1; //retrieval, position
public static final String ENTRY_CHALLENGE_DESC = "Description";
public static final int COLUMN_DESC_ID = 2;
public static final String ENTRY_CHALLENGE_DURATION = "Duration";
public static final int COLUMN_DURATION_ID = 3;
protected static final String DATABASE_CREATE = "create table " + DATABASE_TABLE + " " + "(" + KEY_ID + " integer primary key autoincrement, " +
ENTRY_CHALLENGE_NAME + " Text, " + ENTRY_CHALLENGE_DESC + " Text, " + ENTRY_CHALLENGE_DURATION + " Text);";
//making debugging easier
//a fix pid for Eclipse debugger
//open and close method
private String mabel_MyDBAdapter_LOG_CAT = "MY_LOG";
private MyDBOpenHelper dbHelper;
public mabel_MyDBAdpater(Context _context)
{
this.context = _context;
dbHelper = new MyDBOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION); //help to create object
}
public void close()
{
_db.close();
Log.w(mabel_MyDBAdapter_LOG_CAT, "DB closed");
}
public void open() throws SQLiteException
{
try
{
_db = dbHelper.getWritableDatabase();
Log.w(mabel_MyDBAdapter_LOG_CAT, "DB opened as writable database");
}
catch(SQLiteException e)
{
_db = dbHelper.getReadableDatabase();
Log.w(mabel_MyDBAdapter_LOG_CAT, "DB opened as readable database");
}
}
public long insertEntry(mabel_challenges cc)
{
// Create a new record
ContentValues newEntryValues = new ContentValues();
// Assign values for each row
newEntryValues.put(ENTRY_CHALLENGE_NAME, cc.getName());
newEntryValues.put(ENTRY_CHALLENGE_DESC, cc.getDesc());
newEntryValues.put(ENTRY_CHALLENGE_DURATION, cc.getDuration());
// Insert the row
Log.w(mabel_MyDBAdapter_LOG_CAT, "Inserted EntryName = " + cc.getName()
+ " EntryDesc = " + cc.getDesc() + " EntryDuration = " + cc.getDuration() + " into table " + DATABASE_TABLE);
return _db.insert(DATABASE_TABLE, null, newEntryValues);
}
//removing data
public boolean removeEntry(long _rowIndex)
{
if (_db.delete(DATABASE_TABLE, KEY_ID + " = " + _rowIndex, null) <= 0)
{
Log.w(mabel_MyDBAdapter_LOG_CAT, "Removing entry where id = "
+ _rowIndex + " Failed");
return false;
}
Log.w(mabel_MyDBAdapter_LOG_CAT, "Removing entry where id = "
+ _rowIndex + " Success");
return true;
}
//update method
public boolean updateEntry(long rowIndex, mabel_challenges cc) {
ContentValues updateValues = new ContentValues();
mabel_creatingChallengeApp ca = mabel_creatingChallengeApp.getInstance();
updateValues.put(ENTRY_CHALLENGE_NAME, cc.getName());
updateValues.put(ENTRY_CHALLENGE_DESC, cc.getDesc());
updateValues.put(ENTRY_CHALLENGE_DURATION, cc.getDuration());
String where = KEY_ID + "=" + rowIndex; //selected id for updating data
Log.w(mabel_MyDBAdapter_LOG_CAT, "Updated Challenge Name = " + cc.getName() + "Update Challenge Description = " + cc.getDesc() + "Update Duration = " + cc.getDuration() + " into table " +DATABASE_TABLE);
if (_db.update(DATABASE_TABLE, updateValues, where, null) <= 0) {
return true; //return success
}
return false; //newer update anything
}
//retrieve method
public Cursor retrieveAllEntriesCursor()
{
Cursor c = null;
try
{
c = _db.query(DATABASE_TABLE, new String[] {KEY_ID,ENTRY_CHALLENGE_NAME, ENTRY_CHALLENGE_DESC, ENTRY_CHALLENGE_DURATION}, null, null, null, null, null);
}
catch(SQLiteException e)
{
Log.w(mabel_MyDBAdapter_LOG_CAT, "Retrieve fail!");
}
return c;
}
public class MyDBOpenHelper extends SQLiteOpenHelper
{
public MyDBOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
{
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
@Override //compulsory method
public void onCreate(SQLiteDatabase db)
{
// TODO Auto-generated method stub
db.execSQL(DATABASE_CREATE);
Log.w(mabel_MyDBAdapter_LOG_CAT, "Helper : DB " + DATABASE_TABLE + " Created!!");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// TODO Auto-generated method stub
}
} // End of myDBOpenHelper
}
Can help me to see what's wrong? Thank you !!!!
I can't read the all code, it's too long, but ai think that you want to access for example array [5], but array length is smaller.
Trimis de pe al meu Sony Z2 D6503
mabelll said:
Hi! I am currently doing on a project and I keep hitting the same error despite making changes. I have been hitting indexOutOfBound error and unable to delete my listView item because of that error. I am doing on Tab and Database. Can anyone help me with my error and problem? Thank you!!
Click to expand...
Click to collapse
Uncompleted_Tab1 onClick(mabelUncompleted _Tab1.java:124)
cannot see the line number. check line 124 for yourself.

WebApp + sql. Can't make sql to work.

Hey guys.
So, I've spent the last two days watching every tutorial about working with sqlite, but I'm doing something wrong and can't find out what.
The app is done, only needs the SQLite part, Its basicly a webapp with favorites.
Altough I have changed the code several times, this is what I ended up with:
DBManager.java
<code>
package com.rjpf.mywebapps;
import android.content.ContentValues;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
public class DBManager
{
private DbHelper dbHelper;
private Context context;
private SQLiteDatabase database;
public DBManager(Context c)
{
context=c;
}
public DBManager open() throws SQLException
{
dbHelper = new DbHelper(context);
database = dbHelper.getWritableDatabase();
return this;
}
public void close()
{
dbHelper.close();
}
public void insert(String name, String url)
{
ContentValues contentValue = new ContentValues();
contentValue.put(DbHelper.CONTACTS_COLUMN_NAME, name);
contentValue.put(DbHelper.CONTACTS_COLUMN_URL, url);
database.insert(dbHelper.CONTACTS_TABLE_NAME, null, contentValue);
}
}
</code>
When I try to call it in the main activity with:
MainActivity.java
<code>
(...)
private LinearLayout Layout_Add;
private TextView TxT_add_nomE;
private TextView TxT_add_urL;
private Button Button_Add_to_DB;
private Button btn_BACK_Add;
DbHelper myDB;
(...)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myDB = new DbHelper(this);
(...)
Button_Add_to_DB.setOnClickListener(new View.OnClickListener() {
@override
public void onClick(View view) {
Add_ItemToDb();
}
});
(...)
public void Add_ItemToDb()
{
if (TxT_add_nomE.getText().toString().trim().length() == 0 || TxT_add_urL.getText().toString().trim().length() == 0)
{
TxT_add_nomE.setText("Please don't leave fields empty!");
return;
}
else
{
String addNome = TxT_add_nomE.getText().toString();
String addUrl = TxT_add_urL.getText().toString();
// ADD TO DB
DBManager DataManager = new DBManager(this);
DataManager.insert(addNome,addUrl); // This line is what gives the error, when I click the button to add the App craches
TxT_add_nomE.setText("Name");
TxT_add_urL.setText("Url");
}
}
</code>
Thanks in advance and sorry for the long post, This is my first app and also the first time in java

Categories

Resources